diff --git a/.buildkite/pipelines/security_solution/api_integration.yml b/.buildkite/pipelines/security_solution/api_integration.yml index 8e36fbfa2ae4..5b3394c05ffc 100644 --- a/.buildkite/pipelines/security_solution/api_integration.yml +++ b/.buildkite/pipelines/security_solution/api_integration.yml @@ -1,319 +1,323 @@ steps: - - label: Running exception_workflows:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_workflows:qa:serverless - key: exception_workflows:qa:serverless + - command: .buildkite/scripts/pipelines/security_solution_quality_gate/create_periodic_test_docker_image.sh + label: Build kibana image + key: build_image agents: - queue: n2-4-spot - timeout_in_minutes: 120 + queue: n2-16-spot + timeout_in_minutes: 60 retry: automatic: - - exit_status: '*' - limit: 2 + - exit_status: "-1" + limit: 3 - - label: Running exception_operators_date_numeric_types:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_date_numeric_types:qa:serverless - key: exception_operators_date_numeric_types:qa:serverless + - command: .buildkite/scripts/pipelines/security_solution_quality_gate/upload_image_metadata.sh + label: "Upload runtime info" + key: upload_runtime_info + depends_on: build_image agents: queue: n2-4-spot - timeout_in_minutes: 120 + timeout_in_minutes: 300 retry: automatic: - - exit_status: '*' + - exit_status: "-1" limit: 2 - - label: Running exception_operators_keyword:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_keyword:qa:serverless - key: exception_operators_keyword:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '*' - limit: 2 + - group: "Execute Tests" + depends_on: build_image + steps: + - label: Running exception_workflows:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh exception_workflows:qa:serverless + key: exception_workflows:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "*" + limit: 2 - - label: Running exception_operators_ips:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_ips:qa:serverless - key: exception_operators_ips:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '*' - limit: 2 + - label: Running exception_operators_date_numeric_types:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh exception_operators_date_numeric_types:qa:serverless + key: exception_operators_date_numeric_types:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "*" + limit: 2 - - label: Running exception_operators_long:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_long:qa:serverless - key: exception_operators_long:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running exception_operators_keyword:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh exception_operators_keyword:qa:serverless + key: exception_operators_keyword:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "*" + limit: 2 - - label: Running exception_operators_text:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_operators_text:qa:serverless - key: exception_operators_text:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running exception_operators_ips:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh exception_operators_ips:qa:serverless + key: exception_operators_ips:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "*" + limit: 2 - - label: Running rule_creation:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_creation:qa:serverless - key: rule_creation:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running exception_operators_long:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh exception_operators_long:qa:serverless + key: exception_operators_long:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running rule_creation:essentials:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_creation:essentials:qa:serverless - key: rule_creation:essentials:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running exception_operators_text:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh exception_operators_text:qa:serverless + key: exception_operators_text:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running alerts:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh alerts:qa:serverless - key: alerts:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running rule_creation:essentials:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh rule_creation:essentials:qa:serverless + key: rule_creation:essentials:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 - - label: Running alerts:essentials:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh alerts:essentials:qa:serverless - key: alerts:essentials:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running alerts:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh alerts:qa:serverless + key: alerts:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 - - label: Running actions:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh actions:qa:serverless - key: actions:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running alerts:essentials:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh alerts:essentials:qa:serverless + key: alerts:essentials:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 - - label: Running entity_analytics:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh entity_analytics:qa:serverless - key: entity_analytics:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running actions:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh actions:qa:serverless + key: actions:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 - - label: Running prebuilt_rules_management:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh prebuilt_rules_management:qa:serverless - key: prebuilt_rules_management:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running entity_analytics:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh entity_analytics:qa:serverless + key: entity_analytics:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running prebuilt_rules_bundled_prebuilt_rules_package:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh prebuilt_rules_bundled_prebuilt_rules_package:qa:serverless - key: prebuilt_rules_bundled_prebuilt_rules_package:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running prebuilt_rules_management:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh prebuilt_rules_management:qa:serverless + key: prebuilt_rules_management:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running prebuilt_rules_large_prebuilt_rules_package:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh prebuilt_rules_large_prebuilt_rules_package:qa:serverless - key: prebuilt_rules_large_prebuilt_rules_package:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running prebuilt_rules_bundled_prebuilt_rules_package:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh prebuilt_rules_bundled_prebuilt_rules_package:qa:serverless + key: prebuilt_rules_bundled_prebuilt_rules_package:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running prebuilt_rules_update_prebuilt_rules_package:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh prebuilt_rules_update_prebuilt_rules_package:qa:serverless - key: prebuilt_rules_update_prebuilt_rules_package:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running prebuilt_rules_large_prebuilt_rules_package:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh prebuilt_rules_large_prebuilt_rules_package:qa:serverless + key: prebuilt_rules_large_prebuilt_rules_package:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running rule_execution_logic:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_execution_logic:qa:serverless - key: rule_execution_logic:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running prebuilt_rules_update_prebuilt_rules_package:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh prebuilt_rules_update_prebuilt_rules_package:qa:serverless + key: prebuilt_rules_update_prebuilt_rules_package:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running user_roles:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh user_roles:qa:serverless - key: user_roles:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running rule_execution_logic:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh rule_execution_logic:qa:serverless + key: rule_execution_logic:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running telemetry:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh telemetry:qa:serverless - key: telemetry:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running user_roles:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh user_roles:qa:serverless + key: user_roles:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running rule_delete:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_delete:qa:serverless - key: rule_delete:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running telemetry:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh telemetry:qa:serverless + key: telemetry:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running rule_update:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_update:qa:serverless - key: rule_update:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running rule_delete:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh rule_delete:qa:serverless + key: rule_delete:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running rule_patch:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_patch:qa:serverless - key: rule_patch:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running rule_update:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh rule_update:qa:serverless + key: rule_update:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running rule_import_export:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_import_export:qa:serverless - key: rule_import_export:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running rule_patch:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh rule_patch:qa:serverless + key: rule_patch:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running rule_management:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_management:qa:serverless - key: rule_management:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running rule_import_export:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh rule_import_export:qa:serverless + key: rule_import_export:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running rule_bulk_actions:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_bulk_actions:qa:serverless - key: rule_bulk_actions:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running rule_management:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh rule_management:qa:serverless + key: rule_management:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: "1" + limit: 2 - - label: Running rule_read:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rule_read:qa:serverless - key: rule_read:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running rule_read:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh rule_read:qa:serverless + key: rule_read:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 - - label: Running rules_management:essentials:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rules_management:essentials:qa:serverless - key: rules_management:essentials:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running rules_management:essentials:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh rules_management:essentials:qa:serverless + key: rules_management:essentials:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 - - label: Running exception_lists_items:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh exception_lists_items:qa:serverless - key: exception_lists_items:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running exception_lists_items:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh exception_lists_items:qa:serverless + key: exception_lists_items:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 - - label: Running lists_items:qa:serverless - command: .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh lists_items:qa:serverless - key: lists_items:qa:serverless - agents: - queue: n2-4-spot - timeout_in_minutes: 120 - retry: - automatic: - - exit_status: '1' - limit: 2 + - label: Running lists_items:qa:serverless + command: .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh lists_items:qa:serverless + key: lists_items:qa:serverless + agents: + queue: n2-4-spot + timeout_in_minutes: 120 + retry: + automatic: + - exit_status: '1' + limit: 2 diff --git a/.buildkite/pipelines/security_solution/security_solution_cypress.yml b/.buildkite/pipelines/security_solution/security_solution_cypress.yml index f6fce93c5661..997e607ebb43 100644 --- a/.buildkite/pipelines/security_solution/security_solution_cypress.yml +++ b/.buildkite/pipelines/security_solution/security_solution_cypress.yml @@ -1,96 +1,122 @@ steps: - - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:explore - label: 'Serverless MKI QA Explore - Security Solution Cypress Tests' + - command: .buildkite/scripts/pipelines/security_solution_quality_gate/create_periodic_test_docker_image.sh + label: Build kibana image + key: build_image agents: - queue: n2-4-spot - # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. - timeout_in_minutes: 300 - parallelism: 4 + queue: n2-16-spot + timeout_in_minutes: 60 retry: automatic: - - exit_status: '*' - limit: 1 + - exit_status: "-1" + limit: 3 - - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:investigations - label: 'Serverless MKI QA Investigations - Security Solution Cypress Tests' + - command: .buildkite/scripts/pipelines/security_solution_quality_gate/upload_image_metadata.sh + label: "Upload runtime info" + key: upload_runtime_info + depends_on: build_image agents: queue: n2-4-spot - # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. timeout_in_minutes: 300 - parallelism: 8 retry: automatic: - - exit_status: '*' + - exit_status: "*" limit: 1 - - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:rule_management - label: 'Serverless MKI QA Rule Management - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. - timeout_in_minutes: 300 - parallelism: 8 - retry: - automatic: - - exit_status: '*' - limit: 1 + - group: "Execute Tests" + depends_on: build_image + steps: + # - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:explore + # label: 'Serverless MKI QA Explore - Security Solution Cypress Tests' + # agents: + # queue: n2-4-spot + # # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. + # timeout_in_minutes: 300 + # parallelism: 4 + # retry: + # automatic: + # - exit_status: '*' + # limit: 1 - - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:rule_management:prebuilt_rules - label: 'Serverless MKI QA Rule Management - Prebuilt Rules - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. - timeout_in_minutes: 300 - parallelism: 2 - retry: - automatic: - - exit_status: '*' - limit: 1 + # - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:investigations + # label: 'Serverless MKI QA Investigations - Security Solution Cypress Tests' + # agents: + # queue: n2-4-spot + # # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. + # timeout_in_minutes: 300 + # parallelism: 8 + # retry: + # automatic: + # - exit_status: '*' + # limit: 1 - - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:detection_engine - label: 'Serverless MKI QA Detection Engine - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. - timeout_in_minutes: 300 - parallelism: 8 - retry: - automatic: - - exit_status: '*' - limit: 1 + # - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:rule_management + # label: 'Serverless MKI QA Rule Management - Security Solution Cypress Tests' + # agents: + # queue: n2-4-spot + # # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. + # timeout_in_minutes: 300 + # parallelism: 8 + # retry: + # automatic: + # - exit_status: '*' + # limit: 1 - - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:detection_engine:exceptions - label: 'Serverless MKI QA Detection Engine - Exceptions - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. - timeout_in_minutes: 300 - parallelism: 6 - retry: - automatic: - - exit_status: '*' - limit: 1 + # - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:rule_management:prebuilt_rules + # label: 'Serverless MKI QA Rule Management - Prebuilt Rules - Security Solution Cypress Tests' + # agents: + # queue: n2-4-spot + # # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. + # timeout_in_minutes: 300 + # parallelism: 2 + # retry: + # automatic: + # - exit_status: '*' + # limit: 1 - - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:ai_assistant - label: 'Serverless MKI QA AI Assistant - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. - timeout_in_minutes: 300 - parallelism: 1 - retry: - automatic: - - exit_status: '*' - limit: 1 + # - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:detection_engine + # label: 'Serverless MKI QA Detection Engine - Security Solution Cypress Tests' + # agents: + # queue: n2-4-spot + # # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. + # timeout_in_minutes: 300 + # parallelism: 8 + # retry: + # automatic: + # - exit_status: '*' + # limit: 1 - - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:entity_analytics - label: 'Serverless MKI QA Entity Analytics - Security Solution Cypress Tests' - agents: - queue: n2-4-spot - # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. - timeout_in_minutes: 300 - parallelism: 2 - retry: - automatic: - - exit_status: '*' - limit: 1 \ No newline at end of file + # - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:detection_engine:exceptions + # label: 'Serverless MKI QA Detection Engine - Exceptions - Security Solution Cypress Tests' + # agents: + # queue: n2-4-spot + # # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. + # timeout_in_minutes: 300 + # parallelism: 6 + # retry: + # automatic: + # - exit_status: '*' + # limit: 1 + + - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:ai_assistant + label: 'Serverless MKI QA AI Assistant - Security Solution Cypress Tests' + agents: + queue: n2-4-spot + # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. + timeout_in_minutes: 300 + parallelism: 1 + retry: + automatic: + - exit_status: '*' + limit: 1 + + # - command: .buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh cypress:run:qa:serverless:entity_analytics + # label: 'Serverless MKI QA Entity Analytics - Security Solution Cypress Tests' + # agents: + # queue: n2-4-spot + # # TODO : Revise the timeout when the pipeline will be officially integrated with the quality gate. + # timeout_in_minutes: 300 + # parallelism: 2 + # retry: + # automatic: + # - exit_status: '*' + # limit: 1 \ No newline at end of file diff --git a/.buildkite/scripts/common/activate_service_account.sh b/.buildkite/scripts/common/activate_service_account.sh new file mode 100755 index 000000000000..e5cd116a7bce --- /dev/null +++ b/.buildkite/scripts/common/activate_service_account.sh @@ -0,0 +1,85 @@ +#!/usr/bin/env bash + +set -euo pipefail + +source "$(dirname "${BASH_SOURCE[0]}")/vault_fns.sh" + +BUCKET_OR_EMAIL="${1:-}" +GCLOUD_EMAIL_POSTFIX="elastic-kibana-ci.iam.gserviceaccount.com" +GCLOUD_SA_PROXY_EMAIL="kibana-ci-sa-proxy@$GCLOUD_EMAIL_POSTFIX" + +if [[ -z "$BUCKET_OR_EMAIL" ]]; then + echo "Usage: $0 " + exit 1 +elif [[ "$BUCKET_OR_EMAIL" == "--unset-impersonation" ]]; then + echo "Unsetting impersonation" + gcloud config unset auth/impersonate_service_account + exit 0 +elif [[ "$BUCKET_OR_EMAIL" == "--logout-gcloud" ]]; then + echo "Logging out of gcloud" + if [[ -x "$(command -v gcloud)" ]] && [[ "$(gcloud auth list 2>/dev/null | grep $GCLOUD_SA_PROXY_EMAIL)" != "" ]]; then + gcloud auth revoke $GCLOUD_SA_PROXY_EMAIL --no-user-output-enabled + fi + exit 0 +fi + +CURRENT_GCLOUD_USER=$(gcloud auth list --filter="status=ACTIVE" --format="value(account)") + +# Verify that the service account proxy is activated +if [[ "$CURRENT_GCLOUD_USER" != "$GCLOUD_SA_PROXY_EMAIL" ]]; then + if [[ -x "$(command -v gcloud)" ]]; then + if [[ -z "${KIBANA_SERVICE_ACCOUNT_PROXY_KEY:-}" ]]; then + echo "KIBANA_SERVICE_ACCOUNT_PROXY_KEY is not set, cannot activate service account $GCLOUD_SA_PROXY_EMAIL." + exit 1 + fi + + AUTH_RESULT=$(gcloud auth activate-service-account --key-file="$KIBANA_SERVICE_ACCOUNT_PROXY_KEY" || "FAILURE") + if [[ "$AUTH_RESULT" == "FAILURE" ]]; then + echo "Failed to activate service account $GCLOUD_SA_PROXY_EMAIL." + exit 1 + else + echo "Activated service account $GCLOUD_SA_PROXY_EMAIL" + fi + else + echo "gcloud is not installed, cannot activate service account $GCLOUD_SA_PROXY_EMAIL." + exit 1 + fi +fi + +# Check if the arg is a service account e-mail or a bucket name +EMAIL="" +if [[ "$BUCKET_OR_EMAIL" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then + EMAIL="$BUCKET_OR_EMAIL" +elif [[ "$BUCKET_OR_EMAIL" =~ ^gs://* ]]; then + BUCKET_NAME="${BUCKET_OR_EMAIL:5}" +else + BUCKET_NAME="$BUCKET_OR_EMAIL" +fi + +if [[ -z "$EMAIL" ]]; then + case "$BUCKET_NAME" in + "elastic-kibana-coverage-live") + EMAIL="kibana-ci-access-coverage@$GCLOUD_EMAIL_POSTFIX" + ;; + "kibana-ci-es-snapshots-daily") + EMAIL="kibana-ci-access-es-snapshots@$GCLOUD_EMAIL_POSTFIX" + ;; + "kibana-so-types-snapshots") + EMAIL="kibana-ci-access-so-snapshots@$GCLOUD_EMAIL_POSTFIX" + ;; + "kibana-performance") + EMAIL="kibana-ci-access-perf-stats@$GCLOUD_EMAIL_POSTFIX" + ;; + "ci-artifacts.kibana.dev") + EMAIL="kibana-ci-access-artifacts@$GCLOUD_EMAIL_POSTFIX" + ;; + *) + EMAIL="$BUCKET_NAME@$GCLOUD_EMAIL_POSTFIX" + ;; + esac +fi + +# Activate the service account +echo "Impersonating $EMAIL" +gcloud config set auth/impersonate_service_account "$EMAIL" +echo "Activated service account $EMAIL" diff --git a/.buildkite/scripts/common/setup_bazel.sh b/.buildkite/scripts/common/setup_bazel.sh index ea3c2453de6d..5461f713e0af 100755 --- a/.buildkite/scripts/common/setup_bazel.sh +++ b/.buildkite/scripts/common/setup_bazel.sh @@ -2,6 +2,8 @@ source .buildkite/scripts/common/util.sh +echo '--- Setting up bazel' + echo "[bazel] writing .bazelrc" cat < $KIBANA_DIR/.bazelrc # Generated by .buildkite/scripts/common/setup_bazel.sh @@ -27,16 +29,16 @@ if [[ "$BAZEL_CACHE_MODE" == "gcs" ]]; then echo "[bazel] using GCS bucket: $BAZEL_BUCKET" -cat <> $KIBANA_DIR/.bazelrc + cat <> $KIBANA_DIR/.bazelrc build --remote_cache=https://storage.googleapis.com/$BAZEL_BUCKET - build --google_default_credentials + build --google_credentials=$BAZEL_REMOTE_CACHE_CREDENTIALS_FILE EOF fi if [[ "$BAZEL_CACHE_MODE" == "populate-local-gcs" ]]; then echo "[bazel] enabling caching with GCS buckets for local dev" -cat <> $KIBANA_DIR/.bazelrc + cat <> $KIBANA_DIR/.bazelrc build --remote_cache=https://storage.googleapis.com/kibana-local-bazel-remote-cache build --google_credentials=$BAZEL_LOCAL_DEV_CACHE_CREDENTIALS_FILE EOF diff --git a/.buildkite/scripts/common/util.sh b/.buildkite/scripts/common/util.sh index f80c89678c22..818d712fd2aa 100755 --- a/.buildkite/scripts/common/util.sh +++ b/.buildkite/scripts/common/util.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +source "$(dirname "${BASH_SOURCE[0]}")/vault_fns.sh" + is_pr() { [[ "${GITHUB_PR_NUMBER-}" ]] && return false @@ -170,48 +172,3 @@ npm_install_global() { download_artifact() { retry 3 1 timeout 3m buildkite-agent artifact download "$@" } - -# TODO: remove after https://github.com/elastic/kibana-operations/issues/15 is done -if [[ "${VAULT_ADDR:-}" == *"secrets.elastic.co"* ]]; then - VAULT_PATH_PREFIX="secret/kibana-issues/dev" - VAULT_KV_PREFIX="secret/kibana-issues/dev" - IS_LEGACY_VAULT_ADDR=true -else - VAULT_PATH_PREFIX="secret/ci/elastic-kibana" - VAULT_KV_PREFIX="kv/ci-shared/kibana-deployments" - IS_LEGACY_VAULT_ADDR=false -fi -export IS_LEGACY_VAULT_ADDR - -vault_get() { - key_path=$1 - field=$2 - - fullPath="$VAULT_PATH_PREFIX/$key_path" - - if [[ -z "${2:-}" || "${2:-}" =~ ^-.* ]]; then - retry 5 5 vault read "$fullPath" "${@:2}" - else - retry 5 5 vault read -field="$field" "$fullPath" "${@:3}" - fi -} - -vault_set() { - key_path=$1 - shift - fields=("$@") - - - fullPath="$VAULT_PATH_PREFIX/$key_path" - - # shellcheck disable=SC2068 - retry 5 5 vault write "$fullPath" ${fields[@]} -} - -vault_kv_set() { - kv_path=$1 - shift - fields=("$@") - - vault kv put "$VAULT_KV_PREFIX/$kv_path" "${fields[@]}" -} diff --git a/.buildkite/scripts/common/vault_fns.sh b/.buildkite/scripts/common/vault_fns.sh new file mode 100644 index 000000000000..a7b92a4b05d6 --- /dev/null +++ b/.buildkite/scripts/common/vault_fns.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# TODO: remove after https://github.com/elastic/kibana-operations/issues/15 is done +if [[ "${VAULT_ADDR:-}" == *"secrets.elastic.co"* ]]; then + VAULT_PATH_PREFIX="secret/kibana-issues/dev" + VAULT_KV_PREFIX="secret/kibana-issues/dev" + IS_LEGACY_VAULT_ADDR=true +else + VAULT_PATH_PREFIX="secret/ci/elastic-kibana" + VAULT_KV_PREFIX="kv/ci-shared/kibana-deployments" + IS_LEGACY_VAULT_ADDR=false +fi +export IS_LEGACY_VAULT_ADDR + +retry() { + local retries=$1; shift + local delay=$1; shift + local attempts=1 + + until "$@"; do + retry_exit_status=$? + echo "Exited with $retry_exit_status" >&2 + if (( retries == "0" )); then + return $retry_exit_status + elif (( attempts == retries )); then + echo "Failed $attempts retries" >&2 + return $retry_exit_status + else + echo "Retrying $((retries - attempts)) more times..." >&2 + attempts=$((attempts + 1)) + sleep "$delay" + fi + done +} + +vault_get() { + key_path=${1:-} + field=${2:-} + + fullPath="$VAULT_PATH_PREFIX/$key_path" + + if [[ -z "$field" || "$field" =~ ^-.* ]]; then + retry 5 5 vault read "$fullPath" "${@:2}" + else + retry 5 5 vault read -field="$field" "$fullPath" "${@:3}" + fi +} + +vault_set() { + key_path=$1 + shift + fields=("$@") + + + fullPath="$VAULT_PATH_PREFIX/$key_path" + + # shellcheck disable=SC2068 + retry 5 5 vault write "$fullPath" ${fields[@]} +} + +vault_kv_set() { + kv_path=$1 + shift + fields=("$@") + + vault kv put "$VAULT_KV_PREFIX/$kv_path" "${fields[@]}" +} diff --git a/.buildkite/scripts/lifecycle/post_command.sh b/.buildkite/scripts/lifecycle/post_command.sh index 620041151e58..479608ca3325 100755 --- a/.buildkite/scripts/lifecycle/post_command.sh +++ b/.buildkite/scripts/lifecycle/post_command.sh @@ -2,6 +2,10 @@ set -euo pipefail +echo '--- Log out of gcloud' +./.buildkite/scripts/common/activate_service_account.sh --unset-impersonation || echo "Failed to unset impersonation" +./.buildkite/scripts/common/activate_service_account.sh --logout-gcloud || echo "Failed to log out of gcloud" + echo '--- Agent Debug Info' ts-node .buildkite/scripts/lifecycle/print_agent_links.ts || true diff --git a/.buildkite/scripts/lifecycle/pre_command.sh b/.buildkite/scripts/lifecycle/pre_command.sh index c14cb2c578a8..966ba22c1272 100755 --- a/.buildkite/scripts/lifecycle/pre_command.sh +++ b/.buildkite/scripts/lifecycle/pre_command.sh @@ -167,6 +167,16 @@ BAZEL_LOCAL_DEV_CACHE_CREDENTIALS_FILE="$HOME/.kibana-ci-bazel-remote-cache-loca export BAZEL_LOCAL_DEV_CACHE_CREDENTIALS_FILE vault_get kibana-ci-bazel-remote-cache-local-dev service_account_json > "$BAZEL_LOCAL_DEV_CACHE_CREDENTIALS_FILE" +# Export key for accessing bazel remote cache's GCS bucket +BAZEL_REMOTE_CACHE_CREDENTIALS_FILE="$HOME/.kibana-ci-bazel-remote-cache-gcs.json" +export BAZEL_REMOTE_CACHE_CREDENTIALS_FILE +vault_get kibana-ci-bazel-remote-cache-sa-key key | base64 -d > "$BAZEL_REMOTE_CACHE_CREDENTIALS_FILE" + +# Setup GCS Service Account Proxy for CI +KIBANA_SERVICE_ACCOUNT_PROXY_KEY="$(mktemp -d)/kibana-gcloud-service-account.json" +export KIBANA_SERVICE_ACCOUNT_PROXY_KEY +vault_get kibana-ci-sa-proxy-key key | base64 -d > "$KIBANA_SERVICE_ACCOUNT_PROXY_KEY" + PIPELINE_PRE_COMMAND=${PIPELINE_PRE_COMMAND:-".buildkite/scripts/lifecycle/pipelines/$BUILDKITE_PIPELINE_SLUG/pre_command.sh"} if [[ -f "$PIPELINE_PRE_COMMAND" ]]; then source "$PIPELINE_PRE_COMMAND" diff --git a/.buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh b/.buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh similarity index 67% rename from .buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh rename to .buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh index 1e809b6da6fc..096709dc5da4 100755 --- a/.buildkite/scripts/pipelines/security_solution_quality_gate/api-integration-tests.sh +++ b/.buildkite/scripts/pipelines/security_solution_quality_gate/api_integration/api-integration-tests.sh @@ -15,15 +15,33 @@ cd x-pack/test/security_solution_api_integration set +e QA_API_KEY=$(vault_get security-solution-quality-gate qa_api_key) +QA_CONSOLE_URL=$(vault_get security-solution-quality-gate qa_console_url) # Generate a random 5-digit number random_number=$((10000 + $RANDOM % 90000)) -ENVIRONMENT_DETAILS=$(curl --location 'https://global.qa.cld.elstc.co/api/v1/serverless/projects/security' \ +if [ -z "${KIBANA_MKI_USE_LATEST_COMMIT+x}" ] || [ "$KIBANA_MKI_USE_LATEST_COMMIT" = "0" ]; then + ENVIRONMENT_DETAILS=$(curl --location "$QA_CONSOLE_URL/api/v1/serverless/projects/security" \ --header "Authorization: ApiKey $QA_API_KEY" \ --header 'Content-Type: application/json' \ --data '{ - "name": "ftr-integration-tests-'$random_number'", - "region_id": "aws-eu-west-1"}' | jq '.') + "name": "ftr-integration-tests-'$random_number'", + "region_id": "aws-eu-west-1"}' | jq '.') +else + KBN_COMMIT_HASH=${BUILDKITE_COMMIT:0:12} + ENVIRONMENT_DETAILS=$(curl --location "$QA_CONSOLE_URL/api/v1/serverless/projects/security" \ + --header "Authorization: ApiKey $QA_API_KEY" \ + --header 'Content-Type: application/json' \ + --data '{ + "name": "ftr-integration-tests-'$random_number'", + "region_id": "aws-eu-west-1", + "overrides": { + "kibana": { + "docker_image" : "docker.elastic.co/kibana-ci/kibana-serverless:sec-sol-qg-'$KBN_COMMIT_HASH'" + } + } + }' | jq '.') +fi + NAME=$(echo $ENVIRONMENT_DETAILS | jq -r '.name') ID=$(echo $ENVIRONMENT_DETAILS | jq -r '.id') ES_URL=$(echo $ENVIRONMENT_DETAILS | jq -r '.endpoints.elasticsearch') @@ -33,7 +51,7 @@ KB_URL=$(echo $ENVIRONMENT_DETAILS | jq -r '.endpoints.kibana') sleep 5 # Resetting the credentials of the elastic user in the project -CREDS_BODY=$(curl -s --location --request POST "https://global.qa.cld.elstc.co/api/v1/serverless/projects/security/$ID/_reset-credentials" \ +CREDS_BODY=$(curl -s --location --request POST "$QA_CONSOLE_URL/api/v1/serverless/projects/security/$ID/_reset-credentials" \ --header "Authorization: ApiKey $QA_API_KEY" \ --header 'Content-Type: application/json' | jq '.') USERNAME=$(echo $CREDS_BODY | jq -r '.username') @@ -76,7 +94,7 @@ TEST_CLOUD=1 TEST_ES_URL="https://elastic:$PASSWORD@$FORMATTED_ES_URL:443" TEST_ cmd_status=$? echo "Exit code with status: $cmd_status" -curl --location --request DELETE "https://global.qa.cld.elstc.co/api/v1/serverless/projects/security/$ID" \ +curl --location --request DELETE "$QA_CONSOLE_URL/api/v1/serverless/projects/security/$ID" \ --header "Authorization: ApiKey $QA_API_KEY" exit $cmd_status diff --git a/.buildkite/scripts/pipelines/security_solution_quality_gate/create_periodic_test_docker_image.sh b/.buildkite/scripts/pipelines/security_solution_quality_gate/create_periodic_test_docker_image.sh new file mode 100644 index 000000000000..4e459e23ce25 --- /dev/null +++ b/.buildkite/scripts/pipelines/security_solution_quality_gate/create_periodic_test_docker_image.sh @@ -0,0 +1,83 @@ +#!/bin/bash +if [ -z "${KIBANA_MKI_USE_LATEST_COMMIT+x}" ] || [ "$KIBANA_MKI_USE_LATEST_COMMIT" = "0" ]; then + echo "As we not testing against latest kibana image, this step is exiting with exit code 0" + exit 0 +fi + + +.buildkite/scripts/bootstrap.sh + +source .buildkite/scripts/steps/artifacts/env.sh + +GIT_ABBREV_COMMIT=${BUILDKITE_COMMIT:0:12} +KIBANA_IMAGE_TAG="sec-sol-qg-$GIT_ABBREV_COMMIT" + + +KIBANA_BASE_IMAGE="docker.elastic.co/kibana-ci/kibana-serverless" +export KIBANA_IMAGE="$KIBANA_BASE_IMAGE:$KIBANA_IMAGE_TAG" + +echo "--- Verify manifest does not already exist" +echo "$KIBANA_DOCKER_PASSWORD" | docker login -u "$KIBANA_DOCKER_USERNAME" --password-stdin docker.elastic.co +trap 'docker logout docker.elastic.co' EXIT + +echo "Checking manifest for $KIBANA_IMAGE" +if docker manifest inspect $KIBANA_IMAGE &> /dev/null; then + echo "Manifest already exists, exiting" + exit 0 +fi + +docker pull $KIBANA_BASE_IMAGE:latest + +echo "--- Build images" +node scripts/build \ + --debug \ + --release \ + --docker-cross-compile \ + --docker-images \ + --docker-namespace="kibana-ci" \ + --docker-tag="$KIBANA_IMAGE_TAG" \ + --skip-docker-ubuntu \ + --skip-docker-ubi \ + --skip-docker-cloud \ + --skip-docker-contexts \ + --skip-cdn-assets + +echo "--- Tag images" +docker rmi "$KIBANA_IMAGE" +docker load < "target/kibana-serverless-$BASE_VERSION-docker-image.tar.gz" +docker tag "$KIBANA_IMAGE" "$KIBANA_IMAGE-amd64" + +docker rmi "$KIBANA_IMAGE" +docker load < "target/kibana-serverless-$BASE_VERSION-docker-image-aarch64.tar.gz" +docker tag "$KIBANA_IMAGE" "$KIBANA_IMAGE-arm64" + +echo "--- Push images" +docker image push "$KIBANA_IMAGE-arm64" +docker image push "$KIBANA_IMAGE-amd64" + +echo "--- Create and push manifests" +docker manifest create \ + "$KIBANA_IMAGE" \ + --amend "$KIBANA_IMAGE-arm64" \ + --amend "$KIBANA_IMAGE-amd64" +docker manifest push "$KIBANA_IMAGE" + +if [[ "$BUILDKITE_BRANCH" == "$KIBANA_BASE_BRANCH" ]] && [[ "${BUILDKITE_PULL_REQUEST:-false}" == "false" ]]; then + docker manifest create \ + "$KIBANA_BASE_IMAGE:latest" \ + --amend "$KIBANA_IMAGE-arm64" \ + --amend "$KIBANA_IMAGE-amd64" + docker manifest push "$KIBANA_BASE_IMAGE:latest" +fi + +docker logout docker.elastic.co + +cat << EOF | buildkite-agent annotate --style "info" --context image + ### Serverless Images + + Manifest: \`$KIBANA_IMAGE\` + + AMD64: \`$KIBANA_IMAGE-amd64\` + + ARM64: \`$KIBANA_IMAGE-arm64\` +EOF diff --git a/.buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh b/.buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh index e4b1701f161e..8cce28a1401d 100755 --- a/.buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh +++ b/.buildkite/scripts/pipelines/security_solution_quality_gate/security_solution_cypress/mki_security_solution_cypress.sh @@ -22,7 +22,14 @@ vault_get security-quality-gate/role-users data -format=json > .ftr/role_users.j cd x-pack/test/security_solution_cypress set +e +if [ -z "${KIBANA_MKI_USE_LATEST_COMMIT+x}" ] || [ "$KIBANA_MKI_USE_LATEST_COMMIT" = "0" ]; then + KIBANA_OVERRIDE_FLAG=0 +else + KIBANA_OVERRIDE_FLAG=1 +fi + QA_API_KEY=$(vault_get security-solution-quality-gate qa_api_key) +QA_CONSOLE_URL=$(vault_get security-solution-quality-gate qa_console_url) BK_ANALYTICS_API_KEY=$(vault_get security-solution-quality-gate serverless-sec-sol-cypress-bk-api-key) -BK_ANALYTICS_API_KEY=$BK_ANALYTICS_API_KEY CLOUD_QA_API_KEY=$QA_API_KEY yarn $1; status=$?; yarn junit:merge || :; exit $status \ No newline at end of file +QA_CONSOLE_URL=$QA_CONSOLE_URL KIBANA_MKI_USE_LATEST_COMMIT=$KIBANA_OVERRIDE_FLAG BK_ANALYTICS_API_KEY=$BK_ANALYTICS_API_KEY CLOUD_QA_API_KEY=$QA_API_KEY yarn $1; status=$?; yarn junit:merge || :; exit $status diff --git a/.buildkite/scripts/pipelines/security_solution_quality_gate/upload_image_metadata.sh b/.buildkite/scripts/pipelines/security_solution_quality_gate/upload_image_metadata.sh new file mode 100644 index 000000000000..c1a22d221caf --- /dev/null +++ b/.buildkite/scripts/pipelines/security_solution_quality_gate/upload_image_metadata.sh @@ -0,0 +1,27 @@ +#!/bin/bash +echo "$KIBANA_DOCKER_PASSWORD" | docker login -u "$KIBANA_DOCKER_USERNAME" --password-stdin docker.elastic.co + +KIBANA_BASE_IMAGE="docker.elastic.co/kibana-ci/kibana-serverless" +KIBANA_CURRENT_COMMIT=${KIBANA_BASE_IMAGE}:sec-sol-qg-${BUILDKITE_COMMIT:0:12} +KIBANA_LATEST=${KIBANA_BASE_IMAGE}:latest + +if [ "$KIBANA_MKI_USE_LATEST_COMMIT" = "1" ]; then + KBN_IMAGE=${KIBANA_CURRENT_COMMIT} +else + KBN_IMAGE=${KIBANA_LATEST} +fi + +docker pull ${KBN_IMAGE} +build_date=$(docker inspect ${KBN_IMAGE} | jq -r '.[0].Config.Labels."org.label-schema.build-date"') +vcs_ref=$(docker inspect ${KBN_IMAGE} | jq -r '.[0].Config.Labels."org.label-schema.vcs-ref"') +vcs_url=$(docker inspect ${KBN_IMAGE} | jq -r '.[0].Config.Labels."org.label-schema.vcs-url"') +version=$(docker inspect ${KBN_IMAGE} | jq -r '.[0].Config.Labels."org.label-schema.version"') + +markdown_text=""" + # Kibana Container Metadata + - Build Date : $build_date + - Github Commit Hash : $vcs_ref + - Github Repo : $vcs_url + - Version : $version +""" +echo "${markdown_text//[*\\_]/\\&}" | buildkite-agent annotate --style "info" \ No newline at end of file diff --git a/.buildkite/scripts/steps/archive_so_migration_snapshot.sh b/.buildkite/scripts/steps/archive_so_migration_snapshot.sh index 3db3da975b41..1c791608709c 100755 --- a/.buildkite/scripts/steps/archive_so_migration_snapshot.sh +++ b/.buildkite/scripts/steps/archive_so_migration_snapshot.sh @@ -3,15 +3,16 @@ set -euo pipefail .buildkite/scripts/bootstrap.sh -SO_MIGRATIONS_SNAPSHOT_FOLDER=kibana-so-types-snapshots +SO_MIGRATIONS_SNAPSHOT_BUCKET="gs://kibana-so-types-snapshots" SNAPSHOT_FILE_PATH="${1:-target/plugin_so_types_snapshot.json}" echo "--- Creating snapshot of Saved Object migration info" node scripts/snapshot_plugin_types snapshot --outputPath "$SNAPSHOT_FILE_PATH" echo "--- Uploading as ${BUILDKITE_COMMIT}.json" -SNAPSHOT_PATH="${SO_MIGRATIONS_SNAPSHOT_FOLDER}/${BUILDKITE_COMMIT}.json" -gsutil cp "$SNAPSHOT_FILE_PATH" "gs://$SNAPSHOT_PATH" +SNAPSHOT_PATH="${SO_MIGRATIONS_SNAPSHOT_BUCKET}/${BUILDKITE_COMMIT}.json" +.buildkite/scripts/common/activate_service_account.sh "$SO_MIGRATIONS_SNAPSHOT_BUCKET" +gsutil cp "$SNAPSHOT_FILE_PATH" "$SNAPSHOT_PATH" buildkite-agent annotate --context so_migration_snapshot --style success \ 'Saved Object type snapshot is available at '"$SNAPSHOT_PATH"'' diff --git a/.buildkite/scripts/steps/code_coverage/reporting/downloadPrevSha.sh b/.buildkite/scripts/steps/code_coverage/reporting/downloadPrevSha.sh index af7824841ef2..a77cfbef54d5 100755 --- a/.buildkite/scripts/steps/code_coverage/reporting/downloadPrevSha.sh +++ b/.buildkite/scripts/steps/code_coverage/reporting/downloadPrevSha.sh @@ -6,6 +6,7 @@ set -euo pipefail gsutil -m cp -r gs://elastic-bekitzur-kibana-coverage-live/previous_pointer/previous.txt . || echo "### Previous Pointer NOT FOUND?" # TODO: Activate after the above is removed +#.buildkite/scripts/common/activate_service_account.sh gs://elastic-kibana-coverage-live #gsutil -m cp -r gs://elastic-kibana-coverage-live/previous_pointer/previous.txt . || echo "### Previous Pointer NOT FOUND?" if [ -e ./previous.txt ]; then diff --git a/.buildkite/scripts/steps/code_coverage/reporting/uploadPrevSha.sh b/.buildkite/scripts/steps/code_coverage/reporting/uploadPrevSha.sh index 26d84fa7d602..42ef5faa5cd3 100755 --- a/.buildkite/scripts/steps/code_coverage/reporting/uploadPrevSha.sh +++ b/.buildkite/scripts/steps/code_coverage/reporting/uploadPrevSha.sh @@ -12,4 +12,5 @@ collectPrevious # TODO: Safe to remove this after 2024-03-01 (https://github.com/elastic/kibana/issues/175904) gsutil cp previous.txt gs://elastic-bekitzur-kibana-coverage-live/previous_pointer/ +.buildkite/scripts/common/activate_service_account.sh gs://elastic-kibana-coverage-live gsutil cp previous.txt gs://elastic-kibana-coverage-live/previous_pointer/ diff --git a/.buildkite/scripts/steps/code_coverage/reporting/uploadStaticSite.sh b/.buildkite/scripts/steps/code_coverage/reporting/uploadStaticSite.sh index 20e85a51c377..5bd0c07cc9b9 100755 --- a/.buildkite/scripts/steps/code_coverage/reporting/uploadStaticSite.sh +++ b/.buildkite/scripts/steps/code_coverage/reporting/uploadStaticSite.sh @@ -27,5 +27,6 @@ uploadRest() { echo "--- Uploading static site" +.buildkite/scripts/common/activate_service_account.sh gs://elastic-kibana-coverage-live uploadBase uploadRest diff --git a/.buildkite/scripts/steps/es_serverless/promote_es_serverless_image.sh b/.buildkite/scripts/steps/es_serverless/promote_es_serverless_image.sh index d99cff34f6fb..6a59959ea6fe 100755 --- a/.buildkite/scripts/steps/es_serverless/promote_es_serverless_image.sh +++ b/.buildkite/scripts/steps/es_serverless/promote_es_serverless_image.sh @@ -7,9 +7,6 @@ source .buildkite/scripts/common/util.sh BASE_ES_SERVERLESS_REPO=docker.elastic.co/elasticsearch-ci/elasticsearch-serverless TARGET_IMAGE=docker.elastic.co/kibana-ci/elasticsearch-serverless:latest-verified -ES_SERVERLESS_BUCKET=kibana-ci-es-serverless-images -MANIFEST_FILE_NAME=latest-verified.json - SOURCE_IMAGE_OR_TAG=$1 if [[ $SOURCE_IMAGE_OR_TAG =~ :[a-zA-Z_-]+$ ]]; then # $SOURCE_IMAGE_OR_TAG was a full image @@ -67,36 +64,6 @@ docker logout docker.elastic.co echo "Image push to $TARGET_IMAGE successful." echo "Promotion successful! Henceforth, thou shall be named Sir $TARGET_IMAGE" -MANIFEST_UPLOAD_PATH="Skipped" -if [[ "${PUBLISH_MANIFEST:-}" =~ ^(1|true)$ && "$SOURCE_IMAGE_OR_TAG" =~ ^git-[0-9a-fA-F]{12}$ ]]; then - echo "--- Uploading latest-verified manifest to GCS" - cat << EOT >> $MANIFEST_FILE_NAME -{ - "build_url": "$BUILDKITE_BUILD_URL", - "kibana_commit": "$BUILDKITE_COMMIT", - "kibana_branch": "$BUILDKITE_BRANCH", - "elasticsearch_serverless_tag": "$SOURCE_IMAGE_OR_TAG", - "elasticsearch_serverless_image_url": "$SOURCE_IMAGE", - "elasticsearch_serverless_commit": "TODO: this currently can't be decided", - "elasticsearch_commit": "$ELASTIC_COMMIT_HASH", - "created_at": "`date`", - "timestamp": "`FORCE_COLOR=0 node -p 'Date.now()'`" -} -EOT - - gsutil -h "Cache-Control:no-cache, max-age=0, no-transform" \ - cp $MANIFEST_FILE_NAME "gs://$ES_SERVERLESS_BUCKET/$MANIFEST_FILE_NAME" - gsutil acl ch -u AllUsers:R "gs://$ES_SERVERLESS_BUCKET/$MANIFEST_FILE_NAME" - MANIFEST_UPLOAD_PATH="$MANIFEST_FILE_NAME" - -elif [[ "${PUBLISH_MANIFEST:-}" =~ ^(1|true)$ ]]; then - echo "--- Skipping upload of latest-verified manifest to GCS, ES Serverless build tag is not pointing to a hash" -elif [[ "$SOURCE_IMAGE_OR_TAG" =~ ^git-[0-9a-fA-F]{12}$ ]]; then - echo "--- Skipping upload of latest-verified manifest to GCS, flag was not provided" -else - echo "--- Skipping upload of latest-verified manifest to GCS, no flag and hash provided" -fi - echo "--- Annotating build with info" cat << EOT | buildkite-agent annotate --style "success"

Promotion successful!

@@ -104,5 +71,4 @@ cat << EOT | buildkite-agent annotate --style "success"
Source image: $SOURCE_IMAGE
Kibana commit: $BUILDKITE_COMMIT
Elasticsearch commit: $ELASTIC_COMMIT_HASH -
Manifest file: $MANIFEST_UPLOAD_PATH EOT diff --git a/.buildkite/scripts/steps/es_snapshots/create_manifest.ts b/.buildkite/scripts/steps/es_snapshots/create_manifest.ts index 659a034d793b..c2a3250c1e85 100644 --- a/.buildkite/scripts/steps/es_snapshots/create_manifest.ts +++ b/.buildkite/scripts/steps/es_snapshots/create_manifest.ts @@ -103,6 +103,7 @@ interface ManifestEntry { set -euo pipefail echo '--- Upload files to GCS' + .buildkite/scripts/common/activate_service_account.sh ${BASE_BUCKET_DAILY} cd "${destination}" gsutil -m cp -r *.* gs://${BASE_BUCKET_DAILY}/${DESTINATION} cp manifest.json manifest-latest.json diff --git a/.buildkite/scripts/steps/es_snapshots/promote_manifest.ts b/.buildkite/scripts/steps/es_snapshots/promote_manifest.ts index 7b0f9b7a319a..3d4009139e3d 100644 --- a/.buildkite/scripts/steps/es_snapshots/promote_manifest.ts +++ b/.buildkite/scripts/steps/es_snapshots/promote_manifest.ts @@ -38,6 +38,7 @@ import { BASE_BUCKET_DAILY, BASE_BUCKET_PERMANENT } from './bucket_config'; execSync( ` set -euo pipefail + .buildkite/scripts/common/activate_service_account.sh ${bucket} cp manifest.json manifest-latest-verified.json gsutil -h "Cache-Control:no-cache, max-age=0, no-transform" cp manifest-latest-verified.json gs://${BASE_BUCKET_DAILY}/${version}/ rm manifest.json diff --git a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh index d22e9890b2de..ebf9e28d2c9e 100755 --- a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh +++ b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh @@ -41,6 +41,9 @@ download_artifact kibana-default-plugins.tar.gz "${OUTPUT_DIR}/" --build "${KIBA echo "--- Adding commit info" echo "${BUILDKITE_COMMIT}" > "${OUTPUT_DIR}/KIBANA_COMMIT_HASH" +echo "--- Activating service-account for gsutil to access gs://kibana-performance" +.buildkite/scripts/common/activate_service_account.sh gs://kibana-performance + echo "--- Uploading ${OUTPUT_REL} dir to ${GCS_BUCKET}" cd "${OUTPUT_DIR}/.." gsutil -m cp -r "${BUILD_ID}" "${GCS_BUCKET}" diff --git a/.buildkite/scripts/steps/scalability/benchmarking.sh b/.buildkite/scripts/steps/scalability/benchmarking.sh index 39acf4203af3..79875fb04d5f 100755 --- a/.buildkite/scripts/steps/scalability/benchmarking.sh +++ b/.buildkite/scripts/steps/scalability/benchmarking.sh @@ -19,6 +19,9 @@ rm -rf "${KIBANA_LOAD_TESTING_DIR}" rm -rf "${GCS_ARTIFACTS_DIR}" download_artifacts() { + echo Activating service-account for gsutil to access gs://kibana-performance + .buildkite/scripts/common/activate_service_account.sh gs://kibana-performance + mkdir -p "${GCS_ARTIFACTS_DIR}" gsutil cp "$GCS_BUCKET/latest" "${GCS_ARTIFACTS_DIR}/" diff --git a/.buildkite/scripts/steps/storybooks/build_and_upload.ts b/.buildkite/scripts/steps/storybooks/build_and_upload.ts index 4ea59b4a8298..e7545f5011df 100644 --- a/.buildkite/scripts/steps/storybooks/build_and_upload.ts +++ b/.buildkite/scripts/steps/storybooks/build_and_upload.ts @@ -9,6 +9,7 @@ import { execSync } from 'child_process'; import fs from 'fs'; import path from 'path'; +import { getKibanaDir } from '#pipeline-utils'; // TODO - how to generate this dynamically? const STORYBOOKS = [ @@ -117,7 +118,12 @@ const upload = () => { fs.writeFileSync('index.html', html); console.log('--- Uploading Storybooks'); + const activateScript = path.relative( + process.cwd(), + path.join(getKibanaDir(), '.buildkite', 'scripts', 'common', 'activate_service_account.sh') + ); exec(` + ${activateScript} gs://ci-artifacts.kibana.dev gsutil -q -m cp -r -z js,css,html,json,map,txt,svg '*' 'gs://${STORYBOOK_BUCKET}/${STORYBOOK_DIRECTORY}/${process.env.BUILDKITE_COMMIT}/' gsutil -h "Cache-Control:no-cache, max-age=0, no-transform" cp -z html 'index.html' 'gs://${STORYBOOK_BUCKET}/${STORYBOOK_DIRECTORY}/latest/' `); diff --git a/.buildkite/scripts/steps/webpack_bundle_analyzer/upload.ts b/.buildkite/scripts/steps/webpack_bundle_analyzer/upload.ts index 73c24a82be6d..7bb45990bd46 100644 --- a/.buildkite/scripts/steps/webpack_bundle_analyzer/upload.ts +++ b/.buildkite/scripts/steps/webpack_bundle_analyzer/upload.ts @@ -9,6 +9,7 @@ import { execSync } from 'child_process'; import fs from 'fs'; import path from 'path'; +import { getKibanaDir } from '#pipeline-utils'; const GITHUB_CONTEXT = 'Build and Publish Webpack bundle analyzer reports'; @@ -54,7 +55,12 @@ const upload = () => { fs.writeFileSync('index.html', html); console.log('--- Uploading Webpack Bundle Analyzer reports'); + const activateScript = path.relative( + process.cwd(), + path.join(getKibanaDir(), '.buildkite', 'scripts', 'common', 'activate_service_account.sh') + ); exec(` + ${activateScript} gs://ci-artifacts.kibana.dev gsutil -q -m cp -r -z html '*' 'gs://${WEBPACK_REPORTS_BUCKET}/${WEBPACK_REPORTS}/${process.env.BUILDKITE_COMMIT}/' gsutil -h "Cache-Control:no-cache, max-age=0, no-transform" cp -z html 'index.html' 'gs://${WEBPACK_REPORTS_BUCKET}/${WEBPACK_REPORTS}/latest/' `); diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 02837458e304..72f4dfddb686 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -353,8 +353,8 @@ packages/kbn-docs-utils @elastic/kibana-operations packages/kbn-dom-drag-drop @elastic/kibana-visualizations @elastic/kibana-data-discovery packages/kbn-ebt-tools @elastic/kibana-core packages/kbn-ecs @elastic/kibana-core @elastic/security-threat-hunting-investigations -x-pack/packages/security-solution/ecs_data_quality_dashboard @elastic/security-threat-hunting-investigations -x-pack/plugins/ecs_data_quality_dashboard @elastic/security-threat-hunting-investigations +x-pack/packages/security-solution/ecs_data_quality_dashboard @elastic/security-threat-hunting-explore +x-pack/plugins/ecs_data_quality_dashboard @elastic/security-threat-hunting-explore packages/kbn-elastic-agent-utils @elastic/obs-ux-logs-team x-pack/packages/kbn-elastic-assistant @elastic/security-generative-ai x-pack/packages/kbn-elastic-assistant-common @elastic/security-generative-ai diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index dc6e3424f37c..54037cd3edeb 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index b136669a82af..fb9947f139e1 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] --- import advancedSettingsObj from './advanced_settings.devdocs.json'; diff --git a/api_docs/ai_assistant_management_observability.mdx b/api_docs/ai_assistant_management_observability.mdx index ecbe64788316..32558d156f58 100644 --- a/api_docs/ai_assistant_management_observability.mdx +++ b/api_docs/ai_assistant_management_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementObservability title: "aiAssistantManagementObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementObservability plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementObservability'] --- import aiAssistantManagementObservabilityObj from './ai_assistant_management_observability.devdocs.json'; diff --git a/api_docs/ai_assistant_management_selection.mdx b/api_docs/ai_assistant_management_selection.mdx index 9734e0ef0453..b83874aec836 100644 --- a/api_docs/ai_assistant_management_selection.mdx +++ b/api_docs/ai_assistant_management_selection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiAssistantManagementSelection title: "aiAssistantManagementSelection" image: https://source.unsplash.com/400x175/?github description: API docs for the aiAssistantManagementSelection plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiAssistantManagementSelection'] --- import aiAssistantManagementSelectionObj from './ai_assistant_management_selection.devdocs.json'; diff --git a/api_docs/aiops.devdocs.json b/api_docs/aiops.devdocs.json index 6a4ad90613be..fc291bd72183 100644 --- a/api_docs/aiops.devdocs.json +++ b/api_docs/aiops.devdocs.json @@ -1142,22 +1142,6 @@ "deprecated": false, "trackAdoption": false }, - { - "parentPluginId": "aiops", - "id": "def-public.LogRateAnalysisContentWrapperProps.setGlobalState", - "type": "Any", - "tags": [], - "label": "setGlobalState", - "description": [ - "On global timefilter update" - ], - "signature": [ - "any" - ], - "path": "x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_content/log_rate_analysis_content_wrapper.tsx", - "deprecated": false, - "trackAdoption": false - }, { "parentPluginId": "aiops", "id": "def-public.LogRateAnalysisContentWrapperProps.initialAnalysisStart", diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index 4dc47efaddcc..28e29c47bc22 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] --- import aiopsObj from './aiops.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) for questi | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 70 | 1 | 4 | 1 | +| 69 | 0 | 4 | 1 | ## Client diff --git a/api_docs/alerting.devdocs.json b/api_docs/alerting.devdocs.json index 83be25a7e980..2d02c951d2e7 100644 --- a/api_docs/alerting.devdocs.json +++ b/api_docs/alerting.devdocs.json @@ -3146,10 +3146,10 @@ }, { "parentPluginId": "alerting", - "id": "def-server.Rule.notificationDelay", + "id": "def-server.Rule.alertDelay", "type": "Object", "tags": [], - "label": "notificationDelay", + "label": "alertDelay", "description": [], "signature": [ "Readonly<{} & { active: number; }> | undefined" @@ -3257,7 +3257,7 @@ "section": "def-common.SanitizedRule", "text": "SanitizedRule" }, - ", \"id\" | \"consumer\" | \"name\" | \"actions\" | \"tags\" | \"enabled\" | \"schedule\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"throttle\" | \"muteAll\" | \"notifyWhen\" | \"snoozeSchedule\" | \"revision\"> & { producer: string; ruleTypeId: string; ruleTypeName: string; }" + ", \"id\" | \"consumer\" | \"name\" | \"actions\" | \"tags\" | \"enabled\" | \"schedule\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"throttle\" | \"muteAll\" | \"notifyWhen\" | \"snoozeSchedule\" | \"revision\" | \"alertDelay\"> & { producer: string; ruleTypeId: string; ruleTypeName: string; }" ], "path": "x-pack/plugins/alerting/server/types.ts", "deprecated": false, @@ -6314,6 +6314,48 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "alerting", + "id": "def-common.AlertDelay", + "type": "Interface", + "tags": [], + "label": "AlertDelay", + "description": [], + "signature": [ + { + "pluginId": "alerting", + "scope": "common", + "docId": "kibAlertingPluginApi", + "section": "def-common.AlertDelay", + "text": "AlertDelay" + }, + " extends ", + { + "pluginId": "@kbn/core-saved-objects-common", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsCommonPluginApi", + "section": "def-common.SavedObjectAttributes", + "text": "SavedObjectAttributes" + } + ], + "path": "x-pack/plugins/alerting/common/rule.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "alerting", + "id": "def-common.AlertDelay.active", + "type": "number", + "tags": [], + "label": "active", + "description": [], + "path": "x-pack/plugins/alerting/common/rule.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "alerting", "id": "def-common.AlertingFrameworkHealth", @@ -7845,31 +7887,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "alerting", - "id": "def-common.NotificationDelay", - "type": "Interface", - "tags": [], - "label": "NotificationDelay", - "description": [], - "path": "x-pack/plugins/alerting/common/rule.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "alerting", - "id": "def-common.NotificationDelay.active", - "type": "number", - "tags": [], - "label": "active", - "description": [], - "path": "x-pack/plugins/alerting/common/rule.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "alerting", "id": "def-common.Rule", @@ -8367,18 +8384,18 @@ }, { "parentPluginId": "alerting", - "id": "def-common.Rule.notificationDelay", + "id": "def-common.Rule.alertDelay", "type": "Object", "tags": [], - "label": "notificationDelay", + "label": "alertDelay", "description": [], "signature": [ { "pluginId": "alerting", "scope": "common", "docId": "kibAlertingPluginApi", - "section": "def-common.NotificationDelay", - "text": "NotificationDelay" + "section": "def-common.AlertDelay", + "text": "AlertDelay" }, " | undefined" ], @@ -11546,7 +11563,7 @@ "section": "def-common.SanitizedRule", "text": "SanitizedRule" }, - ", \"id\" | \"consumer\" | \"name\" | \"actions\" | \"tags\" | \"enabled\" | \"schedule\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"throttle\" | \"muteAll\" | \"notifyWhen\" | \"snoozeSchedule\" | \"revision\"> & { producer: string; ruleTypeId: string; ruleTypeName: string; }" + ", \"id\" | \"consumer\" | \"name\" | \"actions\" | \"tags\" | \"enabled\" | \"schedule\" | \"createdBy\" | \"updatedBy\" | \"createdAt\" | \"updatedAt\" | \"throttle\" | \"muteAll\" | \"notifyWhen\" | \"snoozeSchedule\" | \"revision\" | \"alertDelay\"> & { producer: string; ruleTypeId: string; ruleTypeName: string; }" ], "path": "x-pack/plugins/alerting/common/rule.ts", "deprecated": false, @@ -11561,7 +11578,7 @@ "label": "TrackedLifecycleAlertState", "description": [], "signature": [ - "{ alertId: string; alertUuid: string; started: string; flappingHistory: boolean[]; flapping: boolean; pendingRecoveredCount: number; }" + "{ alertId: string; alertUuid: string; started: string; flappingHistory: boolean[]; flapping: boolean; pendingRecoveredCount: number; activeCount: number; }" ], "path": "x-pack/packages/kbn-alerting-state-types/src/lifecycle_state.ts", "deprecated": false, @@ -11601,7 +11618,7 @@ "\nThis is redefined instead of derived from above `wrappedStateRt` because\nthere's no easy way to instantiate generic values such as the runtime type\nfactory function." ], "signature": [ - "RuleTypeState & { wrapped: State; trackedAlerts: Record; trackedAlertsRecovered: Record; }" + "RuleTypeState & { wrapped: State; trackedAlerts: Record; trackedAlertsRecovered: Record; }" ], "path": "x-pack/packages/kbn-alerting-state-types/src/lifecycle_state.ts", "deprecated": false, diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index b28b99e61bf9..5870a15f134a 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 489d0831b12a..47b13e31ab93 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/apm_data_access.mdx b/api_docs/apm_data_access.mdx index e7db9e67d50b..55a18a78b6ad 100644 --- a/api_docs/apm_data_access.mdx +++ b/api_docs/apm_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apmDataAccess title: "apmDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the apmDataAccess plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apmDataAccess'] --- import apmDataAccessObj from './apm_data_access.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index e0faf9044afc..31fff0681b7e 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 99044ae26866..e4979db414c5 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-02-06 +date: 2024-02-07 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 9797b1c42c5a..fc66ffd30c49 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-02-06 +date: 2024-02-07 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 810c371e4fdd..76e21cb4a00f 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-02-06 +date: 2024-02-07 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 7c6cfa724b40..ce1a79df312b 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-02-06 +date: 2024-02-07 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 a3415b68c597..03529c94a9ea 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-02-06 +date: 2024-02-07 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 dd9afabb3bb4..f733add4b999 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-02-06 +date: 2024-02-07 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 ccb04eb45105..fcbf269d5375 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-02-06 +date: 2024-02-07 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 684e79492bc5..bb51d1645f85 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 4b64af843ea2..e6d0c449ec1a 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments'] --- import cloudExperimentsObj from './cloud_experiments.devdocs.json'; diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 54183ea0b6c1..080f0d5cb0c3 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-02-06 +date: 2024-02-07 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 6e3708689ad7..27b4958284e5 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-02-06 +date: 2024-02-07 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 76fdc01c4dbc..dafa7bce29e1 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-02-06 +date: 2024-02-07 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 c2f3050142d1..64d8ca3fd8e7 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-02-06 +date: 2024-02-07 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 1092617fee81..4454a7023894 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-02-06 +date: 2024-02-07 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 bf4b2ad0a570..e82c5a1de361 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-02-06 +date: 2024-02-07 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 5f21dd789ddb..4efbf0051269 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index 58d3d9fbf9ce..48315db6ab3e 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -17339,6 +17339,20 @@ "path": "src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "data", + "id": "def-server.FieldDescriptor.defaultFormatter", + "type": "string", + "tags": [], + "label": "defaultFormatter", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -20030,7 +20044,7 @@ }, " | undefined; fixedInterval?: string[] | undefined; timeZone?: string[] | undefined; timeSeriesDimension?: boolean | undefined; timeSeriesMetric?: ", "MappingTimeSeriesMetricType", - " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; }" + " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; defaultFormatter?: string | undefined; }" ], "path": "src/plugins/data_views/common/fields/data_view_field.ts", "deprecated": false, @@ -20106,6 +20120,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "data", + "id": "def-common.DataViewField.defaultFormatter", + "type": "string", + "tags": [], + "label": "defaultFormatter", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data_views/common/fields/data_view_field.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "data", "id": "def-common.DataViewField.runtimeField", @@ -20693,7 +20721,7 @@ "section": "def-common.IFieldSubType", "text": "IFieldSubType" }, - " | undefined; customLabel: string | undefined; }" + " | undefined; customLabel: string | undefined; defaultFormatter: string | undefined; }" ], "path": "src/plugins/data_views/common/fields/data_view_field.ts", "deprecated": false, @@ -25174,7 +25202,7 @@ }, " | undefined; fixedInterval?: string[] | undefined; timeZone?: string[] | undefined; timeSeriesDimension?: boolean | undefined; timeSeriesMetric?: ", "MappingTimeSeriesMetricType", - " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; }" + " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; defaultFormatter?: string | undefined; }" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 02f2f9a45d5a..318245e38595 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3235 | 31 | 2583 | 23 | +| 3237 | 31 | 2585 | 23 | ## Client diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index d4aaa572a307..05e3acb062a5 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3235 | 31 | 2583 | 23 | +| 3237 | 31 | 2585 | 23 | ## Client diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index 690cf4b26702..736ab6888a41 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3235 | 31 | 2583 | 23 | +| 3237 | 31 | 2585 | 23 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 4ab7ddd93758..a702fe304577 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-02-06 +date: 2024-02-07 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 e55b392d2aa2..4d81b7a67b29 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-02-06 +date: 2024-02-07 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 cf830bb4bee2..500962ad0ea2 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.devdocs.json b/api_docs/data_views.devdocs.json index 4686208acd12..b8995d9fca91 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -1045,7 +1045,7 @@ }, " | undefined; fixedInterval?: string[] | undefined; timeZone?: string[] | undefined; timeSeriesDimension?: boolean | undefined; timeSeriesMetric?: ", "MappingTimeSeriesMetricType", - " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; }" + " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; defaultFormatter?: string | undefined; }" ], "path": "src/plugins/data_views/common/fields/data_view_field.ts", "deprecated": false, @@ -1121,6 +1121,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "dataViews", + "id": "def-public.DataViewField.defaultFormatter", + "type": "string", + "tags": [], + "label": "defaultFormatter", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data_views/common/fields/data_view_field.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "dataViews", "id": "def-public.DataViewField.runtimeField", @@ -1708,7 +1722,7 @@ "section": "def-common.IFieldSubType", "text": "IFieldSubType" }, - " | undefined; customLabel: string | undefined; }" + " | undefined; customLabel: string | undefined; defaultFormatter: string | undefined; }" ], "path": "src/plugins/data_views/common/fields/data_view_field.ts", "deprecated": false, @@ -6327,7 +6341,7 @@ }, " | undefined; fixedInterval?: string[] | undefined; timeZone?: string[] | undefined; timeSeriesDimension?: boolean | undefined; timeSeriesMetric?: ", "MappingTimeSeriesMetricType", - " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; }" + " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; defaultFormatter?: string | undefined; }" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, @@ -10251,6 +10265,20 @@ "path": "src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "dataViews", + "id": "def-server.FieldDescriptor.defaultFormatter", + "type": "string", + "tags": [], + "label": "defaultFormatter", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -10385,7 +10413,7 @@ }, " | undefined; fixedInterval?: string[] | undefined; timeZone?: string[] | undefined; timeSeriesDimension?: boolean | undefined; timeSeriesMetric?: ", "MappingTimeSeriesMetricType", - " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; }" + " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; defaultFormatter?: string | undefined; }" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, @@ -13069,7 +13097,7 @@ }, " | undefined; fixedInterval?: string[] | undefined; timeZone?: string[] | undefined; timeSeriesDimension?: boolean | undefined; timeSeriesMetric?: ", "MappingTimeSeriesMetricType", - " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; }" + " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; defaultFormatter?: string | undefined; }" ], "path": "src/plugins/data_views/common/fields/data_view_field.ts", "deprecated": false, @@ -13145,6 +13173,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "dataViews", + "id": "def-common.DataViewField.defaultFormatter", + "type": "string", + "tags": [], + "label": "defaultFormatter", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/data_views/common/fields/data_view_field.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "dataViews", "id": "def-common.DataViewField.runtimeField", @@ -13732,7 +13774,7 @@ "section": "def-common.IFieldSubType", "text": "IFieldSubType" }, - " | undefined; customLabel: string | undefined; }" + " | undefined; customLabel: string | undefined; defaultFormatter: string | undefined; }" ], "path": "src/plugins/data_views/common/fields/data_view_field.ts", "deprecated": false, @@ -20951,7 +20993,7 @@ }, " | undefined; fixedInterval?: string[] | undefined; timeZone?: string[] | undefined; timeSeriesDimension?: boolean | undefined; timeSeriesMetric?: ", "MappingTimeSeriesMetricType", - " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; }" + " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; defaultFormatter?: string | undefined; }" ], "path": "src/plugins/data_views/common/types.ts", "deprecated": false, diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index d6ae15964c37..2826aa5424d1 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.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 | |-------------------|-----------|------------------------|-----------------| -| 940 | 0 | 273 | 4 | +| 943 | 0 | 276 | 4 | ## Client diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index cbc54a87d05f..27766dc46e00 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/dataset_quality.mdx b/api_docs/dataset_quality.mdx index d0fbeaa3f078..285b2f4d7f7c 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-02-06 +date: 2024-02-07 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 f43faceb9dc2..4d3566baa5a6 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 53e0429bb5be..6d81a57f9015 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index a7977ec321b4..1597b7565e31 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 86251f2a1bba..ebd0134451a3 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 5079b784fd1c..7e487fd29fae 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index fb49a8f059b3..214e4934f054 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index 3d5558a3de2a..6a80d575ecbd 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,14 +8,14 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; APIs used to assess the quality of data in Elasticsearch indexes -Contact [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) for questions regarding this plugin. +Contact [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/elastic_assistant.mdx b/api_docs/elastic_assistant.mdx index da09fc3f341e..a56158deb96f 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-02-06 +date: 2024-02-07 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 24b016ee2226..443871d9e9a1 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-02-06 +date: 2024-02-07 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 221753642615..5d4a086ffa67 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-02-06 +date: 2024-02-07 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 6cce0344d74f..d6b88067724a 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-02-06 +date: 2024-02-07 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 9f40f00bd4d9..976efc6f352f 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 431f364c7154..068973c41333 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 685b7d997712..04ff788135c3 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-02-06 +date: 2024-02-07 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 27147e025d02..678653f01675 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-02-06 +date: 2024-02-07 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 0222d568741d..68c65eed115f 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-02-06 +date: 2024-02-07 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 39d84d6ef6c5..d848fea9dff0 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-02-06 +date: 2024-02-07 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 a1b91726cfda..5a4ab66af2ad 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-02-06 +date: 2024-02-07 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 a257739e8ba2..8e09a01529a5 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-02-06 +date: 2024-02-07 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 23c6c06b9061..34a2a193157b 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-02-06 +date: 2024-02-07 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 6f73940c722f..252a9498bf27 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-02-06 +date: 2024-02-07 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 056436375c2f..dfd42386bd97 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-02-06 +date: 2024-02-07 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 abc5b5e20f06..6b382f9dcd5d 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-02-06 +date: 2024-02-07 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 4bb55dd1267f..0c0dac759050 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-02-06 +date: 2024-02-07 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 a488cb455953..8bf65ad0ab67 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-02-06 +date: 2024-02-07 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 788eff9d3c91..e3f854290b85 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-02-06 +date: 2024-02-07 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 a9e70cdb16a2..e1ad44d96738 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-02-06 +date: 2024-02-07 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 593425fe7790..8c03e3179e3c 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-02-06 +date: 2024-02-07 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 3b3b71384b4b..f6363210818f 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-02-06 +date: 2024-02-07 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 b876e79d5052..9872e1d9d71a 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-02-06 +date: 2024-02-07 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 214de7d3869a..b3e3fa39995d 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-02-06 +date: 2024-02-07 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 90f6f86f6955..3d8ee32fce10 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-02-06 +date: 2024-02-07 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 6c9cafe2c18c..6cf7b1fccd3d 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 76db797294cf..a50d4e8e4735 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-02-06 +date: 2024-02-07 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 d5623f1296f8..6bdc433a462b 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-02-06 +date: 2024-02-07 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 bc92e6c466c6..bab8111ea9ac 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-02-06 +date: 2024-02-07 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 cd548cf1b736..de83a55e605a 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -7065,6 +7065,49 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "fleet", + "id": "def-server.ArtifactsClientInterface.fetchAll", + "type": "Function", + "tags": [], + "label": "fetchAll", + "description": [], + "signature": [ + "(options?: ", + "FetchAllArtifactsOptions", + " | undefined) => AsyncIterable<", + { + "pluginId": "fleet", + "scope": "server", + "docId": "kibFleetPluginApi", + "section": "def-server.Artifact", + "text": "Artifact" + }, + "[]>" + ], + "path": "x-pack/plugins/fleet/server/services/artifacts/types.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.ArtifactsClientInterface.fetchAll.$1", + "type": "CompoundType", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "FetchAllArtifactsOptions", + " | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/artifacts/types.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] } ], "initialIsOpen": false @@ -11299,6 +11342,146 @@ } ], "returnComment": [] + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.fetchAllItemIds", + "type": "Function", + "tags": [], + "label": "fetchAllItemIds", + "description": [ + "\nReturns an `AsyncIterable` for retrieving all integration policy IDs" + ], + "signature": [ + "(soClient: ", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-common.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + }, + ", options?: ", + "PackagePolicyClientFetchAllItemIdsOptions", + " | undefined) => AsyncIterable" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.fetchAllItemIds.$1", + "type": "Object", + "tags": [], + "label": "soClient", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-common.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + } + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.fetchAllItemIds.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "PackagePolicyClientFetchAllItemIdsOptions", + " | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.fetchAllItems", + "type": "Function", + "tags": [], + "label": "fetchAllItems", + "description": [ + "\nReturns an `AsyncIterable` for retrieving all integration policies" + ], + "signature": [ + "(soClient: ", + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-common.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + }, + ", options?: ", + "PackagePolicyClientFetchAllItemsOptions", + " | undefined) => AsyncIterable<", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.PackagePolicy", + "text": "PackagePolicy" + }, + "[]>" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.fetchAllItems.$1", + "type": "Object", + "tags": [], + "label": "soClient", + "description": [], + "signature": [ + { + "pluginId": "@kbn/core-saved-objects-api-server", + "scope": "common", + "docId": "kibKbnCoreSavedObjectsApiServerPluginApi", + "section": "def-common.SavedObjectsClientContract", + "text": "SavedObjectsClientContract" + } + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "fleet", + "id": "def-server.PackagePolicyClient.fetchAllItems.$2", + "type": "Object", + "tags": [], + "label": "options", + "description": [], + "signature": [ + "PackagePolicyClientFetchAllItemsOptions", + " | undefined" + ], + "path": "x-pack/plugins/fleet/server/services/package_policy_service.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [] } ], "initialIsOpen": false diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 66c958995d88..e457af73948a 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-02-06 +date: 2024-02-07 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 | |-------------------|-----------|------------------------|-----------------| -| 1221 | 3 | 1104 | 51 | +| 1229 | 3 | 1110 | 54 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 2e4d5fa494c1..031e986467b9 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-02-06 +date: 2024-02-07 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 f9c8613429c7..c68994c5fdf7 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-02-06 +date: 2024-02-07 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 8343e2b8d0f4..f004aff979b5 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-02-06 +date: 2024-02-07 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 f532c6eb76fa..561f830f5ed1 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-02-06 +date: 2024-02-07 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 43242f928542..f6cf3f300f55 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-02-06 +date: 2024-02-07 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 ac163c523994..3f8c2ff001f1 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index f8be1e039e45..302e477335d1 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-02-06 +date: 2024-02-07 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 6e8564d3f56f..cf427bd90c52 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-02-06 +date: 2024-02-07 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 445cf4f9e908..cdeab5a224d8 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 238b68ae6c28..9b1884dc2a44 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index ce5d3ce46f47..8caec772965e 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_actions_types.mdx b/api_docs/kbn_actions_types.mdx index aec13e35139c..88a29fe0597b 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/actions-types'] --- import kbnActionsTypesObj from './kbn_actions_types.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index df2260a083a4..3258abdd89ff 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index 84c52499a6b8..93defed009bb 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_api_integration_helpers.mdx b/api_docs/kbn_alerting_api_integration_helpers.mdx index 20723328ec71..9a697b4d6144 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-api-integration-helpers'] --- import kbnAlertingApiIntegrationHelpersObj from './kbn_alerting_api_integration_helpers.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.devdocs.json b/api_docs/kbn_alerting_state_types.devdocs.json index 344736f79322..4beda471f14b 100644 --- a/api_docs/kbn_alerting_state_types.devdocs.json +++ b/api_docs/kbn_alerting_state_types.devdocs.json @@ -51,6 +51,8 @@ "BooleanC", "; pendingRecoveredCount: ", "NumberC", + "; activeCount: ", + "NumberC", "; }>>; trackedAlertsRecovered: ", "RecordC", "<", @@ -71,6 +73,8 @@ "BooleanC", "; pendingRecoveredCount: ", "NumberC", + "; activeCount: ", + "NumberC", "; }>>; }>" ], "path": "x-pack/packages/kbn-alerting-state-types/src/lifecycle_state.ts", @@ -255,7 +259,7 @@ "label": "TrackedLifecycleAlertState", "description": [], "signature": [ - "{ alertId: string; alertUuid: string; started: string; flappingHistory: boolean[]; flapping: boolean; pendingRecoveredCount: number; }" + "{ alertId: string; alertUuid: string; started: string; flappingHistory: boolean[]; flapping: boolean; pendingRecoveredCount: number; activeCount: number; }" ], "path": "x-pack/packages/kbn-alerting-state-types/src/lifecycle_state.ts", "deprecated": false, @@ -272,7 +276,7 @@ "\nThis is redefined instead of derived from above `wrappedStateRt` because\nthere's no easy way to instantiate generic values such as the runtime type\nfactory function." ], "signature": [ - "RuleTypeState & { wrapped: State; trackedAlerts: Record; trackedAlertsRecovered: Record; }" + "RuleTypeState & { wrapped: State; trackedAlerts: Record; trackedAlertsRecovered: Record; }" ], "path": "x-pack/packages/kbn-alerting-state-types/src/lifecycle_state.ts", "deprecated": false, diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index 6703b879196e..d0fee964360a 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-02-06 +date: 2024-02-07 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 4e5b7eae73ef..2071cb1dd96e 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-02-06 +date: 2024-02-07 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 fc394d79a70a..2fdfdd3238da 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index 536b17f36b05..d7b8009e7e09 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-02-06 +date: 2024-02-07 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 5daa2678e943..fd4d432cbe61 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 6c83719d87e5..99db6e29b00f 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_collection_utils.mdx b/api_docs/kbn_analytics_collection_utils.mdx index 09c6d66d5590..f18fd4790af5 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-collection-utils'] --- import kbnAnalyticsCollectionUtilsObj from './kbn_analytics_collection_utils.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index e43782aae087..bbaf361280b4 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 0adde9559033..613455dad34a 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index fc2c28465b13..8db8c8d13225 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 944500719f35..964b428217d0 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 0e1f236cc620..00d58ccb6a74 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index 79e56e50a2ef..db071f9e0147 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-02-06 +date: 2024-02-07 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 dbbc48448d5b..6602bb36b702 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index b2826caab129..14eceaf9f6c6 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index ff198bca5c57..8a2a7331cbbe 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-02-06 +date: 2024-02-07 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 8aeccc779a41..e0f13dacf12e 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-02-06 +date: 2024-02-07 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 44e2bc204c6e..e88e9cf0f46a 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-02-06 +date: 2024-02-07 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 a2f54c4292ba..37bb79a8bfab 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-02-06 +date: 2024-02-07 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 de3f668adfbe..595ae33bf58d 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index 2cb17caad46d..8267f3c16f1d 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-02-06 +date: 2024-02-07 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 efc21e990d79..375e367a2ea5 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-02-06 +date: 2024-02-07 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 05739177ae73..9c904d7307dc 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-02-06 +date: 2024-02-07 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 68354bffc37c..1594dae51b9c 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-02-06 +date: 2024-02-07 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 8c66098c6f5d..5e23c1379c32 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-02-06 +date: 2024-02-07 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 c264a1e61105..d274a27de597 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-02-06 +date: 2024-02-07 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 2bf610f5bc5c..e245c1d86e96 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.devdocs.json b/api_docs/kbn_code_editor.devdocs.json index 876090f16122..c523a040f512 100644 --- a/api_docs/kbn_code_editor.devdocs.json +++ b/api_docs/kbn_code_editor.devdocs.json @@ -542,6 +542,22 @@ "path": "packages/shared-ux/code_editor/impl/code_editor.tsx", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/code-editor", + "id": "def-common.CodeEditorProps.fitToContent", + "type": "Object", + "tags": [], + "label": "fitToContent", + "description": [ + "\nEnables the editor to grow vertically to fit its content.\nThis option overrides the `height` option." + ], + "signature": [ + "{ minLines?: number | undefined; maxLines?: number | undefined; } | undefined" + ], + "path": "packages/shared-ux/code_editor/impl/code_editor.tsx", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 27a1e1ff8ae7..3817bba5764d 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 36 | 0 | 15 | 0 | +| 37 | 0 | 15 | 0 | ## Common diff --git a/api_docs/kbn_code_editor_mock.mdx b/api_docs/kbn_code_editor_mock.mdx index 1b5af8cbaf28..42c0c32b12e5 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-02-06 +date: 2024-02-07 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 ebbd487dd641..5ba405fce4db 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-owners'] --- import kbnCodeOwnersObj from './kbn_code_owners.devdocs.json'; diff --git a/api_docs/kbn_coloring.devdocs.json b/api_docs/kbn_coloring.devdocs.json index b16ebabd965d..64eb4e83e772 100644 --- a/api_docs/kbn_coloring.devdocs.json +++ b/api_docs/kbn_coloring.devdocs.json @@ -435,6 +435,39 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getActivePaletteName", + "type": "Function", + "tags": [], + "label": "getActivePaletteName", + "description": [], + "signature": [ + "(name: string | undefined) => string" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.getActivePaletteName.$1", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/kbn-coloring/src/palettes/utils.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "@kbn/coloring", "id": "def-common.getAssignmentColor", @@ -2754,6 +2787,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.COMPLEMENTARY_PALETTE", + "type": "string", + "tags": [], + "label": "COMPLEMENTARY_PALETTE", + "description": [], + "signature": [ + "\"complementary\"" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/coloring", "id": "def-common.CUSTOM_PALETTE", @@ -2799,6 +2847,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.DEFAULT_FALLBACK_PALETTE", + "type": "string", + "tags": [], + "label": "DEFAULT_FALLBACK_PALETTE", + "description": [], + "signature": [ + "\"default\"" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/coloring", "id": "def-common.DEFAULT_MAX_STOP", @@ -2919,6 +2982,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "@kbn/coloring", + "id": "def-common.LEGACY_COMPLIMENTARY_PALETTE", + "type": "string", + "tags": [], + "label": "LEGACY_COMPLIMENTARY_PALETTE", + "description": [], + "signature": [ + "\"complimentary\"" + ], + "path": "packages/kbn-coloring/src/palettes/constants.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "@kbn/coloring", "id": "def-common.NEUTRAL_COLOR_DARK", diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 60fe82bc31c9..89c8701f1916 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/k | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 206 | 0 | 169 | 8 | +| 211 | 0 | 174 | 8 | ## Common diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index efedb2a0e520..673574632e61 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-02-06 +date: 2024-02-07 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 392f659dcd19..c35abb86a957 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-02-06 +date: 2024-02-07 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 c1a7b2ed2684..6ffdca2e390b 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-02-06 +date: 2024-02-07 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 95016c6839b2..f1cef23fdb33 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index da721805655f..e26f8646dc4f 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-02-06 +date: 2024-02-07 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 a60b87e63ff1..b257e36ca7c5 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-02-06 +date: 2024-02-07 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 58feea4bcb91..4300132ed29f 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-02-06 +date: 2024-02-07 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 7797000dd702..9df2310b6aec 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index e7ab24de4825..6e5578f73493 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 65f58da3fee2..c0ea027c1c7a 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-02-06 +date: 2024-02-07 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 875b3c3eb5bc..2cf554b3d109 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-02-06 +date: 2024-02-07 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 d6b823805163..33672c6af029 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 13abfb178cd4..164e19682cf6 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-02-06 +date: 2024-02-07 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 2496d46c7269..e85fd93334a5 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-02-06 +date: 2024-02-07 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 a5bfbf4f9683..0f6fe0dca69f 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-02-06 +date: 2024-02-07 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 aaf8715eb5d6..defdbfcf752d 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-02-06 +date: 2024-02-07 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 7f1def4d0a2a..e462b53bbe0a 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-02-06 +date: 2024-02-07 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 a961d37be58c..554783ac18a7 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-02-06 +date: 2024-02-07 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 2c88d63ab0d8..b9a1be9ff7ba 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-02-06 +date: 2024-02-07 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 228c2020f369..2cf86d87ee44 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-02-06 +date: 2024-02-07 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 01fa939f7915..c342f014d337 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-02-06 +date: 2024-02-07 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 dd124ffcaedd..0f458ac648a8 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-02-06 +date: 2024-02-07 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 71458bff2a57..fb3409a1b72a 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-02-06 +date: 2024-02-07 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 b0a1c5876528..121a253b7fd3 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-02-06 +date: 2024-02-07 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 69697d6d2f47..29d44218fba4 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-02-06 +date: 2024-02-07 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 d5b965e11d2c..e7d08297f3f0 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-02-06 +date: 2024-02-07 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 ef2e9f2a5a74..5bd6809ec7fc 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-02-06 +date: 2024-02-07 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 3563e206a964..9479895594b9 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-02-06 +date: 2024-02-07 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 f6d96fedc306..503f1dd752f2 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-02-06 +date: 2024-02-07 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 e6c1c078cbce..40b5ec41d5b0 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-02-06 +date: 2024-02-07 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 8e0464630823..5c0687ba846e 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-02-06 +date: 2024-02-07 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 d1d29177c928..175d427be133 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-02-06 +date: 2024-02-07 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 d116b29ce8ee..9c964617deec 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-02-06 +date: 2024-02-07 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 fee46feb5b07..31a20ae4eb4a 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-02-06 +date: 2024-02-07 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 b569fa83916a..b58dcee47c56 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-02-06 +date: 2024-02-07 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 6b7afd38ef67..3cc6dc60b704 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-02-06 +date: 2024-02-07 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 f0b8e07e2e9d..9143f421c163 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-02-06 +date: 2024-02-07 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 2e3173be55ed..2255d80da482 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-02-06 +date: 2024-02-07 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 29bb19e33df5..54bb7f13f99b 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-02-06 +date: 2024-02-07 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 438c85d09c14..edaac85c0d9e 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-02-06 +date: 2024-02-07 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 21b0c35b5502..ae7f085a7337 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-02-06 +date: 2024-02-07 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 6fb03f0aa5eb..fe2bc41f4598 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-02-06 +date: 2024-02-07 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 87f6efa4c6a6..ca9cf933ee7b 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-02-06 +date: 2024-02-07 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 fd55ac491cd7..063ad28cfb84 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-02-06 +date: 2024-02-07 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 a69316b541d8..721614015137 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-02-06 +date: 2024-02-07 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 27c608dd9130..3c4f18032a02 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-02-06 +date: 2024-02-07 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 60128b006cf7..c31342361655 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-02-06 +date: 2024-02-07 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 ed0e3a6bdfcd..1665c11768fb 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-02-06 +date: 2024-02-07 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 c98ff042a8a1..5f563aad2126 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-02-06 +date: 2024-02-07 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 a80094812354..aa05ee1e48ae 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-02-06 +date: 2024-02-07 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 c4e2b026fb5e..4a47db4503d2 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-02-06 +date: 2024-02-07 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 60131299942e..a535c44c1086 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-02-06 +date: 2024-02-07 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 a88a158600a1..82ddfe913f04 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-02-06 +date: 2024-02-07 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 40c2774754ed..063206d39208 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-02-06 +date: 2024-02-07 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 e49fdfbd8163..2951f1f0ae58 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-02-06 +date: 2024-02-07 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 a5ca3bde5e01..62ca17a0e5ed 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-02-06 +date: 2024-02-07 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 c72c70190e53..8b1312793623 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-02-06 +date: 2024-02-07 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 97ec876ed71c..dd8d00c19a9c 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-02-06 +date: 2024-02-07 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 978eef3c68a0..f27c008baf81 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-02-06 +date: 2024-02-07 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 938a4a00244c..c269780d7290 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-02-06 +date: 2024-02-07 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 55864a854420..090d6a37c599 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-02-06 +date: 2024-02-07 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 1882082ad9c8..b9f02f7b8063 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-02-06 +date: 2024-02-07 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 fedd31f22a2d..72c15222edf1 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-02-06 +date: 2024-02-07 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 f361165a1596..7084245ddd0c 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-02-06 +date: 2024-02-07 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 0789371fbea3..7079ebd6a73a 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-02-06 +date: 2024-02-07 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 acc9c2857d08..b22d1453c6f5 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-02-06 +date: 2024-02-07 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 f325cc00a78c..182e61b01ac2 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index b33b06c0ea59..c5611f0d5ecb 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-02-06 +date: 2024-02-07 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 538b48354645..ec1a657fa133 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-02-06 +date: 2024-02-07 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 a9e748cede53..b60018e61198 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-02-06 +date: 2024-02-07 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 02303e8c6e9e..efdf29935243 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-02-06 +date: 2024-02-07 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 e4e95e1c2ded..22864c7ec1db 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-02-06 +date: 2024-02-07 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 170bf5bef525..6559762b2f80 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-02-06 +date: 2024-02-07 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 ae0385605894..6a4a7db0eaed 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-02-06 +date: 2024-02-07 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 e4ea770897c3..9304825ba54e 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-02-06 +date: 2024-02-07 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 7217d645f164..2cf5108285fc 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-02-06 +date: 2024-02-07 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 bee5f215e488..c41cdefa3da7 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-02-06 +date: 2024-02-07 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 4e201f8fd0ed..9124cb698c65 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 2196942caa8d..de2bc5689514 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-02-06 +date: 2024-02-07 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 dd8b245f82d1..80085f910f5e 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-02-06 +date: 2024-02-07 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 49d9bb653fe6..7a2b9c8ac112 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index fe1d6c5b8e71..d9c5d66a99bb 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-02-06 +date: 2024-02-07 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 ba2ee1d33dae..30c4af84e5a4 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-02-06 +date: 2024-02-07 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 b274a12dd05d..ba4733defd34 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-02-06 +date: 2024-02-07 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 13357217e24d..4a15dc47c816 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-02-06 +date: 2024-02-07 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 df12817ab9a4..6cf979f0261f 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-02-06 +date: 2024-02-07 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 3cd093904020..4c587e63db3b 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-02-06 +date: 2024-02-07 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 9004d9222d10..ab2a4d0be730 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-02-06 +date: 2024-02-07 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 2cd080e06f37..806b69e27e05 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-02-06 +date: 2024-02-07 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 6feab333d928..68a98c721226 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-02-06 +date: 2024-02-07 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 c55751c63f6c..748950c569ab 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-02-06 +date: 2024-02-07 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 9b5370c4b82a..151e4ffa3998 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-02-06 +date: 2024-02-07 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 663337ece23c..d64103a09a6c 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-02-06 +date: 2024-02-07 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 f5fcf617a256..5a382a3192a5 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-02-06 +date: 2024-02-07 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 65a943f74a81..705c34f87bab 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-02-06 +date: 2024-02-07 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 8470b1a4d3dc..4742b413aa6d 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-02-06 +date: 2024-02-07 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 ee4434b1803b..ca1e370734c6 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-02-06 +date: 2024-02-07 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 7e932afec8f0..85d427df7c71 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-02-06 +date: 2024-02-07 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 84ea1690ee3d..0a4f67b9a753 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-02-06 +date: 2024-02-07 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 1ae529f7456e..df82765ea644 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-02-06 +date: 2024-02-07 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 b2398805a454..d73f84ec7fd4 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-02-06 +date: 2024-02-07 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 6674e8316ca9..e1e27f1cdf29 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-02-06 +date: 2024-02-07 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 262e41de053e..7eac5a6600a8 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-02-06 +date: 2024-02-07 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 613892121690..7d0b25e8fabd 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-02-06 +date: 2024-02-07 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 51418ee079d5..4d7d6a2e2d22 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-02-06 +date: 2024-02-07 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 2f153b9bb19c..e7968c98c421 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-02-06 +date: 2024-02-07 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 49f8dcf2cab0..562ac202418c 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-02-06 +date: 2024-02-07 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 c46847bc8cb2..9f3cdd38409c 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-02-06 +date: 2024-02-07 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 f0d2aa8a0658..8beea22f363c 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-02-06 +date: 2024-02-07 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 c909c6a46f64..0c9fe7d2c3f1 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-02-06 +date: 2024-02-07 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 54a7ef7037c7..3607a652afbc 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-02-06 +date: 2024-02-07 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 ac3bcf794e6b..eb3bea3079a5 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-02-06 +date: 2024-02-07 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 48e1d28773ad..c7ed781fafec 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-02-06 +date: 2024-02-07 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 f8980967a8b5..fbb9d03805dc 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-02-06 +date: 2024-02-07 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 8bb456a5b54c..93bf10eaa2ea 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-02-06 +date: 2024-02-07 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 eeb6564f1416..d566c128b696 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-02-06 +date: 2024-02-07 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 588c3a1f3aa8..a6427417916f 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-02-06 +date: 2024-02-07 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 9702734df04e..b8ad18194e5d 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-02-06 +date: 2024-02-07 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 84b3e36a3f83..5263ad7d7c4d 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-02-06 +date: 2024-02-07 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 450b0acd26b3..f2e104f8c13f 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-02-06 +date: 2024-02-07 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 7ad27b405842..88c731a141f5 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index f9aead4dc80f..4e1d813cdd84 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-02-06 +date: 2024-02-07 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 fef386d75747..7d5928c49700 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-02-06 +date: 2024-02-07 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 5eea0fb87076..1c53b5d41579 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-02-06 +date: 2024-02-07 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 1fb2a54ca2d0..3323d8bd2395 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-02-06 +date: 2024-02-07 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 8d04c99906e9..66b77f3667e5 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-02-06 +date: 2024-02-07 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.devdocs.json b/api_docs/kbn_core_saved_objects_api_server.devdocs.json index 606ddff1badb..3b1b515c4465 100644 --- a/api_docs/kbn_core_saved_objects_api_server.devdocs.json +++ b/api_docs/kbn_core_saved_objects_api_server.devdocs.json @@ -2688,7 +2688,7 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" + "path": "x-pack/plugins/alerting/common/rule.ts" }, { "plugin": "alerting", @@ -2708,7 +2708,7 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" + "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" }, { "plugin": "alerting", @@ -2716,7 +2716,7 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/types.ts" + "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" }, { "plugin": "alerting", diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index a368849d16b6..d8043104507f 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-02-06 +date: 2024-02-07 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 985d89fac09a..0d1c875736b9 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-02-06 +date: 2024-02-07 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 0c9020243e0f..633b52e220da 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-02-06 +date: 2024-02-07 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 4ce9b3cfa38e..f2453ed77fac 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-02-06 +date: 2024-02-07 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 39839ac0a25a..ea082bd4f468 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-02-06 +date: 2024-02-07 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 99afe2bcc887..2e5d73970fad 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-02-06 +date: 2024-02-07 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 6ed8b1ecd614..d3075162b50f 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-02-06 +date: 2024-02-07 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 b124f8debcf7..5c0a58f6b910 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-02-06 +date: 2024-02-07 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 e9a23417bebb..be0edf30eb7d 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-02-06 +date: 2024-02-07 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 898fe16bac52..61823b55025d 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-02-06 +date: 2024-02-07 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 b1d3cf267ee9..7737c3dfcdc8 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-02-06 +date: 2024-02-07 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 3432f4b3b16e..550d257671bf 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-02-06 +date: 2024-02-07 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 87524176d720..9bcb155c4e2b 100644 --- a/api_docs/kbn_core_saved_objects_server.devdocs.json +++ b/api_docs/kbn_core_saved_objects_server.devdocs.json @@ -6153,7 +6153,7 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" + "path": "x-pack/plugins/alerting/common/rule.ts" }, { "plugin": "alerting", @@ -6173,7 +6173,7 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" + "path": "x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts" }, { "plugin": "alerting", @@ -6181,7 +6181,7 @@ }, { "plugin": "alerting", - "path": "x-pack/plugins/alerting/server/types.ts" + "path": "x-pack/plugins/alerting/server/rules_client/common/inject_references.ts" }, { "plugin": "alerting", diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 1c24ac52319f..b95826689a52 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-02-06 +date: 2024-02-07 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 fbbcddac6830..3f5db434d2fd 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-02-06 +date: 2024-02-07 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 7dff2c04d722..e19262fe28b0 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-02-06 +date: 2024-02-07 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 b87494b4f06c..90818591895a 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 7f097998ff59..c33731667715 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 4495fda10856..0f7ee0de49fc 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index 087f37221e83..e7e419b29859 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-02-06 +date: 2024-02-07 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 9ae8e4574055..8fdeb27e63cf 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-02-06 +date: 2024-02-07 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 3b15855ef32d..57d27b65f4fb 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-02-06 +date: 2024-02-07 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 1b2701833b89..2f98bdd5ba8d 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-02-06 +date: 2024-02-07 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 31dfd2c74531..41fc0ff7ffbf 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-02-06 +date: 2024-02-07 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 968d1581023b..ff8569e7830b 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-02-06 +date: 2024-02-07 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 78938506b042..013ec2fe582f 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-02-06 +date: 2024-02-07 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 d12acbe12399..84474e2d8a5a 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-02-06 +date: 2024-02-07 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 3428d38ff24b..a2454558d877 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-02-06 +date: 2024-02-07 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 2a2af27f31ef..f27753fd06fe 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-02-06 +date: 2024-02-07 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 ff13e715fc0d..a4fc9aae34f5 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-02-06 +date: 2024-02-07 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 6aa50869ac90..3602bf585846 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-02-06 +date: 2024-02-07 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 a9bb775f0a87..54aa3ab2c1eb 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-02-06 +date: 2024-02-07 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 82f29c19d596..82fcc597ecee 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-02-06 +date: 2024-02-07 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 65c54c8be109..3697a60de41c 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-02-06 +date: 2024-02-07 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 8ffecb0c9c2a..2087c10bd0b6 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-02-06 +date: 2024-02-07 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 ace3240eb7d6..fa0d22c41b7e 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-02-06 +date: 2024-02-07 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 eb49bee9ae66..f863f1bd1bc9 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-02-06 +date: 2024-02-07 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 db2c3f0f3535..b34cbe38e144 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-02-06 +date: 2024-02-07 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 425ceb071460..783abef87e49 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-02-06 +date: 2024-02-07 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 1501cf4b2696..084adca5b387 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index b8c0f53bb2a2..778faf430744 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index fec6068427ac..a5baffb86544 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 5da7b2b15aa0..5e971a65909a 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-02-06 +date: 2024-02-07 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 0cfff6a5347e..1e5c50e4a495 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-02-06 +date: 2024-02-07 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 e9c592581124..057726904409 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-02-06 +date: 2024-02-07 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 b8b96ecc6067..2e0fce4a2866 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-02-06 +date: 2024-02-07 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 d24ee19bc4e7..7b8c477df7fb 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-02-06 +date: 2024-02-07 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 828ab8627e78..2589f904480f 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-02-06 +date: 2024-02-07 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 460845d7f4da..0bebaa9bbafd 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-02-06 +date: 2024-02-07 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 816344847b2b..36519191727a 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-02-06 +date: 2024-02-07 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 c19090b52a50..f52ee3404261 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-stream-adapter'] --- import kbnDataStreamAdapterObj from './kbn_data_stream_adapter.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index e787c9a27d73..3cd087353772 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-02-06 +date: 2024-02-07 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 41d4ec9b8b59..1c18b0f38da1 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-02-06 +date: 2024-02-07 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 d77e79da1bbe..e06313d5e26b 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index 2432b3da767c..0110986c4236 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-02-06 +date: 2024-02-07 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 2f26ee59c758..72559ebe19e0 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-02-06 +date: 2024-02-07 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 d8b2cee06eac..0a2ae4ff3d01 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-02-06 +date: 2024-02-07 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 6adc27bb6bb4..322e7f952dee 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index 16f0e1e32b39..ec04c8d3098d 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-02-06 +date: 2024-02-07 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 5c69e07a049f..242fb6d69d83 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-02-06 +date: 2024-02-07 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 00b33c7e5759..9ec2da49f04a 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-02-06 +date: 2024-02-07 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 93829acabe4c..d2ceda766c05 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-02-06 +date: 2024-02-07 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 7616688e5f3d..68353954d9e6 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-02-06 +date: 2024-02-07 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 876628413d81..9c17d43669d8 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-02-06 +date: 2024-02-07 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 a9b08a7ac926..380b09055b98 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-02-06 +date: 2024-02-07 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 32fb2f770d64..719e14e2f62f 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 62fcf0a671a0..39d3a3891f4a 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-02-06 +date: 2024-02-07 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 df299f1012b6..dcfc6e4a6a4a 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-02-06 +date: 2024-02-07 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 55f1d9b07d68..49bc90f53ca0 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-02-06 +date: 2024-02-07 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 852703f630cd..a019b3bb74be 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-02-06 +date: 2024-02-07 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 38200d421625..6282aa3edfae 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 4cd147a3272e..25e32dfe402b 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index 76ccb301aa05..41867eca525c 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,14 +8,14 @@ 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; -Contact [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) for questions regarding this plugin. +Contact [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) for questions regarding this plugin. **Code health stats** diff --git a/api_docs/kbn_elastic_agent_utils.mdx b/api_docs/kbn_elastic_agent_utils.mdx index 97b89901634b..adfdd843f70e 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-02-06 +date: 2024-02-07 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 22fe5bde1140..ae338e411547 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-02-06 +date: 2024-02-07 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 cb3d84351eeb..20aaa7176032 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant-common'] --- import kbnElasticAssistantCommonObj from './kbn_elastic_assistant_common.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 0893d7529d22..8b252d558d15 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-02-06 +date: 2024-02-07 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 fc3b897160d5..efa1967e1ac9 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-02-06 +date: 2024-02-07 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 f96d10525c4a..a25b94c26975 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-02-06 +date: 2024-02-07 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 bfdf28c2ec20..b1d831e76150 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.devdocs.json b/api_docs/kbn_es_types.devdocs.json index 91d8256af2de..5ace284b455c 100644 --- a/api_docs/kbn_es_types.devdocs.json +++ b/api_docs/kbn_es_types.devdocs.json @@ -199,6 +199,20 @@ "path": "packages/kbn-es-types/src/search.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "@kbn/es-types", + "id": "def-common.ESQLSearchParams.dropNullColumns", + "type": "CompoundType", + "tags": [], + "label": "dropNullColumns", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "packages/kbn-es-types/src/search.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 1324271d4210..48b0328864cf 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 31 | 0 | 31 | 0 | +| 32 | 0 | 32 | 0 | ## Common diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 4b157a443cf5..b7e8a2218fdb 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-02-06 +date: 2024-02-07 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_utils.mdx b/api_docs/kbn_esql_utils.mdx index 547f34558cb8..2a064b15d03b 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/esql-utils'] --- import kbnEsqlUtilsObj from './kbn_esql_utils.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index 08e7de2f799e..72293fae53ab 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-02-06 +date: 2024-02-07 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 d60e3e73c5bc..6497854ede2b 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-02-06 +date: 2024-02-07 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 bbc7cdcd8df7..289cdd0a644d 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-02-06 +date: 2024-02-07 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 f8e6e0216525..735ece03762c 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-02-06 +date: 2024-02-07 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 4235cb3f7332..8b6cc0a5b1f7 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-02-06 +date: 2024-02-07 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 b9a765a1e7a1..2fea6be43d4c 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index de924d6ddcd5..3f128871c2ab 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-02-06 +date: 2024-02-07 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 a47592eeef1c..160dcb36b94d 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-02-06 +date: 2024-02-07 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 7506a658de0a..34509d60e8ec 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-02-06 +date: 2024-02-07 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 a7bb62530a3a..9913901a3f50 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-02-06 +date: 2024-02-07 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.devdocs.json b/api_docs/kbn_generate_csv.devdocs.json index 2c04fe339b8d..95e83e2c2293 100644 --- a/api_docs/kbn_generate_csv.devdocs.json +++ b/api_docs/kbn_generate_csv.devdocs.json @@ -84,6 +84,21 @@ "id": "def-server.CsvESQLGenerator.Unnamed.$3", "type": "Object", "tags": [], + "label": "taskInstanceFields", + "description": [], + "signature": [ + "TaskInstanceFields" + ], + "path": "packages/kbn-generate-csv/src/generate_csv_esql.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/generate-csv", + "id": "def-server.CsvESQLGenerator.Unnamed.$4", + "type": "Object", + "tags": [], "label": "clients", "description": [], "signature": [ @@ -96,7 +111,7 @@ }, { "parentPluginId": "@kbn/generate-csv", - "id": "def-server.CsvESQLGenerator.Unnamed.$4", + "id": "def-server.CsvESQLGenerator.Unnamed.$5", "type": "Object", "tags": [], "label": "cancellationToken", @@ -117,7 +132,7 @@ }, { "parentPluginId": "@kbn/generate-csv", - "id": "def-server.CsvESQLGenerator.Unnamed.$5", + "id": "def-server.CsvESQLGenerator.Unnamed.$6", "type": "Object", "tags": [], "label": "logger", @@ -138,7 +153,7 @@ }, { "parentPluginId": "@kbn/generate-csv", - "id": "def-server.CsvESQLGenerator.Unnamed.$6", + "id": "def-server.CsvESQLGenerator.Unnamed.$7", "type": "Object", "tags": [], "label": "stream", diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index e1cb72049c4c..eb4420f2bfce 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 25 | 0 | 25 | 1 | +| 26 | 0 | 26 | 1 | ## Server diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index eeb4d22e129e..573755f508a8 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-02-06 +date: 2024-02-07 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 0b72e3d554cd..a084cd640a59 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-02-06 +date: 2024-02-07 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 d04a04ed6c18..ec6163cbb74f 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-02-06 +date: 2024-02-07 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 472014d1613f..cafa671eba42 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-02-06 +date: 2024-02-07 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 a0651d103e0a..93a390b1aaac 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-02-06 +date: 2024-02-07 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 e4c6bf586d13..81df1c1ced89 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-02-06 +date: 2024-02-07 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 bc77044f72cf..120ce9b73114 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-02-06 +date: 2024-02-07 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 d7d3f798c8b1..751c1c5a7f70 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-02-06 +date: 2024-02-07 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 2528b53c34a3..bf7579288297 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index 22fe238380de..23fdabc43b59 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-02-06 +date: 2024-02-07 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 d981494b8edb..8d076669808d 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index a51c7212f56f..a5c74c37a920 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index b215a975547a..9a0baf4aa8c3 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-02-06 +date: 2024-02-07 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 2226d8756766..262147a7a3e1 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-02-06 +date: 2024-02-07 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 3dc1448fa0ae..043223345837 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 4c57c6fd07cb..9f12ba2aef38 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index ed5f8232c52b..08c19c2aef81 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_lens_embeddable_utils.mdx b/api_docs/kbn_lens_embeddable_utils.mdx index 4818309ae805..03bb0eb19268 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-02-06 +date: 2024-02-07 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 f19a58524b96..a9bc9f0fcc49 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-02-06 +date: 2024-02-07 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 eb44abe43784..9dbe6ce12058 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-02-06 +date: 2024-02-07 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 f741c1fbdace..ce83ceb399c8 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-02-06 +date: 2024-02-07 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 80b99c251cad..93d8f78ae67c 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-02-06 +date: 2024-02-07 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 30b842fc1c90..958857f7ca63 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-02-06 +date: 2024-02-07 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 2b90e436b28c..79cfc21a6789 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-02-06 +date: 2024-02-07 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 5d245064c6a5..3cfca3b87651 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-02-06 +date: 2024-02-07 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 9fccc82c6657..332a136ca42b 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-02-06 +date: 2024-02-07 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 2a07753fc657..e9f9ded87a48 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-02-06 +date: 2024-02-07 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 48973d1dc44b..ebf02d9f74f4 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-02-06 +date: 2024-02-07 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 06e2601224c1..463c2a3a7897 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-02-06 +date: 2024-02-07 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 14cbadf9f7e8..faf8e0b173dd 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-02-06 +date: 2024-02-07 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 44309b4d7bfe..c3f9577e72bb 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-02-06 +date: 2024-02-07 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 d044ebd5f34d..ca62c84ccce5 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-02-06 +date: 2024-02-07 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 c85740d0526a..0eaf07f4388c 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-02-06 +date: 2024-02-07 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 8022f1827fe2..b78b135f68c1 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-02-06 +date: 2024-02-07 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 589ce76ac467..b120fd79c6b6 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index c459fc919d07..4c2fd9c354c4 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-02-06 +date: 2024-02-07 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 5c2456534e63..3156a0b5253b 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-02-06 +date: 2024-02-07 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 1ed88e5862fe..65fa63b4b0fa 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-02-06 +date: 2024-02-07 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 7772fbf05a6c..8f3c352f2bdc 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-02-06 +date: 2024-02-07 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 c2448dbeac55..96fea890ba88 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-02-06 +date: 2024-02-07 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 75f6f227f960..371bb202c9ad 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-02-06 +date: 2024-02-07 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 6e62058076a4..80c63d0937b1 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-02-06 +date: 2024-02-07 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 d8acc972e5f3..442f2c67ec3a 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-02-06 +date: 2024-02-07 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 40ba8011e9f2..2af285926a1b 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-02-06 +date: 2024-02-07 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 68706d43e368..bd2cdbfa3b20 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-02-06 +date: 2024-02-07 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 54836fba2567..d38c3ca14864 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-02-06 +date: 2024-02-07 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 fbb184a614d2..aa4eccea2633 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index 4b39c2b82305..9a43b5dd01fd 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-02-06 +date: 2024-02-07 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 59706d8d98b2..cc059d71e8c4 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-02-06 +date: 2024-02-07 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 db64fb9b2559..5ce23fd69cc0 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-02-06 +date: 2024-02-07 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 842c5ecd55d9..6ede7c856148 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-02-06 +date: 2024-02-07 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 49a2d524d419..8bfbfb5ac2ae 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-02-06 +date: 2024-02-07 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 181a27d2f508..f7d711f7a4a7 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-02-06 +date: 2024-02-07 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 e51866d50d45..be07b8ea9014 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index e54a874bb6b7..9a40e0d51ef5 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-02-06 +date: 2024-02-07 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 08c3661724bc..11d18ded956d 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-02-06 +date: 2024-02-07 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 96a746bb7893..273ba65c6eb2 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-02-06 +date: 2024-02-07 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 b7dc4f841cbf..9fd0dcbb0d14 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-02-06 +date: 2024-02-07 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 789bfb24bfdd..5d2919ca314a 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 71081d69a172..47fb2ddfcd11 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-02-06 +date: 2024-02-07 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 b67e9905b57f..d82e91afb17b 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-02-06 +date: 2024-02-07 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 ddb44af1648c..7b6df5cca772 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_mock_idp_utils.mdx b/api_docs/kbn_mock_idp_utils.mdx index 0276054e65e3..03d015430996 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-02-06 +date: 2024-02-07 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 1bd748850dfb..811e3a48e3bf 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-02-06 +date: 2024-02-07 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 e4ebca8c7c3d..bd7fc4c86ab0 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index fb6b83ae28c4..5ee6ac304825 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_observability_alerting_test_data.mdx b/api_docs/kbn_observability_alerting_test_data.mdx index 6dbe1c8bd9a0..04a28191684b 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-02-06 +date: 2024-02-07 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 706f0db8f861..8231ab4d5566 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-get-padded-alert-time-range-util'] --- import kbnObservabilityGetPaddedAlertTimeRangeUtilObj from './kbn_observability_get_padded_alert_time_range_util.devdocs.json'; diff --git a/api_docs/kbn_openapi_bundler.mdx b/api_docs/kbn_openapi_bundler.mdx index 9c1f2f6c169c..b0bf138817dc 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-02-06 +date: 2024-02-07 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 af493391a409..14b1f907daa3 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-02-06 +date: 2024-02-07 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 ead372562c7e..981ee63b9fe7 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-02-06 +date: 2024-02-07 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 4936d037ec02..71150e348958 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-02-06 +date: 2024-02-07 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 6c45eaf31e16..ecb0af21bf21 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-02-06 +date: 2024-02-07 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 2c2b3fd19fe0..84be618cee3f 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-02-06 +date: 2024-02-07 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 1c5f0f0c4170..a34bab2f85fc 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-02-06 +date: 2024-02-07 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 0b3ba8b76977..c712168992dc 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-02-06 +date: 2024-02-07 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 f879b4e8236a..9c66e48a438a 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-02-06 +date: 2024-02-07 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 0fc6b89f143f..39dbef24ba4d 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-02-06 +date: 2024-02-07 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 0935b4bb7425..a44d44c1edea 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-containers'] --- import kbnPresentationContainersObj from './kbn_presentation_containers.devdocs.json'; diff --git a/api_docs/kbn_presentation_library.mdx b/api_docs/kbn_presentation_library.mdx index 0d36335b26da..c151a8d33566 100644 --- a/api_docs/kbn_presentation_library.mdx +++ b/api_docs/kbn_presentation_library.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-presentation-library title: "@kbn/presentation-library" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/presentation-library plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-library'] --- import kbnPresentationLibraryObj from './kbn_presentation_library.devdocs.json'; diff --git a/api_docs/kbn_presentation_publishing.mdx b/api_docs/kbn_presentation_publishing.mdx index ad99ee373708..1a149f1ea300 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/presentation-publishing'] --- import kbnPresentationPublishingObj from './kbn_presentation_publishing.devdocs.json'; diff --git a/api_docs/kbn_profiling_utils.mdx b/api_docs/kbn_profiling_utils.mdx index 179a1ab961ec..b8b1337aa4e6 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-02-06 +date: 2024-02-07 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 c8cb939c8cf3..0501b7bf93dc 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-02-06 +date: 2024-02-07 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 ab090b72f9f1..c1caca7f748d 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index 99753a56a4b3..69a9dae1a196 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-02-06 +date: 2024-02-07 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 466d6a4b769d..740aa5050817 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-02-06 +date: 2024-02-07 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 2072a990a74a..5a735e4cf3de 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-02-06 +date: 2024-02-07 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 09aa19ae4bc7..266795961f42 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-02-06 +date: 2024-02-07 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 92a6872e643b..52e6c4cfd2c6 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-02-06 +date: 2024-02-07 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 badc14cc8e9e..75c8572a3904 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index ccc2cc63268c..7a05363a5214 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-02-06 +date: 2024-02-07 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 5e4ebc3565ac..1e894cf273c4 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-02-06 +date: 2024-02-07 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 62cdfd40fcff..bc95c05cf2a1 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-02-06 +date: 2024-02-07 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 991da947619d..6261995e2152 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-02-06 +date: 2024-02-07 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 f9df3e1d6f75..ffc494375b77 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_reporting_export_types_csv.mdx b/api_docs/kbn_reporting_export_types_csv.mdx index 4d9808caae0a..0925fa800805 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-02-06 +date: 2024-02-07 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 1d2e0cb5f145..e9bf662be5cb 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-02-06 +date: 2024-02-07 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 f7b500e5a235..0508c69fc9ff 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-02-06 +date: 2024-02-07 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 3739963bf9dd..dd9a403c7bd8 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-02-06 +date: 2024-02-07 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 9496b7901f6d..00413562e36a 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-02-06 +date: 2024-02-07 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 504ec31b49a3..3703793a166b 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-02-06 +date: 2024-02-07 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 64a51744fbcf..8920bec39bf6 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-02-06 +date: 2024-02-07 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 45116d97eb98..ad51a406bd91 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-02-06 +date: 2024-02-07 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 db291a86830a..916ad049b16d 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-02-06 +date: 2024-02-07 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 d9173a65b476..437df4dce017 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/resizable-layout'] --- import kbnResizableLayoutObj from './kbn_resizable_layout.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index c4f4203f935d..5b05a13a7ee9 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_router_utils.mdx b/api_docs/kbn_router_utils.mdx index bee4c01d9855..1cef1db77856 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-02-06 +date: 2024-02-07 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 d62bd8b3f391..9b4d6f908ac8 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-02-06 +date: 2024-02-07 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 cb00e1cd8546..27a4f1fb5ddf 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-02-06 +date: 2024-02-07 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 83edce7d987a..fe319b552d26 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_search_api_panels.mdx b/api_docs/kbn_search_api_panels.mdx index 1e2765a78bef..980026cb46f0 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-02-06 +date: 2024-02-07 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 8e4485adab1a..e0e95a1b88c2 100644 --- a/api_docs/kbn_search_connectors.devdocs.json +++ b/api_docs/kbn_search_connectors.devdocs.json @@ -1350,8 +1350,8 @@ "text": "ElasticsearchClient" }, ", connectorId: string, isNative: boolean) => Promise<", - "UpdateResponse", - ">" + "Result", + ">" ], "path": "packages/kbn-search-connectors/lib/update_native.ts", "deprecated": false, @@ -1898,7 +1898,7 @@ "text": "ElasticsearchClient" }, ", connectorId: string, indexName: string) => Promise<", - "WriteResponseBase", + "Result", ">" ], "path": "packages/kbn-search-connectors/lib/update_connector_index_name.ts", @@ -2258,7 +2258,7 @@ "text": "ConnectorStatus" }, ") => Promise<", - "WriteResponseBase", + "Result", ">" ], "path": "packages/kbn-search-connectors/lib/update_connector_status.ts", diff --git a/api_docs/kbn_search_connectors.mdx b/api_docs/kbn_search_connectors.mdx index 4a20dc3f3643..5b48e6afa90a 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-connectors'] --- import kbnSearchConnectorsObj from './kbn_search_connectors.devdocs.json'; diff --git a/api_docs/kbn_search_errors.mdx b/api_docs/kbn_search_errors.mdx index ba6a624965f7..7eaa6b747aa5 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-02-06 +date: 2024-02-07 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 0a04eafb8703..81dd1e0727bf 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-02-06 +date: 2024-02-07 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 a034030c2007..d1a8b19013b1 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/search-response-warnings'] --- import kbnSearchResponseWarningsObj from './kbn_search_response_warnings.devdocs.json'; diff --git a/api_docs/kbn_security_plugin_types_common.mdx b/api_docs/kbn_security_plugin_types_common.mdx index e48936a57e8b..26578a20ada2 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-02-06 +date: 2024-02-07 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 eb0dc50628d0..4cb43c5300c8 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-02-06 +date: 2024-02-07 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 f983957c4380..4a16025702cd 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-02-06 +date: 2024-02-07 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_solution_features.mdx b/api_docs/kbn_security_solution_features.mdx index 97d1145b772c..2114c9b35835 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-02-06 +date: 2024-02-07 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 383aeb868d21..dccd3e8b2bc2 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-02-06 +date: 2024-02-07 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 a9a5a80552a5..d5ab11ffa55e 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-02-06 +date: 2024-02-07 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 ba0077491597..2e00413d1d20 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 25d574c3cf91..c5ed87981cbe 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-02-06 +date: 2024-02-07 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 b464bbcfd170..053e4097ff49 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-02-06 +date: 2024-02-07 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 c2dd690fe0d9..42d769bea843 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-02-06 +date: 2024-02-07 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 9b2b2a341d49..fe8b7c70ee53 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-02-06 +date: 2024-02-07 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 a1d63457ed60..947265540f56 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 35ed6dea5380..9ec6d33ef602 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 5d24b3dfb264..90c6011c58e2 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-02-06 +date: 2024-02-07 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 69715001964b..a20b15ca253a 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-02-06 +date: 2024-02-07 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 cb61e0d0384a..76787f54b5f5 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-02-06 +date: 2024-02-07 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 ab83f59b9971..7de1ceeb6748 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-02-06 +date: 2024-02-07 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 b17f32e82c20..fb562facd22b 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-02-06 +date: 2024-02-07 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 f1202e093f82..3fc3a0250b1e 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-02-06 +date: 2024-02-07 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 5b7cced8976d..1ad56da232f8 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-02-06 +date: 2024-02-07 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 f3b28d5c1dc5..35a6c48669d6 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-02-06 +date: 2024-02-07 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 4ce5ff65b39e..154eb52d0463 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-02-06 +date: 2024-02-07 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 0c149fe3dc14..bf953c9cac54 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-02-06 +date: 2024-02-07 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 e5e2cff0bd26..b45c9209aa46 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-02-06 +date: 2024-02-07 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 8d6715e6c164..cd737dcbce57 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-02-06 +date: 2024-02-07 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 c65173d23988..e7a8d5fda826 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-02-06 +date: 2024-02-07 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 7602ff2991b0..9d1746430fd3 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_common_settings.mdx b/api_docs/kbn_serverless_common_settings.mdx index 76da512c0663..a2ea62bf8d8f 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-02-06 +date: 2024-02-07 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 7f698d6757ae..fd5b569a35d7 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-02-06 +date: 2024-02-07 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 afd21ef474ee..e45f587b3306 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-02-06 +date: 2024-02-07 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 ce09e222b9c3..7f941b99fd3c 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-02-06 +date: 2024-02-07 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 02b4f1c9695f..d8ed16116d30 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-02-06 +date: 2024-02-07 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 8df47db0ab74..2cd19490dc41 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-02-06 +date: 2024-02-07 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 2275a324c281..a8621f5cfb8f 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-02-06 +date: 2024-02-07 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 196bbce1d06b..84595af506bc 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-02-06 +date: 2024-02-07 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 0635a33afad9..fc4494749851 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-02-06 +date: 2024-02-07 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 cda917e73230..bbd742127371 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-02-06 +date: 2024-02-07 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 6442eeb2b4eb..aaf383f2235d 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-02-06 +date: 2024-02-07 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 6f3105d66dc4..a2eea7464b58 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-02-06 +date: 2024-02-07 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 54770eb79543..2b5147e127d0 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-02-06 +date: 2024-02-07 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 650edf07e823..bf9ba0a0a366 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-02-06 +date: 2024-02-07 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 2ffd7a4b71b9..f3945a4f9a57 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-02-06 +date: 2024-02-07 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 6b4010ae5b34..dfc1c7ce08e5 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-02-06 +date: 2024-02-07 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 a9d059487be0..5409cc9b1fea 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-02-06 +date: 2024-02-07 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 85ea2f535620..89023f195088 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-02-06 +date: 2024-02-07 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 8c1616d34ff8..7017e8b730be 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-02-06 +date: 2024-02-07 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 7c87846acafe..a0a1c1c5401e 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-02-06 +date: 2024-02-07 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 8d6d4260b489..389eac8a318c 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-02-06 +date: 2024-02-07 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 6e214e67b898..2de007264f07 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-02-06 +date: 2024-02-07 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 5bcd57c80834..e2c789981630 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-02-06 +date: 2024-02-07 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 f60540cc7cfc..9614c2d9ec72 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-02-06 +date: 2024-02-07 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 2119b3136ef7..d429245466b1 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-02-06 +date: 2024-02-07 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 202ca03eaae5..23cf080050d2 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-02-06 +date: 2024-02-07 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 8c0881e96c45..5754df2b1c92 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-02-06 +date: 2024-02-07 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 3d77c6179323..037c5534676a 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-02-06 +date: 2024-02-07 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 638ce190d1f8..65c22c57b12c 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-02-06 +date: 2024-02-07 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 cd54fc9267ac..7cff5aa8ac6c 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-02-06 +date: 2024-02-07 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 d93fbd83448f..2f92c76ede63 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-02-06 +date: 2024-02-07 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 8d0d7cc536eb..c03aa44c1273 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-02-06 +date: 2024-02-07 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 5e4e559083fd..44b448913fc0 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-02-06 +date: 2024-02-07 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 467d09ef6efd..ca2aa34d8d30 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-02-06 +date: 2024-02-07 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 d11feaec25c7..7b49d2bfa155 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-02-06 +date: 2024-02-07 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 e28ff141b4ea..0c964dc868df 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-02-06 +date: 2024-02-07 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 9dade6e95627..3b9847017840 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-02-06 +date: 2024-02-07 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 811ccc936df2..294dff1106e5 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-02-06 +date: 2024-02-07 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 46ac16689d4f..ff2135568798 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-02-06 +date: 2024-02-07 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 3ef1c6243eeb..abedb63711b0 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-02-06 +date: 2024-02-07 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 00409bdebddf..9cd99643b0ad 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-02-06 +date: 2024-02-07 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 61a758c6dfd3..54a3934ef59d 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-02-06 +date: 2024-02-07 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 7c36ca5ff5cd..72f3abd64678 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-02-06 +date: 2024-02-07 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 d861b5802005..64487e494b69 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index ec74b937ad55..58db85c5e810 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index c2d21afadd19..0fffc0c9814c 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-02-06 +date: 2024-02-07 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 dc8471e4cfd9..18d8ef126699 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-02-06 +date: 2024-02-07 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 a7a2140d1755..ebd8ff3489b1 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-predicates'] --- import kbnSortPredicatesObj from './kbn_sort_predicates.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 7a183b3fce7e..bfd29dc3cd15 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-02-06 +date: 2024-02-07 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 3421c3fbe76e..9e64640e1928 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-02-06 +date: 2024-02-07 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 0bb118f5c1cc..1e4a273d6180 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 6e477790c4ae..5145a4afe06c 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-02-06 +date: 2024-02-07 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 2c6d0bbe545b..f5cd10097d9a 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-02-06 +date: 2024-02-07 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 474ca0b9ebce..04687f3194fb 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-02-06 +date: 2024-02-07 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 b578040573a1..53df9442b295 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index c7619eaa4cf9..450a98bdd3cf 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 34ebd2aea1d5..7128842bcddc 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 468076bb301e..cd004a4ffae0 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_triggers_actions_ui_types.mdx b/api_docs/kbn_triggers_actions_ui_types.mdx index a4961d8756b1..e6650effde67 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-02-06 +date: 2024-02-07 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_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index a33be4bdb63a..e495faad72c9 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-02-06 +date: 2024-02-07 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 7f82c740cc53..e81492896807 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-02-06 +date: 2024-02-07 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 e8e621db5c7d..a233dedd0ea3 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-02-06 +date: 2024-02-07 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 b14a87e8df07..1cdea5c282b8 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-02-06 +date: 2024-02-07 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 1eb6c751fe1b..5cec48c951d7 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_data_table.mdx b/api_docs/kbn_unified_data_table.mdx index a67438bd8f59..65d7a7dffcff 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-data-table'] --- import kbnUnifiedDataTableObj from './kbn_unified_data_table.devdocs.json'; diff --git a/api_docs/kbn_unified_doc_viewer.mdx b/api_docs/kbn_unified_doc_viewer.mdx index 4ba759e7d01f..af6d742fbbb6 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-02-06 +date: 2024-02-07 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 2b492c5feb05..29cf70e2bcb5 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-02-06 +date: 2024-02-07 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 f80f216498af..fc3bbc2c287d 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unsaved-changes-badge'] --- import kbnUnsavedChangesBadgeObj from './kbn_unsaved_changes_badge.devdocs.json'; diff --git a/api_docs/kbn_use_tracked_promise.mdx b/api_docs/kbn_use_tracked_promise.mdx index ad59a5ff17b3..2437fad6cdda 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-02-06 +date: 2024-02-07 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 84ba87243798..9b3f4b02f8af 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-02-06 +date: 2024-02-07 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 9bc1a008d863..fb19a2483463 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-02-06 +date: 2024-02-07 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 cac623498d06..b88380e4f777 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-02-06 +date: 2024-02-07 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 3eeb83a0cf67..8b23ecd6fb0b 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-02-06 +date: 2024-02-07 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 d29f7db4e9a3..ee10e9585752 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-02-06 +date: 2024-02-07 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 9e66c056c09f..0b925c4d868c 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-02-06 +date: 2024-02-07 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 3bf8c944b4bc..e12fe7d8b0db 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-02-06 +date: 2024-02-07 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 0ddb8d234ac7..eaaa54243e24 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kbn_zod_helpers.mdx b/api_docs/kbn_zod_helpers.mdx index f91c25f1f07b..bae132683b88 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-02-06 +date: 2024-02-07 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 ca6dcd32d475..eb1820b3150f 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index 047ff4223189..2dbf5cea1cff 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -3314,7 +3314,7 @@ "label": "UrlTemplateEditor", "description": [], "signature": [ - "({ height, value, variables, onChange, placeholder, onEditor, Editor, }: React.PropsWithChildren<", + "({ height, fitToContent, value, variables, onChange, placeholder, onEditor, Editor, }: React.PropsWithChildren<", { "pluginId": "kibanaReact", "scope": "public", @@ -3333,7 +3333,7 @@ "id": "def-public.UrlTemplateEditor.$1", "type": "CompoundType", "tags": [], - "label": "{\n height = 105,\n value,\n variables,\n onChange,\n placeholder,\n onEditor,\n Editor = CodeEditor,\n}", + "label": "{\n height = 105,\n fitToContent,\n value,\n variables,\n onChange,\n placeholder,\n onEditor,\n Editor = CodeEditor,\n}", "description": [], "signature": [ "React.PropsWithChildren<", @@ -4532,6 +4532,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "kibanaReact", + "id": "def-public.UrlTemplateEditorProps.fitToContent", + "type": "Object", + "tags": [], + "label": "fitToContent", + "description": [], + "signature": [ + "{ minLines?: number | undefined; maxLines?: number | undefined; } | undefined" + ], + "path": "src/plugins/kibana_react/public/url_template_editor/url_template_editor.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "kibanaReact", "id": "def-public.UrlTemplateEditorProps.variables", diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 5c9340749a24..ad7821e034e2 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sh | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 152 | 0 | 120 | 3 | +| 153 | 0 | 121 | 3 | ## Client diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index 41a88487c0d9..f4535a9e9d3f 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-02-06 +date: 2024-02-07 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 cf2ebe35ced8..fd26049c8d62 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 72dfa569ce44..b0464814b07d 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-02-06 +date: 2024-02-07 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 786e473883e7..58d2d9c9771b 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-02-06 +date: 2024-02-07 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 d3230751b8f3..0f1e4bf4e4cd 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index ed3d43b9283c..ad5bad5f28d9 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-02-06 +date: 2024-02-07 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 101992398f94..3d3f3edd5deb 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-02-06 +date: 2024-02-07 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 709a76f67ba9..5af85f966824 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_explorer.mdx b/api_docs/logs_explorer.mdx index 7912f40fe48b..09de1f2649d9 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-02-06 +date: 2024-02-07 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 e1e789c745eb..fd2f4b7d5cc1 100644 --- a/api_docs/logs_shared.devdocs.json +++ b/api_docs/logs_shared.devdocs.json @@ -6419,7 +6419,7 @@ }, " | undefined; fixedInterval?: string[] | undefined; timeZone?: string[] | undefined; timeSeriesDimension?: boolean | undefined; timeSeriesMetric?: ", "MappingTimeSeriesMetricType", - " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; }" + " | undefined; shortDotsEnable?: boolean | undefined; isMapped?: boolean | undefined; parentName?: string | undefined; defaultFormatter?: string | undefined; }" ], "path": "x-pack/plugins/logs_shared/common/log_views/resolved_log_view.ts", "deprecated": false, diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index 0939b1f917b5..2679d57071b6 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index b6d07c65413f..f0162cca4a28 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-02-06 +date: 2024-02-07 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 a7aa4c8766f1..a167d3a2f1c4 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-02-06 +date: 2024-02-07 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 fba027ab99ad..09130b89cd55 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-02-06 +date: 2024-02-07 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 1fcabbd72df0..4f41218ac454 100644 --- a/api_docs/metrics_data_access.mdx +++ b/api_docs/metrics_data_access.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/metricsDataAccess title: "metricsDataAccess" image: https://source.unsplash.com/400x175/?github description: API docs for the metricsDataAccess plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'metricsDataAccess'] --- import metricsDataAccessObj from './metrics_data_access.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 49d390b94159..4e67147a0549 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-02-06 +date: 2024-02-07 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 74181d8ba9bf..cc67220cd5de 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-02-06 +date: 2024-02-07 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 490cba220192..10874e9c8b9c 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-02-06 +date: 2024-02-07 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 e4734285acc0..f2a2a8830e3d 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-02-06 +date: 2024-02-07 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 1d16d21a63aa..a789717fe52c 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-02-06 +date: 2024-02-07 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 a386f38712dd..5f0e641c2ef9 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-02-06 +date: 2024-02-07 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 0576a8a2f479..151e94c5fae1 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-02-06 +date: 2024-02-07 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 6675f47fd28b..096dac0cf4d6 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 53dff8eaf288..04d5141c71f8 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index f4287021cca1..a4fd4c7d0970 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_logs_explorer.mdx b/api_docs/observability_logs_explorer.mdx index 0deea2f3d7f9..d71b6d3b1369 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-02-06 +date: 2024-02-07 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 6232f5be089e..5a860c5feb07 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-02-06 +date: 2024-02-07 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 a41fbeb99d85..4bc22a31b5e3 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-02-06 +date: 2024-02-07 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 4c05a952db36..2fbd67b92f0f 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-02-06 +date: 2024-02-07 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 e6b7b9b56b44..1b44890f8445 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-02-06 +date: 2024-02-07 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 e6356743276f..dd622bf6e51c 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 79704 | 229 | 68272 | 1731 | +| 79725 | 228 | 68291 | 1734 | ## Plugin Directory @@ -31,7 +31,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux @elastic/platform-deployment-management](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) | - | 2 | 0 | 2 | 0 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 2 | 0 | 2 | 0 | -| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 70 | 1 | 4 | 1 | +| | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | AIOps plugin maintained by ML team. | 69 | 0 | 4 | 1 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | - | 835 | 1 | 804 | 51 | | | [@elastic/obs-ux-infra_services-team](https://github.com/orgs/elastic/teams/obs-ux-infra_services-team) | The user interface for Elastic APM | 29 | 0 | 29 | 125 | | | [@elastic/obs-knowledge-team](https://github.com/orgs/elastic/teams/obs-knowledge-team) | - | 9 | 0 | 9 | 0 | @@ -57,17 +57,17 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 268 | 0 | 249 | 1 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 108 | 0 | 105 | 12 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 54 | 0 | 51 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3235 | 31 | 2583 | 23 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3237 | 31 | 2585 | 23 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin provides the ability to create data views via a modal flyout inside Kibana apps | 35 | 0 | 25 | 5 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Reusable data view field editor across Kibana | 72 | 0 | 33 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data view management app | 2 | 0 | 2 | 0 | -| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 940 | 0 | 273 | 4 | +| | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 943 | 0 | 276 | 4 | | | [@elastic/ml-ui](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 31 | 3 | 25 | 1 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | This plugin introduces the concept of dataset quality, where users can easily get an overview on the datasets they have. | 10 | 0 | 10 | 5 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 12 | 0 | 10 | 3 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 151 | 0 | 104 | 22 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | -| | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | APIs used to assess the quality of data in Elasticsearch indexes | 2 | 0 | 0 | 0 | +| | [@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 | 41 | 0 | 27 | 0 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds embeddables service to Kibana | 557 | 1 | 452 | 8 | | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | @@ -97,7 +97,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-gis](https://github.com/orgs/elastic/teams/kibana-gis) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 84 | 0 | 84 | 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 | 2 | 0 | 2 | 0 | -| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1221 | 3 | 1104 | 51 | +| | [@elastic/fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1229 | 3 | 1110 | 54 | | 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) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 0 | 0 | 0 | 0 | @@ -115,7 +115,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | - | 127 | 2 | 100 | 4 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides UI and APIs for the interactive setup mode. | 28 | 0 | 18 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 6 | 0 | 6 | 0 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 152 | 0 | 120 | 3 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 153 | 0 | 121 | 3 | | kibanaUsageCollection | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 609 | 3 | 416 | 9 | | | [@elastic/kibana-cloud-security-posture](https://github.com/orgs/elastic/teams/kibana-cloud-security-posture) | - | 5 | 0 | 5 | 1 | @@ -253,10 +253,10 @@ 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/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 36 | 0 | 15 | 0 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 37 | 0 | 15 | 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) | - | 8 | 0 | 4 | 0 | -| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 206 | 0 | 169 | 8 | +| | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 211 | 0 | 174 | 8 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 76 | 0 | 47 | 9 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 24 | 0 | 24 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 140 | 3 | 137 | 18 | @@ -454,7 +454,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 39 | 0 | 26 | 5 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 19 | 0 | 11 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 35125 | 0 | 34718 | 0 | -| | [@elastic/security-threat-hunting-investigations](https://github.com/orgs/elastic/teams/security-threat-hunting-investigations) | - | 13 | 0 | 5 | 0 | +| | [@elastic/security-threat-hunting-explore](https://github.com/orgs/elastic/teams/security-threat-hunting-explore) | - | 13 | 0 | 5 | 0 | | | [@elastic/obs-ux-logs-team](https://github.com/orgs/elastic/teams/obs-ux-logs-team) | - | 35 | 0 | 34 | 0 | | | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | - | 104 | 0 | 84 | 6 | | | [@elastic/security-generative-ai](https://github.com/orgs/elastic/teams/security-generative-ai) | - | 59 | 0 | 57 | 0 | @@ -462,7 +462,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@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) | - | 7 | 0 | 3 | 0 | | | [@elastic/kibana-data-discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 263 | 1 | 202 | 15 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 31 | 0 | 31 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 32 | 0 | 32 | 0 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 2 | 0 | 1 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 14 | 0 | 13 | 0 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 39 | 0 | 39 | 0 | @@ -475,7 +475,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-qa](https://github.com/orgs/elastic/teams/appex-qa) | - | 550 | 6 | 510 | 2 | | | [@elastic/kibana-operations](https://github.com/orgs/elastic/teams/kibana-operations) | - | 1 | 0 | 0 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 1 | 0 | 1 | 0 | -| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 25 | 0 | 25 | 1 | +| | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 26 | 0 | 26 | 1 | | | [@elastic/platform-onboarding](https://github.com/orgs/elastic/teams/platform-onboarding) | - | 49 | 0 | 47 | 0 | | | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | - | 33 | 3 | 24 | 6 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 3 | 0 | 3 | 0 | diff --git a/api_docs/presentation_panel.mdx b/api_docs/presentation_panel.mdx index adeac7299439..b160f7e62ef3 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-02-06 +date: 2024-02-07 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 fbda6034b337..92cce48e5f8d 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index f6385f8c3c34..69b5facaf15c 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-02-06 +date: 2024-02-07 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 46e49804f795..d7592150f126 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-02-06 +date: 2024-02-07 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 e7dc5abaf599..2ab200ba8cfe 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-02-06 +date: 2024-02-07 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 f41e5dd6aff9..7d02e444371a 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-02-06 +date: 2024-02-07 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 d4921a045d52..fce7892027c3 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-02-06 +date: 2024-02-07 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 354271bad580..856e54fd3b9d 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-02-06 +date: 2024-02-07 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 e83957355230..3a192e41075d 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-02-06 +date: 2024-02-07 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 7a62df5e4eec..caad57d964dd 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-02-06 +date: 2024-02-07 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 d197e06b12f0..8b6746c496c9 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-02-06 +date: 2024-02-07 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 f23a23b21c6d..5856df267d93 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-02-06 +date: 2024-02-07 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 509e2387508d..4c7268b2f1be 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-02-06 +date: 2024-02-07 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 c761a95662c0..e1140371d426 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-02-06 +date: 2024-02-07 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 5c1b3b39af07..9d3c73292fb1 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-02-06 +date: 2024-02-07 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 2c75d771fe21..e8ff668a90b2 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-02-06 +date: 2024-02-07 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 4e820e2cb8ff..58bdd6065c1e 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index c36c13c747ec..840391e9b964 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-02-06 +date: 2024-02-07 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 705bd3950d0e..6088d1fa3033 100644 --- a/api_docs/security_solution.devdocs.json +++ b/api_docs/security_solution.devdocs.json @@ -3030,7 +3030,7 @@ "label": "ConfigType", "description": [], "signature": [ - "Omit; }>, \"offeringSettings\"> & { experimentalFeatures: ", + "Omit; }>, \"offeringSettings\"> & { experimentalFeatures: ", { "pluginId": "securitySolution", "scope": "common", diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index ab806e2570c1..cbd71985d822 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index 83fb684b85ba..63f3bd08ddb3 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-02-06 +date: 2024-02-07 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 9e996af7b7f3..d1494e047821 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-02-06 +date: 2024-02-07 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 afc76d64388e..0e198b2b7a0f 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-02-06 +date: 2024-02-07 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 e1aec4968889..23ea04c7f572 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-02-06 +date: 2024-02-07 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 dfd9fd016141..6dd06f6a0bb8 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-02-06 +date: 2024-02-07 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 28baa23abbf2..d1bca6bdcf5c 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-02-06 +date: 2024-02-07 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 f93d6be30181..0c5fde709cbd 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 2615877a40f6..98108ace6775 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-02-06 +date: 2024-02-07 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 4b5669be3d20..87ffc5796009 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-02-06 +date: 2024-02-07 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 50ed8ddde197..6711616b9573 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-02-06 +date: 2024-02-07 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 b4a962ff1e87..d60f8893a3d5 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index ae70dddd6abd..5f01b6242761 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-02-06 +date: 2024-02-07 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 ceca201c9a3f..f452244c7ac5 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-02-06 +date: 2024-02-07 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 cf45c9305631..e751675914de 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 85c5f17ce7cf..600f107c7adc 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 2dce5b896421..00e30d5a67f7 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index f583dd7b65e4..8d8f72de8369 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2024-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 1c6ec938eb49..b40240b83567 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-02-06 +date: 2024-02-07 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 f83e497d28b6..ac0256289d20 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-02-06 +date: 2024-02-07 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 24491c857335..f70b80d7700d 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index 43889de19ef3..4a9016b138d6 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -5102,7 +5102,7 @@ "label": "setRuleProperty", "description": [], "signature": [ - "(key: Prop, value: ", + "(key: Prop, value: ", "SanitizedRule", "[Prop] | null) => void" ], diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index b6db50861a06..428f3e914ad3 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-02-06 +date: 2024-02-07 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 dcd3834f37d1..0f9cfba95dbe 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-02-06 +date: 2024-02-07 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 4ed23567a6e6..bc657402727d 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-02-06 +date: 2024-02-07 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 01ef74424e1b..636e1e8a71ad 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-02-06 +date: 2024-02-07 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 aa0bbd2d32e7..dadf411df077 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-02-06 +date: 2024-02-07 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 7b5fcf9e147f..8fa821d0bbc1 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-02-06 +date: 2024-02-07 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 d63253fa6e08..9b27d641f394 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-02-06 +date: 2024-02-07 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 ca74eeb826c0..272789745af9 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-02-06 +date: 2024-02-07 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 1340273a664f..fafc955715cf 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-02-06 +date: 2024-02-07 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 336a32edb6db..8b1aaec03bc7 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-02-06 +date: 2024-02-07 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 0ae5fe27283f..e77e838c7203 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-02-06 +date: 2024-02-07 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 2e331e3c556a..822f8ed9ee93 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-02-06 +date: 2024-02-07 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 9c3a5ad02d03..5d28070a30b3 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-02-06 +date: 2024-02-07 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 4ddda8b91e1b..c546d638347c 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-02-06 +date: 2024-02-07 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 014f02b6b1f3..94f494248c61 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-02-06 +date: 2024-02-07 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 8c0d6dad016b..c61e06c24591 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-02-06 +date: 2024-02-07 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 cb7d00efda18..5faa721b0b77 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-02-06 +date: 2024-02-07 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 e1388019e8f5..335949c6de1d 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-02-06 +date: 2024-02-07 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 827e071dad14..0d1db20335a4 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-02-06 +date: 2024-02-07 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 2163580af6b4..35bf09c113d8 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-02-06 +date: 2024-02-07 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 c9255a3e35a4..35458e93479c 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index fd4b0f082a8a..0fba29839bcf 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-02-06 +date: 2024-02-07 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; diff --git a/config/serverless.oblt.yml b/config/serverless.oblt.yml index e30424b5355a..e74210acbd2d 100644 --- a/config/serverless.oblt.yml +++ b/config/serverless.oblt.yml @@ -39,7 +39,11 @@ xpack.uptime.service.tls.certificate: /mnt/elastic-internal/http-certs/tls.crt xpack.uptime.service.tls.key: /mnt/elastic-internal/http-certs/tls.key # Fleet specific configuration -xpack.fleet.internal.registry.capabilities: ['apm', 'observability'] +xpack.fleet.internal.registry.capabilities: [ + 'apm', + 'observability', + 'uptime', +] xpack.fleet.internal.registry.kibanaVersionCheckEnabled: false xpack.fleet.internal.registry.spec.max: '3.0' # Temporary until all packages implement new spec https://github.com/elastic/kibana/issues/166742 diff --git a/docs/settings/reporting-settings.asciidoc b/docs/settings/reporting-settings.asciidoc index 192a47e184c4..ab80c11139a5 100644 --- a/docs/settings/reporting-settings.asciidoc +++ b/docs/settings/reporting-settings.asciidoc @@ -232,10 +232,10 @@ You may need to lower this setting if the default number of documents creates a ============ `xpack.reporting.csv.scroll.duration`:: -Amount of {time-units}[time] allowed before {kib} cleans the scroll context during a CSV export. Defaults to `30s`. +Amount of {time-units}[time] allowed before {kib} cleans the scroll context during a CSV export. Valid option is either `auto` or {time-units}[time], Defaults to `30s`. [NOTE] ============ -If search latency in {es} is sufficiently high, such as if you are using {ccs}, you may need to increase the setting. +If search latency in {es} is sufficiently high, such as if you are using {ccs}, you may either need to increase the time setting or set this config value to `auto`. When the config value is set to `auto` the scroll context will be preserved for as long as is possible, before the report task is terminated due to the limits of `xpack.reporting.queue.timeout`. ============ `xpack.reporting.csv.scroll.strategy`:: diff --git a/package.json b/package.json index 3bcd5075747e..2c71bd4dd679 100644 --- a/package.json +++ b/package.json @@ -1064,7 +1064,6 @@ "react-popper-tooltip": "^3.1.1", "react-redux": "^7.2.8", "react-resizable": "^3.0.4", - "react-resize-detector": "^7.1.1", "react-reverse-portal": "^2.1.0", "react-router": "^5.3.4", "react-router-config": "^5.1.1", diff --git a/packages/analytics/shippers/fullstory/src/fullstory_shipper.ts b/packages/analytics/shippers/fullstory/src/fullstory_shipper.ts index a4ad730f87b2..d02e87cace6b 100644 --- a/packages/analytics/shippers/fullstory/src/fullstory_shipper.ts +++ b/packages/analytics/shippers/fullstory/src/fullstory_shipper.ts @@ -30,7 +30,7 @@ const PAGE_VARS_KEYS = [ // Deployment-specific keys 'version', // x4, split to version_major, version_minor, version_patch for easier filtering - 'buildNum', // May be useful for Serverless + 'buildNum', // May be useful for Serverless, TODO: replace with buildHash 'cloudId', 'deploymentId', 'projectId', // projectId and deploymentId are mutually exclusive. They shouldn't be sent in the same offering. diff --git a/packages/core/apps/core-apps-server-internal/src/bundle_routes/register_bundle_routes.test.ts b/packages/core/apps/core-apps-server-internal/src/bundle_routes/register_bundle_routes.test.ts index e6550f6e86cb..8a0ae599150f 100644 --- a/packages/core/apps/core-apps-server-internal/src/bundle_routes/register_bundle_routes.test.ts +++ b/packages/core/apps/core-apps-server-internal/src/bundle_routes/register_bundle_routes.test.ts @@ -13,10 +13,12 @@ import { httpServiceMock } from '@kbn/core-http-server-mocks'; import type { InternalPluginInfo, UiPlugins } from '@kbn/core-plugins-base-server-internal'; import { registerBundleRoutes } from './register_bundle_routes'; import { FileHashCache } from './file_hash_cache'; +import { BasePath, StaticAssets } from '@kbn/core-http-server-internal'; const createPackageInfo = (parts: Partial = {}): PackageInfo => ({ buildNum: 42, - buildSha: 'sha', + buildSha: 'shasha', + buildShaShort: 'sha', dist: true, branch: 'master', version: '8.0.0', @@ -41,9 +43,12 @@ const createUiPlugins = (...ids: string[]): UiPlugins => ({ describe('registerBundleRoutes', () => { let router: ReturnType; + let staticAssets: StaticAssets; beforeEach(() => { router = httpServiceMock.createRouter(); + const basePath = httpServiceMock.createBasePath('/server-base-path') as unknown as BasePath; + staticAssets = new StaticAssets({ basePath, cdnConfig: {} as any, shaDigest: 'sha' }); }); afterEach(() => { @@ -53,7 +58,7 @@ describe('registerBundleRoutes', () => { it('registers core and shared-dep bundles', () => { registerBundleRoutes({ router, - serverBasePath: '/server-base-path', + staticAssets, packageInfo: createPackageInfo(), uiPlugins: createUiPlugins(), }); @@ -64,39 +69,39 @@ describe('registerBundleRoutes', () => { fileHashCache: expect.any(FileHashCache), isDist: true, bundlesPath: 'uiSharedDepsSrcDistDir', - publicPath: '/server-base-path/42/bundles/kbn-ui-shared-deps-src/', - routePath: '/42/bundles/kbn-ui-shared-deps-src/', + publicPath: '/server-base-path/sha/bundles/kbn-ui-shared-deps-src/', + routePath: '/sha/bundles/kbn-ui-shared-deps-src/', }); expect(registerRouteForBundleMock).toHaveBeenCalledWith(router, { fileHashCache: expect.any(FileHashCache), isDist: true, bundlesPath: 'uiSharedDepsNpmDistDir', - publicPath: '/server-base-path/42/bundles/kbn-ui-shared-deps-npm/', - routePath: '/42/bundles/kbn-ui-shared-deps-npm/', + publicPath: '/server-base-path/sha/bundles/kbn-ui-shared-deps-npm/', + routePath: '/sha/bundles/kbn-ui-shared-deps-npm/', }); expect(registerRouteForBundleMock).toHaveBeenCalledWith(router, { fileHashCache: expect.any(FileHashCache), isDist: true, bundlesPath: expect.stringMatching(/\/@kbn\/core\/target\/public$/), - publicPath: '/server-base-path/42/bundles/core/', - routePath: '/42/bundles/core/', + publicPath: '/server-base-path/sha/bundles/core/', + routePath: '/sha/bundles/core/', }); expect(registerRouteForBundleMock).toHaveBeenCalledWith(router, { fileHashCache: expect.any(FileHashCache), isDist: true, bundlesPath: 'kbnMonacoBundleDir', - publicPath: '/server-base-path/42/bundles/kbn-monaco/', - routePath: '/42/bundles/kbn-monaco/', + publicPath: '/server-base-path/sha/bundles/kbn-monaco/', + routePath: '/sha/bundles/kbn-monaco/', }); }); it('registers plugin bundles', () => { registerBundleRoutes({ router, - serverBasePath: '/server-base-path', + staticAssets, packageInfo: createPackageInfo(), uiPlugins: createUiPlugins('plugin-a', 'plugin-b'), }); @@ -107,16 +112,16 @@ describe('registerBundleRoutes', () => { fileHashCache: expect.any(FileHashCache), isDist: true, bundlesPath: '/plugins/plugin-a/public-target-dir', - publicPath: '/server-base-path/42/bundles/plugin/plugin-a/8.0.0/', - routePath: '/42/bundles/plugin/plugin-a/8.0.0/', + publicPath: '/server-base-path/sha/bundles/plugin/plugin-a/8.0.0/', + routePath: '/sha/bundles/plugin/plugin-a/8.0.0/', }); expect(registerRouteForBundleMock).toHaveBeenCalledWith(router, { fileHashCache: expect.any(FileHashCache), isDist: true, bundlesPath: '/plugins/plugin-b/public-target-dir', - publicPath: '/server-base-path/42/bundles/plugin/plugin-b/8.0.0/', - routePath: '/42/bundles/plugin/plugin-b/8.0.0/', + publicPath: '/server-base-path/sha/bundles/plugin/plugin-b/8.0.0/', + routePath: '/sha/bundles/plugin/plugin-b/8.0.0/', }); }); }); diff --git a/packages/core/apps/core-apps-server-internal/src/bundle_routes/register_bundle_routes.ts b/packages/core/apps/core-apps-server-internal/src/bundle_routes/register_bundle_routes.ts index 22266e97355e..617f085c8ad4 100644 --- a/packages/core/apps/core-apps-server-internal/src/bundle_routes/register_bundle_routes.ts +++ b/packages/core/apps/core-apps-server-internal/src/bundle_routes/register_bundle_routes.ts @@ -13,6 +13,7 @@ import { distDir as UiSharedDepsSrcDistDir } from '@kbn/ui-shared-deps-src'; import * as KbnMonaco from '@kbn/monaco/server'; import type { IRouter } from '@kbn/core-http-server'; import type { UiPlugins } from '@kbn/core-plugins-base-server-internal'; +import { InternalStaticAssets } from '@kbn/core-http-server-internal'; import { FileHashCache } from './file_hash_cache'; import { registerRouteForBundle } from './bundles_route'; @@ -28,56 +29,61 @@ import { registerRouteForBundle } from './bundles_route'; */ export function registerBundleRoutes({ router, - serverBasePath, uiPlugins, packageInfo, + staticAssets, }: { router: IRouter; - serverBasePath: string; uiPlugins: UiPlugins; packageInfo: PackageInfo; + staticAssets: InternalStaticAssets; }) { - const { dist: isDist, buildNum } = packageInfo; + const { dist: isDist } = packageInfo; // rather than calculate the fileHash on every request, we // provide a cache object to `resolveDynamicAssetResponse()` that // will store the most recently used hashes. const fileHashCache = new FileHashCache(); + const sharedNpmDepsPath = '/bundles/kbn-ui-shared-deps-npm/'; registerRouteForBundle(router, { - publicPath: `${serverBasePath}/${buildNum}/bundles/kbn-ui-shared-deps-npm/`, - routePath: `/${buildNum}/bundles/kbn-ui-shared-deps-npm/`, + publicPath: staticAssets.prependPublicUrl(sharedNpmDepsPath) + '/', + routePath: staticAssets.prependServerPath(sharedNpmDepsPath) + '/', bundlesPath: UiSharedDepsNpm.distDir, fileHashCache, isDist, }); + const sharedDepsPath = '/bundles/kbn-ui-shared-deps-src/'; registerRouteForBundle(router, { - publicPath: `${serverBasePath}/${buildNum}/bundles/kbn-ui-shared-deps-src/`, - routePath: `/${buildNum}/bundles/kbn-ui-shared-deps-src/`, + publicPath: staticAssets.prependPublicUrl(sharedDepsPath) + '/', + routePath: staticAssets.prependServerPath(sharedDepsPath) + '/', bundlesPath: UiSharedDepsSrcDistDir, fileHashCache, isDist, }); + const coreBundlePath = '/bundles/core/'; registerRouteForBundle(router, { - publicPath: `${serverBasePath}/${buildNum}/bundles/core/`, - routePath: `/${buildNum}/bundles/core/`, + publicPath: staticAssets.prependPublicUrl(coreBundlePath) + '/', + routePath: staticAssets.prependServerPath(coreBundlePath) + '/', bundlesPath: isDist ? fromRoot('node_modules/@kbn/core/target/public') : fromRoot('src/core/target/public'), fileHashCache, isDist, }); + const monacoEditorPath = '/bundles/kbn-monaco/'; registerRouteForBundle(router, { - publicPath: `${serverBasePath}/${buildNum}/bundles/kbn-monaco/`, - routePath: `/${buildNum}/bundles/kbn-monaco/`, + publicPath: staticAssets.prependPublicUrl(monacoEditorPath) + '/', + routePath: staticAssets.prependServerPath(monacoEditorPath) + '/', bundlesPath: KbnMonaco.bundleDir, fileHashCache, isDist, }); [...uiPlugins.internal.entries()].forEach(([id, { publicTargetDir, version }]) => { + const pluginBundlesPath = `/bundles/plugin/${id}/${version}/`; registerRouteForBundle(router, { - publicPath: `${serverBasePath}/${buildNum}/bundles/plugin/${id}/${version}/`, - routePath: `/${buildNum}/bundles/plugin/${id}/${version}/`, + publicPath: staticAssets.prependPublicUrl(pluginBundlesPath) + '/', + routePath: staticAssets.prependServerPath(pluginBundlesPath) + '/', bundlesPath: publicTargetDir, fileHashCache, isDist, diff --git a/packages/core/apps/core-apps-server-internal/src/core_app.test.ts b/packages/core/apps/core-apps-server-internal/src/core_app.test.ts index 851f443cd3e1..f0bde326b7b7 100644 --- a/packages/core/apps/core-apps-server-internal/src/core_app.test.ts +++ b/packages/core/apps/core-apps-server-internal/src/core_app.test.ts @@ -16,8 +16,8 @@ import { httpResourcesMock } from '@kbn/core-http-resources-server-mocks'; import { PluginType } from '@kbn/core-base-common'; import type { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server'; import { coreInternalLifecycleMock } from '@kbn/core-lifecycle-server-mocks'; -import { CoreAppsService } from './core_app'; import { of } from 'rxjs'; +import { CoreAppsService } from './core_app'; const emptyPlugins = (): UiPlugins => ({ internal: new Map(), @@ -146,7 +146,7 @@ describe('CoreApp', () => { uiPlugins: prebootUIPlugins, router: expect.any(Object), packageInfo: coreContext.env.packageInfo, - serverBasePath: internalCorePreboot.http.basePath.serverBasePath, + staticAssets: expect.any(Object), }); }); @@ -245,7 +245,23 @@ describe('CoreApp', () => { uiPlugins, router: expect.any(Object), packageInfo: coreContext.env.packageInfo, - serverBasePath: internalCoreSetup.http.basePath.serverBasePath, + staticAssets: expect.any(Object), }); }); + + it('registers SHA-scoped and non-SHA-scoped UI bundle routes', async () => { + const uiPlugins = emptyPlugins(); + internalCoreSetup.http.staticAssets.prependServerPath.mockReturnValue('/some-path'); + await coreApp.setup(internalCoreSetup, uiPlugins); + + expect(internalCoreSetup.http.registerStaticDir).toHaveBeenCalledTimes(2); + expect(internalCoreSetup.http.registerStaticDir).toHaveBeenCalledWith( + '/some-path', + expect.any(String) + ); + expect(internalCoreSetup.http.registerStaticDir).toHaveBeenCalledWith( + '/ui/{path*}', + expect.any(String) + ); + }); }); diff --git a/packages/core/apps/core-apps-server-internal/src/core_app.ts b/packages/core/apps/core-apps-server-internal/src/core_app.ts index 3de295874d3f..1e54d7d8aaa2 100644 --- a/packages/core/apps/core-apps-server-internal/src/core_app.ts +++ b/packages/core/apps/core-apps-server-internal/src/core_app.ts @@ -22,6 +22,7 @@ import type { import type { UiPlugins } from '@kbn/core-plugins-base-server-internal'; import type { HttpResources, HttpResourcesServiceToolkit } from '@kbn/core-http-resources-server'; import type { InternalCorePreboot, InternalCoreSetup } from '@kbn/core-lifecycle-server-internal'; +import type { InternalStaticAssets } from '@kbn/core-http-server-internal'; import { firstValueFrom, map, type Observable } from 'rxjs'; import { CoreAppConfig, type CoreAppConfigType, CoreAppPath } from './core_app_config'; import { registerBundleRoutes } from './bundle_routes'; @@ -33,6 +34,7 @@ interface CommonRoutesParams { httpResources: HttpResources; basePath: IBasePath; uiPlugins: UiPlugins; + staticAssets: InternalStaticAssets; onResourceNotFound: ( req: KibanaRequest, res: HttpResourcesServiceToolkit & KibanaResponseFactory @@ -77,10 +79,11 @@ export class CoreAppsService { this.registerCommonDefaultRoutes({ basePath: corePreboot.http.basePath, httpResources: corePreboot.httpResources.createRegistrar(router), + staticAssets: corePreboot.http.staticAssets, router, uiPlugins, onResourceNotFound: async (req, res) => - // THe API consumers might call various Kibana APIs (e.g. `/api/status`) when Kibana is still at the preboot + // The API consumers might call various Kibana APIs (e.g. `/api/status`) when Kibana is still at the preboot // stage, and the main HTTP server that registers API handlers isn't up yet. At this stage we don't know if // the API endpoint exists or not, and hence cannot reply with `404`. We also should not reply with completely // unexpected response (`200 text/html` for the Core app). The only suitable option is to reply with `503` @@ -125,6 +128,7 @@ export class CoreAppsService { this.registerCommonDefaultRoutes({ basePath: coreSetup.http.basePath, httpResources: resources, + staticAssets: coreSetup.http.staticAssets, router, uiPlugins, onResourceNotFound: async (req, res) => res.notFound(), @@ -210,6 +214,7 @@ export class CoreAppsService { private registerCommonDefaultRoutes({ router, basePath, + staticAssets, uiPlugins, onResourceNotFound, httpResources, @@ -259,17 +264,23 @@ export class CoreAppsService { registerBundleRoutes({ router, uiPlugins, + staticAssets, packageInfo: this.env.packageInfo, - serverBasePath: basePath.serverBasePath, }); } // After the package is built and bootstrap extracts files to bazel-bin, // assets are exposed at the root of the package and in the package's node_modules dir private registerStaticDirs(core: InternalCoreSetup | InternalCorePreboot) { - core.http.registerStaticDir( - '/ui/{path*}', - fromRoot('node_modules/@kbn/core-apps-server-internal/assets') - ); + /** + * Serve UI from sha-scoped and not-sha-scoped paths to allow time for plugin code to migrate + * Eventually we only want to serve from the sha scoped path + */ + [core.http.staticAssets.prependServerPath('/ui/{path*}'), '/ui/{path*}'].forEach((path) => { + core.http.registerStaticDir( + path, + fromRoot('node_modules/@kbn/core-apps-server-internal/assets') + ); + }); } } diff --git a/packages/core/apps/core-apps-server-internal/tsconfig.json b/packages/core/apps/core-apps-server-internal/tsconfig.json index 36ecc68c7cbc..fc8aa9f25349 100644 --- a/packages/core/apps/core-apps-server-internal/tsconfig.json +++ b/packages/core/apps/core-apps-server-internal/tsconfig.json @@ -32,6 +32,7 @@ "@kbn/core-lifecycle-server-mocks", "@kbn/core-ui-settings-server", "@kbn/monaco", + "@kbn/core-http-server-internal", ], "exclude": [ "target/**/*", diff --git a/packages/core/base/core-base-browser-mocks/src/core_context.mock.ts b/packages/core/base/core-base-browser-mocks/src/core_context.mock.ts index 53933d4146df..cdbafc09c5c0 100644 --- a/packages/core/base/core-base-browser-mocks/src/core_context.mock.ts +++ b/packages/core/base/core-base-browser-mocks/src/core_context.mock.ts @@ -24,6 +24,7 @@ function createCoreContext({ production = false }: { production?: boolean } = {} branch: 'branch', buildNum: 100, buildSha: 'buildSha', + buildShaShort: 'buildShaShort', dist: false, buildDate: new Date('2023-05-15T23:12:09.000Z'), buildFlavor: 'traditional', diff --git a/packages/core/http/core-http-server-internal/index.ts b/packages/core/http/core-http-server-internal/index.ts index 2867b5d2a031..b9d4edd8a862 100644 --- a/packages/core/http/core-http-server-internal/index.ts +++ b/packages/core/http/core-http-server-internal/index.ts @@ -17,6 +17,7 @@ export type { InternalHttpServiceStart, } from './src/types'; export { BasePath } from './src/base_path_service'; +export { type InternalStaticAssets, StaticAssets } from './src/static_assets'; export { cspConfig, CspConfig, type CspConfigType } from './src/csp'; diff --git a/packages/core/http/core-http-server-internal/src/cdn.test.ts b/packages/core/http/core-http-server-internal/src/cdn_config.test.ts similarity index 98% rename from packages/core/http/core-http-server-internal/src/cdn.test.ts rename to packages/core/http/core-http-server-internal/src/cdn_config.test.ts index 74f165bfd0f2..b6a954782f52 100644 --- a/packages/core/http/core-http-server-internal/src/cdn.test.ts +++ b/packages/core/http/core-http-server-internal/src/cdn_config.test.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { CdnConfig } from './cdn'; +import { CdnConfig } from './cdn_config'; describe('CdnConfig', () => { it.each([ diff --git a/packages/core/http/core-http-server-internal/src/cdn.ts b/packages/core/http/core-http-server-internal/src/cdn_config.ts similarity index 90% rename from packages/core/http/core-http-server-internal/src/cdn.ts rename to packages/core/http/core-http-server-internal/src/cdn_config.ts index 0f9b386b0923..e6fa29200ac7 100644 --- a/packages/core/http/core-http-server-internal/src/cdn.ts +++ b/packages/core/http/core-http-server-internal/src/cdn_config.ts @@ -14,15 +14,15 @@ export interface Input { } export class CdnConfig { - private url: undefined | URL; + private readonly url: undefined | URL; constructor(url?: string) { if (url) { - this.url = new URL(url); // This will throw for invalid URLs + this.url = new URL(url); // This will throw for invalid URLs, although should be validated before reaching this point } } public get host(): undefined | string { - return this.url?.host ?? undefined; + return this.url?.host; } public get baseHref(): undefined | string { diff --git a/packages/core/http/core-http-server-internal/src/http_config.test.ts b/packages/core/http/core-http-server-internal/src/http_config.test.ts index 28abe6513ced..f0bd5773b40b 100644 --- a/packages/core/http/core-http-server-internal/src/http_config.test.ts +++ b/packages/core/http/core-http-server-internal/src/http_config.test.ts @@ -16,8 +16,8 @@ const invalidHostnames = ['asdf$%^', '0']; let mockHostname = 'kibana-hostname'; -jest.mock('os', () => { - const original = jest.requireActual('os'); +jest.mock('node:os', () => { + const original = jest.requireActual('node:os'); return { ...original, @@ -530,6 +530,29 @@ describe('restrictInternalApis', () => { }); }); +describe('cdn', () => { + it('allows correct URL', () => { + expect(config.schema.validate({ cdn: { url: 'https://cdn.example.com' } })).toMatchObject({ + cdn: { url: 'https://cdn.example.com' }, + }); + }); + it.each([['foo'], ['http:./']])('throws for invalid URL %s', (url) => { + expect(() => config.schema.validate({ cdn: { url } })).toThrowErrorMatchingInlineSnapshot( + `"[cdn.url]: expected URI with scheme [http|https]."` + ); + }); + it.each([ + ['https://cdn.example.com:1234/asd?thing=1', 'URL query string not allowed'], + ['https://cdn.example.com:1234/asd#cool', 'URL fragment not allowed'], + [ + 'https://cdn.example.com:1234/asd?thing=1#cool', + 'URL fragment not allowed, but found "#cool"\nURL query string not allowed, but found "?thing=1"', + ], + ])('throws for disallowed values %s', (url, expecterError) => { + expect(() => config.schema.validate({ cdn: { url } })).toThrow(expecterError); + }); +}); + describe('HttpConfig', () => { it('converts customResponseHeaders to strings or arrays of strings', () => { const httpSchema = config.schema; diff --git a/packages/core/http/core-http-server-internal/src/http_config.ts b/packages/core/http/core-http-server-internal/src/http_config.ts index f6880c38e49b..54b8e808f675 100644 --- a/packages/core/http/core-http-server-internal/src/http_config.ts +++ b/packages/core/http/core-http-server-internal/src/http_config.ts @@ -12,8 +12,8 @@ import type { ServiceConfigDescriptor } from '@kbn/core-base-server-internal'; import { uuidRegexp } from '@kbn/core-base-server-internal'; import type { ICspConfig, IExternalUrlConfig } from '@kbn/core-http-server'; -import { hostname } from 'os'; -import url from 'url'; +import { hostname, EOL } from 'node:os'; +import url, { URL } from 'node:url'; import type { Duration } from 'moment'; import type { IHttpEluMonitorConfig } from '@kbn/core-http-server/src/elu_monitor'; @@ -24,7 +24,7 @@ import { securityResponseHeadersSchema, parseRawSecurityResponseHeadersConfig, } from './security_response_headers_config'; -import { CdnConfig } from './cdn'; +import { CdnConfig } from './cdn_config'; const validBasePathRegex = /^\/.*[^\/]$/; @@ -40,6 +40,24 @@ const validHostName = () => { return hostname().replace(/[^\x00-\x7F]/g, ''); }; +/** + * We assume the URL does not contain anything after the pathname so that + * we can safely append values to the pathname at runtime. + */ +function validateCdnURL(urlString: string): undefined | string { + const cdnURL = new URL(urlString); + const errors: string[] = []; + if (cdnURL.hash.length) { + errors.push(`URL fragment not allowed, but found "${cdnURL.hash}"`); + } + if (cdnURL.search.length) { + errors.push(`URL query string not allowed, but found "${cdnURL.search}"`); + } + if (errors.length) { + return `CDN URL "${cdnURL.href}" is invalid:${EOL}${errors.join(EOL)}`; + } +} + const configSchema = schema.object( { name: schema.string({ defaultValue: () => validHostName() }), @@ -60,7 +78,7 @@ const configSchema = schema.object( }, }), cdn: schema.object({ - url: schema.maybe(schema.uri({ scheme: ['http', 'https'] })), + url: schema.maybe(schema.uri({ scheme: ['http', 'https'], validate: validateCdnURL })), }), cors: schema.object( { diff --git a/packages/core/http/core-http-server-internal/src/http_server.test.ts b/packages/core/http/core-http-server-internal/src/http_server.test.ts index 8f5ae22612b4..129efea82cc8 100644 --- a/packages/core/http/core-http-server-internal/src/http_server.test.ts +++ b/packages/core/http/core-http-server-internal/src/http_server.test.ts @@ -30,6 +30,7 @@ import { Readable } from 'stream'; import { KBN_CERT_PATH, KBN_KEY_PATH } from '@kbn/dev-utils'; import moment from 'moment'; import { of, Observable, BehaviorSubject } from 'rxjs'; +import { mockCoreContext } from '@kbn/core-base-server-mocks'; const routerOptions: RouterOptions = { isDev: false, @@ -54,8 +55,9 @@ let config$: Observable; let configWithSSL: HttpConfig; let configWithSSL$: Observable; -const loggingService = loggingSystemMock.create(); -const logger = loggingService.get(); +const coreContext = mockCoreContext.create(); +const loggingService = coreContext.logger; +const logger = coreContext.logger.get(); const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {}); let certificate: string; @@ -99,7 +101,7 @@ beforeEach(() => { } as HttpConfig; configWithSSL$ = of(configWithSSL); - server = new HttpServer(loggingService, 'tests', of(config.shutdownTimeout)); + server = new HttpServer(coreContext, 'tests', of(config.shutdownTimeout)); }); afterEach(async () => { diff --git a/packages/core/http/core-http-server-internal/src/http_server.ts b/packages/core/http/core-http-server-internal/src/http_server.ts index 1361c64bb67c..ae9025d5cd9a 100644 --- a/packages/core/http/core-http-server-internal/src/http_server.ts +++ b/packages/core/http/core-http-server-internal/src/http_server.ts @@ -48,6 +48,8 @@ import { performance } from 'perf_hooks'; import { isBoom } from '@hapi/boom'; import { identity } from 'lodash'; import { IHttpEluMonitorConfig } from '@kbn/core-http-server/src/elu_monitor'; +import { Env } from '@kbn/config'; +import { CoreContext } from '@kbn/core-base-server-internal'; import { HttpConfig } from './http_config'; import { adoptToHapiAuthFormat } from './lifecycle/auth'; import { adoptToHapiOnPreAuth } from './lifecycle/on_pre_auth'; @@ -178,15 +180,20 @@ export class HttpServer { private stopped = false; private readonly log: Logger; + private readonly logger: LoggerFactory; private readonly authState: AuthStateStorage; private readonly authRequestHeaders: AuthHeadersStorage; private readonly authResponseHeaders: AuthHeadersStorage; + private readonly env: Env; constructor( - private readonly logger: LoggerFactory, + private readonly coreContext: CoreContext, private readonly name: string, private readonly shutdownTimeout$: Observable ) { + const { logger, env } = this.coreContext; + this.logger = logger; + this.env = env; this.authState = new AuthStateStorage(() => this.authRegistered); this.authRequestHeaders = new AuthHeadersStorage(); this.authResponseHeaders = new AuthHeadersStorage(); @@ -269,7 +276,11 @@ export class HttpServer { this.setupResponseLogging(); this.setupGracefulShutdownHandlers(); - const staticAssets = new StaticAssets(basePathService, config.cdn); + const staticAssets = new StaticAssets({ + basePath: basePathService, + cdnConfig: config.cdn, + shaDigest: this.env.packageInfo.buildShaShort, + }); return { registerRouter: this.registerRouter.bind(this), diff --git a/packages/core/http/core-http-server-internal/src/http_service.ts b/packages/core/http/core-http-server-internal/src/http_service.ts index 1ce15eb06b23..3dcab5be510e 100644 --- a/packages/core/http/core-http-server-internal/src/http_service.ts +++ b/packages/core/http/core-http-server-internal/src/http_service.ts @@ -76,8 +76,8 @@ export class HttpService configService.atPath(externalUrlConfig.path), ]).pipe(map(([http, csp, externalUrl]) => new HttpConfig(http, csp, externalUrl))); const shutdownTimeout$ = this.config$.pipe(map(({ shutdownTimeout }) => shutdownTimeout)); - this.prebootServer = new HttpServer(logger, 'Preboot', shutdownTimeout$); - this.httpServer = new HttpServer(logger, 'Kibana', shutdownTimeout$); + this.prebootServer = new HttpServer(coreContext, 'Preboot', shutdownTimeout$); + this.httpServer = new HttpServer(coreContext, 'Kibana', shutdownTimeout$); this.httpsRedirectServer = new HttpsRedirectServer(logger.get('http', 'redirect', 'server')); } diff --git a/packages/core/http/core-http-server-internal/src/static_assets.test.ts b/packages/core/http/core-http-server-internal/src/static_assets.test.ts deleted file mode 100644 index 0b1acd4e73fd..000000000000 --- a/packages/core/http/core-http-server-internal/src/static_assets.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { StaticAssets } from './static_assets'; -import { BasePath } from './base_path_service'; -import { CdnConfig } from './cdn'; - -describe('StaticAssets', () => { - let basePath: BasePath; - let cdnConfig: CdnConfig; - let staticAssets: StaticAssets; - - beforeEach(() => { - basePath = new BasePath('/base-path'); - }); - - describe('#getHrefBase()', () => { - it('provides fallback to server base path', () => { - cdnConfig = CdnConfig.from(); - staticAssets = new StaticAssets(basePath, cdnConfig); - expect(staticAssets.getHrefBase()).toEqual('/base-path'); - }); - - it('provides the correct HREF given a CDN is configured', () => { - cdnConfig = CdnConfig.from({ url: 'https://cdn.example.com/test' }); - staticAssets = new StaticAssets(basePath, cdnConfig); - expect(staticAssets.getHrefBase()).toEqual('https://cdn.example.com/test'); - }); - }); - - describe('#getPluginAssetHref()', () => { - it('returns the expected value when CDN config is not set', () => { - cdnConfig = CdnConfig.from(); - staticAssets = new StaticAssets(basePath, cdnConfig); - expect(staticAssets.getPluginAssetHref('foo', 'path/to/img.gif')).toEqual( - '/base-path/plugins/foo/assets/path/to/img.gif' - ); - }); - - it('returns the expected value when CDN config is set', () => { - cdnConfig = CdnConfig.from({ url: 'https://cdn.example.com/test' }); - staticAssets = new StaticAssets(basePath, cdnConfig); - expect(staticAssets.getPluginAssetHref('bar', 'path/to/img.gif')).toEqual( - 'https://cdn.example.com/test/plugins/bar/assets/path/to/img.gif' - ); - }); - - it('removes leading slash from the', () => { - cdnConfig = CdnConfig.from(); - staticAssets = new StaticAssets(basePath, cdnConfig); - expect(staticAssets.getPluginAssetHref('dolly', '/path/for/something.svg')).toEqual( - '/base-path/plugins/dolly/assets/path/for/something.svg' - ); - }); - }); -}); diff --git a/packages/core/http/core-http-server-internal/src/static_assets.ts b/packages/core/http/core-http-server-internal/src/static_assets.ts deleted file mode 100644 index 4dfe46d8d31a..000000000000 --- a/packages/core/http/core-http-server-internal/src/static_assets.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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import type { BasePath } from './base_path_service'; -import { CdnConfig } from './cdn'; - -export interface InternalStaticAssets { - getHrefBase(): string; - getPluginAssetHref(pluginName: string, assetPath: string): string; -} - -export class StaticAssets implements InternalStaticAssets { - private readonly assetsHrefBase: string; - - constructor(basePath: BasePath, cdnConfig: CdnConfig) { - const hrefToUse = cdnConfig.baseHref ?? basePath.serverBasePath; - this.assetsHrefBase = hrefToUse.endsWith('/') ? hrefToUse.slice(0, -1) : hrefToUse; - } - - /** - * Returns a href (hypertext reference) intended to be used as the base for constructing - * other hrefs to static assets. - */ - getHrefBase(): string { - return this.assetsHrefBase; - } - - getPluginAssetHref(pluginName: string, assetPath: string): string { - if (assetPath.startsWith('/')) { - assetPath = assetPath.slice(1); - } - return `${this.assetsHrefBase}/plugins/${pluginName}/assets/${assetPath}`; - } -} diff --git a/packages/core/http/core-http-server-internal/src/static_assets/index.ts b/packages/core/http/core-http-server-internal/src/static_assets/index.ts new file mode 100644 index 000000000000..1f4dc880583c --- /dev/null +++ b/packages/core/http/core-http-server-internal/src/static_assets/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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { type InternalStaticAssets, StaticAssets } from './static_assets'; diff --git a/packages/core/http/core-http-server-internal/src/static_assets/static_assets.test.ts b/packages/core/http/core-http-server-internal/src/static_assets/static_assets.test.ts new file mode 100644 index 000000000000..438a87765d85 --- /dev/null +++ b/packages/core/http/core-http-server-internal/src/static_assets/static_assets.test.ts @@ -0,0 +1,132 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { StaticAssets, type StaticAssetsParams } from './static_assets'; +import { BasePath } from '../base_path_service'; +import { CdnConfig } from '../cdn_config'; + +describe('StaticAssets', () => { + let basePath: BasePath; + let cdnConfig: CdnConfig; + let staticAssets: StaticAssets; + let args: StaticAssetsParams; + + beforeEach(() => { + basePath = new BasePath('/base-path'); + cdnConfig = CdnConfig.from(); + args = { basePath, cdnConfig, shaDigest: '' }; + }); + + describe('#getHrefBase()', () => { + it('provides fallback to server base path', () => { + staticAssets = new StaticAssets(args); + expect(staticAssets.getHrefBase()).toEqual('/base-path'); + }); + + it('provides the correct HREF given a CDN is configured', () => { + args.cdnConfig = CdnConfig.from({ url: 'https://cdn.example.com/test' }); + staticAssets = new StaticAssets(args); + expect(staticAssets.getHrefBase()).toEqual('https://cdn.example.com/test'); + }); + }); + + describe('#getPluginAssetHref()', () => { + it('returns the expected value when CDN is not configured', () => { + staticAssets = new StaticAssets(args); + expect(staticAssets.getPluginAssetHref('foo', 'path/to/img.gif')).toEqual( + '/base-path/plugins/foo/assets/path/to/img.gif' + ); + }); + + it('returns the expected value when CDN is configured', () => { + args.cdnConfig = CdnConfig.from({ url: 'https://cdn.example.com/test' }); + staticAssets = new StaticAssets(args); + expect(staticAssets.getPluginAssetHref('bar', 'path/to/img.gif')).toEqual( + 'https://cdn.example.com/test/plugins/bar/assets/path/to/img.gif' + ); + }); + + it('removes leading and trailing slash from the assetPath', () => { + staticAssets = new StaticAssets(args); + expect(staticAssets.getPluginAssetHref('dolly', '/path/for/something.svg/')).toEqual( + '/base-path/plugins/dolly/assets/path/for/something.svg' + ); + }); + it('removes leading and trailing slash from the assetPath when CDN is configured', () => { + args.cdnConfig = CdnConfig.from({ url: 'https://cdn.example.com/test' }); + staticAssets = new StaticAssets(args); + expect(staticAssets.getPluginAssetHref('dolly', '/path/for/something.svg/')).toEqual( + 'https://cdn.example.com/test/plugins/dolly/assets/path/for/something.svg' + ); + }); + }); + + describe('with a SHA digest provided', () => { + describe('cdn', () => { + it.each([ + ['https://cdn.example.com', 'https://cdn.example.com/beef', undefined], + ['https://cdn.example.com:1234', 'https://cdn.example.com:1234/beef', undefined], + [ + 'https://cdn.example.com:1234/roast', + 'https://cdn.example.com:1234/roast/beef', + undefined, + ], + // put slashes around shaDigest + [ + 'https://cdn.example.com:1234/roast-slash', + 'https://cdn.example.com:1234/roast-slash/beef', + '/beef/', + ], + ])('suffixes the digest to the CDNs path value (%s)', (url, expectedHref, shaDigest) => { + args.shaDigest = shaDigest ?? 'beef'; + args.cdnConfig = CdnConfig.from({ url }); + staticAssets = new StaticAssets(args); + expect(staticAssets.getHrefBase()).toEqual(expectedHref); + }); + }); + + describe('base path', () => { + it.each([ + ['', '/beef', undefined], + ['/', '/beef', undefined], + ['/roast', '/roast/beef', undefined], + ['/roast/', '/roast/beef', '/beef/'], // cheeky test adding a slashes to digest + ])('suffixes the digest to the server base path "%s")', (url, expectedPath, shaDigest) => { + basePath = new BasePath(url); + args.basePath = basePath; + args.shaDigest = shaDigest ?? 'beef'; + staticAssets = new StaticAssets(args); + expect(staticAssets.getHrefBase()).toEqual(expectedPath); + }); + }); + }); + + describe('#getPluginServerPath()', () => { + it('provides the path plugin assets can use for server routes', () => { + args.shaDigest = '1234'; + staticAssets = new StaticAssets(args); + expect(staticAssets.getPluginServerPath('myPlugin', '/fun/times')).toEqual( + '/1234/plugins/myPlugin/assets/fun/times' + ); + }); + }); + describe('#prependPublicUrl()', () => { + it('with a CDN it appends as expected', () => { + args.cdnConfig = CdnConfig.from({ url: 'http://cdn.example.com/cool?123=true' }); + staticAssets = new StaticAssets(args); + expect(staticAssets.prependPublicUrl('beans')).toEqual( + 'http://cdn.example.com/cool/beans?123=true' + ); + }); + + it('without a CDN it appends as expected', () => { + staticAssets = new StaticAssets(args); + expect(staticAssets.prependPublicUrl('/cool/beans')).toEqual('/base-path/cool/beans'); + }); + }); +}); diff --git a/packages/core/http/core-http-server-internal/src/static_assets/static_assets.ts b/packages/core/http/core-http-server-internal/src/static_assets/static_assets.ts new file mode 100644 index 000000000000..f5f7d7ac8043 --- /dev/null +++ b/packages/core/http/core-http-server-internal/src/static_assets/static_assets.ts @@ -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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { BasePath } from '../base_path_service'; +import { CdnConfig } from '../cdn_config'; +import { + suffixPathnameToPathname, + suffixPathnameToURLPathname, + removeSurroundingSlashes, +} from './util'; + +export interface InternalStaticAssets { + getHrefBase(): string; + /** + * Intended for use by server code rendering UI or generating links to static assets + * that will ultimately be called from the browser and must respect settings like + * serverBasePath + */ + getPluginAssetHref(pluginName: string, assetPath: string): string; + /** + * Intended for use by server code wanting to register static assets against Kibana + * as server paths + */ + getPluginServerPath(pluginName: string, assetPath: string): string; + /** + * Similar to getPluginServerPath, but not plugin-scoped + */ + prependServerPath(pathname: string): string; + + /** + * Will append the given path segment to the configured public path. + * + * @note This could return a path or full URL depending on whether a CDN is configured. + */ + prependPublicUrl(pathname: string): string; +} + +/** @internal */ +export interface StaticAssetsParams { + basePath: BasePath; + cdnConfig: CdnConfig; + shaDigest: string; +} + +/** + * Convention is for trailing slashes in pathnames are stripped. + */ +export class StaticAssets implements InternalStaticAssets { + private readonly assetsHrefBase: string; + private readonly assetsServerPathBase: string; + private readonly hasCdnHost: boolean; + + constructor({ basePath, cdnConfig, shaDigest }: StaticAssetsParams) { + const cdnBaseHref = cdnConfig.baseHref; + if (cdnBaseHref) { + this.hasCdnHost = true; + this.assetsHrefBase = suffixPathnameToURLPathname(cdnBaseHref, shaDigest); + } else { + this.hasCdnHost = false; + this.assetsHrefBase = suffixPathnameToPathname(basePath.serverBasePath, shaDigest); + } + this.assetsServerPathBase = `/${shaDigest}`; + } + + /** + * Returns a href (hypertext reference) intended to be used as the base for constructing + * other hrefs to static assets. + */ + public getHrefBase(): string { + return this.assetsHrefBase; + } + + public getPluginAssetHref(pluginName: string, assetPath: string): string { + if (assetPath.startsWith('/')) { + assetPath = assetPath.slice(1); + } + return `${this.assetsHrefBase}/plugins/${pluginName}/assets/${removeSurroundingSlashes( + assetPath + )}`; + } + + public prependServerPath(path: string): string { + return `${this.assetsServerPathBase}/${removeSurroundingSlashes(path)}`; + } + + public prependPublicUrl(pathname: string): string { + if (this.hasCdnHost) { + return suffixPathnameToURLPathname(this.assetsHrefBase, pathname); + } + return suffixPathnameToPathname(this.assetsHrefBase, pathname); + } + + public getPluginServerPath(pluginName: string, assetPath: string): string { + return `${this.assetsServerPathBase}/plugins/${pluginName}/assets/${removeSurroundingSlashes( + assetPath + )}`; + } +} diff --git a/packages/core/http/core-http-server-internal/src/static_assets/util.ts b/packages/core/http/core-http-server-internal/src/static_assets/util.ts new file mode 100644 index 000000000000..c86f56fc239a --- /dev/null +++ b/packages/core/http/core-http-server-internal/src/static_assets/util.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { URL, format } from 'node:url'; + +function isEmptyPathname(pathname: string): boolean { + return !pathname || pathname === '/'; +} + +function removeTailSlashes(pathname: string): string { + return pathname.replace(/\/+$/, ''); +} + +function removeLeadSlashes(pathname: string): string { + return pathname.replace(/^\/+/, ''); +} + +export function removeSurroundingSlashes(pathname: string): string { + return removeLeadSlashes(removeTailSlashes(pathname)); +} + +export function suffixPathnameToURLPathname(urlString: string, pathname: string): string { + const url = new URL(urlString); + url.pathname = suffixPathnameToPathname(url.pathname, pathname); + return format(url); +} + +/** + * Appends a value to pathname. Pathname is assumed to come from URL.pathname + * Also do some quality control on the path to ensure that it matches URL.pathname. + */ +export function suffixPathnameToPathname(pathnameA: string, pathnameB: string): string { + if (isEmptyPathname(pathnameA)) { + return `/${removeSurroundingSlashes(pathnameB)}`; + } + if (isEmptyPathname(pathnameB)) { + return `/${removeSurroundingSlashes(pathnameA)}`; + } + return `/${removeSurroundingSlashes(pathnameA)}/${removeSurroundingSlashes(pathnameB)}`; +} diff --git a/packages/core/http/core-http-server-internal/tsconfig.json b/packages/core/http/core-http-server-internal/tsconfig.json index e163741c21c7..7c52ff584a53 100644 --- a/packages/core/http/core-http-server-internal/tsconfig.json +++ b/packages/core/http/core-http-server-internal/tsconfig.json @@ -33,6 +33,7 @@ "@kbn/core-execution-context-server-mocks", "@kbn/core-http-context-server-mocks", "@kbn/logging-mocks", + "@kbn/core-base-server-mocks", ], "exclude": [ "target/**/*", diff --git a/packages/core/http/core-http-server-mocks/src/http_service.mock.ts b/packages/core/http/core-http-server-mocks/src/http_service.mock.ts index f8ecfadfeb87..7172accf98a9 100644 --- a/packages/core/http/core-http-server-mocks/src/http_service.mock.ts +++ b/packages/core/http/core-http-server-mocks/src/http_service.mock.ts @@ -87,8 +87,11 @@ const createInternalStaticAssetsMock = ( basePath: BasePathMocked, cdnUrl: undefined | string = undefined ): InternalStaticAssetsMocked => ({ - getHrefBase: jest.fn(() => cdnUrl ?? basePath.serverBasePath), + getHrefBase: jest.fn().mockReturnValue(cdnUrl ?? basePath.serverBasePath), getPluginAssetHref: jest.fn().mockReturnValue(cdnUrl ?? basePath.serverBasePath), + getPluginServerPath: jest.fn((v, _) => v), + prependServerPath: jest.fn((v) => v), + prependPublicUrl: jest.fn((v) => v), }); const createAuthMock = () => { @@ -212,6 +215,7 @@ const createSetupContractMock = < getServerInfo: internalMock.getServerInfo, staticAssets: { getPluginAssetHref: jest.fn().mockImplementation((assetPath: string) => assetPath), + prependPublicUrl: jest.fn().mockImplementation((pathname: string) => pathname), }, }; @@ -227,6 +231,7 @@ const createStartContractMock = () => { getServerInfo: jest.fn(), staticAssets: { getPluginAssetHref: jest.fn().mockImplementation((assetPath: string) => assetPath), + prependPublicUrl: jest.fn().mockImplementation((pathname: string) => pathname), }, }; diff --git a/packages/core/http/core-http-server/src/static_assets.ts b/packages/core/http/core-http-server/src/static_assets.ts index c0cc8597d154..a839beae8023 100644 --- a/packages/core/http/core-http-server/src/static_assets.ts +++ b/packages/core/http/core-http-server/src/static_assets.ts @@ -23,4 +23,23 @@ export interface IStaticAssets { * ``` */ getPluginAssetHref(assetPath: string): string; + + /** + * Will return an href, either a path for or full URL with the provided path + * appended to the static assets public base path. + * + * Useful for instances were you need to render your own HTML page and link to + * certain static assets. + * + * @example + * ```ts + * // I want to retrieve the href for Kibana's favicon, requires knowledge of path: + * const favIconHref = core.http.statisAssets.prependPublicUrl('/ui/favicons/favicon.svg'); + * ``` + * + * @note Only use this if you know what you are doing and there is no other option. + * This creates a strong coupling between asset dir structure and your code. + * @param pathname + */ + prependPublicUrl(pathname: string): string; } diff --git a/packages/core/plugins/core-plugins-browser-internal/src/test_helpers/mocks.ts b/packages/core/plugins/core-plugins-browser-internal/src/test_helpers/mocks.ts index 787a7d767819..38b86ed553cf 100644 --- a/packages/core/plugins/core-plugins-browser-internal/src/test_helpers/mocks.ts +++ b/packages/core/plugins/core-plugins-browser-internal/src/test_helpers/mocks.ts @@ -23,6 +23,7 @@ export const createPluginInitializerContextMock = (config: unknown = {}) => { branch: 'branch', buildNum: 100, buildSha: 'buildSha', + buildShaShort: 'buildShaShort', dist: false, buildDate: new Date('2023-05-15T23:12:09.000Z'), buildFlavor: 'traditional', diff --git a/packages/core/plugins/core-plugins-browser-mocks/src/plugins_service.mock.ts b/packages/core/plugins/core-plugins-browser-mocks/src/plugins_service.mock.ts index ff3d60c5c570..6a52194d520f 100644 --- a/packages/core/plugins/core-plugins-browser-mocks/src/plugins_service.mock.ts +++ b/packages/core/plugins/core-plugins-browser-mocks/src/plugins_service.mock.ts @@ -49,6 +49,7 @@ const createPluginInitializerContextMock = ( branch: 'branch', buildNum: 100, buildSha: 'buildSha', + buildShaShort: 'buildShaShort', dist: false, buildDate: new Date('2023-05-15T23:12:09.000Z'), buildFlavor, diff --git a/packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.test.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.test.ts index 202cef2ca09d..cdcf7ac7063f 100644 --- a/packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.test.ts +++ b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.test.ts @@ -19,6 +19,7 @@ const packageInfo: PackageInfo = { branch: 'master', buildNum: 1, buildSha: '', + buildShaShort: '', version: '7.0.0-alpha1', dist: false, buildDate: new Date('2023-05-15T23:12:09.000Z'), diff --git a/packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts b/packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts index c3ed7f6a433b..3cb8777d647d 100644 --- a/packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts +++ b/packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts @@ -236,6 +236,7 @@ export function createPluginSetupContext({ registerOnPreResponse: deps.http.registerOnPreResponse, basePath: deps.http.basePath, staticAssets: { + prependPublicUrl: (pathname: string) => deps.http.staticAssets.prependPublicUrl(pathname), getPluginAssetHref: (assetPath: string) => deps.http.staticAssets.getPluginAssetHref(plugin.name, assetPath), }, @@ -329,6 +330,7 @@ export function createPluginStartContext({ basePath: deps.http.basePath, getServerInfo: deps.http.getServerInfo, staticAssets: { + prependPublicUrl: (pathname: string) => deps.http.staticAssets.prependPublicUrl(pathname), getPluginAssetHref: (assetPath: string) => deps.http.staticAssets.getPluginAssetHref(plugin.name, assetPath), }, diff --git a/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts index 2185bfe13fb1..e25a1b924e42 100644 --- a/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts +++ b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts @@ -1165,8 +1165,10 @@ describe('PluginsService', () => { }); describe('plugin initialization', () => { + let prebootPlugins: PluginWrapper[]; + let standardPlugins: PluginWrapper[]; beforeEach(() => { - const prebootPlugins = [ + prebootPlugins = [ createPlugin('plugin-1-preboot', { type: PluginType.preboot, path: 'path-1-preboot', @@ -1178,7 +1180,7 @@ describe('PluginsService', () => { version: 'version-2', }), ]; - const standardPlugins = [ + standardPlugins = [ createPlugin('plugin-1-standard', { path: 'path-1-standard', version: 'version-1', @@ -1299,6 +1301,31 @@ describe('PluginsService', () => { expect(standardMockPluginSystem.setupPlugins).not.toHaveBeenCalled(); }); + it('#preboot registers expected static dirs', async () => { + prebootDeps.http.staticAssets.getPluginServerPath.mockImplementation( + (pluginName: string) => `/static-assets/${pluginName}` + ); + await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot }); + await pluginsService.preboot(prebootDeps); + expect(prebootDeps.http.registerStaticDir).toHaveBeenCalledTimes(prebootPlugins.length * 2); + expect(prebootDeps.http.registerStaticDir).toHaveBeenCalledWith( + '/static-assets/plugin-1-preboot', + expect.any(String) + ); + expect(prebootDeps.http.registerStaticDir).toHaveBeenCalledWith( + '/plugins/plugin-1-preboot/assets/{path*}', + expect.any(String) + ); + expect(prebootDeps.http.registerStaticDir).toHaveBeenCalledWith( + '/static-assets/plugin-2-preboot', + expect.any(String) + ); + expect(prebootDeps.http.registerStaticDir).toHaveBeenCalledWith( + '/plugins/plugin-2-preboot/assets/{path*}', + expect.any(String) + ); + }); + it('#setup does initialize `standard` plugins if plugins.initialize is true', async () => { config$.next({ plugins: { initialize: true } }); await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot }); @@ -1319,6 +1346,32 @@ describe('PluginsService', () => { expect(prebootMockPluginSystem.setupPlugins).not.toHaveBeenCalled(); expect(initialized).toBe(false); }); + + it('#setup registers expected static dirs', async () => { + await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot }); + await pluginsService.preboot(prebootDeps); + setupDeps.http.staticAssets.getPluginServerPath.mockImplementation( + (pluginName: string) => `/static-assets/${pluginName}` + ); + await pluginsService.setup(setupDeps); + expect(setupDeps.http.registerStaticDir).toHaveBeenCalledTimes(standardPlugins.length * 2); + expect(setupDeps.http.registerStaticDir).toHaveBeenCalledWith( + '/static-assets/plugin-1-standard', + expect.any(String) + ); + expect(setupDeps.http.registerStaticDir).toHaveBeenCalledWith( + '/plugins/plugin-1-standard/assets/{path*}', + expect.any(String) + ); + expect(setupDeps.http.registerStaticDir).toHaveBeenCalledWith( + '/static-assets/plugin-2-standard', + expect.any(String) + ); + expect(setupDeps.http.registerStaticDir).toHaveBeenCalledWith( + '/plugins/plugin-2-standard/assets/{path*}', + expect.any(String) + ); + }); }); describe('#getExposedPluginConfigsToUsage', () => { diff --git a/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts index a5f7bfaef7d7..da5d77d8be67 100644 --- a/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts +++ b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts @@ -448,10 +448,16 @@ export class PluginsService uiPluginInternalInfo: Map ) { for (const [pluginName, pluginInfo] of uiPluginInternalInfo) { - deps.http.registerStaticDir( + /** + * Serve UI from sha-scoped and not-sha-scoped paths to allow time for plugin code to migrate + * Eventually we only want to serve from the sha scoped path + */ + [ + deps.http.staticAssets.getPluginServerPath(pluginName, '{path*}'), `/plugins/${pluginName}/assets/{path*}`, - pluginInfo.publicAssetsDir - ); + ].forEach((path) => { + deps.http.registerStaticDir(path, pluginInfo.publicAssetsDir); + }); } } } diff --git a/packages/core/rendering/core-rendering-server-internal/src/__snapshots__/rendering_service.test.ts.snap b/packages/core/rendering/core-rendering-server-internal/src/__snapshots__/rendering_service.test.ts.snap index 535624e4a832..b6fedfd8644e 100644 --- a/packages/core/rendering/core-rendering-server-internal/src/__snapshots__/rendering_service.test.ts.snap +++ b/packages/core/rendering/core-rendering-server-internal/src/__snapshots__/rendering_service.test.ts.snap @@ -24,6 +24,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -92,6 +93,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -156,6 +158,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -224,6 +227,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -288,6 +292,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -352,6 +357,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -420,6 +426,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -484,6 +491,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -553,6 +561,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -621,6 +630,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -690,6 +700,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -763,6 +774,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -827,6 +839,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -896,6 +909,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -969,6 +983,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, @@ -1038,6 +1053,7 @@ Object { "buildFlavor": Any, "buildNum": Any, "buildSha": Any, + "buildShaShort": "XXXXXX", "dist": Any, "version": Any, }, diff --git a/packages/core/rendering/core-rendering-server-internal/src/bootstrap/bootstrap_renderer.test.ts b/packages/core/rendering/core-rendering-server-internal/src/bootstrap/bootstrap_renderer.test.ts index 5c699e905e9c..e959b3aff356 100644 --- a/packages/core/rendering/core-rendering-server-internal/src/bootstrap/bootstrap_renderer.test.ts +++ b/packages/core/rendering/core-rendering-server-internal/src/bootstrap/bootstrap_renderer.test.ts @@ -25,6 +25,7 @@ const createPackageInfo = (parts: Partial = {}): PackageInfo => ({ branch: 'master', buildNum: 42, buildSha: 'buildSha', + buildShaShort: 'buildShaShort', buildDate: new Date('2023-05-15T23:12:09.000Z'), dist: false, version: '8.0.0', @@ -62,7 +63,7 @@ describe('bootstrapRenderer', () => { auth, packageInfo, uiPlugins, - baseHref: '/base-path', + baseHref: `/base-path/${packageInfo.buildShaShort}`, // the base href as provided by static assets module }); }); @@ -319,7 +320,7 @@ describe('bootstrapRenderer', () => { expect(getPluginsBundlePathsMock).toHaveBeenCalledWith({ isAnonymousPage, uiPlugins, - bundlesHref: '/base-path/42/bundles', + bundlesHref: '/base-path/buildShaShort/bundles', }); }); }); @@ -338,7 +339,7 @@ describe('bootstrapRenderer', () => { expect(getJsDependencyPathsMock).toHaveBeenCalledTimes(1); expect(getJsDependencyPathsMock).toHaveBeenCalledWith( - '/base-path/42/bundles', + '/base-path/buildShaShort/bundles', pluginsBundlePaths ); }); diff --git a/packages/core/rendering/core-rendering-server-internal/src/bootstrap/bootstrap_renderer.ts b/packages/core/rendering/core-rendering-server-internal/src/bootstrap/bootstrap_renderer.ts index e8c30819a0b6..57cd247b4f6f 100644 --- a/packages/core/rendering/core-rendering-server-internal/src/bootstrap/bootstrap_renderer.ts +++ b/packages/core/rendering/core-rendering-server-internal/src/bootstrap/bootstrap_renderer.ts @@ -79,8 +79,7 @@ export const bootstrapRendererFactory: BootstrapRendererFactory = ({ themeVersion, darkMode, }); - const buildHash = packageInfo.buildNum; - const bundlesHref = getBundlesHref(baseHref, String(buildHash)); + const bundlesHref = getBundlesHref(baseHref); const bundlePaths = getPluginsBundlePaths({ uiPlugins, diff --git a/packages/core/rendering/core-rendering-server-internal/src/render_utils.test.ts b/packages/core/rendering/core-rendering-server-internal/src/render_utils.test.ts index 8a5d2e4c7377..e52e18e03776 100644 --- a/packages/core/rendering/core-rendering-server-internal/src/render_utils.test.ts +++ b/packages/core/rendering/core-rendering-server-internal/src/render_utils.test.ts @@ -16,14 +16,14 @@ describe('getStylesheetPaths', () => { getStylesheetPaths({ darkMode: true, themeVersion: 'v8', - baseHref: '/base-path', + baseHref: '/base-path/buildShaShort', buildNum: 17, }) ).toMatchInlineSnapshot(` Array [ - "/base-path/17/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.v8.dark.css", - "/base-path/17/bundles/kbn-ui-shared-deps-src/kbn-ui-shared-deps-src.css", - "/base-path/ui/legacy_dark_theme.min.css", + "/base-path/buildShaShort/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.v8.dark.css", + "/base-path/buildShaShort/bundles/kbn-ui-shared-deps-src/kbn-ui-shared-deps-src.css", + "/base-path/buildShaShort/ui/legacy_dark_theme.min.css", ] `); }); @@ -36,14 +36,14 @@ describe('getStylesheetPaths', () => { getStylesheetPaths({ darkMode: false, themeVersion: 'v8', - baseHref: '/base-path', + baseHref: '/base-path/buildShaShort', buildNum: 69, }) ).toMatchInlineSnapshot(` Array [ - "/base-path/69/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.v8.light.css", - "/base-path/69/bundles/kbn-ui-shared-deps-src/kbn-ui-shared-deps-src.css", - "/base-path/ui/legacy_light_theme.min.css", + "/base-path/buildShaShort/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.v8.light.css", + "/base-path/buildShaShort/bundles/kbn-ui-shared-deps-src/kbn-ui-shared-deps-src.css", + "/base-path/buildShaShort/ui/legacy_light_theme.min.css", ] `); }); diff --git a/packages/core/rendering/core-rendering-server-internal/src/render_utils.ts b/packages/core/rendering/core-rendering-server-internal/src/render_utils.ts index 6f74320098b1..51f15a2ba034 100644 --- a/packages/core/rendering/core-rendering-server-internal/src/render_utils.ts +++ b/packages/core/rendering/core-rendering-server-internal/src/render_utils.ts @@ -22,8 +22,7 @@ export const getSettingValue = ( return convert(value); }; -export const getBundlesHref = (baseHref: string, buildNr: string): string => - `${baseHref}/${buildNr}/bundles`; +export const getBundlesHref = (baseHref: string): string => `${baseHref}/bundles`; export const getStylesheetPaths = ({ themeVersion, @@ -36,7 +35,7 @@ export const getStylesheetPaths = ({ buildNum: number; baseHref: string; }) => { - const bundlesHref = getBundlesHref(baseHref, String(buildNum)); + const bundlesHref = getBundlesHref(baseHref); return [ ...(darkMode ? [ diff --git a/packages/kbn-config/src/__snapshots__/env.test.ts.snap b/packages/kbn-config/src/__snapshots__/env.test.ts.snap index e5d5a3816ced..4bc87fb5f240 100644 --- a/packages/kbn-config/src/__snapshots__/env.test.ts.snap +++ b/packages/kbn-config/src/__snapshots__/env.test.ts.snap @@ -32,6 +32,7 @@ Env { "buildFlavor": "traditional", "buildNum": 9007199254740991, "buildSha": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "buildShaShort": "XXXXXXXXXXXX", "dist": false, "version": "v1", }, @@ -75,6 +76,7 @@ Env { "buildFlavor": "traditional", "buildNum": 9007199254740991, "buildSha": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "buildShaShort": "XXXXXXXXXXXX", "dist": false, "version": "v1", }, @@ -117,6 +119,7 @@ Env { "buildFlavor": "traditional", "buildNum": 9007199254740991, "buildSha": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "buildShaShort": "XXXXXXXXXXXX", "dist": false, "version": "some-version", }, @@ -159,6 +162,7 @@ Env { "buildFlavor": "traditional", "buildNum": 100, "buildSha": "feature-v1-build-sha", + "buildShaShort": "feature-v1-b", "dist": true, "version": "v1", }, @@ -201,6 +205,7 @@ Env { "buildFlavor": "traditional", "buildNum": 9007199254740991, "buildSha": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", + "buildShaShort": "XXXXXXXXXXXX", "dist": false, "version": "v1", }, @@ -243,6 +248,7 @@ Env { "buildFlavor": "traditional", "buildNum": 100, "buildSha": "feature-v1-build-sha", + "buildShaShort": "feature-v1-b", "dist": true, "version": "v1", }, diff --git a/packages/kbn-config/src/env.test.ts b/packages/kbn-config/src/env.test.ts index 7c301ff83e6f..45f037500b77 100644 --- a/packages/kbn-config/src/env.test.ts +++ b/packages/kbn-config/src/env.test.ts @@ -248,3 +248,35 @@ describe('packageInfo.buildFlavor', () => { expect(env.packageInfo.buildFlavor).toEqual('traditional'); }); }); + +describe('packageInfo.buildShaShort', () => { + const sha = 'c6e1a25bea71a623929a8f172c0273bf0c811ca0'; + it('provides the sha and a short version of the sha', () => { + mockPackage.raw = { + branch: 'some-branch', + version: 'some-version', + }; + + const env = new Env( + '/some/home/dir', + { + branch: 'whathaveyou', + version: 'v1', + build: { + distributable: true, + number: 100, + sha, + date: BUILD_DATE, + }, + }, + getEnvOptions({ + cliArgs: { dev: false }, + configs: ['/some/other/path/some-kibana.yml'], + repoPackages: ['FakePackage1', 'FakePackage2'] as unknown as Package[], + }) + ); + + expect(env.packageInfo.buildSha).toEqual('c6e1a25bea71a623929a8f172c0273bf0c811ca0'); + expect(env.packageInfo.buildShaShort).toEqual('c6e1a25bea71'); + }); +}); diff --git a/packages/kbn-config/src/env.ts b/packages/kbn-config/src/env.ts index 99728f0dfc41..4b2c93611615 100644 --- a/packages/kbn-config/src/env.ts +++ b/packages/kbn-config/src/env.ts @@ -121,6 +121,7 @@ export class Env { branch: pkg.branch, buildNum: isKibanaDistributable ? pkg.build.number : Number.MAX_SAFE_INTEGER, buildSha: isKibanaDistributable ? pkg.build.sha : 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + buildShaShort: isKibanaDistributable ? pkg.build.sha.slice(0, 12) : 'XXXXXXXXXXXX', version: pkg.version, dist: isKibanaDistributable, buildDate: isKibanaDistributable ? new Date(pkg.build.date) : new Date(), diff --git a/packages/kbn-config/src/types.ts b/packages/kbn-config/src/types.ts index f9038a1a7fd2..91706bb9f2cb 100644 --- a/packages/kbn-config/src/types.ts +++ b/packages/kbn-config/src/types.ts @@ -14,6 +14,7 @@ export interface PackageInfo { branch: string; buildNum: number; buildSha: string; + buildShaShort: string; buildDate: Date; buildFlavor: BuildFlavor; dist: boolean; diff --git a/packages/kbn-es-types/src/search.ts b/packages/kbn-es-types/src/search.ts index 461a32f14984..4351ac91e5c1 100644 --- a/packages/kbn-es-types/src/search.ts +++ b/packages/kbn-es-types/src/search.ts @@ -678,4 +678,5 @@ export interface ESQLSearchParams { query: string; filter?: unknown; locale?: string; + dropNullColumns?: boolean; } diff --git a/packages/kbn-generate-csv/src/__snapshots__/generate_csv.test.ts.snap b/packages/kbn-generate-csv/src/__snapshots__/generate_csv.test.ts.snap index 778ec83563ca..ec692fe0fea6 100644 --- a/packages/kbn-generate-csv/src/__snapshots__/generate_csv.test.ts.snap +++ b/packages/kbn-generate-csv/src/__snapshots__/generate_csv.test.ts.snap @@ -226,6 +226,14 @@ exports[`CsvGenerator Scroll strategy uses the scroll context to page all the da " `; +exports[`CsvGenerator export behavior when scroll duration config is auto csv gets generated if search resolves without errors before the computed timeout value passed to the search data client elapses 1`] = ` +"a,b +a1,b1 +a1,b1 +a1,b1 +" +`; + exports[`CsvGenerator fields from job.columns (7.13+ generated) cells can be multi-value 1`] = ` "product,category coconut,\\"cool, rad\\" diff --git a/packages/kbn-generate-csv/src/generate_csv.test.ts b/packages/kbn-generate-csv/src/generate_csv.test.ts index 8d831895173e..86a88fe3d3fb 100644 --- a/packages/kbn-generate-csv/src/generate_csv.test.ts +++ b/packages/kbn-generate-csv/src/generate_csv.test.ts @@ -9,6 +9,7 @@ import { identity, range } from 'lodash'; import * as Rx from 'rxjs'; import type { Writable } from 'stream'; +import { add, type Duration } from 'date-fns'; import { errors as esErrors, estypes } from '@elastic/elasticsearch'; import type { SearchResponse } from '@elastic/elasticsearch/lib/api/types'; @@ -21,6 +22,8 @@ import { } from '@kbn/core/server/mocks'; import { ISearchClient, ISearchStartSearchSource } from '@kbn/data-plugin/common'; import { searchSourceInstanceMock } from '@kbn/data-plugin/common/search/search_source/mocks'; +import type { IScopedSearchClient } from '@kbn/data-plugin/server'; +import type { IKibanaSearchResponse } from '@kbn/data-plugin/common'; import { dataPluginMock } from '@kbn/data-plugin/server/mocks'; import { FieldFormatsRegistry } from '@kbn/field-formats-plugin/common'; import { CancellationToken } from '@kbn/reporting-common'; @@ -360,7 +363,11 @@ describe('CsvGenerator', () => { expect(mockDataClient.search).toHaveBeenCalledTimes(10); expect(mockDataClient.search).toBeCalledWith( { params: { body: {}, ignore_throttled: undefined, max_concurrent_shard_requests: 5 } }, - { strategy: 'es', transport: { maxRetries: 0, requestTimeout: '30s' } } + { + abortSignal: expect.any(AbortSignal), + strategy: 'es', + transport: { maxRetries: 0, requestTimeout: '30s' }, + } ); expect(mockEsClient.asCurrentUser.openPointInTime).toHaveBeenCalledTimes(1); @@ -370,7 +377,12 @@ describe('CsvGenerator', () => { index: 'logstash-*', keep_alive: '30s', }, - { maxConcurrentShardRequests: 5, maxRetries: 0, requestTimeout: '30s' } + { + maxConcurrentShardRequests: 5, + maxRetries: 0, + requestTimeout: '30s', + signal: expect.any(AbortSignal), + } ); expect(mockEsClient.asCurrentUser.closePointInTime).toHaveBeenCalledTimes(1); @@ -548,6 +560,203 @@ describe('CsvGenerator', () => { }); }); + describe('export behavior when scroll duration config is auto', () => { + const getTaskInstanceFields = (intervalFromNow: Duration) => { + const now = new Date(Date.now()); + return { startedAt: now, retryAt: add(now, intervalFromNow) }; + }; + + let mockConfigWithAutoScrollDuration: ReportingConfigType['csv']; + let mockDataClientSearchFn: jest.MockedFunction; + + beforeEach(() => { + mockConfigWithAutoScrollDuration = { + ...mockConfig, + scroll: { + ...mockConfig.scroll, + duration: 'auto', + }, + }; + + mockDataClientSearchFn = jest.fn(); + + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.clearAllTimers(); + jest.useRealTimers(); + + mockDataClientSearchFn.mockRestore(); + }); + + it('csv gets generated if search resolves without errors before the computed timeout value passed to the search data client elapses', async () => { + const timeFromNowInMs = 4 * 60 * 1000; + + const taskInstanceFields = getTaskInstanceFields({ + seconds: timeFromNowInMs / 1000, + }); + + mockDataClientSearchFn.mockImplementation((_, options) => { + const getSearchResult = () => { + const queuedAt = Date.now(); + + return new Promise>>( + (resolve, reject) => { + setTimeout(() => { + if ( + new Date(Date.now()).getTime() - new Date(queuedAt).getTime() > + Number((options?.transport?.requestTimeout! as string).replace(/ms/, '')) + ) { + reject( + new esErrors.ResponseError({ statusCode: 408, meta: {} as any, warnings: [] }) + ); + } else { + resolve({ + rawResponse: getMockRawResponse( + [ + { + fields: { a: ['a1'], b: ['b1'] }, + } as unknown as estypes.SearchHit, + ], + 3 + ), + }); + } + }, timeFromNowInMs / 4); + } + ); + }; + + return Rx.defer(getSearchResult); + }); + + const generateCsvPromise = new CsvGenerator( + createMockJob({ searchSource: {}, columns: ['a', 'b'] }), + mockConfigWithAutoScrollDuration, + taskInstanceFields, + { + es: mockEsClient, + data: { + ...mockDataClient, + search: mockDataClientSearchFn, + }, + uiSettings: uiSettingsClient, + }, + { + searchSourceStart: mockSearchSourceService, + fieldFormatsRegistry: mockFieldFormatsRegistry, + }, + new CancellationToken(), + mockLogger, + stream + ).generateData(); + + await jest.advanceTimersByTimeAsync(timeFromNowInMs); + + expect(await generateCsvPromise).toEqual( + expect.objectContaining({ + warnings: [], + }) + ); + + expect(mockDataClientSearchFn).toBeCalledWith( + { params: { body: {}, ignore_throttled: undefined, max_concurrent_shard_requests: 5 } }, + { + abortSignal: expect.any(AbortSignal), + strategy: 'es', + transport: { maxRetries: 0, requestTimeout: `${timeFromNowInMs}ms` }, + } + ); + + expect(content).toMatchSnapshot(); + }); + + it('csv generation errors if search request does not resolve before the computed timeout value passed to the search data client elapses', async () => { + const timeFromNowInMs = 4 * 60 * 1000; + + const taskInstanceFields = getTaskInstanceFields({ + seconds: timeFromNowInMs / 1000, + }); + + const requestDuration = timeFromNowInMs + 1000; + + mockDataClientSearchFn.mockImplementation((_, options) => { + const getSearchResult = () => { + const queuedAt = Date.now(); + + return new Promise>>( + (resolve, reject) => { + setTimeout(() => { + if ( + new Date(Date.now()).getTime() - new Date(queuedAt).getTime() > + Number((options?.transport?.requestTimeout! as string).replace(/ms/, '')) + ) { + reject( + new esErrors.ResponseError({ statusCode: 408, meta: {} as any, warnings: [] }) + ); + } else { + resolve({ + rawResponse: getMockRawResponse( + [ + { + fields: { a: ['a1'], b: ['b1'] }, + } as unknown as estypes.SearchHit, + ], + 3 + ), + }); + } + }, requestDuration); + } + ); + }; + + return Rx.defer(getSearchResult); + }); + + const generateCsvPromise = new CsvGenerator( + createMockJob({ searchSource: {}, columns: ['a', 'b'] }), + mockConfigWithAutoScrollDuration, + taskInstanceFields, + { + es: mockEsClient, + data: { + ...mockDataClient, + search: mockDataClientSearchFn, + }, + uiSettings: uiSettingsClient, + }, + { + searchSourceStart: mockSearchSourceService, + fieldFormatsRegistry: mockFieldFormatsRegistry, + }, + new CancellationToken(), + mockLogger, + stream + ).generateData(); + + await jest.advanceTimersByTimeAsync(requestDuration); + + expect(await generateCsvPromise).toEqual( + expect.objectContaining({ + warnings: expect.arrayContaining([ + expect.stringContaining('Received a 408 response from Elasticsearch'), + ]), + }) + ); + + expect(mockDataClientSearchFn).toBeCalledWith( + { params: { body: {}, ignore_throttled: undefined, max_concurrent_shard_requests: 5 } }, + { + abortSignal: expect.any(AbortSignal), + strategy: 'es', + transport: { maxRetries: 0, requestTimeout: `${timeFromNowInMs}ms` }, + } + ); + }); + }); + describe('Scroll strategy', () => { const mockJobUsingScrollPaging = createMockJob({ columns: ['date', 'ip', 'message'], @@ -654,7 +863,11 @@ describe('CsvGenerator', () => { max_concurrent_shard_requests: 5, }), }, - { strategy: 'es', transport: { maxRetries: 0, requestTimeout: '30s' } } + { + abortSignal: expect.any(AbortSignal), + strategy: 'es', + transport: { maxRetries: 0, requestTimeout: '30s' }, + } ); expect(mockEsClient.asCurrentUser.openPointInTime).not.toHaveBeenCalled(); @@ -1200,17 +1413,12 @@ describe('CsvGenerator', () => { index: 'logstash-*', keep_alive: '30s', }, - { maxConcurrentShardRequests: 5, maxRetries: 0, requestTimeout: '30s' } - ); - - expect(mockEsClient.asCurrentUser.openPointInTime).toHaveBeenCalledWith( { - ignore_unavailable: true, - ignore_throttled: false, - index: 'logstash-*', - keep_alive: '30s', - }, - { maxConcurrentShardRequests: 5, maxRetries: 0, requestTimeout: '30s' } + maxConcurrentShardRequests: 5, + maxRetries: 0, + requestTimeout: '30s', + signal: expect.any(AbortSignal), + } ); expect(mockDataClient.search).toBeCalledWith( @@ -1220,7 +1428,11 @@ describe('CsvGenerator', () => { max_concurrent_shard_requests: 5, }, }, - { strategy: 'es', transport: { maxRetries: 0, requestTimeout: '30s' } } + { + abortSignal: expect.any(AbortSignal), + strategy: 'es', + transport: { maxRetries: 0, requestTimeout: '30s' }, + } ); }); diff --git a/packages/kbn-generate-csv/src/generate_csv.ts b/packages/kbn-generate-csv/src/generate_csv.ts index 18ee2cdb0005..c59e4fd40aaf 100644 --- a/packages/kbn-generate-csv/src/generate_csv.ts +++ b/packages/kbn-generate-csv/src/generate_csv.ts @@ -21,9 +21,9 @@ import type { } from '@kbn/field-formats-plugin/common'; import { AuthenticationExpiredError, + byteSizeValueToNumber, CancellationToken, ReportingError, - byteSizeValueToNumber, } from '@kbn/reporting-common'; import type { TaskInstanceFields, TaskRunResult } from '@kbn/reporting-common/types'; import type { ReportingConfigType } from '@kbn/reporting-server'; @@ -63,7 +63,6 @@ export class CsvGenerator { private logger: Logger, private stream: Writable ) {} - /* * Load field formats for each field in the list */ @@ -180,9 +179,9 @@ export class CsvGenerator { /* * Intrinsically, generating the rows is a synchronous process. Awaiting - * on a setImmediate call here partititions what could be a very long and - * CPU-intenstive synchronous process into asychronous processes. This - * give NodeJS to process other asychronous events that wait on the Event + * on a setImmediate call here partitions what could be a very long and + * CPU-intensive synchronous process into asynchronous processes. This + * give NodeJS to process other asynchronous events that wait on the Event * Loop. * * See: https://nodejs.org/en/docs/guides/dont-block-the-event-loop/ @@ -225,7 +224,13 @@ export class CsvGenerator { public async generateData(): Promise { const logger = this.logger; const [settings, searchSource] = await Promise.all([ - getExportSettings(this.clients.uiSettings, this.config, this.job.browserTimezone, logger), + getExportSettings( + this.clients.uiSettings, + this.taskInstanceFields, + this.config, + this.job.browserTimezone, + logger + ), this.dependencies.searchSourceStart.create(this.job.searchSource), ]); @@ -252,15 +257,30 @@ export class CsvGenerator { let totalRecords: number | undefined; let reportingError: undefined | ReportingError; + const abortController = new AbortController(); + this.cancellationToken.on(() => abortController.abort()); + // use a class to internalize the paging strategy let cursor: SearchCursor; if (this.job.pagingStrategy === 'scroll') { // Optional strategy: scan-and-scroll - cursor = new SearchCursorScroll(indexPatternTitle, settings, this.clients, this.logger); + cursor = new SearchCursorScroll( + indexPatternTitle, + settings, + this.clients, + abortController, + this.logger + ); logger.debug('Using search strategy: scroll'); } else { // Default strategy: point-in-time - cursor = new SearchCursorPit(indexPatternTitle, settings, this.clients, this.logger); + cursor = new SearchCursorPit( + indexPatternTitle, + settings, + this.clients, + abortController, + this.logger + ); logger.debug('Using search strategy: pit'); } await cursor.initialize(); @@ -289,6 +309,7 @@ export class CsvGenerator { if (this.cancellationToken.isCancelled()) { break; } + searchSource.setField('size', settings.scroll.size); let results: estypes.SearchResponse | undefined; @@ -406,7 +427,7 @@ export class CsvGenerator { /* * Add the errors into the CSV content. This makes error messages more * discoverable. When the export was automated or triggered by an API - * call or is automated, the user doesn't necesssarily go through the + * call or is automated, the user doesn't necessarily go through the * Kibana UI to download the export and might not otherwise see the * error message. */ diff --git a/packages/kbn-generate-csv/src/generate_csv_esql.test.ts b/packages/kbn-generate-csv/src/generate_csv_esql.test.ts index 3ef6e3b2318a..3e925893d37e 100644 --- a/packages/kbn-generate-csv/src/generate_csv_esql.test.ts +++ b/packages/kbn-generate-csv/src/generate_csv_esql.test.ts @@ -8,6 +8,7 @@ import * as Rx from 'rxjs'; import type { Writable } from 'stream'; +import { add, type Duration } from 'date-fns'; import { errors as esErrors } from '@elastic/elasticsearch'; import type { IScopedClusterClient, IUiSettingsClient, Logger } from '@kbn/core/server'; @@ -20,9 +21,9 @@ import { import { IKibanaSearchResponse } from '@kbn/data-plugin/common'; import { IScopedSearchClient } from '@kbn/data-plugin/server'; import { dataPluginMock } from '@kbn/data-plugin/server/mocks'; -import type { ESQLSearchReponse } from '@kbn/es-types'; import { CancellationToken } from '@kbn/reporting-common'; import type { ReportingConfigType } from '@kbn/reporting-server'; +import type { ESQLSearchReponse as ESQLSearchResponse } from '@kbn/es-types'; import { UI_SETTINGS_CSV_QUOTE_VALUES, UI_SETTINGS_CSV_SEPARATOR, @@ -37,6 +38,8 @@ const createMockJob = ( query: { esql: '' }, }); +const mockTaskInstanceFields = { startedAt: null, retryAt: null }; + describe('CsvESQLGenerator', () => { let mockEsClient: IScopedClusterClient; let mockDataClient: IScopedSearchClient; @@ -47,20 +50,20 @@ describe('CsvESQLGenerator', () => { let content: string; const getMockRawResponse = ( - esqlResponse: ESQLSearchReponse = { + esqlResponse: ESQLSearchResponse = { columns: [], values: [], } - ): ESQLSearchReponse => esqlResponse; + ): ESQLSearchResponse => esqlResponse; const mockDataClientSearchDefault = jest.fn().mockImplementation( - (): Rx.Observable> => + (): Rx.Observable> => Rx.of({ rawResponse: getMockRawResponse(), }) ); - const mockSearchResponse = (response: ESQLSearchReponse) => { + const mockSearchResponse = (response: ESQLSearchResponse) => { mockDataClient.search = jest.fn().mockImplementation(() => Rx.of({ rawResponse: getMockRawResponse(response), @@ -105,6 +108,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob({ columns: ['date', 'ip', 'message'] }), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -136,6 +140,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob(), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -163,6 +168,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob(), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -192,6 +198,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob(), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -211,6 +218,189 @@ describe('CsvESQLGenerator', () => { `); }); + describe('"auto" scroll duration config', () => { + const getTaskInstanceFields = (intervalFromNow: Duration) => { + const now = new Date(Date.now()); + return { startedAt: now, retryAt: add(now, intervalFromNow) }; + }; + + let mockConfigWithAutoScrollDuration: ReportingConfigType['csv']; + let mockDataClientSearchFn: jest.MockedFunction; + + beforeEach(() => { + mockConfigWithAutoScrollDuration = { + ...mockConfig, + scroll: { + ...mockConfig.scroll, + duration: 'auto', + }, + }; + + mockDataClientSearchFn = jest.fn(); + + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.clearAllTimers(); + jest.useRealTimers(); + + mockDataClientSearchFn.mockRestore(); + }); + + it('csv gets generated if search resolves without errors before the computed timeout value passed to the search data client elapses', async () => { + const timeFromNowInMs = 4 * 60 * 1000; + + const taskInstanceFields = getTaskInstanceFields({ + seconds: timeFromNowInMs / 1000, + }); + + mockDataClientSearchFn.mockImplementation((_, options) => { + const getSearchResult = () => { + const queuedAt = Date.now(); + + return new Promise>>( + (resolve, reject) => { + setTimeout(() => { + if ( + new Date(Date.now()).getTime() - new Date(queuedAt).getTime() > + Number((options?.transport?.requestTimeout! as string).replace(/ms/, '')) + ) { + reject( + new esErrors.ResponseError({ statusCode: 408, meta: {} as any, warnings: [] }) + ); + } else { + resolve({ + rawResponse: getMockRawResponse({ + columns: [{ name: 'message', type: 'string' }], + values: Array(100).fill(['This is a great message!']), + }), + }); + } + }, timeFromNowInMs / 4); + } + ); + }; + + return Rx.defer(getSearchResult); + }); + + const generateCsvPromise = new CsvESQLGenerator( + createMockJob(), + mockConfigWithAutoScrollDuration, + taskInstanceFields, + { + es: mockEsClient, + data: { + ...mockDataClient, + search: mockDataClientSearchFn, + }, + uiSettings: uiSettingsClient, + }, + new CancellationToken(), + mockLogger, + stream + ).generateData(); + + await jest.advanceTimersByTimeAsync(timeFromNowInMs); + + expect(await generateCsvPromise).toEqual( + expect.objectContaining({ + warnings: [], + }) + ); + + expect(mockDataClientSearchFn).toBeCalledWith( + { params: { filter: undefined, locale: 'en', query: '' } }, + { + strategy: 'esql', + transport: { + requestTimeout: `${timeFromNowInMs}ms`, + }, + abortSignal: expect.any(AbortSignal), + } + ); + }); + + it('csv generation errors if search request does not resolve before the computed timeout value passed to the search data client elapses', async () => { + const timeFromNowInMs = 4 * 60 * 1000; + + const taskInstanceFields = getTaskInstanceFields({ + seconds: timeFromNowInMs / 1000, + }); + + const requestDuration = timeFromNowInMs + 1000; + + mockDataClientSearchFn.mockImplementation((_, options) => { + const getSearchResult = () => { + const queuedAt = Date.now(); + + return new Promise>>( + (resolve, reject) => { + setTimeout(() => { + if ( + new Date(Date.now()).getTime() - new Date(queuedAt).getTime() > + Number((options?.transport?.requestTimeout! as string).replace(/ms/, '')) + ) { + reject( + new esErrors.ResponseError({ statusCode: 408, meta: {} as any, warnings: [] }) + ); + } else { + resolve({ + rawResponse: getMockRawResponse({ + columns: [{ name: 'message', type: 'string' }], + values: Array(100).fill(['This is a great message!']), + }), + }); + } + }, requestDuration); + } + ); + }; + + return Rx.defer(getSearchResult); + }); + + const generateCsvPromise = new CsvESQLGenerator( + createMockJob(), + mockConfigWithAutoScrollDuration, + taskInstanceFields, + { + es: mockEsClient, + data: { + ...mockDataClient, + search: mockDataClientSearchFn, + }, + uiSettings: uiSettingsClient, + }, + new CancellationToken(), + mockLogger, + stream + ).generateData(); + + await jest.advanceTimersByTimeAsync(requestDuration); + + expect(await generateCsvPromise).toEqual( + expect.objectContaining({ + warnings: expect.arrayContaining([ + expect.stringContaining('Received a 408 response from Elasticsearch'), + ]), + }) + ); + + expect(mockDataClientSearchFn).toBeCalledWith( + { params: { filter: undefined, locale: 'en', query: '' } }, + { + strategy: 'esql', + transport: { + requestTimeout: `${timeFromNowInMs}ms`, + }, + abortSignal: expect.any(AbortSignal), + } + ); + }); + }); + describe('jobParams', () => { it('uses columns to select columns', async () => { mockSearchResponse({ @@ -225,6 +415,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob({ columns: ['message', 'date', 'something else'] }), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -259,6 +450,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob({ query, filters }), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -318,6 +510,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob(), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -347,6 +540,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob(), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -385,6 +579,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob(), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -413,6 +608,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob(), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, @@ -449,6 +645,7 @@ describe('CsvESQLGenerator', () => { const generateCsv = new CsvESQLGenerator( createMockJob(), mockConfig, + mockTaskInstanceFields, { es: mockEsClient, data: mockDataClient, diff --git a/packages/kbn-generate-csv/src/generate_csv_esql.ts b/packages/kbn-generate-csv/src/generate_csv_esql.ts index 567d4121af21..cea0838460ab 100644 --- a/packages/kbn-generate-csv/src/generate_csv_esql.ts +++ b/packages/kbn-generate-csv/src/generate_csv_esql.ts @@ -30,6 +30,7 @@ import { } from '@kbn/reporting-common'; import type { TaskRunResult } from '@kbn/reporting-common/types'; import type { ReportingConfigType } from '@kbn/reporting-server'; +import { type TaskInstanceFields } from '@kbn/reporting-common/types'; import { zipObject } from 'lodash'; import { CONTENT_TYPE_CSV } from '../constants'; @@ -58,6 +59,7 @@ export class CsvESQLGenerator { constructor( private job: JobParamsCsvESQL, private config: ReportingConfigType['csv'], + private taskInstanceFields: TaskInstanceFields, private clients: Clients, private cancellationToken: CancellationToken, private logger: Logger, @@ -67,6 +69,7 @@ export class CsvESQLGenerator { public async generateData(): Promise { const settings = await getExportSettings( this.clients.uiSettings, + this.taskInstanceFields, this.config, this.job.browserTimezone, this.logger @@ -111,7 +114,7 @@ export class CsvESQLGenerator { strategy: ESQL_SEARCH_STRATEGY, abortSignal: abortController.signal, transport: { - requestTimeout: settings.scroll.duration, + requestTimeout: settings.scroll.duration(this.taskInstanceFields), }, }) ); diff --git a/packages/kbn-generate-csv/src/lib/get_export_settings.test.ts b/packages/kbn-generate-csv/src/lib/get_export_settings.test.ts index a732bc73f570..9a9b2e5ff358 100644 --- a/packages/kbn-generate-csv/src/lib/get_export_settings.test.ts +++ b/packages/kbn-generate-csv/src/lib/get_export_settings.test.ts @@ -13,6 +13,8 @@ import { uiSettingsServiceMock, } from '@kbn/core/server/mocks'; import type { ReportingConfigType } from '@kbn/reporting-server'; +import type { TaskInstanceFields } from '@kbn/reporting-common/types'; +import { sub, add, type Duration } from 'date-fns'; import { UI_SETTINGS_CSV_QUOTE_VALUES, @@ -25,6 +27,7 @@ import { getExportSettings } from './get_export_settings'; describe('getExportSettings', () => { let uiSettingsClient: IUiSettingsClient; let config: ReportingConfigType['csv']; + let taskInstanceFields: TaskInstanceFields; const logger = loggingSystemMock.createLogger(); beforeEach(() => { @@ -38,6 +41,8 @@ describe('getExportSettings', () => { enablePanelActionDownload: true, }; + taskInstanceFields = { startedAt: null, retryAt: null }; + uiSettingsClient = uiSettingsServiceMock .createStartContract() .asScopedToClient(savedObjectsClientMock.create()); @@ -53,31 +58,42 @@ describe('getExportSettings', () => { return false; } - return 'helo world'; + return 'hello world'; }); }); test('getExportSettings: returns the expected result', async () => { - expect(await getExportSettings(uiSettingsClient, config, '', logger)).toMatchObject({ - bom: '', - checkForFormulas: true, - escapeFormulaValues: false, - includeFrozen: false, - maxConcurrentShardRequests: 5, - maxSizeBytes: 180000, - scroll: { - duration: '30s', - size: 500, - }, - separator: ',', - timezone: 'UTC', - }); + expect(await getExportSettings(uiSettingsClient, taskInstanceFields, config, '', logger)) + .toMatchInlineSnapshot(` + Object { + "bom": "", + "checkForFormulas": true, + "escapeFormulaValues": false, + "escapeValue": [Function], + "includeFrozen": false, + "maxConcurrentShardRequests": 5, + "maxSizeBytes": 180000, + "scroll": Object { + "duration": [Function], + "size": 500, + "strategy": "pit", + }, + "separator": ",", + "taskInstanceFields": Object { + "retryAt": null, + "startedAt": null, + }, + "timezone": "UTC", + } + `); }); test('does not add a default scroll strategy', async () => { // @ts-expect-error undefined isn't allowed config = { ...config, scroll: { strategy: undefined } }; - expect(await getExportSettings(uiSettingsClient, config, '', logger)).toMatchObject( + expect( + await getExportSettings(uiSettingsClient, taskInstanceFields, config, '', logger) + ).toMatchObject( expect.objectContaining({ scroll: expect.objectContaining({ strategy: undefined }) }) ); }); @@ -85,7 +101,9 @@ describe('getExportSettings', () => { test('passes the scroll=pit strategy through', async () => { config = { ...config, scroll: { ...config.scroll, strategy: 'pit' } }; - expect(await getExportSettings(uiSettingsClient, config, '', logger)).toMatchObject( + expect( + await getExportSettings(uiSettingsClient, taskInstanceFields, config, '', logger) + ).toMatchObject( expect.objectContaining({ scroll: expect.objectContaining({ strategy: 'pit' }) }) ); }); @@ -93,7 +111,9 @@ describe('getExportSettings', () => { test('passes the scroll=scroll strategy through', async () => { config = { ...config, scroll: { ...config.scroll, strategy: 'scroll' } }; - expect(await getExportSettings(uiSettingsClient, config, '', logger)).toMatchObject( + expect( + await getExportSettings(uiSettingsClient, taskInstanceFields, config, '', logger) + ).toMatchObject( expect.objectContaining({ scroll: expect.objectContaining({ strategy: 'scroll', @@ -103,7 +123,13 @@ describe('getExportSettings', () => { }); test('escapeValue function', async () => { - const { escapeValue } = await getExportSettings(uiSettingsClient, config, '', logger); + const { escapeValue } = await getExportSettings( + uiSettingsClient, + taskInstanceFields, + config, + '', + logger + ); expect(escapeValue(`test`)).toBe(`test`); expect(escapeValue(`this is, a test`)).toBe(`"this is, a test"`); expect(escapeValue(`"tet"`)).toBe(`"""tet"""`); @@ -119,7 +145,111 @@ describe('getExportSettings', () => { }); expect( - await getExportSettings(uiSettingsClient, config, '', logger).then(({ timezone }) => timezone) + await getExportSettings(uiSettingsClient, taskInstanceFields, config, '', logger).then( + ({ timezone }) => timezone + ) ).toBe(`America/Aruba`); }); + + describe('scroll duration function', () => { + let spiedDateNow: jest.Spied; + let mockedTaskInstanceFields: TaskInstanceFields; + const durationApart: Duration = { minutes: 5 }; + + beforeEach(() => { + const now = Date.now(); + + // freeze time for test + spiedDateNow = jest.spyOn(Date, 'now').mockReturnValue(now); + + mockedTaskInstanceFields = { + startedAt: sub(new Date(Date.now()), durationApart), + retryAt: add(new Date(Date.now()), durationApart), + }; + }); + + afterEach(() => { + spiedDateNow.mockRestore(); + }); + + it('returns its specified value when value is not auto', async () => { + const { scroll } = await getExportSettings( + uiSettingsClient, + taskInstanceFields, + config, + '', + logger + ); + + expect(scroll.duration(mockedTaskInstanceFields)).toBe(config.scroll.duration); + }); + + it('throws when the scroll duration config is auto and retryAt value of the taskInstanceField passed is falsy', async () => { + const configWithScrollAutoDuration = { + ...config, + scroll: { + ...config.scroll, + duration: 'auto', + }, + }; + + const { scroll } = await getExportSettings( + uiSettingsClient, + taskInstanceFields, + configWithScrollAutoDuration, + '', + logger + ); + + expect( + scroll.duration.bind(null, { startedAt: new Date(Date.now()), retryAt: null }) + ).toThrow(); + }); + + it('returns a value that is the difference of the current time from the value of retryAt provided in the passed taskInstanceFields', async () => { + const configWithScrollAutoDuration = { + ...config, + scroll: { + ...config.scroll, + duration: 'auto', + }, + }; + + const { scroll } = await getExportSettings( + uiSettingsClient, + taskInstanceFields, + configWithScrollAutoDuration, + '', + logger + ); + + expect(scroll.duration(mockedTaskInstanceFields)).toBe( + `${durationApart.minutes! * 60 * 1000}ms` + ); + }); + + it('returns 0 if current time exceeds the value of retryAt provided in the passed taskInstanceFields', async () => { + const configWithScrollAutoDuration = { + ...config, + scroll: { + ...config.scroll, + duration: 'auto', + }, + }; + + spiedDateNow.mockReturnValue( + add(mockedTaskInstanceFields.retryAt!, { minutes: 5 }).getTime() + ); + + const { scroll } = await getExportSettings( + uiSettingsClient, + taskInstanceFields, + configWithScrollAutoDuration, + '', + logger + ); + + expect(scroll.duration(mockedTaskInstanceFields)).toBe('0ms'); + }); + }); }); diff --git a/packages/kbn-generate-csv/src/lib/get_export_settings.ts b/packages/kbn-generate-csv/src/lib/get_export_settings.ts index 20830a3c3c02..a3a8b5625bff 100644 --- a/packages/kbn-generate-csv/src/lib/get_export_settings.ts +++ b/packages/kbn-generate-csv/src/lib/get_export_settings.ts @@ -10,7 +10,7 @@ import type { ByteSizeValue } from '@kbn/config-schema'; import type { IUiSettingsClient, Logger } from '@kbn/core/server'; import { createEscapeValue } from '@kbn/data-plugin/common'; import type { ReportingConfigType } from '@kbn/reporting-server'; - +import type { TaskInstanceFields } from '@kbn/reporting-common/types'; import { CSV_BOM_CHARS, UI_SETTINGS_CSV_QUOTE_VALUES, @@ -22,10 +22,14 @@ import { CsvPagingStrategy } from '../../types'; export interface CsvExportSettings { timezone: string; + taskInstanceFields: TaskInstanceFields; scroll: { strategy?: CsvPagingStrategy; size: number; - duration: string; + /** + * compute scroll duration, duration is returned in ms by default + */ + duration: (args: TaskInstanceFields, format?: 'ms' | 's') => string; }; bom: string; separator: string; @@ -39,6 +43,7 @@ export interface CsvExportSettings { export const getExportSettings = async ( client: IUiSettingsClient, + taskInstanceFields: TaskInstanceFields, config: ReportingConfigType['csv'], timezone: string | undefined, logger: Logger @@ -75,10 +80,33 @@ export const getExportSettings = async ( return { timezone: setTimezone, + taskInstanceFields, scroll: { strategy: config.scroll.strategy as CsvPagingStrategy, size: config.scroll.size, - duration: config.scroll.duration, + duration: ({ retryAt }, format = 'ms') => { + if (config.scroll.duration !== 'auto') { + return config.scroll.duration; + } + + if (!retryAt) { + throw new Error( + 'config "xpack.reporting.csv.scroll.duration" of "auto" mandates that the task instance field passed specifies a retryAt value' + ); + } + + const now = new Date(Date.now()).getTime(); + const timeTillRetry = new Date(retryAt).getTime(); + + if (now >= timeTillRetry) { + return `0${format}`; + } + + const _duration = timeTillRetry - now; + const result = format === 'ms' ? `${_duration}ms` : `${_duration / 1000}s`; + logger.debug(`using timeout duration of ${result} for csv scroll`); + return result; + }, }, bom, includeFrozen, diff --git a/packages/kbn-generate-csv/src/lib/search_cursor.ts b/packages/kbn-generate-csv/src/lib/search_cursor.ts index 9632564492e3..834f5d6fb2fb 100644 --- a/packages/kbn-generate-csv/src/lib/search_cursor.ts +++ b/packages/kbn-generate-csv/src/lib/search_cursor.ts @@ -23,7 +23,7 @@ export interface SearchCursorClients { export type SearchCursorSettings = Pick< CsvExportSettings, - 'scroll' | 'includeFrozen' | 'maxConcurrentShardRequests' + 'scroll' | 'includeFrozen' | 'maxConcurrentShardRequests' | 'taskInstanceFields' >; export abstract class SearchCursor { @@ -33,6 +33,7 @@ export abstract class SearchCursor { protected indexPatternTitle: string, protected settings: SearchCursorSettings, protected clients: SearchCursorClients, + protected abortController: AbortController, protected logger: Logger ) {} diff --git a/packages/kbn-generate-csv/src/lib/search_cursor_pit.test.ts b/packages/kbn-generate-csv/src/lib/search_cursor_pit.test.ts index c76a66a98389..4fb3ccda06c6 100644 --- a/packages/kbn-generate-csv/src/lib/search_cursor_pit.test.ts +++ b/packages/kbn-generate-csv/src/lib/search_cursor_pit.test.ts @@ -24,11 +24,12 @@ describe('CSV Export Search Cursor', () => { beforeEach(async () => { settings = { scroll: { - duration: '10m', + duration: jest.fn(() => '10m'), size: 500, }, includeFrozen: false, maxConcurrentShardRequests: 5, + taskInstanceFields: { startedAt: null, retryAt: null }, }; es = elasticsearchServiceMock.createScopedClusterClient(); @@ -37,7 +38,13 @@ describe('CSV Export Search Cursor', () => { logger = loggingSystemMock.createLogger(); - cursor = new SearchCursorPit('test-index-pattern-string', settings, { data, es }, logger); + cursor = new SearchCursorPit( + 'test-index-pattern-string', + settings, + { data, es }, + new AbortController(), + logger + ); const openPointInTimeSpy = jest // @ts-expect-error create spy on private method diff --git a/packages/kbn-generate-csv/src/lib/search_cursor_pit.ts b/packages/kbn-generate-csv/src/lib/search_cursor_pit.ts index 110e15ca8a60..a7099f841933 100644 --- a/packages/kbn-generate-csv/src/lib/search_cursor_pit.ts +++ b/packages/kbn-generate-csv/src/lib/search_cursor_pit.ts @@ -24,9 +24,10 @@ export class SearchCursorPit extends SearchCursor { indexPatternTitle: string, settings: SearchCursorSettings, clients: SearchCursorClients, + abortController: AbortController, logger: Logger ) { - super(indexPatternTitle, settings, clients, logger); + super(indexPatternTitle, settings, clients, abortController, logger); } /** @@ -37,7 +38,7 @@ export class SearchCursorPit extends SearchCursor { } private async openPointInTime() { - const { includeFrozen, maxConcurrentShardRequests, scroll } = this.settings; + const { includeFrozen, maxConcurrentShardRequests, scroll, taskInstanceFields } = this.settings; let pitId: string | undefined; @@ -47,13 +48,14 @@ export class SearchCursorPit extends SearchCursor { const response = await this.clients.es.asCurrentUser.openPointInTime( { index: this.indexPatternTitle, - keep_alive: scroll.duration, + keep_alive: scroll.duration(taskInstanceFields), ignore_unavailable: true, // @ts-expect-error ignore_throttled is not in the type definition, but it is accepted by es ignore_throttled: includeFrozen ? false : undefined, // "true" will cause deprecation warnings logged in ES }, { - requestTimeout: scroll.duration, + signal: this.abortController.signal, + requestTimeout: scroll.duration(taskInstanceFields), maxRetries: 0, maxConcurrentShardRequests, } @@ -73,7 +75,7 @@ export class SearchCursorPit extends SearchCursor { } private async searchWithPit(searchBody: SearchRequest) { - const { maxConcurrentShardRequests, scroll } = this.settings; + const { maxConcurrentShardRequests, scroll, taskInstanceFields } = this.settings; const searchParamsPit = { params: { @@ -85,22 +87,25 @@ export class SearchCursorPit extends SearchCursor { return await lastValueFrom( this.clients.data.search(searchParamsPit, { strategy: ES_SEARCH_STRATEGY, + abortSignal: this.abortController.signal, transport: { maxRetries: 0, // retrying reporting jobs is handled in the task manager scheduling logic - requestTimeout: scroll.duration, + requestTimeout: scroll.duration(taskInstanceFields), }, }) ); } public async getPage(searchSource: ISearchSource) { + const { scroll, taskInstanceFields } = this.settings; + if (!this.cursorId) { throw new Error(`No access to valid PIT ID!`); } searchSource.setField('pit', { id: this.cursorId, - keep_alive: this.settings.scroll.duration, + keep_alive: scroll.duration(taskInstanceFields), }); const searchAfter = this.getSearchAfter(); diff --git a/packages/kbn-generate-csv/src/lib/search_cursor_scroll.test.ts b/packages/kbn-generate-csv/src/lib/search_cursor_scroll.test.ts index 4b4ae4a05f4e..6d36ee64d576 100644 --- a/packages/kbn-generate-csv/src/lib/search_cursor_scroll.test.ts +++ b/packages/kbn-generate-csv/src/lib/search_cursor_scroll.test.ts @@ -24,10 +24,11 @@ describe('CSV Export Search Cursor', () => { beforeEach(async () => { settings = { scroll: { - duration: '10m', + duration: jest.fn(() => '10m'), size: 500, }, includeFrozen: false, + taskInstanceFields: { startedAt: null, retryAt: null }, maxConcurrentShardRequests: 5, }; @@ -37,7 +38,14 @@ describe('CSV Export Search Cursor', () => { logger = loggingSystemMock.createLogger(); - cursor = new SearchCursorScroll('test-index-pattern-string', settings, { data, es }, logger); + cursor = new SearchCursorScroll( + 'test-index-pattern-string', + settings, + { data, es }, + new AbortController(), + logger + ); + await cursor.initialize(); }); diff --git a/packages/kbn-generate-csv/src/lib/search_cursor_scroll.ts b/packages/kbn-generate-csv/src/lib/search_cursor_scroll.ts index 6e2bc2100a14..8b8e41da3970 100644 --- a/packages/kbn-generate-csv/src/lib/search_cursor_scroll.ts +++ b/packages/kbn-generate-csv/src/lib/search_cursor_scroll.ts @@ -23,22 +23,23 @@ export class SearchCursorScroll extends SearchCursor { indexPatternTitle: string, settings: SearchCursorSettings, clients: SearchCursorClients, + abortController: AbortController, logger: Logger ) { - super(indexPatternTitle, settings, clients, logger); + super(indexPatternTitle, settings, clients, abortController, logger); } // The first search query begins the scroll context in ES public async initialize() {} private async scan(searchBody: SearchRequest) { - const { includeFrozen, maxConcurrentShardRequests, scroll } = this.settings; + const { includeFrozen, maxConcurrentShardRequests, scroll, taskInstanceFields } = this.settings; const searchParamsScan = { params: { body: searchBody, index: this.indexPatternTitle, - scroll: scroll.duration, + scroll: scroll.duration(taskInstanceFields), size: scroll.size, ignore_throttled: includeFrozen ? false : undefined, // "true" will cause deprecation warnings logged in ES max_concurrent_shard_requests: maxConcurrentShardRequests, @@ -48,21 +49,23 @@ export class SearchCursorScroll extends SearchCursor { return await lastValueFrom( this.clients.data.search(searchParamsScan, { strategy: ES_SEARCH_STRATEGY, + abortSignal: this.abortController.signal, transport: { maxRetries: 0, // retrying reporting jobs is handled in the task manager scheduling logic - requestTimeout: scroll.duration, + requestTimeout: scroll.duration(taskInstanceFields), }, }) ); } private async scroll() { - const { duration } = this.settings.scroll; + const { scroll, taskInstanceFields } = this.settings; return await this.clients.es.asCurrentUser.scroll( - { scroll: duration, scroll_id: this.cursorId }, + { scroll: scroll.duration(taskInstanceFields), scroll_id: this.cursorId }, { + signal: this.abortController.signal, maxRetries: 0, // retrying reporting jobs is handled in the task manager scheduling logic - requestTimeout: duration, + requestTimeout: scroll.duration(taskInstanceFields), } ); } diff --git a/packages/kbn-reporting/export_types/csv/csv_v2.ts b/packages/kbn-reporting/export_types/csv/csv_v2.ts index 3bea7f03375b..aeaee5b98d7c 100644 --- a/packages/kbn-reporting/export_types/csv/csv_v2.ts +++ b/packages/kbn-reporting/export_types/csv/csv_v2.ts @@ -147,6 +147,7 @@ export class CsvV2ExportType extends ExportType< ...job, }, csvConfig, + taskInstanceFields, clients, cancellationToken, logger, diff --git a/packages/kbn-reporting/server/config_schema.ts b/packages/kbn-reporting/server/config_schema.ts index a823babde8f0..0c602b1bb340 100644 --- a/packages/kbn-reporting/server/config_schema.ts +++ b/packages/kbn-reporting/server/config_schema.ts @@ -74,10 +74,10 @@ const CsvSchema = schema.object({ { defaultValue: 'pit' } ), duration: schema.string({ - defaultValue: '30s', // this value is passed directly to ES, so string only format is preferred + defaultValue: '30s', // values other than "auto" are passed directly to ES, so string only format is preferred validate(value) { - if (!/^[0-9]+(d|h|m|s|ms|micros|nanos)$/.test(value)) { - return 'must be a duration string'; + if (!/(^[0-9]+(d|h|m|s|ms|micros|nanos)|auto)$/.test(value)) { + return 'must be either "auto" or a duration string'; } }, }), diff --git a/packages/kbn-search-connectors/components/configuration/connector_configuration.tsx b/packages/kbn-search-connectors/components/configuration/connector_configuration.tsx index b3fc911460bf..1377626f3cd5 100644 --- a/packages/kbn-search-connectors/components/configuration/connector_configuration.tsx +++ b/packages/kbn-search-connectors/components/configuration/connector_configuration.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React, { createContext, useEffect, useState } from 'react'; +import React, { createContext, useEffect, useRef, useState } from 'react'; import { EuiButton, @@ -20,8 +20,15 @@ import { import { i18n } from '@kbn/i18n'; +import { isDeepEqual } from 'react-use/lib/util'; import { sortAndFilterConnectorConfiguration } from '../../utils/connector_configuration_utils'; -import { Connector, ConnectorConfigProperties, ConnectorStatus, FeatureName } from '../..'; +import { + Connector, + ConnectorConfigProperties, + ConnectorConfiguration, + ConnectorStatus, + FeatureName, +} from '../..'; import { ConnectorConfigurationForm } from './connector_configuration_form'; @@ -82,6 +89,7 @@ export const ConnectorConfigurationComponent: React.FC { + const configurationRef = useRef({}); const { configuration, error, @@ -95,7 +103,10 @@ export const ConnectorConfigurationComponent: React.FC { - setIsEditing(false); + if (!isDeepEqual(configuration, configurationRef.current)) { + configurationRef.current = configuration; + setIsEditing(false); + } }, [configuration]); useEffect(() => { diff --git a/packages/kbn-securitysolution-grouping/src/hooks/use_get_group_selector.test.tsx b/packages/kbn-securitysolution-grouping/src/hooks/use_get_group_selector.test.tsx index e6221c677b9d..1ebd2b5a1817 100644 --- a/packages/kbn-securitysolution-grouping/src/hooks/use_get_group_selector.test.tsx +++ b/packages/kbn-securitysolution-grouping/src/hooks/use_get_group_selector.test.tsx @@ -237,6 +237,26 @@ describe('Group Selector Hooks', () => { ); }); + it('On group change, unselected group, does not sends telemetry', () => { + const testGroup = { + [groupingId]: { + ...defaultGroup, + options: defaultGroupingOptions, + activeGroups: ['host.name', customField], + }, + }; + const { result } = renderHook((props) => useGetGroupSelector(props), { + initialProps: { + ...defaultArgs, + groupingState: { + groupById: testGroup, + }, + }, + }); + act(() => result.current.props.onGroupChange(customField)); + expect(defaultArgs.tracker).not.toHaveBeenCalled(); + }); + it('On group change, executes callback', () => { const testGroup = { [groupingId]: { @@ -258,6 +278,32 @@ describe('Group Selector Hooks', () => { expect(defaultArgs.onGroupChange).toHaveBeenCalledWith({ tableId: groupingId, groupByField: customField, + groupByFields: ['host.name', customField], + }); + }); + + it('On group change, unselected group, executes callback', () => { + const testGroup = { + [groupingId]: { + ...defaultGroup, + options: defaultGroupingOptions, + activeGroups: ['host.name', customField], + }, + }; + const { result } = renderHook((props) => useGetGroupSelector(props), { + initialProps: { + ...defaultArgs, + groupingState: { + groupById: testGroup, + }, + }, + }); + act(() => result.current.props.onGroupChange(customField)); + expect(defaultArgs.onGroupChange).toHaveBeenCalledTimes(1); + expect(defaultArgs.onGroupChange).toHaveBeenCalledWith({ + tableId: groupingId, + groupByField: customField, + groupByFields: ['host.name'], }); }); diff --git a/packages/kbn-securitysolution-grouping/src/hooks/use_get_group_selector.tsx b/packages/kbn-securitysolution-grouping/src/hooks/use_get_group_selector.tsx index d3e518a48fe5..bec790ca8cce 100644 --- a/packages/kbn-securitysolution-grouping/src/hooks/use_get_group_selector.tsx +++ b/packages/kbn-securitysolution-grouping/src/hooks/use_get_group_selector.tsx @@ -24,7 +24,11 @@ export interface UseGetGroupSelectorArgs { groupingState: GroupMap; maxGroupingLevels?: number; onOptionsChange?: (newOptions: GroupOption[]) => void; - onGroupChange?: (param: { groupByField: string; tableId: string }) => void; + onGroupChange?: (param: { + groupByField: string; + groupByFields: string[]; + tableId: string; + }) => void; tracker?: ( type: UiCounterMetricType, event: string | string[], @@ -112,33 +116,46 @@ export const useGetGroupSelector = ({ const onChange = useCallback( (groupSelection: string) => { + let newSelectedGroups: string[] = []; + let sendTelemetry = true; // Simulate a toggle behavior when maxGroupingLevels is 1 if (maxGroupingLevels === 1) { - setSelectedGroups([groupSelection]); + newSelectedGroups = [groupSelection]; } else { + // if the group is already selected, remove it if (selectedGroups.find((selected) => selected === groupSelection)) { + sendTelemetry = false; const groups = selectedGroups.filter((selectedGroup) => selectedGroup !== groupSelection); if (groups.length === 0) { - setSelectedGroups(['none']); + newSelectedGroups = ['none']; } else { - setSelectedGroups(groups); + newSelectedGroups = groups; } - return; + } else { + newSelectedGroups = isNoneGroup([groupSelection]) + ? [groupSelection] + : [ + ...selectedGroups.filter((selectedGroup) => selectedGroup !== 'none'), + groupSelection, + ]; } - - const newSelectedGroups = isNoneGroup([groupSelection]) - ? [groupSelection] - : [...selectedGroups.filter((selectedGroup) => selectedGroup !== 'none'), groupSelection]; - setSelectedGroups(newSelectedGroups); } - // built-in telemetry: UI-counter - tracker?.( - METRIC_TYPE.CLICK, - getTelemetryEvent.groupChanged({ groupingId, selected: groupSelection }) - ); + setSelectedGroups(newSelectedGroups); - onGroupChange?.({ tableId: groupingId, groupByField: groupSelection }); + if (sendTelemetry) { + // built-in telemetry: UI-counter + tracker?.( + METRIC_TYPE.CLICK, + getTelemetryEvent.groupChanged({ groupingId, selected: groupSelection }) + ); + } + + onGroupChange?.({ + tableId: groupingId, + groupByField: groupSelection, + groupByFields: newSelectedGroups, + }); }, [groupingId, maxGroupingLevels, onGroupChange, selectedGroups, setSelectedGroups, tracker] ); diff --git a/packages/kbn-securitysolution-grouping/src/hooks/use_grouping.tsx b/packages/kbn-securitysolution-grouping/src/hooks/use_grouping.tsx index 3ff2232acbd7..38ada10a74b9 100644 --- a/packages/kbn-securitysolution-grouping/src/hooks/use_grouping.tsx +++ b/packages/kbn-securitysolution-grouping/src/hooks/use_grouping.tsx @@ -65,7 +65,11 @@ interface GroupingArgs { /** for tracking * @param param { groupByField: string; tableId: string } selected group and table id */ - onGroupChange?: (param: { groupByField: string; tableId: string }) => void; + onGroupChange?: (param: { + groupByField: string; + groupByFields: string[]; + tableId: string; + }) => void; onOptionsChange?: (options: GroupOption[]) => void; tracker?: ( type: UiCounterMetricType, diff --git a/packages/shared-ux/code_editor/impl/BUILD.bazel b/packages/shared-ux/code_editor/impl/BUILD.bazel index ad571cb379af..24f18820496a 100644 --- a/packages/shared-ux/code_editor/impl/BUILD.bazel +++ b/packages/shared-ux/code_editor/impl/BUILD.bazel @@ -25,7 +25,6 @@ BUNDLER_DEPS = [ "@npm//react", "@npm//tslib", "@npm//react-monaco-editor", - "@npm//react-resize-detector", ] js_library( diff --git a/packages/shared-ux/code_editor/impl/code_editor.stories.tsx b/packages/shared-ux/code_editor/impl/code_editor.stories.tsx index 38c063e4ebe2..e4a78b328cbe 100644 --- a/packages/shared-ux/code_editor/impl/code_editor.stories.tsx +++ b/packages/shared-ux/code_editor/impl/code_editor.stories.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { useState } from 'react'; import { action } from '@storybook/addon-actions'; import { monaco as monacoEditor } from '@kbn/monaco'; @@ -32,7 +32,13 @@ const argTypes = mock.getArgumentTypes(); export const Basic = (params: CodeEditorStorybookParams) => { return ( - + ); }; @@ -199,3 +205,39 @@ export const HoverProvider = () => { ); }; + +export const AutomaticResize = (params: CodeEditorStorybookParams) => { + return ( +
+ +
+ ); +}; + +AutomaticResize.argTypes = argTypes; + +export const FitToContent = (params: CodeEditorStorybookParams) => { + const [value, setValue] = useState('hello'); + return ( + { + setValue(newValue); + action('on change'); + }} + value={value} + fitToContent={{ minLines: 3, maxLines: 5 }} + options={{ automaticLayout: true }} + /> + ); +}; + +FitToContent.argTypes = argTypes; diff --git a/packages/shared-ux/code_editor/impl/code_editor.tsx b/packages/shared-ux/code_editor/impl/code_editor.tsx index b41906d5ed45..54be81c2df4b 100644 --- a/packages/shared-ux/code_editor/impl/code_editor.tsx +++ b/packages/shared-ux/code_editor/impl/code_editor.tsx @@ -7,7 +7,6 @@ */ import React, { useState, useRef, useCallback, useMemo, useEffect, KeyboardEvent } from 'react'; -import { useResizeDetector } from 'react-resize-detector'; import ReactMonacoEditor, { type MonacoEditorProps as ReactMonacoEditorProps, } from 'react-monaco-editor'; @@ -140,6 +139,15 @@ export interface CodeEditorProps { * Alternate text to display, when an attempt is made to edit read only content. (Defaults to "Cannot edit in read-only editor") */ readOnlyMessage?: string; + + /** + * Enables the editor to grow vertically to fit its content. + * This option overrides the `height` option. + */ + fitToContent?: { + minLines?: number; + maxLines?: number; + }; } export const CodeEditor: React.FC = ({ @@ -168,6 +176,7 @@ export const CodeEditor: React.FC = ({ readOnlyMessage = i18n.translate('sharedUXPackages.codeEditor.readOnlyMessage', { defaultMessage: 'Cannot edit in read-only editor', }), + fitToContent, }) => { const { colorMode, euiTheme } = useEuiTheme(); const useDarkTheme = useDarkThemeProp ?? colorMode === 'DARK'; @@ -189,7 +198,7 @@ export const CodeEditor: React.FC = ({ const isReadOnly = options?.readOnly ?? false; - const _editor = useRef(null); + const [_editor, setEditor] = useState(null); const _placeholderWidget = useRef(null); const isSuggestionMenuOpen = useRef(false); const editorHint = useRef(null); @@ -197,21 +206,10 @@ export const CodeEditor: React.FC = ({ const [isHintActive, setIsHintActive] = useState(true); - const _updateDimensions = useCallback(() => { - _editor.current?.layout(); - }, []); - - useResizeDetector({ - handleWidth: true, - handleHeight: true, - onResize: _updateDimensions, - refreshMode: 'debounce', - }); - const startEditing = useCallback(() => { setIsHintActive(false); - _editor.current?.focus(); - }, []); + _editor?.focus(); + }, [_editor]); const stopEditing = useCallback(() => { setIsHintActive(true); @@ -391,8 +389,6 @@ export const CodeEditor: React.FC = ({ remeasureFonts(); - _editor.current = editor; - const textbox = editor.getDomNode()?.getElementsByTagName('textarea')[0]; if (textbox) { // Make sure the textarea is not directly accessible with TAB @@ -435,6 +431,7 @@ export const CodeEditor: React.FC = ({ } editorDidMount?.(editor); + setEditor(editor); }, [editorDidMount, onBlurMonaco, onKeydownMonaco, readOnlyMessage] ); @@ -454,16 +451,18 @@ export const CodeEditor: React.FC = ({ }, []); useEffect(() => { - if (placeholder && !value && _editor.current) { + if (placeholder && !value && _editor) { // Mounts editor inside constructor - _placeholderWidget.current = new PlaceholderWidget(placeholder, euiTheme, _editor.current); + _placeholderWidget.current = new PlaceholderWidget(placeholder, euiTheme, _editor); } return () => { _placeholderWidget.current?.dispose(); _placeholderWidget.current = null; }; - }, [placeholder, value, euiTheme]); + }, [placeholder, value, euiTheme, _editor]); + + useFitToContent({ editor: _editor, fitToContent, isFullScreen }); const { CopyButton } = useCopy({ isCopyable, value }); @@ -512,7 +511,7 @@ export const CodeEditor: React.FC = ({ value={value} onChange={onChange} width={isFullScreen ? '100vw' : width} - height={isFullScreen ? '100vh' : height} + height={isFullScreen ? '100vh' : fitToContent ? undefined : height} editorWillMount={_editorWillMount} editorDidMount={_editorDidMount} editorWillUnmount={_editorWillUnmount} @@ -640,3 +639,40 @@ const useCopy = ({ isCopyable, value }: { isCopyable: boolean; value: string }) return { showCopyButton, CopyButton }; }; + +const useFitToContent = ({ + editor, + fitToContent, + isFullScreen, +}: { + editor: monaco.editor.IStandaloneCodeEditor | null; + isFullScreen: boolean; + fitToContent?: { minLines?: number; maxLines?: number }; +}) => { + const isFitToContent = !!fitToContent; + const minLines = fitToContent?.minLines; + const maxLines = fitToContent?.maxLines; + useEffect(() => { + if (!editor) return; + if (isFullScreen) return; + if (!isFitToContent) return; + + const updateHeight = () => { + const contentHeight = editor.getContentHeight(); + const lineHeight = editor.getOption(monaco.editor.EditorOption.lineHeight); + const minHeight = (minLines ?? 1) * lineHeight; + let maxHeight = maxLines ? maxLines * lineHeight : contentHeight; + maxHeight = Math.max(minHeight, maxHeight); + editor.layout({ + height: Math.min(maxHeight, Math.max(minHeight, contentHeight)), + width: editor.getLayoutInfo().width, + }); + }; + updateHeight(); + const disposable = editor.onDidContentSizeChange(updateHeight); + return () => { + disposable.dispose(); + editor.layout(); // reset the layout that was controlled by the fitToContent + }; + }, [editor, isFitToContent, minLines, maxLines, isFullScreen]); +}; diff --git a/packages/shared-ux/code_editor/mocks/monaco_mock/index.tsx b/packages/shared-ux/code_editor/mocks/monaco_mock/index.tsx index f5b2fc9ab410..d9b2d4093e67 100644 --- a/packages/shared-ux/code_editor/mocks/monaco_mock/index.tsx +++ b/packages/shared-ux/code_editor/mocks/monaco_mock/index.tsx @@ -106,7 +106,9 @@ export const MockedMonacoEditor = ({ className?: string; ['data-test-subj']?: string; }) => { - editorWillMount?.(monaco); + useComponentWillMount(() => { + editorWillMount?.(monaco); + }); useEffect(() => { editorDidMount?.( @@ -133,3 +135,11 @@ export const MockedMonacoEditor = ({ ); }; + +const useComponentWillMount = (cb: Function) => { + const willMount = React.useRef(true); + + if (willMount.current) cb(); + + willMount.current = false; +}; diff --git a/src/core/server/integration_tests/core_app/bundle_routes.test.ts b/src/core/server/integration_tests/core_app/bundle_routes.test.ts index af3782b01591..b53bc07a8549 100644 --- a/src/core/server/integration_tests/core_app/bundle_routes.test.ts +++ b/src/core/server/integration_tests/core_app/bundle_routes.test.ts @@ -17,7 +17,7 @@ import { HttpService } from '@kbn/core-http-server-internal'; import { createHttpServer } from '@kbn/core-http-server-mocks'; import { registerRouteForBundle, FileHashCache } from '@kbn/core-apps-server-internal'; -const buildNum = 1234; +const buildHash = 'buildHash'; const fooPluginFixture = resolve(__dirname, './__fixtures__/plugin/foo'); describe('bundle routes', () => { @@ -47,8 +47,8 @@ describe('bundle routes', () => { isDist, fileHashCache, bundlesPath: fooPluginFixture, - routePath: `/${buildNum}/bundles/plugin/foo/`, - publicPath: `/${buildNum}/bundles/plugin/foo/`, + routePath: `/${buildHash}/bundles/plugin/foo/`, + publicPath: `/${buildHash}/bundles/plugin/foo/`, }); }; @@ -62,7 +62,7 @@ describe('bundle routes', () => { await server.start(); const response = await supertest(innerServer.listener) - .get(`/${buildNum}/bundles/plugin/foo/image.png`) + .get(`/${buildHash}/bundles/plugin/foo/image.png`) .expect(200); const actualImage = await readFile(resolve(fooPluginFixture, 'image.png')); @@ -80,7 +80,7 @@ describe('bundle routes', () => { await server.start(); const response = await supertest(innerServer.listener) - .get(`/${buildNum}/bundles/plugin/foo/plugin.js`) + .get(`/${buildHash}/bundles/plugin/foo/plugin.js`) .expect(200); const actualFile = await readFile(resolve(fooPluginFixture, 'plugin.js')); @@ -98,7 +98,7 @@ describe('bundle routes', () => { await server.start(); await supertest(innerServer.listener) - .get(`/${buildNum}/bundles/plugin/foo/../outside_output.js`) + .get(`/${buildHash}/bundles/plugin/foo/../outside_output.js`) .expect(404); }); @@ -112,7 +112,7 @@ describe('bundle routes', () => { await server.start(); await supertest(innerServer.listener) - .get(`/${buildNum}/bundles/plugin/foo/missing.js`) + .get(`/${buildHash}/bundles/plugin/foo/missing.js`) .expect(404); }); @@ -126,7 +126,7 @@ describe('bundle routes', () => { await server.start(); const response = await supertest(innerServer.listener) - .get(`/${buildNum}/bundles/plugin/foo/gzip_chunk.js`) + .get(`/${buildHash}/bundles/plugin/foo/gzip_chunk.js`) .expect(200); expect(response.get('content-encoding')).toEqual('gzip'); @@ -151,7 +151,7 @@ describe('bundle routes', () => { await server.start(); const response = await supertest(innerServer.listener) - .get(`/${buildNum}/bundles/plugin/foo/gzip_chunk.js`) + .get(`/${buildHash}/bundles/plugin/foo/gzip_chunk.js`) .expect(200); expect(response.get('cache-control')).toEqual('max-age=31536000'); @@ -170,7 +170,7 @@ describe('bundle routes', () => { await server.start(); const response = await supertest(innerServer.listener) - .get(`/${buildNum}/bundles/plugin/foo/gzip_chunk.js`) + .get(`/${buildHash}/bundles/plugin/foo/gzip_chunk.js`) .expect(200); expect(response.get('cache-control')).toEqual('must-revalidate'); diff --git a/src/core/server/integration_tests/http/http_server.test.ts b/src/core/server/integration_tests/http/http_server.test.ts index eeb6b46c9ff4..f58bfba11186 100644 --- a/src/core/server/integration_tests/http/http_server.test.ts +++ b/src/core/server/integration_tests/http/http_server.test.ts @@ -11,19 +11,21 @@ import supertest from 'supertest'; import moment from 'moment'; import { of } from 'rxjs'; import { ByteSizeValue } from '@kbn/config-schema'; -import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { Router } from '@kbn/core-http-router-server-internal'; import { HttpServer, HttpConfig } from '@kbn/core-http-server-internal'; +import { mockCoreContext } from '@kbn/core-base-server-mocks'; +import type { Logger } from '@kbn/logging'; describe('Http server', () => { let server: HttpServer; let config: HttpConfig; - let logger: ReturnType; + let logger: Logger; + let coreContext: ReturnType; const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {}); beforeEach(() => { - const loggingService = loggingSystemMock.create(); - logger = loggingSystemMock.createLogger(); + coreContext = mockCoreContext.create(); + logger = coreContext.logger.get(); config = { name: 'kibana', @@ -43,7 +45,7 @@ describe('Http server', () => { shutdownTimeout: moment.duration(5, 's'), } as any; - server = new HttpServer(loggingService, 'tests', of(config.shutdownTimeout)); + server = new HttpServer(coreContext, 'tests', of(config.shutdownTimeout)); }); describe('Graceful shutdown', () => { diff --git a/src/core/server/integration_tests/http/tls_config_reload.test.ts b/src/core/server/integration_tests/http/tls_config_reload.test.ts index 3603f76ebc67..ad2c530faae5 100644 --- a/src/core/server/integration_tests/http/tls_config_reload.test.ts +++ b/src/core/server/integration_tests/http/tls_config_reload.test.ts @@ -10,7 +10,6 @@ import supertest from 'supertest'; import { duration } from 'moment'; import { BehaviorSubject, of } from 'rxjs'; import { KBN_CERT_PATH, KBN_KEY_PATH, ES_KEY_PATH, ES_CERT_PATH } from '@kbn/dev-utils'; -import { loggingSystemMock } from '@kbn/core-logging-server-mocks'; import { Router } from '@kbn/core-http-router-server-internal'; import { HttpServer, @@ -20,6 +19,8 @@ import { externalUrlConfig, } from '@kbn/core-http-server-internal'; import { isServerTLS, flattenCertificateChain, fetchPeerCertificate } from './tls_utils'; +import { mockCoreContext } from '@kbn/core-base-server-mocks'; +import type { Logger } from '@kbn/logging'; const CSP_CONFIG = cspConfig.schema.validate({}); const EXTERNAL_URL_CONFIG = externalUrlConfig.schema.validate({}); @@ -27,16 +28,16 @@ const enhanceWithContext = (fn: (...args: any[]) => any) => fn.bind(null, {}); describe('HttpServer - TLS config', () => { let server: HttpServer; - let logger: ReturnType; + let logger: Logger; beforeAll(() => { process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; }); beforeEach(() => { - const loggingService = loggingSystemMock.create(); - logger = loggingSystemMock.createLogger(); - server = new HttpServer(loggingService, 'tests', of(duration('1s'))); + const coreContext = mockCoreContext.create(); + logger = coreContext.logger.get(); + server = new HttpServer(coreContext, 'tests', of(duration('1s'))); }); it('supports dynamic reloading of the TLS configuration', async () => { diff --git a/src/core/server/integration_tests/status/routes/status.test.ts b/src/core/server/integration_tests/status/routes/status.test.ts index 0d7d6a84e249..755b9fc9b46f 100644 --- a/src/core/server/integration_tests/status/routes/status.test.ts +++ b/src/core/server/integration_tests/status/routes/status.test.ts @@ -83,6 +83,7 @@ describe('GET /api/status', () => { branch: 'xbranch', buildNum: 1234, buildSha: 'xsha', + buildShaShort: 'x', dist: true, version: '9.9.9-SNAPSHOT', buildDate: new Date('2023-05-15T23:12:09.000Z'), diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index 62dd66f63ec6..b76a9c37dd6d 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -98,6 +98,7 @@ function pluginInitializerContextMock(config: T = {} as T) { branch: 'branch', buildNum: 100, buildSha: 'buildSha', + buildShaShort: 'buildShaShort', dist: false, buildDate: new Date('2023-05-15T23:12:09.000Z'), buildFlavor: 'traditional', diff --git a/src/core/tsconfig.json b/src/core/tsconfig.json index 78219114a51d..06e6cf68d3a9 100644 --- a/src/core/tsconfig.json +++ b/src/core/tsconfig.json @@ -157,6 +157,7 @@ "@kbn/core-plugins-contracts-server", "@kbn/dev-utils", "@kbn/server-http-tools", + "@kbn/core-base-server-mocks", ], "exclude": [ "target/**/*", diff --git a/src/plugins/data/common/search/expressions/esql.ts b/src/plugins/data/common/search/expressions/esql.ts index 1a2c7695bbf3..ce32d3626bcf 100644 --- a/src/plugins/data/common/search/expressions/esql.ts +++ b/src/plugins/data/common/search/expressions/esql.ts @@ -194,7 +194,10 @@ export const getEsqlFn = ({ getStartDependencies }: EsqlFnArguments) => { return search< IKibanaSearchRequest, IKibanaSearchResponse - >({ params }, { abortSignal, strategy: ESQL_ASYNC_SEARCH_STRATEGY }).pipe( + >( + { params: { ...params, dropNullColumns: true } }, + { abortSignal, strategy: ESQL_ASYNC_SEARCH_STRATEGY } + ).pipe( catchError((error) => { if (!error.attributes) { error.message = `Unexpected error from Elasticsearch: ${error.message}`; diff --git a/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.test.ts b/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.test.ts index b8a16113d128..bc7bf3122494 100644 --- a/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.test.ts +++ b/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.test.ts @@ -123,7 +123,7 @@ describe('ES|QL async search strategy', () => { it('sets transport options on POST requests', async () => { const transportOptions = { maxRetries: 1 }; mockApiCaller.mockResolvedValueOnce(mockAsyncResponse); - const params = {}; + const params = { query: 'from logs' }; const esSearch = esqlAsyncSearchStrategyProvider(mockSearchConfig, mockLogger); await firstValueFrom( @@ -139,6 +139,7 @@ describe('ES|QL async search strategy', () => { keep_alive: '60000ms', wait_for_completion_timeout: '100ms', keep_on_completion: false, + query: 'from logs', }, }), expect.objectContaining({ maxRetries: 1, meta: true, signal: undefined }) diff --git a/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts b/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts index f052e6749e72..8bde400db2b4 100644 --- a/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts +++ b/src/plugins/data/server/search/strategies/esql_async_search/esql_async_search_strategy.ts @@ -11,6 +11,7 @@ import { catchError, tap } from 'rxjs/operators'; import { getKbnServerError } from '@kbn/kibana-utils-plugin/server'; import { SqlQueryRequest } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { SqlGetAsyncResponse } from '@elastic/elasticsearch/lib/api/types'; +import type { ESQLSearchParams } from '@kbn/es-types'; import { getCommonDefaultAsyncSubmitParams, getCommonDefaultAsyncGetParams, @@ -22,12 +23,18 @@ import { IKibanaSearchRequest, IKibanaSearchResponse, pollSearch } from '../../. import { toAsyncKibanaSearchResponse } from './response_utils'; import { SearchConfigSchema } from '../../../../config'; +// `drop_null_columns` is going to change the response +// now we get `all_columns` and `columns` +// `columns` contain only columns with data +// `all_columns` contain everything +type ESQLQueryRequest = ESQLSearchParams & SqlQueryRequest['body']; + export const esqlAsyncSearchStrategyProvider = ( searchConfig: SearchConfigSchema, logger: Logger, useInternalUser: boolean = false ): ISearchStrategy< - IKibanaSearchRequest, + IKibanaSearchRequest, IKibanaSearchResponse > => { function cancelAsyncSearch(id: string, esClient: IScopedClusterClient) { @@ -46,12 +53,12 @@ export const esqlAsyncSearchStrategyProvider = ( } function asyncSearch( - { id, ...request }: IKibanaSearchRequest, + { id, ...request }: IKibanaSearchRequest, options: IAsyncSearchOptions, { esClient, uiSettingsClient }: SearchStrategyDependencies ) { const client = useInternalUser ? esClient.asInternalUser : esClient.asCurrentUser; - + const { dropNullColumns, ...requestParams } = request.params ?? {}; const search = async () => { const params = id ? { @@ -63,7 +70,7 @@ export const esqlAsyncSearchStrategyProvider = ( } : { ...(await getCommonDefaultAsyncSubmitParams(searchConfig, options)), - ...request.params, + ...requestParams, }; const { body, headers, meta } = id ? await client.transport.request( @@ -79,7 +86,7 @@ export const esqlAsyncSearchStrategyProvider = ( method: 'POST', path: `/_query/async`, body: params, - querystring: 'drop_null_columns', + querystring: dropNullColumns ? 'drop_null_columns' : '', }, { ...options.transport, signal: options.abortSignal, meta: true } ); diff --git a/src/plugins/data/server/search/strategies/esql_search/esql_search_strategy.ts b/src/plugins/data/server/search/strategies/esql_search/esql_search_strategy.ts index e9a6499b4aa1..73e77e53555e 100644 --- a/src/plugins/data/server/search/strategies/esql_search/esql_search_strategy.ts +++ b/src/plugins/data/server/search/strategies/esql_search/esql_search_strategy.ts @@ -32,12 +32,16 @@ export const esqlSearchStrategyProvider = ( const search = async () => { try { - const { terminateAfter, ...requestParams } = request.params ?? {}; + // `drop_null_columns` is going to change the response + // now we get `all_columns` and `columns` + // `columns` contain only columns with data + // `all_columns` contain everything + const { terminateAfter, dropNullColumns, ...requestParams } = request.params ?? {}; const { headers, body, meta } = await esClient.asCurrentUser.transport.request( { method: 'POST', path: `/_query`, - querystring: 'drop_null_columns', + querystring: dropNullColumns ? 'drop_null_columns' : '', body: { ...requestParams, }, diff --git a/src/plugins/data_views/common/data_views/__snapshots__/data_views.test.ts.snap b/src/plugins/data_views/common/data_views/__snapshots__/data_views.test.ts.snap index 53b77e28a416..cb9bb0517f50 100644 --- a/src/plugins/data_views/common/data_views/__snapshots__/data_views.test.ts.snap +++ b/src/plugins/data_views/common/data_views/__snapshots__/data_views.test.ts.snap @@ -7,6 +7,7 @@ FldList [ "conflictDescriptions": undefined, "count": 5, "customLabel": "A Runtime Field", + "defaultFormatter": undefined, "esTypes": Array [ "keyword", ], diff --git a/src/plugins/data_views/common/data_views/abstract_data_views.ts b/src/plugins/data_views/common/data_views/abstract_data_views.ts index 15ec8342cfd5..cc69ed7e7ced 100644 --- a/src/plugins/data_views/common/data_views/abstract_data_views.ts +++ b/src/plugins/data_views/common/data_views/abstract_data_views.ts @@ -24,6 +24,7 @@ import type { RuntimeField, } from '../types'; import { removeFieldAttrs } from './utils'; +import { metaUnitsToFormatter } from './meta_units_to_formatter'; import type { DataViewAttributes, FieldAttrs, FieldAttrSet } from '..'; @@ -251,6 +252,11 @@ export abstract class AbstractDataView { return fieldFormat; } + const fmt = field.defaultFormatter ? metaUnitsToFormatter[field.defaultFormatter] : undefined; + if (fmt) { + return this.fieldFormats.getInstance(fmt.id, fmt.params); + } + return this.fieldFormats.getDefaultInstance( field.type as KBN_FIELD_TYPES, field.esTypes as ES_FIELD_TYPES[] diff --git a/src/plugins/data_views/common/data_views/meta_units_to_formatter.ts b/src/plugins/data_views/common/data_views/meta_units_to_formatter.ts new file mode 100644 index 000000000000..2989bf5828c3 --- /dev/null +++ b/src/plugins/data_views/common/data_views/meta_units_to_formatter.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { FieldFormatParams } from '@kbn/field-formats-plugin/common'; + +const timeUnitToDurationFmt = (inputFormat = 'milliseconds') => { + return { + id: 'duration', + params: { + inputFormat, + outputFormat: 'humanizePrecise', + outputPrecision: 2, + includeSpaceWithSuffix: true, + useShortSuffix: true, + }, + }; +}; + +export const metaUnitsToFormatter: Record = { + percent: { id: 'percent' }, + byte: { id: 'bytes' }, + nanos: timeUnitToDurationFmt('nanoseconds'), + micros: timeUnitToDurationFmt('microseconds'), + ms: timeUnitToDurationFmt('milliseconds'), + s: timeUnitToDurationFmt('seconds'), + m: timeUnitToDurationFmt('minutes'), + h: timeUnitToDurationFmt('hours'), + d: timeUnitToDurationFmt('days'), +}; diff --git a/src/plugins/data_views/common/fields/data_view_field.ts b/src/plugins/data_views/common/fields/data_view_field.ts index 36cd78682aa9..52c304dbf27f 100644 --- a/src/plugins/data_views/common/fields/data_view_field.ts +++ b/src/plugins/data_views/common/fields/data_view_field.ts @@ -69,6 +69,10 @@ export class DataViewField implements DataViewFieldBase { this.spec.count = count; } + public get defaultFormatter() { + return this.spec.defaultFormatter; + } + /** * Returns runtime field definition or undefined if field is not runtime field. */ @@ -370,6 +374,7 @@ export class DataViewField implements DataViewFieldBase { readFromDocValues: this.readFromDocValues, subType: this.subType, customLabel: this.customLabel, + defaultFormatter: this.defaultFormatter, }; } @@ -403,6 +408,7 @@ export class DataViewField implements DataViewFieldBase { timeSeriesMetric: this.spec.timeSeriesMetric, timeZone: this.spec.timeZone, fixedInterval: this.spec.fixedInterval, + defaultFormatter: this.defaultFormatter, }; // Filter undefined values from the spec diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts index 2177f51621fe..caf1fc80dc5b 100644 --- a/src/plugins/data_views/common/types.ts +++ b/src/plugins/data_views/common/types.ts @@ -462,6 +462,8 @@ export type FieldSpec = DataViewFieldBase & { * Name of parent field for composite runtime field subfields. */ parentName?: string; + + defaultFormatter?: string; }; export type DataViewFieldMap = Record; diff --git a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts index aca312c8ea64..15ee00e5118c 100644 --- a/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts +++ b/src/plugins/data_views/server/fetcher/index_patterns_fetcher.ts @@ -32,6 +32,7 @@ export interface FieldDescriptor { timeZone?: string[]; timeSeriesMetric?: estypes.MappingTimeSeriesMetricType; timeSeriesDimension?: boolean; + defaultFormatter?: string; } interface FieldSubType { diff --git a/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.test.js b/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.test.js index e0722125cf7d..61f345876ac8 100644 --- a/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.test.js +++ b/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.test.js @@ -165,5 +165,22 @@ describe('index_patterns/field_capabilities/field_caps_response', () => { expect(child).not.toHaveProperty('subType'); }); }); + + it('sets default field formatter', () => { + const fields = readFieldCapsResponse({ + fields: { + seconds: { + long: { + searchable: true, + aggregatable: true, + meta: { + unit: ['s'], + }, + }, + }, + }, + }); + expect(fields[0].defaultFormatter).toEqual('s'); + }); }); }); diff --git a/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.ts b/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.ts index 715fea9beef3..805dbb9deb5f 100644 --- a/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.ts +++ b/src/plugins/data_views/server/fetcher/lib/field_capabilities/field_caps_response.ts @@ -12,6 +12,11 @@ import { castEsToKbnFieldTypeName } from '@kbn/field-types'; import { shouldReadFieldFromDocValues } from './should_read_field_from_doc_values'; import { FieldDescriptor } from '../..'; +// The array will have different values if values vary across indices +const unitsArrayToFormatter = (unitArr: string[]) => { + return unitArr.find((unit) => unitArr[0] !== unit) ? undefined : unitArr[0]; +}; + /** * Read the response from the _field_caps API to determine the type and * "aggregatable"/"searchable" status of each field. @@ -134,7 +139,11 @@ export function readFieldCapsResponse( timeSeriesMetricType = 'position'; } const esType = types[0]; - const field = { + + const defaultFormatter = + capsByType[types[0]].meta?.unit && unitsArrayToFormatter(capsByType[types[0]].meta?.unit); + + const field: FieldDescriptor = { name: fieldName, type: castEsToKbnFieldTypeName(esType), esTypes: types, @@ -147,6 +156,11 @@ export function readFieldCapsResponse( timeSeriesMetric: timeSeriesMetricType, timeSeriesDimension: capsByType[types[0]].time_series_dimension, }; + + if (defaultFormatter) { + field.defaultFormatter = defaultFormatter; + } + // This is intentionally using a "hash" and a "push" to be highly optimized with very large indexes agg.array.push(field); agg.hash[fieldName] = field; diff --git a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts index 98b4086bf161..1d5f8e636315 100644 --- a/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts +++ b/src/plugins/data_views/server/rest_api_routes/internal/fields_for.ts @@ -99,6 +99,7 @@ const FieldDescriptorSchema = schema.object({ conflictDescriptions: schema.maybe( schema.recordOf(schema.string(), schema.arrayOf(schema.string())) ), + defaultFormatter: schema.maybe(schema.string()), }); export const validate: FullValidationConfig = { diff --git a/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts b/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts index 1540fe9f3fe8..49e010d13a04 100644 --- a/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts +++ b/src/plugins/discover/public/application/main/hooks/use_text_based_query_language.ts @@ -18,7 +18,7 @@ import { FetchStatus } from '../../types'; const MAX_NUM_OF_COLUMNS = 50; // For ES|QL we want in case of the following commands to display a table view, otherwise display a document view -const TRANSFORMATIONAL_COMMANDS = ['stats', 'project', 'keep']; +const TRANSFORMATIONAL_COMMANDS = ['stats', 'keep']; /** * Hook to take care of text based query language state transformations when a new result is returned diff --git a/src/plugins/kibana_react/public/url_template_editor/styles.scss b/src/plugins/kibana_react/public/url_template_editor/styles.scss index 99379b21454e..1bff88195807 100644 --- a/src/plugins/kibana_react/public/url_template_editor/styles.scss +++ b/src/plugins/kibana_react/public/url_template_editor/styles.scss @@ -1,5 +1,5 @@ .urlTemplateEditor__container { .monaco-editor .lines-content.monaco-editor-background { - margin: $euiSizeS; + margin: 0 $euiSizeS; } } diff --git a/src/plugins/kibana_react/public/url_template_editor/url_template_editor.tsx b/src/plugins/kibana_react/public/url_template_editor/url_template_editor.tsx index 770753bc8c35..13773396eba7 100644 --- a/src/plugins/kibana_react/public/url_template_editor/url_template_editor.tsx +++ b/src/plugins/kibana_react/public/url_template_editor/url_template_editor.tsx @@ -22,6 +22,7 @@ export interface UrlTemplateEditorVariable { export interface UrlTemplateEditorProps { value: string; height?: CodeEditorProps['height']; + fitToContent?: CodeEditorProps['fitToContent']; variables?: UrlTemplateEditorVariable[]; onChange: CodeEditorProps['onChange']; onEditor?: (editor: monaco.editor.IStandaloneCodeEditor) => void; @@ -31,6 +32,7 @@ export interface UrlTemplateEditorProps { export const UrlTemplateEditor: React.FC = ({ height = 105, + fitToContent, value, variables, onChange, @@ -127,6 +129,7 @@ export const UrlTemplateEditor: React.FC = ({ = ({ }, wordWrap: 'on', wrappingIndent: 'none', + automaticLayout: true, + scrollBeyondLastLine: false, + overviewRulerLanes: 0, + padding: { top: 8, bottom: 8 }, }} /> diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/url_drilldown_collect_config/url_drilldown_collect_config.tsx b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/url_drilldown_collect_config/url_drilldown_collect_config.tsx index 0495f2d61063..4db2510ba22e 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/url_drilldown_collect_config/url_drilldown_collect_config.tsx +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/url_drilldown_collect_config/url_drilldown_collect_config.tsx @@ -88,6 +88,7 @@ export const UrlDrilldownCollectConfig: React.FC labelAppend={variablesDropdown} > { let queryHasTransformationalCommands = false; diff --git a/test/api_integration/apis/search/bsearch.ts b/test/api_integration/apis/search/bsearch.ts index 867ae83864a7..96b4bbbf622c 100644 --- a/test/api_integration/apis/search/bsearch.ts +++ b/test/api_integration/apis/search/bsearch.ts @@ -428,7 +428,6 @@ export default function ({ getService }: FtrProviderContext) { expect(jsonBody[0].result.requestParams).to.eql({ method: 'POST', path: '/_query', - querystring: 'drop_null_columns', }); }); @@ -457,7 +456,6 @@ export default function ({ getService }: FtrProviderContext) { expect(jsonBody[0].error.attributes.requestParams).to.eql({ method: 'POST', path: '/_query', - querystring: 'drop_null_columns', }); }); }); diff --git a/test/functional/apps/bundles/index.js b/test/functional/apps/bundles/index.js index aa175f16e5d4..7363d9f0b525 100644 --- a/test/functional/apps/bundles/index.js +++ b/test/functional/apps/bundles/index.js @@ -14,38 +14,38 @@ export default function ({ getService }) { const supertest = getService('supertest'); describe('bundle compression', function () { - let buildNum; + let buildHash; before(async () => { const resp = await supertest.get('/api/status').expect(200); - buildNum = resp.body.version.build_number; + buildHash = resp.body.version.build_hash.slice(0, 12); }); it('returns gzip files when client only supports gzip', () => supertest // We use the kbn-ui-shared-deps for these tests since they are always built with br compressed outputs, // even in dev. Bundles built by @kbn/optimizer are only built with br compression in dist mode. - .get(`/${buildNum}/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js`) + .get(`/${buildHash}/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js`) .set('Accept-Encoding', 'gzip') .expect(200) .expect('Content-Encoding', 'gzip')); it('returns br files when client only supports br', () => supertest - .get(`/${buildNum}/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js`) + .get(`/${buildHash}/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js`) .set('Accept-Encoding', 'br') .expect(200) .expect('Content-Encoding', 'br')); it('returns br files when client only supports gzip and br', () => supertest - .get(`/${buildNum}/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js`) + .get(`/${buildHash}/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js`) .set('Accept-Encoding', 'gzip, br') .expect(200) .expect('Content-Encoding', 'br')); it('returns gzip files when client prefers gzip', () => supertest - .get(`/${buildNum}/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js`) + .get(`/${buildHash}/bundles/kbn-ui-shared-deps-npm/kbn-ui-shared-deps-npm.dll.js`) .set('Accept-Encoding', 'gzip;q=1.0, br;q=0.5') .expect(200) .expect('Content-Encoding', 'gzip')); diff --git a/test/functional/apps/management/data_views/_field_formatter.ts b/test/functional/apps/management/data_views/_field_formatter.ts index dfcdc0b87758..cddbe8ccf5ce 100644 --- a/test/functional/apps/management/data_views/_field_formatter.ts +++ b/test/functional/apps/management/data_views/_field_formatter.ts @@ -413,6 +413,51 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ]); }); }); + + describe('default formatter by field meta value', () => { + const indexTitle = 'field_formats_management_functional_tests'; + + before(async () => { + if (await es.indices.exists({ index: indexTitle })) { + await es.indices.delete({ index: indexTitle }); + } + }); + + it('should apply default formatter by field meta value', async () => { + await es.indices.create({ + index: indexTitle, + body: { + mappings: { + properties: { + seconds: { type: 'long', meta: { unit: 's' } }, + }, + }, + }, + }); + + const docResult = await es.index({ + index: indexTitle, + body: { seconds: 1234 }, + refresh: 'wait_for', + }); + + const testDocumentId = docResult._id; + + const indexPatternResult = await indexPatterns.create( + { title: `${indexTitle}*` }, // sidesteps field caching when index pattern is reused + { override: true } + ); + + await PageObjects.common.navigateToApp('discover', { + hash: `/doc/${indexPatternResult.id}/${indexTitle}?id=${testDocumentId}`, + }); + await testSubjects.exists('doc-hit'); + + const renderedValue = await testSubjects.find(`tableDocViewRow-seconds-value`); + const text = await renderedValue.getVisibleText(); + expect(text).to.be('20.57 min'); + }); + }); }); /** diff --git a/versions.json b/versions.json index 90d1a205d66d..8a5f18231e40 100644 --- a/versions.json +++ b/versions.json @@ -8,13 +8,13 @@ "currentMinor": true }, { - "version": "8.12.1", + "version": "8.12.2", "branch": "8.12", "currentMajor": true, "previousMinor": true }, { - "version": "7.17.18", + "version": "7.17.19", "branch": "7.17", "previousMajor": true } diff --git a/x-pack/packages/kbn-alerting-state-types/src/lifecycle_state.ts b/x-pack/packages/kbn-alerting-state-types/src/lifecycle_state.ts index 8fa5cb111f6d..f82791dd4e4e 100644 --- a/x-pack/packages/kbn-alerting-state-types/src/lifecycle_state.ts +++ b/x-pack/packages/kbn-alerting-state-types/src/lifecycle_state.ts @@ -20,6 +20,8 @@ const trackedAlertStateRt = t.type({ // count of consecutive recovered alerts for flapping // will reset if the alert is active or if equal to the statusChangeThreshold stored in the rule settings pendingRecoveredCount: t.number, + // count of consecutive active alerts will reset if the alert is recovered + activeCount: t.number, }); export type TrackedLifecycleAlertState = t.TypeOf; diff --git a/x-pack/packages/kbn-alerting-state-types/src/task_state/v1/schema.ts b/x-pack/packages/kbn-alerting-state-types/src/task_state/v1/schema.ts index 247c0d7fc8d8..247cc7124c00 100644 --- a/x-pack/packages/kbn-alerting-state-types/src/task_state/v1/schema.ts +++ b/x-pack/packages/kbn-alerting-state-types/src/task_state/v1/schema.ts @@ -36,8 +36,7 @@ export const metaSchema = schema.object({ // will reset if the alert is active or if equal to the statusChangeThreshold stored in the rule settings pendingRecoveredCount: schema.maybe(schema.number()), uuid: schema.maybe(schema.string()), - // count of consecutive active alerts - // will reset if the alert is recovered or if equal to notificationDelay.active stored in the rule + // count of consecutive active alerts will reset if the alert is recovered activeCount: schema.maybe(schema.number()), }); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/index_properties/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/index_properties/index.tsx index 3de5aba8bcc5..6e1819d35537 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/index_properties/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/index_properties/index.tsx @@ -44,7 +44,7 @@ import { useAddToNewCase } from '../../use_add_to_new_case'; import { useMappings } from '../../use_mappings'; import { useUnallowedValues } from '../../use_unallowed_values'; import { useDataQualityContext } from '../data_quality_context'; -import { getSizeInBytes, postResult } from '../../helpers'; +import { formatStorageResult, postStorageResult, getSizeInBytes } from '../../helpers'; const EMPTY_MARKDOWN_COMMENTS: string[] = []; @@ -249,6 +249,8 @@ const IndexPropertiesComponent: React.FC = ({ }) : EMPTY_MARKDOWN_COMMENTS; + const checkedAt = partitionedFieldMetadata ? Date.now() : undefined; + const updatedRollup = { ...patternRollup, results: { @@ -262,13 +264,14 @@ const IndexPropertiesComponent: React.FC = ({ markdownComments, pattern, sameFamily: indexSameFamily, + checkedAt, }, }, }; updatePatternRollup(updatedRollup); if (indexId && requestTime != null && requestTime > 0 && partitionedFieldMetadata) { - const checkMetadata = { + const report = { batchId: uuidv4(), ecsVersion: EcsVersion, errorCount: error ? 1 : 0, @@ -294,10 +297,13 @@ const IndexPropertiesComponent: React.FC = ({ partitionedFieldMetadata.incompatible ), }; - telemetryEvents.reportDataQualityIndexChecked?.(checkMetadata); + telemetryEvents.reportDataQualityIndexChecked?.(report); - const result = { meta: checkMetadata, rollup: updatedRollup }; - postResult({ result, httpFetch, toasts, abortController: new AbortController() }); + const result = updatedRollup.results[indexName]; + if (result) { + const storageResult = formatStorageResult({ result, report, partitionedFieldMetadata }); + postStorageResult({ storageResult, httpFetch, toasts }); + } } } } diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/pattern/helpers.test.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/pattern/helpers.test.ts index b2a7f6ef26a6..cdf625111375 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/pattern/helpers.test.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/pattern/helpers.test.ts @@ -274,6 +274,7 @@ describe('helpers', () => { ], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: 1706526408000, }, }; const isILMAvailable = true; @@ -300,6 +301,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 733175040, + checkedAt: undefined, }, { docsCount: 1628343, @@ -309,6 +311,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 731583142, + checkedAt: undefined, }, { docsCount: 4, @@ -318,6 +321,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 28413, + checkedAt: 1706526408000, }, ]); }); @@ -344,6 +348,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 733175040, + checkedAt: undefined, }, { docsCount: 1628343, @@ -353,6 +358,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 731583142, + checkedAt: undefined, }, { docsCount: 4, @@ -362,6 +368,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 28413, + checkedAt: 1706526408000, }, ]); }); @@ -388,6 +395,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 28413, + checkedAt: 1706526408000, }, { docsCount: 1628343, @@ -397,6 +405,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 731583142, + checkedAt: undefined, }, { docsCount: 1630289, @@ -406,6 +415,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 733175040, + checkedAt: undefined, }, ]); }); @@ -432,6 +442,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 0, + checkedAt: undefined, }, { docsCount: 0, @@ -441,6 +452,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 0, + checkedAt: undefined, }, { docsCount: 0, @@ -450,6 +462,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 4, sizeInBytes: 0, + checkedAt: undefined, }, ]); }); @@ -701,6 +714,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 43357342, + checkedAt: 1706526408000, }, { docsCount: 48068, @@ -710,6 +724,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 32460397, + checkedAt: 1706526408000, }, { docsCount: 48064, @@ -719,6 +734,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 42782794, + checkedAt: 1706526408000, }, { docsCount: 47868, @@ -728,6 +744,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 31575964, + checkedAt: 1706526408000, }, { docsCount: 47827, @@ -737,6 +754,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 44130657, + checkedAt: 1706526408000, }, { docsCount: 47642, @@ -746,6 +764,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 42412521, + checkedAt: 1706526408000, }, { docsCount: 47545, @@ -755,6 +774,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 41423244, + checkedAt: 1706526408000, }, { docsCount: 47531, @@ -764,6 +784,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 32394133, + checkedAt: 1706526408000, }, { docsCount: 47530, @@ -773,6 +794,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 43015519, + checkedAt: 1706526408000, }, { docsCount: 47520, @@ -782,6 +804,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 42230604, + checkedAt: 1706526408000, }, { docsCount: 47496, @@ -791,6 +814,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 41710968, + checkedAt: 1706526408000, }, { docsCount: 47486, @@ -800,6 +824,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 42295944, + checkedAt: 1706526408000, }, { docsCount: 47486, @@ -809,6 +834,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 41761321, + checkedAt: 1706526408000, }, { docsCount: 47460, @@ -818,6 +844,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 30481198, + checkedAt: 1706526408000, }, { docsCount: 47439, @@ -827,6 +854,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 41554041, + checkedAt: 1706526408000, }, { docsCount: 47395, @@ -836,6 +864,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 42815907, + checkedAt: 1706526408000, }, { docsCount: 47394, @@ -845,6 +874,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 41157112, + checkedAt: 1706526408000, }, { docsCount: 47372, @@ -854,6 +884,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 31626792, + checkedAt: 1706526408000, }, { docsCount: 47369, @@ -863,6 +894,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 41828969, + checkedAt: 1706526408000, }, { docsCount: 47348, @@ -872,6 +904,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 40010773, + checkedAt: 1706526408000, }, { docsCount: 47339, @@ -881,6 +914,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 43480570, + checkedAt: 1706526408000, }, { docsCount: 47325, @@ -890,6 +924,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 41822475, + checkedAt: 1706526408000, }, { docsCount: 47294, @@ -899,6 +934,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 43018490, + checkedAt: 1706526408000, }, { docsCount: 24276, @@ -908,6 +944,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 23579440, + checkedAt: 1706526408000, }, { docsCount: 4, @@ -917,6 +954,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 28409, + checkedAt: 1706526408000, }, { docsCount: 0, @@ -926,6 +964,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 1118155, sizeInBytes: 247, + checkedAt: 1706526408000, }, ], pageSize: 10, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/pattern/helpers.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/pattern/helpers.ts index 82fd312a947e..1bddcd83e7a1 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/pattern/helpers.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/pattern/helpers.ts @@ -172,6 +172,7 @@ export const getSummaryTableItems = ({ pattern, patternDocsCount, sizeInBytes: getSizeInBytes({ stats, indexName }), + checkedAt: results?.[indexName]?.checkedAt, })); return orderBy([sortByColumn], [sortByDirection], summaryTableItems); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/helpers.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/helpers.test.tsx index 6ab874eeac5b..cfcd23b86d2a 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/helpers.test.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/helpers.test.tsx @@ -143,6 +143,7 @@ describe('helpers', () => { pattern: 'auditbeat-*', patternDocsCount: 57410, sizeInBytes: 103344068, + checkedAt: Date.now(), }; const hasIncompatible: IndexSummaryTableItem = { @@ -188,6 +189,7 @@ describe('helpers', () => { }, { field: 'ilmPhase', name: 'ILM Phase', sortable: true, truncateText: false }, { field: 'sizeInBytes', name: 'Size', sortable: true, truncateText: false }, + { field: 'checkedAt', name: 'Last check', sortable: true, truncateText: false }, ]); }); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/helpers.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/helpers.tsx index f80678fff8cb..55e26200f0e4 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/helpers.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/helpers.tsx @@ -5,8 +5,9 @@ * 2.0. */ -import type { EuiBasicTableColumn } from '@elastic/eui'; import { + EuiBasicTableColumn, + EuiText, EuiBadge, EuiButtonIcon, EuiIcon, @@ -17,6 +18,7 @@ import { RIGHT_ALIGNMENT, } from '@elastic/eui'; import React from 'react'; +import moment from 'moment'; import styled from 'styled-components'; import { EMPTY_STAT, getIlmPhaseDescription, getIncompatibleStatColor } from '../../helpers'; @@ -41,6 +43,7 @@ export interface IndexSummaryTableItem { pattern: string; patternDocsCount: number; sizeInBytes: number; + checkedAt: number | undefined; } export const getResultToolTip = (incompatible: number | undefined): string => { @@ -237,6 +240,17 @@ export const getSummaryTableColumns = ({ sortable: true, truncateText: false, }, + { + field: 'checkedAt', + name: i18n.LAST_CHECK, + render: (_, { checkedAt }) => ( + + {checkedAt && moment(checkedAt).isValid() ? moment(checkedAt).fromNow() : EMPTY_STAT} + + ), + sortable: true, + truncateText: false, + }, ]; export const getShowPagination = ({ diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/translations.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/translations.ts index 0101708db9f9..8d8e4adb9944 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/translations.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/data_quality_panel/summary_table/translations.ts @@ -111,6 +111,13 @@ export const SIZE = i18n.translate( } ); +export const LAST_CHECK = i18n.translate( + 'securitySolutionPackages.ecsDataQualityDashboard.summaryTable.lastCheckColumn', + { + defaultMessage: 'Last check', + } +); + export const THIS_INDEX_HAS_NOT_BEEN_CHECKED = i18n.translate( 'securitySolutionPackages.ecsDataQualityDashboard.summaryTable.thisIndexHasNotBeenCheckedTooltip', { diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/helpers.test.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/helpers.test.ts index a20c8144c577..830d463f5fe5 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/helpers.test.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/helpers.test.ts @@ -35,9 +35,9 @@ import { getTotalSizeInBytes, hasValidTimestampMapping, isMappingCompatible, - postResult, - getResults, - ResultData, + postStorageResult, + getStorageResults, + StorageResult, } from './helpers'; import { hostNameWithTextMapping, @@ -102,6 +102,7 @@ describe('helpers', () => { ], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: Date.now(), }; it('returns undefined when results is undefined', () => { @@ -1193,6 +1194,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: 'packetbeat-*', sameFamily: 0, + checkedAt: Date.now(), }, '.ds-packetbeat-8.6.1-2023.02.04-000001': { docsCount: 1628343, @@ -1203,6 +1205,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: 'packetbeat-*', sameFamily: 0, + checkedAt: Date.now(), }, }; @@ -1220,6 +1223,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: Date.now(), }, 'auditbeat-custom-index-1': { docsCount: 4, @@ -1230,6 +1234,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: Date.now(), }, 'auditbeat-custom-empty-index-1': { docsCount: 0, @@ -1240,6 +1245,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: Date.now(), }, }; @@ -1257,6 +1263,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: Date.now(), }, 'auditbeat-custom-index-1': { docsCount: 4, @@ -1267,6 +1274,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: Date.now(), }, 'auditbeat-custom-empty-index-1': { docsCount: 0, @@ -1277,6 +1285,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: Date.now(), }, }; @@ -1342,6 +1351,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: 'packetbeat-*', sameFamily: 0, + checkedAt: Date.now(), }; expect(getErrorSummary(resultWithError)).toEqual({ @@ -1495,7 +1505,7 @@ describe('helpers', () => { }); }); - describe('postResult', () => { + describe('postStorageResult', () => { const { fetch } = httpServiceMock.createStartContract(); const { toasts } = notificationServiceMock.createStartContract(); beforeEach(() => { @@ -1503,10 +1513,10 @@ describe('helpers', () => { }); test('it posts the result', async () => { - const result = { meta: {}, rollup: {} } as unknown as ResultData; - await postResult({ + const storageResult = { indexName: 'test' } as unknown as StorageResult; + await postStorageResult({ + storageResult, httpFetch: fetch, - result, abortController: new AbortController(), toasts, }); @@ -1515,17 +1525,17 @@ describe('helpers', () => { '/internal/ecs_data_quality_dashboard/results', expect.objectContaining({ method: 'POST', - body: JSON.stringify(result), + body: JSON.stringify(storageResult), }) ); }); test('it throws error', async () => { - const result = { meta: {}, rollup: {} } as unknown as ResultData; + const storageResult = { indexName: 'test' } as unknown as StorageResult; fetch.mockRejectedValueOnce('test-error'); - await postResult({ + await postStorageResult({ httpFetch: fetch, - result, + storageResult, abortController: new AbortController(), toasts, }); @@ -1533,7 +1543,7 @@ describe('helpers', () => { }); }); - describe('getResults', () => { + describe('getStorageResults', () => { const { fetch } = httpServiceMock.createStartContract(); const { toasts } = notificationServiceMock.createStartContract(); beforeEach(() => { @@ -1541,10 +1551,10 @@ describe('helpers', () => { }); test('it gets the results', async () => { - await getResults({ + await getStorageResults({ httpFetch: fetch, abortController: new AbortController(), - patterns: ['auditbeat-*', 'packetbeat-*'], + pattern: 'auditbeat-*', toasts, }); @@ -1552,7 +1562,7 @@ describe('helpers', () => { '/internal/ecs_data_quality_dashboard/results', expect.objectContaining({ method: 'GET', - query: { patterns: 'auditbeat-*,packetbeat-*' }, + query: { pattern: 'auditbeat-*' }, }) ); }); @@ -1560,10 +1570,10 @@ describe('helpers', () => { it('should catch error', async () => { fetch.mockRejectedValueOnce('test-error'); - const results = await getResults({ + const results = await getStorageResults({ httpFetch: fetch, abortController: new AbortController(), - patterns: ['auditbeat-*', 'packetbeat-*'], + pattern: 'auditbeat-*', toasts, }); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/helpers.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/helpers.ts index a4d51233232e..2107e7d3949d 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/helpers.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/helpers.ts @@ -23,6 +23,7 @@ import type { EcsMetadata, EnrichedFieldMetadata, ErrorSummary, + IlmPhase, PartitionedFieldMetadata, PartitionedFieldMetadataStats, PatternRollup, @@ -449,51 +450,116 @@ export const getErrorSummaries = ( export const RESULTS_API_ROUTE = '/internal/ecs_data_quality_dashboard/results'; -export interface ResultData { - meta: DataQualityIndexCheckedParams; - rollup: PatternRollup; +export interface StorageResult { + batchId: string; + indexName: string; + isCheckAll: boolean; + checkedAt: number; + docsCount: number; + totalFieldCount: number; + ecsFieldCount: number; + customFieldCount: number; + incompatibleFieldCount: number; + sameFamilyFieldCount: number; + sameFamilyFields: string[]; + unallowedMappingFields: string[]; + unallowedValueFields: string[]; + sizeInBytes: number; + ilmPhase?: IlmPhase; + markdownComments: string[]; + ecsVersion: string; + indexId: string; + error: string | null; } -export async function postResult({ +export const formatStorageResult = ({ result, + report, + partitionedFieldMetadata, +}: { + result: DataQualityCheckResult; + report: DataQualityIndexCheckedParams; + partitionedFieldMetadata: PartitionedFieldMetadata; +}): StorageResult => ({ + batchId: report.batchId, + indexName: result.indexName, + isCheckAll: report.isCheckAll, + checkedAt: result.checkedAt ?? Date.now(), + docsCount: result.docsCount ?? 0, + totalFieldCount: partitionedFieldMetadata.all.length, + ecsFieldCount: partitionedFieldMetadata.ecsCompliant.length, + customFieldCount: partitionedFieldMetadata.custom.length, + incompatibleFieldCount: partitionedFieldMetadata.incompatible.length, + sameFamilyFieldCount: partitionedFieldMetadata.sameFamily.length, + sameFamilyFields: report.sameFamilyFields ?? [], + unallowedMappingFields: report.unallowedMappingFields ?? [], + unallowedValueFields: report.unallowedValueFields ?? [], + sizeInBytes: report.sizeInBytes ?? 0, + ilmPhase: result.ilmPhase, + markdownComments: result.markdownComments, + ecsVersion: report.ecsVersion, + indexId: report.indexId, + error: result.error, +}); + +export const formatResultFromStorage = ({ + storageResult, + pattern, +}: { + storageResult: StorageResult; + pattern: string; +}): DataQualityCheckResult => ({ + docsCount: storageResult.docsCount, + error: storageResult.error, + ilmPhase: storageResult.ilmPhase, + incompatible: storageResult.incompatibleFieldCount, + indexName: storageResult.indexName, + markdownComments: storageResult.markdownComments, + sameFamily: storageResult.sameFamilyFieldCount, + checkedAt: storageResult.checkedAt, + pattern, +}); + +export async function postStorageResult({ + storageResult, httpFetch, toasts, - abortController, + abortController = new AbortController(), }: { - result: ResultData; + storageResult: StorageResult; httpFetch: HttpHandler; toasts: IToasts; - abortController: AbortController; + abortController?: AbortController; }): Promise { try { await httpFetch(RESULTS_API_ROUTE, { method: 'POST', signal: abortController.signal, version: INTERNAL_API_VERSION, - body: JSON.stringify(result), + body: JSON.stringify(storageResult), }); } catch (err) { toasts.addError(err, { title: i18n.POST_RESULT_ERROR_TITLE }); } } -export async function getResults({ - patterns, +export async function getStorageResults({ + pattern, httpFetch, toasts, abortController, }: { - patterns: string[]; + pattern: string; httpFetch: HttpHandler; toasts: IToasts; abortController: AbortController; -}): Promise { +}): Promise { try { - const results = await httpFetch(RESULTS_API_ROUTE, { + const results = await httpFetch(RESULTS_API_ROUTE, { method: 'GET', signal: abortController.signal, version: INTERNAL_API_VERSION, - query: { patterns: patterns.join(',') }, + query: { pattern }, }); return results; } catch (err) { diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/data_quality_check_result/mock_index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/data_quality_check_result/mock_index.tsx index f179a82c232e..7f61f91b8721 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/data_quality_check_result/mock_index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/data_quality_check_result/mock_index.tsx @@ -23,6 +23,7 @@ export const mockDataQualityCheckResult: Record ], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: 1706526408000, }, 'auditbeat-7.9.3-2023.02.13-000001': { docsCount: 2438, @@ -39,5 +40,6 @@ export const mockDataQualityCheckResult: Record ], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: 1706526408000, }, }; diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_alerts_pattern_rollup.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_alerts_pattern_rollup.ts index f121621ff1ac..513d034f5226 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_alerts_pattern_rollup.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_alerts_pattern_rollup.ts @@ -83,6 +83,7 @@ export const alertIndexWithAllResults: PatternRollup = { markdownComments: ['foo', 'bar', 'baz'], pattern: '.alerts-security.alerts-default', sameFamily: 0, + checkedAt: 1706526408000, }, }, sizeInBytes: 29717961631, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_auditbeat_pattern_rollup.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_auditbeat_pattern_rollup.ts index 2f83f899dc0d..15bb39a01714 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_auditbeat_pattern_rollup.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_auditbeat_pattern_rollup.ts @@ -155,6 +155,7 @@ export const auditbeatWithAllResults: PatternRollup = { markdownComments: ['foo', 'bar', 'baz'], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: 1706526408000, }, 'auditbeat-custom-index-1': { docsCount: 4, @@ -165,6 +166,7 @@ export const auditbeatWithAllResults: PatternRollup = { markdownComments: ['foo', 'bar', 'baz'], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: 1706526408000, }, 'auditbeat-custom-empty-index-1': { docsCount: 0, @@ -175,6 +177,7 @@ export const auditbeatWithAllResults: PatternRollup = { markdownComments: ['foo', 'bar', 'baz'], pattern: 'auditbeat-*', sameFamily: 0, + checkedAt: 1706526408000, }, }, sizeInBytes: 18820446, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_packetbeat_pattern_rollup.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_packetbeat_pattern_rollup.ts index 369803a44a3d..339f1993e292 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_packetbeat_pattern_rollup.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/mock/pattern_rollup/mock_packetbeat_pattern_rollup.ts @@ -132,6 +132,7 @@ export const packetbeatWithSomeErrors: PatternRollup = { markdownComments: ['foo', 'bar', 'baz'], pattern: 'packetbeat-*', sameFamily: undefined, + checkedAt: 1706526408000, }, '.ds-packetbeat-8.6.1-2023.02.04-000001': { docsCount: 1628343, @@ -142,6 +143,7 @@ export const packetbeatWithSomeErrors: PatternRollup = { markdownComments: ['foo', 'bar', 'baz'], pattern: 'packetbeat-*', sameFamily: 0, + checkedAt: 1706526408000, }, }, sizeInBytes: 1096520898, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/types.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/types.ts index 9f507992d150..f462777e1fc0 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/types.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/types.ts @@ -107,6 +107,7 @@ export interface DataQualityCheckResult { markdownComments: string[]; sameFamily: number | undefined; pattern: string; + checkedAt: number | undefined; } export interface PatternRollup { @@ -186,8 +187,8 @@ export type DataQualityIndexCheckedParams = DataQualityCheckAllCompletedParams & export interface DataQualityCheckAllCompletedParams { batchId: string; - ecsVersion?: string; - isCheckAll?: boolean; + ecsVersion: string; + isCheckAll: boolean; numberOfDocuments?: number; numberOfIncompatibleFields?: number; numberOfIndices?: number; diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/helpers.test.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/helpers.test.ts index b37d0aecc25c..b948b9584f99 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/helpers.test.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/helpers.test.ts @@ -61,6 +61,7 @@ describe('helpers', () => { markdownComments: ['foo', 'bar', 'baz'], pattern: '.alerts-security.alerts-default', sameFamily: 7, + checkedAt: 1706526408000, }; const alertIndexWithSameFamily: PatternRollup = { @@ -260,6 +261,7 @@ describe('helpers', () => { ], pattern: 'packetbeat-*', sameFamily: 0, + checkedAt: expect.any(Number), }, }, sizeInBytes: 1464758182, @@ -361,6 +363,7 @@ describe('helpers', () => { ], pattern: 'packetbeat-*', sameFamily: 0, + checkedAt: expect.any(Number), }, }, sizeInBytes: 1464758182, @@ -450,6 +453,7 @@ describe('helpers', () => { indexName: '.ds-packetbeat-8.6.1-2023.02.04-000001', markdownComments: [], pattern: 'packetbeat-*', + checkedAt: undefined, }, }, sizeInBytes: 1464758182, @@ -510,6 +514,7 @@ describe('helpers', () => { ], pattern: 'packetbeat-*', sameFamily: 0, + checkedAt: expect.any(Number), }, }, sizeInBytes: 1464758182, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/helpers.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/helpers.ts index cca8ac331aa8..07f51572b6ba 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/helpers.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/helpers.ts @@ -140,6 +140,7 @@ export const updateResultOnCheckCompleted = ({ const incompatible = partitionedFieldMetadata?.incompatible.length; const sameFamily = partitionedFieldMetadata?.sameFamily.length; + const checkedAt = partitionedFieldMetadata ? Date.now() : undefined; return { ...patternRollups, @@ -156,6 +157,7 @@ export const updateResultOnCheckCompleted = ({ markdownComments, pattern, sameFamily, + checkedAt, }, }, }, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/index.tsx index 27810fedffde..907ffca5a45f 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality/use_results_rollup/index.tsx @@ -19,14 +19,16 @@ import { updateResultOnCheckCompleted, } from './helpers'; -import type { OnCheckCompleted, PatternRollup } from '../types'; +import type { DataQualityCheckResult, OnCheckCompleted, PatternRollup } from '../types'; import { getDocsCount, getIndexId, - getResults, + getStorageResults, getSizeInBytes, getTotalPatternSameFamily, - postResult, + postStorageResult, + formatStorageResult, + formatResultFromStorage, } from '../helpers'; import { getIlmPhase, getIndexIncompatible } from '../data_quality_panel/pattern/helpers'; import { useDataQualityContext } from '../data_quality_panel/data_quality_context'; @@ -60,9 +62,11 @@ interface UseResultsRollup { updatePatternRollup: (patternRollup: PatternRollup) => void; } -const useStoredPatternRollups = (patterns: string[]) => { +const useStoredPatternResults = (patterns: string[]) => { const { httpFetch, toasts } = useDataQualityContext(); - const [storedRollups, setStoredRollups] = useState>({}); + const [storedPatternResults, setStoredPatternResults] = useState< + Array<{ pattern: string; results: Record }> + >([]); useEffect(() => { if (isEmpty(patterns)) { @@ -71,20 +75,31 @@ const useStoredPatternRollups = (patterns: string[]) => { let ignore = false; const abortController = new AbortController(); - const fetchStoredRollups = async () => { - const results = await getResults({ httpFetch, abortController, patterns, toasts }); - if (results?.length && !ignore) { - setStoredRollups(Object.fromEntries(results.map(({ rollup }) => [rollup.pattern, rollup]))); + const fetchStoredPatternResults = async () => { + const requests = patterns.map((pattern) => + getStorageResults({ pattern, httpFetch, abortController, toasts }).then((results = []) => ({ + pattern, + results: Object.fromEntries( + results.map((storageResult) => [ + storageResult.indexName, + formatResultFromStorage({ storageResult, pattern }), + ]) + ), + })) + ); + const patternResults = await Promise.all(requests); + if (patternResults?.length && !ignore) { + setStoredPatternResults(patternResults); } }; - fetchStoredRollups(); + fetchStoredPatternResults(); return () => { ignore = true; }; }, [httpFetch, patterns, toasts]); - return storedRollups; + return storedPatternResults; }; export const useResultsRollup = ({ ilmPhases, patterns }: Props): UseResultsRollup => { @@ -92,28 +107,36 @@ export const useResultsRollup = ({ ilmPhases, patterns }: Props): UseResultsRoll const [patternIndexNames, setPatternIndexNames] = useState>({}); const [patternRollups, setPatternRollups] = useState>({}); - const storedPatternsRollups = useStoredPatternRollups(patterns); + const storedPatternsResults = useStoredPatternResults(patterns); useEffect(() => { - if (!isEmpty(storedPatternsRollups)) { - setPatternRollups((current) => ({ ...current, ...storedPatternsRollups })); + if (!isEmpty(storedPatternsResults)) { + setPatternRollups((current) => + storedPatternsResults.reduce( + (acc, { pattern, results }) => ({ + ...acc, + [pattern]: { + ...current[pattern], + pattern, + results, + }, + }), + current + ) + ); } - }, [storedPatternsRollups]); - - const updatePatternRollups = useCallback( - (updateRollups: (current: Record) => Record) => { - setPatternRollups((current) => updateRollups(current)); - }, - [] - ); + }, [storedPatternsResults]); const { telemetryEvents, isILMAvailable } = useDataQualityContext(); - const updatePatternRollup = useCallback( - (patternRollup: PatternRollup) => { - updatePatternRollups((current) => ({ ...current, [patternRollup.pattern]: patternRollup })); - }, - [updatePatternRollups] - ); + const updatePatternRollup = useCallback((patternRollup: PatternRollup) => { + setPatternRollups((current) => ({ + ...current, + [patternRollup.pattern]: { + ...patternRollup, + results: patternRollup.results ?? current[patternRollup.pattern]?.results, // prevent undefined results override existing + }, + })); + }, []); const totalDocsCount = useMemo(() => getTotalDocsCount(patternRollups), [patternRollups]); const totalIncompatible = useMemo(() => getTotalIncompatible(patternRollups), [patternRollups]); @@ -170,7 +193,7 @@ export const useResultsRollup = ({ ilmPhases, patterns }: Props): UseResultsRoll requestTime > 0 && partitionedFieldMetadata ) { - const metadata = { + const report = { batchId, ecsVersion: EcsVersion, errorCount: error ? 1 : 0, @@ -199,10 +222,13 @@ export const useResultsRollup = ({ ilmPhases, patterns }: Props): UseResultsRoll partitionedFieldMetadata.incompatible ), }; - telemetryEvents.reportDataQualityIndexChecked?.(metadata); + telemetryEvents.reportDataQualityIndexChecked?.(report); - const result = { meta: metadata, rollup: updatedRollup }; - postResult({ result, httpFetch, toasts, abortController: new AbortController() }); + const result = results[indexName]; + if (result) { + const storageResult = formatStorageResult({ result, report, partitionedFieldMetadata }); + postStorageResult({ storageResult, httpFetch, toasts }); + } } if (isLastCheck) { diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/kibana.jsonc b/x-pack/packages/security-solution/ecs_data_quality_dashboard/kibana.jsonc index a001420fade8..30cc9cf24982 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/kibana.jsonc +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/kibana.jsonc @@ -1,5 +1,5 @@ { "type": "shared-browser", "id": "@kbn/ecs-data-quality-dashboard", - "owner": "@elastic/security-threat-hunting-investigations" + "owner": "@elastic/security-threat-hunting-explore" } diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts index bdc60a6562fe..7d1a37b7c75f 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/create/schemas/v1.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { validateDurationV1, validateHoursV1, validateTimezoneV1 } from '../../../validation'; -import { notifyWhenSchemaV1, notificationDelaySchemaV1 } from '../../../response'; +import { notifyWhenSchemaV1, alertDelaySchemaV1 } from '../../../response'; import { alertsFilterQuerySchemaV1 } from '../../../../alerts_filter_query'; export const actionFrequencySchema = schema.object({ @@ -68,7 +68,7 @@ export const createBodySchema = schema.object({ }), actions: schema.arrayOf(actionSchema, { defaultValue: [] }), notify_when: schema.maybe(schema.nullable(notifyWhenSchemaV1)), - notification_delay: schema.maybe(notificationDelaySchemaV1), + alert_delay: schema.maybe(alertDelaySchemaV1), }); export const createParamsSchema = schema.object({ diff --git a/x-pack/plugins/alerting/common/routes/rule/apis/create/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/apis/create/types/v1.ts index 328f44fe185b..9d5d1e39525a 100644 --- a/x-pack/plugins/alerting/common/routes/rule/apis/create/types/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/apis/create/types/v1.ts @@ -30,7 +30,7 @@ export interface CreateRuleRequestBody { schedule: CreateBodySchema['schedule']; actions: CreateBodySchema['actions']; notify_when?: CreateBodySchema['notify_when']; - notification_delay?: CreateBodySchema['notification_delay']; + alert_delay?: CreateBodySchema['alert_delay']; } export interface CreateRuleResponse { diff --git a/x-pack/plugins/alerting/common/routes/rule/response/index.ts b/x-pack/plugins/alerting/common/routes/rule/response/index.ts index 8e405c599e48..8c784e744d47 100644 --- a/x-pack/plugins/alerting/common/routes/rule/response/index.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/index.ts @@ -37,7 +37,7 @@ export { ruleSnoozeScheduleSchema as ruleSnoozeScheduleSchemaV1, notifyWhenSchema as notifyWhenSchemaV1, scheduleIdsSchema as scheduleIdsSchemaV1, - notificationDelaySchema as notificationDelaySchemaV1, + alertDelaySchema as alertDelaySchemaV1, } from './schemas/v1'; export type { diff --git a/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts index 67f57926d546..f485aa7374d6 100644 --- a/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/schemas/v1.ts @@ -182,7 +182,7 @@ export const ruleSnoozeScheduleSchema = schema.object({ skipRecurrences: schema.maybe(schema.arrayOf(schema.string())), }); -export const notificationDelaySchema = schema.object({ +export const alertDelaySchema = schema.object({ active: schema.number(), }); @@ -218,7 +218,7 @@ export const ruleResponseSchema = schema.object({ revision: schema.number(), running: schema.maybe(schema.nullable(schema.boolean())), view_in_app_relative_url: schema.maybe(schema.nullable(schema.string())), - notification_delay: schema.maybe(notificationDelaySchema), + alert_delay: schema.maybe(alertDelaySchema), }); export const scheduleIdsSchema = schema.maybe(schema.arrayOf(schema.string())); diff --git a/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts b/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts index 453d1a96d24d..25e08ab407eb 100644 --- a/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts +++ b/x-pack/plugins/alerting/common/routes/rule/response/types/v1.ts @@ -53,5 +53,5 @@ export interface RuleResponse { revision: RuleResponseSchemaType['revision']; running?: RuleResponseSchemaType['running']; view_in_app_relative_url?: RuleResponseSchemaType['view_in_app_relative_url']; - notification_delay?: RuleResponseSchemaType['notification_delay']; + alert_delay?: RuleResponseSchemaType['alert_delay']; } diff --git a/x-pack/plugins/alerting/common/rule.ts b/x-pack/plugins/alerting/common/rule.ts index 590c1d4312d5..7cec5bdbdd7a 100644 --- a/x-pack/plugins/alerting/common/rule.ts +++ b/x-pack/plugins/alerting/common/rule.ts @@ -141,7 +141,7 @@ export interface MappedParamsProperties { export type MappedParams = SavedObjectAttributes & MappedParamsProperties; -export interface NotificationDelay { +export interface AlertDelay extends SavedObjectAttributes { active: number; } @@ -178,7 +178,7 @@ export interface Rule { revision: number; running?: boolean | null; viewInAppRelativeUrl?: string; - notificationDelay?: NotificationDelay; + alertDelay?: AlertDelay; } export interface SanitizedAlertsFilter extends AlertsFilter { @@ -222,6 +222,7 @@ export type SanitizedRuleConfig = Pick< | 'muteAll' | 'revision' | 'snoozeSchedule' + | 'alertDelay' > & { producer: string; ruleTypeId: string; diff --git a/x-pack/plugins/alerting/server/alerts_client/alerts_client.test.ts b/x-pack/plugins/alerting/server/alerts_client/alerts_client.test.ts index 0ef8f7c31e01..81848c3e6568 100644 --- a/x-pack/plugins/alerting/server/alerts_client/alerts_client.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/alerts_client.test.ts @@ -308,6 +308,7 @@ describe('Alerts Client', () => { flappingSettings: DEFAULT_FLAPPING_SETTINGS, notifyOnActionGroupChange: true, maintenanceWindowIds: [], + alertDelay: 0, }; }); @@ -516,6 +517,25 @@ describe('Alerts Client', () => { }); }); + test('should not index new alerts if the activeCount is less than the rule alertDelay', async () => { + const alertsClient = new AlertsClient<{}, {}, {}, 'default', 'recovered'>({ + ...alertsClientParams, + rule: { ...alertsClientParams.rule, alertDelay: 3 }, + }); + + await alertsClient.initializeExecution(defaultExecutionOpts); + + // Report 1 new alerts + const alertExecutorService = alertsClient.factory(); + alertExecutorService.create('1').scheduleActions('default'); + + alertsClient.processAndLogAlerts(processAndLogAlertsOpts); + + await alertsClient.persistAlerts(); + + expect(clusterClient.bulk).not.toHaveBeenCalled(); + }); + test('should update ongoing alerts in existing index', async () => { clusterClient.search.mockResolvedValue({ took: 10, diff --git a/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts index cc443975cee4..0c1eb897a6e5 100644 --- a/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts +++ b/x-pack/plugins/alerting/server/alerts_client/alerts_client.ts @@ -344,6 +344,11 @@ export class AlertsClient< }) ); } else { + // skip writing the alert document if the number of consecutive + // active alerts is less than the rule alertDelay threshold + if (activeAlerts[id].getActiveCount() < this.options.rule.alertDelay) { + continue; + } activeAlertsToIndex.push( buildNewAlert< AlertData, diff --git a/x-pack/plugins/alerting/server/alerts_client/alerts_client_fixtures.ts b/x-pack/plugins/alerting/server/alerts_client/alerts_client_fixtures.ts index 90c2f4c40b65..0da20a5e49b7 100644 --- a/x-pack/plugins/alerting/server/alerts_client/alerts_client_fixtures.ts +++ b/x-pack/plugins/alerting/server/alerts_client/alerts_client_fixtures.ts @@ -25,6 +25,7 @@ export const alertRuleData: AlertRuleData = { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }; export const mockAAD = { diff --git a/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.test.ts b/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.test.ts index 446ecfd79c8b..d01060820ae5 100644 --- a/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.test.ts @@ -245,6 +245,7 @@ describe('Legacy Alerts Client', () => { flappingSettings: DEFAULT_FLAPPING_SETTINGS, notifyOnActionGroupChange: true, maintenanceWindowIds: ['window-id1', 'window-id2'], + alertDelay: 5, }); expect(processAlerts).toHaveBeenCalledWith({ @@ -275,13 +276,15 @@ describe('Legacy Alerts Client', () => { }, true, 'default', + 5, {}, { '1': new Alert('1', testAlert1), '2': new Alert('2', testAlert2), }, {}, - {} + {}, + null ); expect(logAlerts).toHaveBeenCalledWith({ diff --git a/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts b/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts index 0de97a8a29be..a5cfc642a19e 100644 --- a/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts +++ b/x-pack/plugins/alerting/server/alerts_client/legacy_alerts_client.ts @@ -140,6 +140,7 @@ export class LegacyAlertsClient< notifyOnActionGroupChange, flappingSettings, maintenanceWindowIds, + alertDelay, }: ProcessAlertsOpts) { const { newAlerts: processedAlertsNew, @@ -168,10 +169,12 @@ export class LegacyAlertsClient< flappingSettings, notifyOnActionGroupChange, this.options.ruleType.defaultActionGroupId, + alertDelay, processedAlertsNew, processedAlertsActive, trimmedAlertsRecovered, - processedAlertsRecoveredCurrent + processedAlertsRecoveredCurrent, + this.startedAtString ); alerts.currentRecoveredAlerts = merge(alerts.currentRecoveredAlerts, earlyRecoveredAlerts); @@ -203,11 +206,13 @@ export class LegacyAlertsClient< flappingSettings, notifyOnActionGroupChange, maintenanceWindowIds, + alertDelay, }: ProcessAndLogAlertsOpts) { this.processAlerts({ notifyOnActionGroupChange, flappingSettings, maintenanceWindowIds, + alertDelay, }); this.logAlerts({ diff --git a/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.test.ts b/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.test.ts index 9f335f8266b2..c9cc7fbefbfa 100644 --- a/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.test.ts +++ b/x-pack/plugins/alerting/server/alerts_client/lib/format_rule.test.ts @@ -61,6 +61,7 @@ describe('formatRule', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, ruleType, }) diff --git a/x-pack/plugins/alerting/server/alerts_client/types.ts b/x-pack/plugins/alerting/server/alerts_client/types.ts index 44690d588117..1de1c06f5e82 100644 --- a/x-pack/plugins/alerting/server/alerts_client/types.ts +++ b/x-pack/plugins/alerting/server/alerts_client/types.ts @@ -47,6 +47,7 @@ export interface AlertRuleData { revision: number; spaceId: string; tags: string[]; + alertDelay: number; } export interface AlertRule { @@ -111,12 +112,14 @@ export interface ProcessAndLogAlertsOpts { flappingSettings: RulesSettingsFlappingProperties; notifyOnActionGroupChange: boolean; maintenanceWindowIds: string[]; + alertDelay: number; } export interface ProcessAlertsOpts { flappingSettings: RulesSettingsFlappingProperties; notifyOnActionGroupChange: boolean; maintenanceWindowIds: string[]; + alertDelay: number; } export interface LogAlertsOpts { diff --git a/x-pack/plugins/alerting/server/alerts_service/alerts_service.test.ts b/x-pack/plugins/alerting/server/alerts_service/alerts_service.test.ts index b73f671ab069..def19570f7e0 100644 --- a/x-pack/plugins/alerting/server/alerts_service/alerts_service.test.ts +++ b/x-pack/plugins/alerting/server/alerts_service/alerts_service.test.ts @@ -1475,6 +1475,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }); @@ -1495,6 +1496,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, kibanaVersion: '8.8.0', }); @@ -1528,6 +1530,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }); @@ -1576,6 +1579,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }); @@ -1610,6 +1614,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, kibanaVersion: '8.8.0', }); @@ -1674,6 +1679,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }), alertsService.createAlertsClient({ @@ -1691,6 +1697,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }), ]); @@ -1725,6 +1732,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, kibanaVersion: '8.8.0', }); @@ -1781,6 +1789,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }); @@ -1801,6 +1810,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, kibanaVersion: '8.8.0', }); @@ -1865,6 +1875,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }); }; @@ -1892,6 +1903,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, kibanaVersion: '8.8.0', }); @@ -1961,6 +1973,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }); }; @@ -2026,6 +2039,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }); @@ -2091,6 +2105,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }); @@ -2154,6 +2169,7 @@ describe('Alerts Service', () => { revision: 0, spaceId: 'default', tags: ['rule-', '-tags'], + alertDelay: 0, }, }); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts index 44a89e05992f..9d1823381d17 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/create/schemas/create_rule_data_schema.ts @@ -7,11 +7,7 @@ import { schema } from '@kbn/config-schema'; import { validateDuration } from '../../../validation'; -import { - notifyWhenSchema, - actionAlertsFilterSchema, - notificationDelaySchema, -} from '../../../schemas'; +import { notifyWhenSchema, actionAlertsFilterSchema, alertDelaySchema } from '../../../schemas'; export const createRuleDataSchema = schema.object({ name: schema.string(), @@ -44,5 +40,5 @@ export const createRuleDataSchema = schema.object({ { defaultValue: [] } ), notifyWhen: schema.maybe(schema.nullable(notifyWhenSchema)), - notificationDelay: schema.maybe(notificationDelaySchema), + alertDelay: schema.maybe(alertDelaySchema), }); diff --git a/x-pack/plugins/alerting/server/application/rule/methods/create/types/create_rule_data.ts b/x-pack/plugins/alerting/server/application/rule/methods/create/types/create_rule_data.ts index f99beda90e80..abee30ec9a52 100644 --- a/x-pack/plugins/alerting/server/application/rule/methods/create/types/create_rule_data.ts +++ b/x-pack/plugins/alerting/server/application/rule/methods/create/types/create_rule_data.ts @@ -22,5 +22,5 @@ export interface CreateRuleData { schedule: CreateRuleDataType['schedule']; actions: CreateRuleDataType['actions']; notifyWhen?: CreateRuleDataType['notifyWhen']; - notificationDelay?: CreateRuleDataType['notificationDelay']; + alertDelay?: CreateRuleDataType['alertDelay']; } diff --git a/x-pack/plugins/alerting/server/application/rule/schemas/index.ts b/x-pack/plugins/alerting/server/application/rule/schemas/index.ts index d039d190f1e9..06645e90d7ba 100644 --- a/x-pack/plugins/alerting/server/application/rule/schemas/index.ts +++ b/x-pack/plugins/alerting/server/application/rule/schemas/index.ts @@ -13,7 +13,7 @@ export { monitoringSchema, ruleSchema, ruleDomainSchema, - notificationDelaySchema, + alertDelaySchema, } from './rule_schemas'; export { diff --git a/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts b/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts index b75a6e4f76aa..6041e475daf5 100644 --- a/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts +++ b/x-pack/plugins/alerting/server/application/rule/schemas/rule_schemas.ts @@ -132,7 +132,7 @@ export const snoozeScheduleSchema = schema.object({ skipRecurrences: schema.maybe(schema.arrayOf(schema.string())), }); -export const notificationDelaySchema = schema.object({ +export const alertDelaySchema = schema.object({ active: schema.number(), }); @@ -172,7 +172,7 @@ export const ruleDomainSchema = schema.object({ revision: schema.number(), running: schema.maybe(schema.nullable(schema.boolean())), viewInAppRelativeUrl: schema.maybe(schema.nullable(schema.string())), - notificationDelay: schema.maybe(notificationDelaySchema), + alertDelay: schema.maybe(alertDelaySchema), }); /** @@ -210,5 +210,5 @@ export const ruleSchema = schema.object({ revision: schema.number(), running: schema.maybe(schema.nullable(schema.boolean())), viewInAppRelativeUrl: schema.maybe(schema.nullable(schema.string())), - notificationDelay: schema.maybe(notificationDelaySchema), + alertDelay: schema.maybe(alertDelaySchema), }); diff --git a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts index ea331cec4fcc..9cc8131b1fa2 100644 --- a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts +++ b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_attributes_to_rule_domain.ts @@ -216,7 +216,7 @@ export const transformRuleAttributesToRuleDomain = ( revision: ruleDomain.revision, running: ruleDomain.running, viewInAppRelativeUrl: ruleDomain.viewInAppRelativeUrl, - notificationDelay: ruleDomain.notificationDelay, + alertDelay: ruleDomain.alertDelay, }; if (isPublic) { diff --git a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts index 2eb21c42587d..e527bd6f31df 100644 --- a/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts +++ b/x-pack/plugins/alerting/server/application/rule/transforms/transform_rule_domain_to_rule_attributes.ts @@ -68,6 +68,6 @@ export const transformRuleDomainToRuleAttributes = ( ...(rule.nextRun !== undefined ? { nextRun: rule.nextRun?.toISOString() || null } : {}), revision: rule.revision, ...(rule.running !== undefined ? { running: rule.running } : {}), - ...(rule.notificationDelay !== undefined ? { notificationDelay: rule.notificationDelay } : {}), + ...(rule.alertDelay !== undefined ? { alertDelay: rule.alertDelay } : {}), }; }; diff --git a/x-pack/plugins/alerting/server/application/rule/types/rule.ts b/x-pack/plugins/alerting/server/application/rule/types/rule.ts index 1a7e7e1d3711..f59056b38244 100644 --- a/x-pack/plugins/alerting/server/application/rule/types/rule.ts +++ b/x-pack/plugins/alerting/server/application/rule/types/rule.ts @@ -85,7 +85,7 @@ export interface Rule { revision: RuleSchemaType['revision']; running?: RuleSchemaType['running']; viewInAppRelativeUrl?: RuleSchemaType['viewInAppRelativeUrl']; - notificationDelay?: RuleSchemaType['notificationDelay']; + alertDelay?: RuleSchemaType['alertDelay']; } export interface RuleDomain { @@ -121,5 +121,5 @@ export interface RuleDomain { revision: RuleDomainSchemaType['revision']; running?: RuleDomainSchemaType['running']; viewInAppRelativeUrl?: RuleDomainSchemaType['viewInAppRelativeUrl']; - notificationDelay?: RuleSchemaType['notificationDelay']; + alertDelay?: RuleSchemaType['alertDelay']; } diff --git a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts index 316578149c5c..e047be1b9cdd 100644 --- a/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts +++ b/x-pack/plugins/alerting/server/data/rule/types/rule_attributes.ts @@ -142,7 +142,7 @@ interface RuleMetaAttributes { versionApiKeyLastmodified?: string; } -interface NotificationDelayAttributes { +interface AlertDelayAttributes { active: number; } @@ -178,5 +178,5 @@ export interface RuleAttributes { nextRun?: string | null; revision: number; running?: boolean | null; - notificationDelay?: NotificationDelayAttributes; + alertDelay?: AlertDelayAttributes; } diff --git a/x-pack/plugins/alerting/server/lib/get_alerts_for_notification.test.ts b/x-pack/plugins/alerting/server/lib/get_alerts_for_notification.test.ts index c1465d5b7a23..4656f4377f13 100644 --- a/x-pack/plugins/alerting/server/lib/get_alerts_for_notification.test.ts +++ b/x-pack/plugins/alerting/server/lib/get_alerts_for_notification.test.ts @@ -21,6 +21,7 @@ describe('getAlertsForNotification', () => { DEFAULT_FLAPPING_SETTINGS, true, 'default', + 0, { '1': alert1, }, @@ -89,6 +90,7 @@ describe('getAlertsForNotification', () => { DEFAULT_FLAPPING_SETTINGS, true, 'default', + 0, {}, {}, { @@ -222,6 +224,7 @@ describe('getAlertsForNotification', () => { DISABLE_FLAPPING_SETTINGS, true, 'default', + 0, {}, {}, { @@ -353,6 +356,7 @@ describe('getAlertsForNotification', () => { DEFAULT_FLAPPING_SETTINGS, false, 'default', + 0, {}, {}, { @@ -455,10 +459,11 @@ describe('getAlertsForNotification', () => { }); const alert2 = new Alert('2', { meta: { uuid: 'uuid-2' } }); - const { newAlerts, activeAlerts } = getAlertsForNotification( + const { newAlerts, activeAlerts, currentActiveAlerts } = getAlertsForNotification( DEFAULT_FLAPPING_SETTINGS, true, 'default', + 0, { '1': alert1, }, @@ -507,6 +512,30 @@ describe('getAlertsForNotification', () => { }, } `); + expect(currentActiveAlerts).toMatchInlineSnapshot(` + Object { + "1": Object { + "meta": Object { + "activeCount": 2, + "flappingHistory": Array [], + "maintenanceWindowIds": Array [], + "pendingRecoveredCount": 0, + "uuid": "uuid-1", + }, + "state": Object {}, + }, + "2": Object { + "meta": Object { + "activeCount": 1, + "flappingHistory": Array [], + "maintenanceWindowIds": Array [], + "pendingRecoveredCount": 0, + "uuid": "uuid-2", + }, + "state": Object {}, + }, + } + `); }); test('should reset activeCount for all recovered alerts', () => { @@ -517,6 +546,7 @@ describe('getAlertsForNotification', () => { DEFAULT_FLAPPING_SETTINGS, true, 'default', + 0, {}, {}, { @@ -574,4 +604,78 @@ describe('getAlertsForNotification', () => { } `); }); + + test('should remove the alert from newAlerts and should not return the alert in currentActiveAlerts if the activeCount is less than the rule alertDelay', () => { + const alert1 = new Alert('1', { + meta: { activeCount: 1, uuid: 'uuid-1' }, + }); + const alert2 = new Alert('2', { meta: { uuid: 'uuid-2' } }); + + const { newAlerts, activeAlerts, currentActiveAlerts } = getAlertsForNotification( + DEFAULT_FLAPPING_SETTINGS, + true, + 'default', + 5, + { + '1': alert1, + }, + { + '1': alert1, + '2': alert2, + }, + {}, + {} + ); + expect(newAlerts).toMatchInlineSnapshot(`Object {}`); + expect(activeAlerts).toMatchInlineSnapshot(` + Object { + "1": Object { + "meta": Object { + "activeCount": 2, + "flappingHistory": Array [], + "maintenanceWindowIds": Array [], + "pendingRecoveredCount": 0, + "uuid": "uuid-1", + }, + "state": Object {}, + }, + "2": Object { + "meta": Object { + "activeCount": 1, + "flappingHistory": Array [], + "maintenanceWindowIds": Array [], + "pendingRecoveredCount": 0, + "uuid": "uuid-2", + }, + "state": Object {}, + }, + } + `); + expect(currentActiveAlerts).toMatchInlineSnapshot(`Object {}`); + }); + + test('should update active alert to look like a new alert if the activeCount is equal to the rule alertDelay', () => { + const alert2 = new Alert('2', { meta: { uuid: 'uuid-2' } }); + + const { newAlerts, activeAlerts, currentActiveAlerts } = getAlertsForNotification( + DEFAULT_FLAPPING_SETTINGS, + true, + 'default', + 1, + {}, + { + '2': alert2, + }, + {}, + {} + ); + expect(newAlerts['2'].getState().duration).toBe('0'); + expect(newAlerts['2'].getState().start).toBeTruthy(); + + expect(activeAlerts['2'].getState().duration).toBe('0'); + expect(activeAlerts['2'].getState().start).toBeTruthy(); + + expect(currentActiveAlerts['2'].getState().duration).toBe('0'); + expect(currentActiveAlerts['2'].getState().start).toBeTruthy(); + }); }); diff --git a/x-pack/plugins/alerting/server/lib/get_alerts_for_notification.ts b/x-pack/plugins/alerting/server/lib/get_alerts_for_notification.ts index 63e95402549a..593d92b35383 100644 --- a/x-pack/plugins/alerting/server/lib/get_alerts_for_notification.ts +++ b/x-pack/plugins/alerting/server/lib/get_alerts_for_notification.ts @@ -19,10 +19,12 @@ export function getAlertsForNotification< flappingSettings: RulesSettingsFlappingProperties, notifyOnActionGroupChange: boolean, actionGroupId: string, + alertDelay: number, newAlerts: Record> = {}, activeAlerts: Record> = {}, recoveredAlerts: Record> = {}, - currentRecoveredAlerts: Record> = {} + currentRecoveredAlerts: Record> = {}, + startedAt?: string | null ) { const currentActiveAlerts: Record> = {}; @@ -30,7 +32,22 @@ export function getAlertsForNotification< const alert = activeAlerts[id]; alert.incrementActiveCount(); alert.resetPendingRecoveredCount(); - currentActiveAlerts[id] = alert; + // do not trigger an action notification if the number of consecutive + // active alerts is less than the rule alertDelay threshold + if (alert.getActiveCount() < alertDelay) { + // remove from new alerts + delete newAlerts[id]; + } else { + currentActiveAlerts[id] = alert; + // if the active count is equal to the alertDelay it is considered a new alert + if (alert.getActiveCount() === alertDelay) { + const currentTime = startedAt ?? new Date().toISOString(); + const state = alert.getState(); + // keep the state and update the start time and duration + alert.replaceState({ ...state, start: currentTime, duration: '0' }); + newAlerts[id] = alert; + } + } } for (const id of keys(currentRecoveredAlerts)) { diff --git a/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts b/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts index fcf92b386aaa..5dea295c40ed 100644 --- a/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts @@ -58,6 +58,6 @@ export const transformCreateBody = ( schedule: createBody.schedule, actions: transformCreateBodyActions(createBody.actions), ...(createBody.notify_when ? { notifyWhen: createBody.notify_when } : {}), - ...(createBody.notification_delay ? { notificationDelay: createBody.notification_delay } : {}), + ...(createBody.alert_delay ? { alertDelay: createBody.alert_delay } : {}), }; }; diff --git a/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts b/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts index 4f55401160ce..f4fdedfc6f43 100644 --- a/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts +++ b/x-pack/plugins/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts @@ -119,5 +119,5 @@ export const transformRuleToRuleResponse = ( ...(rule.viewInAppRelativeUrl !== undefined ? { view_in_app_relative_url: rule.viewInAppRelativeUrl } : {}), - ...(rule.notificationDelay !== undefined ? { notification_delay: rule.notificationDelay } : {}), + ...(rule.alertDelay !== undefined ? { alert_delay: rule.alertDelay } : {}), }); diff --git a/x-pack/plugins/alerting/server/saved_objects/schemas/raw_rule/v1.ts b/x-pack/plugins/alerting/server/saved_objects/schemas/raw_rule/v1.ts index 495c2493f2e4..e0641e9b275e 100644 --- a/x-pack/plugins/alerting/server/saved_objects/schemas/raw_rule/v1.ts +++ b/x-pack/plugins/alerting/server/saved_objects/schemas/raw_rule/v1.ts @@ -213,7 +213,7 @@ const rawRuleActionSchema = schema.object({ useAlertDataForTemplate: schema.maybe(schema.boolean()), }); -export const notificationDelaySchema = schema.object({ +export const alertDelaySchema = schema.object({ active: schema.number(), }); @@ -274,5 +274,5 @@ export const rawRuleSchema = schema.object({ ), params: schema.recordOf(schema.string(), schema.maybe(schema.any())), typeVersion: schema.maybe(schema.number()), - notificationDelay: schema.maybe(notificationDelaySchema), + alertDelay: schema.maybe(alertDelaySchema), }); diff --git a/x-pack/plugins/alerting/server/task_runner/execution_handler.test.ts b/x-pack/plugins/alerting/server/task_runner/execution_handler.test.ts index 8f5147ea4de3..a742afb152b1 100644 --- a/x-pack/plugins/alerting/server/task_runner/execution_handler.test.ts +++ b/x-pack/plugins/alerting/server/task_runner/execution_handler.test.ts @@ -2052,165 +2052,6 @@ describe('Execution Handler', () => { `); }); - test('does not schedule actions for alerts with activeCount less than the notificationDelay.active threshold', async () => { - const executionHandler = new ExecutionHandler( - generateExecutionParams({ - ...defaultExecutionParams, - rule: { - ...defaultExecutionParams.rule, - notificationDelay: { - active: 3, - }, - }, - }) - ); - - await executionHandler.run({ - ...generateAlert({ id: 1 }), - ...generateAlert({ id: 2, activeCount: 2 }), - }); - - expect(actionsClient.bulkEnqueueExecution).not.toHaveBeenCalled(); - expect(defaultExecutionParams.logger.debug).toHaveBeenCalledTimes(2); - - expect(defaultExecutionParams.logger.debug).toHaveBeenCalledWith( - 'no scheduling of action "1" for rule "1": the alert activeCount: 0 is less than the rule notificationDelay.active: 3 threshold.' - ); - expect(defaultExecutionParams.logger.debug).toHaveBeenCalledWith( - 'no scheduling of action "1" for rule "1": the alert activeCount: 2 is less than the rule notificationDelay.active: 3 threshold.' - ); - }); - - test('schedules actions for alerts with activeCount greater than or equal the notificationDelay.active threshold', async () => { - const executionHandler = new ExecutionHandler( - generateExecutionParams({ - ...defaultExecutionParams, - rule: { - ...defaultExecutionParams.rule, - notificationDelay: { - active: 3, - }, - }, - }) - ); - - await executionHandler.run({ - ...generateAlert({ id: 1, activeCount: 3 }), - ...generateAlert({ id: 2, activeCount: 4 }), - }); - - expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); - expect(actionsClient.bulkEnqueueExecution.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - Array [ - Object { - "actionTypeId": "test", - "apiKey": "MTIzOmFiYw==", - "consumer": "rule-consumer", - "executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28", - "id": "1", - "params": Object { - "alertVal": "My 1 name-of-alert test1 tag-A,tag-B 1 goes here", - "contextVal": "My goes here", - "foo": true, - "stateVal": "My goes here", - }, - "relatedSavedObjects": Array [ - Object { - "id": "1", - "namespace": "test1", - "type": "alert", - "typeId": "test", - }, - ], - "source": Object { - "source": Object { - "id": "1", - "type": "alert", - }, - "type": "SAVED_OBJECT", - }, - "spaceId": "test1", - }, - Object { - "actionTypeId": "test", - "apiKey": "MTIzOmFiYw==", - "consumer": "rule-consumer", - "executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28", - "id": "1", - "params": Object { - "alertVal": "My 1 name-of-alert test1 tag-A,tag-B 2 goes here", - "contextVal": "My goes here", - "foo": true, - "stateVal": "My goes here", - }, - "relatedSavedObjects": Array [ - Object { - "id": "1", - "namespace": "test1", - "type": "alert", - "typeId": "test", - }, - ], - "source": Object { - "source": Object { - "id": "1", - "type": "alert", - }, - "type": "SAVED_OBJECT", - }, - "spaceId": "test1", - }, - ], - ] - `); - }); - - test('schedules actions if notificationDelay.active threshold is not defined', async () => { - const executionHandler = new ExecutionHandler(generateExecutionParams()); - - await executionHandler.run({ - ...generateAlert({ id: 1, activeCount: 1 }), - }); - - expect(actionsClient.bulkEnqueueExecution).toHaveBeenCalledTimes(1); - expect(actionsClient.bulkEnqueueExecution.mock.calls[0]).toMatchInlineSnapshot(` - Array [ - Array [ - Object { - "actionTypeId": "test", - "apiKey": "MTIzOmFiYw==", - "consumer": "rule-consumer", - "executionId": "5f6aa57d-3e22-484e-bae8-cbed868f4d28", - "id": "1", - "params": Object { - "alertVal": "My 1 name-of-alert test1 tag-A,tag-B 1 goes here", - "contextVal": "My goes here", - "foo": true, - "stateVal": "My goes here", - }, - "relatedSavedObjects": Array [ - Object { - "id": "1", - "namespace": "test1", - "type": "alert", - "typeId": "test", - }, - ], - "source": Object { - "source": Object { - "id": "1", - "type": "alert", - }, - "type": "SAVED_OBJECT", - }, - "spaceId": "test1", - }, - ], - ] - `); - }); - describe('rule url', () => { const ruleWithUrl = { ...rule, diff --git a/x-pack/plugins/alerting/server/task_runner/execution_handler.ts b/x-pack/plugins/alerting/server/task_runner/execution_handler.ts index e118b4d327ce..ec690bb8ba0f 100644 --- a/x-pack/plugins/alerting/server/task_runner/execution_handler.ts +++ b/x-pack/plugins/alerting/server/task_runner/execution_handler.ts @@ -628,22 +628,6 @@ export class ExecutionHandler< continue; } - if ( - this.rule.notificationDelay && - alert.getActiveCount() < this.rule.notificationDelay.active - ) { - this.logger.debug( - `no scheduling of action "${action.id}" for rule "${ - this.taskInstance.params.alertId - }": the alert activeCount: ${alert.getActiveCount()} is less than the rule notificationDelay.active: ${ - this.rule.notificationDelay.active - } threshold.` - ); - continue; - } else { - alert.resetActiveCount(); - } - const actionGroup = this.getActionGroup(alert); if (!this.ruleTypeActionGroups!.has(actionGroup)) { diff --git a/x-pack/plugins/alerting/server/task_runner/fixtures.ts b/x-pack/plugins/alerting/server/task_runner/fixtures.ts index 3d647966414f..b2a984ea5768 100644 --- a/x-pack/plugins/alerting/server/task_runner/fixtures.ts +++ b/x-pack/plugins/alerting/server/task_runner/fixtures.ts @@ -454,7 +454,7 @@ export const generateAlertInstance = ( flapping: false, maintenanceWindowIds: maintenanceWindowIds || [], pendingRecoveredCount: 0, - activeCount: 0, + activeCount: 1, }, state: { bar: false, 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 d14d44010252..e4afa351d4f1 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 @@ -2954,7 +2954,7 @@ describe('Task Runner', () => { maintenanceWindowIds: [], flapping: false, pendingRecoveredCount: 0, - activeCount: 0, + activeCount: 1, }, state: { duration: '0', @@ -3125,7 +3125,7 @@ describe('Task Runner', () => { maintenanceWindowIds: [], flapping: false, pendingRecoveredCount: 0, - activeCount: 0, + activeCount: 1, }, state: { duration: '0', @@ -3143,7 +3143,7 @@ describe('Task Runner', () => { maintenanceWindowIds: [], flapping: false, pendingRecoveredCount: 0, - activeCount: 0, + activeCount: 1, }, state: { duration: '0', diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 208e46b88a1f..93f655965e92 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -257,6 +257,7 @@ export class TaskRunner< revision: rule.revision, spaceId, tags: rule.tags, + alertDelay: rule.alertDelay?.active ?? 0, }; } @@ -311,6 +312,7 @@ export class TaskRunner< muteAll, revision, snoozeSchedule, + alertDelay, } = rule; const { params: { alertId: ruleId, spaceId }, @@ -525,6 +527,7 @@ export class TaskRunner< notifyWhen, muteAll, snoozeSchedule, + alertDelay, }, logger: this.logger, flappingSettings, @@ -582,6 +585,7 @@ export class TaskRunner< notifyWhen === RuleNotifyWhen.CHANGE || some(actions, (action) => action.frequency?.notifyWhen === RuleNotifyWhen.CHANGE), maintenanceWindowIds: maintenanceWindowsWithoutScopedQueryIds, + alertDelay: alertDelay?.active ?? 0, }); }); 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 ebf81f5bf050..bd47acbbdb8c 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 @@ -302,6 +302,7 @@ describe('Task Runner', () => { ruleType: ruleTypeWithAlerts, namespace: 'default', rule: { + alertDelay: 0, consumer: 'bar', executionId: '5f6aa57d-3e22-484e-bae8-cbed868f4d28', id: '1', @@ -800,6 +801,7 @@ describe('Task Runner', () => { expect(alertsClientToUse.processAlerts).toHaveBeenCalledWith({ notifyOnActionGroupChange: false, + alertDelay: 0, flappingSettings: { enabled: true, lookBackWindow: 20, diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index ff16cfb593c2..eeb13576ce39 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -62,7 +62,7 @@ import { AlertsFilter, AlertsFilterTimeframe, RuleAlertData, - NotificationDelay, + AlertDelay, } from '../common'; import { PublicAlertFactory } from './alert/create_alert_factory'; import { RulesSettingsFlappingProperties } from '../common/rules_settings'; @@ -423,7 +423,6 @@ export type PublicRuleResultService = PublicLastRunSetters; export interface RawRuleLastRun extends SavedObjectAttributes, RuleLastRun {} export interface RawRuleMonitoring extends SavedObjectAttributes, RuleMonitoring {} -export interface RawNotificationDelay extends SavedObjectAttributes, NotificationDelay {} export interface RawRuleAlertsFilter extends AlertsFilter { query?: { @@ -500,7 +499,7 @@ export interface RawRule extends SavedObjectAttributes { nextRun?: string | null; revision: number; running?: boolean | null; - notificationDelay?: RawNotificationDelay; + alertDelay?: AlertDelay; } export type { DataStreamAdapter } from './alerts_service/lib/data_stream_adapter'; diff --git a/x-pack/plugins/cloud_integrations/cloud_full_story/public/plugin.ts b/x-pack/plugins/cloud_integrations/cloud_full_story/public/plugin.ts index 7636d38b681e..a9af52c9a6b3 100755 --- a/x-pack/plugins/cloud_integrations/cloud_full_story/public/plugin.ts +++ b/x-pack/plugins/cloud_integrations/cloud_full_story/public/plugin.ts @@ -77,7 +77,10 @@ export class CloudFullStoryPlugin implements Plugin { ...(pageVarsDebounceTime ? { pageVarsDebounceTimeMs: duration(pageVarsDebounceTime).asMilliseconds() } : {}), - // Load an Elastic-internally audited script. Ideally, it should be hosted on a CDN. + /** + * FIXME: this should use the {@link IStaticAssets['getPluginAssetHref']} + * function. Then we can avoid registering our own endpoint in this plugin. + */ scriptUrl: basePath.prepend( `/internal/cloud/${this.initializerContext.env.packageInfo.buildNum}/fullstory.js` ), diff --git a/x-pack/plugins/cloud_security_posture/common/types/rules/v4.ts b/x-pack/plugins/cloud_security_posture/common/types/rules/v4.ts index 78680bf111dc..33134eed32e3 100644 --- a/x-pack/plugins/cloud_security_posture/common/types/rules/v4.ts +++ b/x-pack/plugins/cloud_security_posture/common/types/rules/v4.ts @@ -120,6 +120,7 @@ export interface BenchmarkRuleSelectParams { export interface PageUrlParams { benchmarkId: BenchmarksCisId; benchmarkVersion: string; + ruleId?: string; } export const rulesToUpdate = schema.arrayOf( diff --git a/x-pack/plugins/cloud_security_posture/public/common/navigation/constants.ts b/x-pack/plugins/cloud_security_posture/public/common/navigation/constants.ts index 674a28f34e97..7390d2d846f1 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/navigation/constants.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/navigation/constants.ts @@ -63,7 +63,7 @@ export const cloudPosturePages: Record = { export const benchmarksNavigation: Record = { rules: { name: NAV_ITEMS_NAMES.RULES, - path: `${CLOUD_SECURITY_POSTURE_BASE_PATH}/benchmarks/:benchmarkId/:benchmarkVersion/rules`, + path: `${CLOUD_SECURITY_POSTURE_BASE_PATH}/benchmarks/:benchmarkId/:benchmarkVersion/rules/:ruleId?`, id: 'cloud_security_posture-benchmarks-rules', }, }; diff --git a/x-pack/plugins/cloud_security_posture/public/common/types.ts b/x-pack/plugins/cloud_security_posture/public/common/types.ts index d402ea293906..f2881c179888 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/types.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/types.ts @@ -17,6 +17,10 @@ export interface FindingsBaseURLQuery { * Filters that are part of the query but not persisted in the URL or in the Filter Manager */ nonPersistedFilters?: Filter[]; + /** + * Grouping component selection + */ + groupBy?: string[]; } export interface FindingsBaseESQueryConfig { diff --git a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_grouping/use_cloud_security_grouping.ts b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_grouping/use_cloud_security_grouping.ts index 05dc555bc3f7..cd45c28f90d8 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/cloud_security_grouping/use_cloud_security_grouping.ts +++ b/x-pack/plugins/cloud_security_posture/public/components/cloud_security_grouping/use_cloud_security_grouping.ts @@ -69,8 +69,11 @@ export const useCloudSecurityGrouping = ({ groupingId: groupingLocalStorageKey, maxGroupingLevels, title: groupingTitle, - onGroupChange: () => { + onGroupChange: ({ groupByFields }) => { setActivePageIndex(0); + setUrlQuery({ + groupBy: groupByFields, + }); }, }); @@ -85,6 +88,16 @@ export const useCloudSecurityGrouping = ({ setActivePageIndex(0); }, [urlQuery.filters, urlQuery.query]); + /** + * Set the selected groups from the URL query on the initial render + */ + useEffect(() => { + if (urlQuery.groupBy) { + grouping.setSelectedGroups(urlQuery.groupBy); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + // This is recommended by the grouping component to cover an edge case // where the selectedGroup has multiple values const uniqueValue = useMemo(() => `${selectedGroup}-${uuid.v4()}`, [selectedGroup]); diff --git a/x-pack/plugins/cloud_security_posture/public/components/column_name_with_tooltip.tsx b/x-pack/plugins/cloud_security_posture/public/components/column_name_with_tooltip.tsx index e0b3da860a1c..24f57dadea80 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/column_name_with_tooltip.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/column_name_with_tooltip.tsx @@ -15,14 +15,14 @@ export const ColumnNameWithTooltip = ({ tooltipContent: EuiToolTipProps['content']; columnName: ReactNode; }) => ( - - - - {columnName} - - - - - - + + + {columnName} + + + + + + + ); diff --git a/x-pack/plugins/cloud_security_posture/public/components/vulnerability_badges.tsx b/x-pack/plugins/cloud_security_posture/public/components/vulnerability_badges.tsx index ff8924833a29..25a77b332876 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/vulnerability_badges.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/vulnerability_badges.tsx @@ -24,8 +24,10 @@ interface SeverityStatusBadgeProps { export const CVSScoreBadge = ({ score, version }: CVSScoreBadgeProps) => { if (!score) return null; + const color = getCvsScoreColor(score); const versionDisplay = version ? `v${version.split('.')[0]}` : null; + return ( { + const { application } = useKibana().services; + + const ruleFlyoutLink = application.getUrlForApp('security', { + path: generatePath(benchmarksNavigation.rules.path, { + benchmarkVersion: findings.rule.benchmark.version.split('v')[1], // removing the v from the version + benchmarkId: findings.rule.benchmark.id, + ruleId: findings.rule.id, + }), + }); + switch (tab.id) { case 'overview': - return ; + return ; case 'rule': - return ; + return ; case 'table': return ; case 'json': diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/overview_tab.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/overview_tab.tsx index e6e5b1386652..42808c02f505 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/overview_tab.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/overview_tab.tsx @@ -13,6 +13,7 @@ import { EuiPanel, EuiSpacer, EuiText, + EuiToolTip, } from '@elastic/eui'; import React, { useMemo } from 'react'; import moment from 'moment'; @@ -36,12 +37,21 @@ import { FindingsDetectionRuleCounter } from './findings_detection_rule_counter' type Accordion = Pick & Pick; -const getDetailsList = (data: CspFinding, discoverIndexLink: string | undefined) => [ +const getDetailsList = (data: CspFinding, ruleFlyoutLink: string, discoverIndexLink?: string) => [ { title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.ruleNameTitle', { defaultMessage: 'Rule Name', }), - description: data.rule.name, + description: ( + + {data.rule.name} + + ), }, { title: i18n.translate('xpack.csp.findings.findingsFlyout.overviewTab.alertsTitle', { @@ -160,10 +170,14 @@ const getEvidenceList = ({ result }: CspFinding) => }, ].filter(truthy); -export const OverviewTab = ({ data }: { data: CspFinding }) => { - const { - services: { discover }, - } = useKibana(); +export const OverviewTab = ({ + data, + ruleFlyoutLink, +}: { + data: CspFinding; + ruleFlyoutLink: string; +}) => { + const { discover } = useKibana().services; const latestFindingsDataView = useLatestFindingsDataView(LATEST_FINDINGS_INDEX_PATTERN); const discoverIndexLink = useMemo( @@ -185,7 +199,7 @@ export const OverviewTab = ({ data }: { data: CspFinding }) => { defaultMessage: 'Details', }), id: 'detailsAccordion', - listItems: getDetailsList(data, discoverIndexLink), + listItems: getDetailsList(data, ruleFlyoutLink, discoverIndexLink), }, { initialIsOpen: true, @@ -206,7 +220,7 @@ export const OverviewTab = ({ data }: { data: CspFinding }) => { listItems: getEvidenceList(data), }, ].filter(truthy), - [data, discoverIndexLink, hasEvidence] + [data, discoverIndexLink, hasEvidence, ruleFlyoutLink] ); return ( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/rule_tab.tsx b/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/rule_tab.tsx index 816717943bdd..9b7b400a5819 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/rule_tab.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/findings_flyout/rule_tab.tsx @@ -5,18 +5,35 @@ * 2.0. */ -import { EuiBadge, EuiDescriptionList } from '@elastic/eui'; +import { EuiBadge, EuiDescriptionList, EuiLink, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; +import { FormattedMessage } from '@kbn/i18n-react'; import { CspFinding } from '../../../../common/schemas/csp_finding'; +import { RulesDetectionRuleCounter } from '../../rules/rules_detection_rule_counter'; import { CisKubernetesIcons, CspFlyoutMarkdown } from './findings_flyout'; -export const getRuleList = (rule: CspFinding['rule']) => [ +export const getRuleList = ( + rule: CspFinding['rule'], + ruleState = 'unmuted', + ruleFlyoutLink?: string +) => [ { title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.nameTitle', { defaultMessage: 'Name', }), - description: rule.name, + description: ruleFlyoutLink ? ( + + {rule.name} + + ) : ( + rule.name + ), }, { title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.descriptionTitle', { @@ -24,6 +41,20 @@ export const getRuleList = (rule: CspFinding['rule']) => [ }), description: {rule.description}, }, + { + title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.AlertsTitle', { + defaultMessage: 'Alerts', + }), + description: + ruleState === 'unmuted' ? ( + + ) : ( + + ), + }, { title: i18n.translate('xpack.csp.findings.findingsFlyout.ruleTab.tagsTitle', { defaultMessage: 'Tags', @@ -80,6 +111,6 @@ export const getRuleList = (rule: CspFinding['rule']) => [ : []), ]; -export const RuleTab = ({ data }: { data: CspFinding }) => ( - -); +export const RuleTab = ({ data, ruleFlyoutLink }: { data: CspFinding; ruleFlyoutLink: string }) => { + return ; +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_benchmark.ts b/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_benchmark.ts new file mode 100644 index 000000000000..f445761ed844 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/configurations/utils/create_detection_rule_from_benchmark.ts @@ -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 { HttpSetup } from '@kbn/core/public'; +import { CspBenchmarkRule } from '../../../../common/types/latest'; +import { + FINDINGS_INDEX_PATTERN, + LATEST_FINDINGS_RETENTION_POLICY, +} from '../../../../common/constants'; +import { createDetectionRule } from '../../../common/api/create_detection_rule'; +import { generateBenchmarkRuleTags } from '../../../../common/utils/detection_rules'; + +const DEFAULT_RULE_RISK_SCORE = 0; +const DEFAULT_RULE_SEVERITY = 'low'; +const DEFAULT_RULE_ENABLED = true; +const DEFAULT_RULE_AUTHOR = 'Elastic'; +const DEFAULT_RULE_LICENSE = 'Elastic License v2'; +const DEFAULT_MAX_ALERTS_PER_RULE = 100; +const ALERT_SUPPRESSION_FIELD = 'resource.id'; +const ALERT_TIMESTAMP_FIELD = 'event.ingested'; +const DEFAULT_INVESTIGATION_FIELDS = { + field_names: ['resource.name', 'resource.id', 'resource.type', 'resource.sub_type'], +}; + +enum AlertSuppressionMissingFieldsStrategy { + // per each document a separate alert will be created + DoNotSuppress = 'doNotSuppress', + // only one alert will be created per suppress by bucket + Suppress = 'suppress', +} + +const convertReferencesLinksToArray = (input: string | undefined) => { + if (!input) { + return []; + } + // Match all URLs in the input string using a regular expression + const matches = input.match(/(https?:\/\/\S+)/g); + + if (!matches) { + return []; + } + + // Remove the numbers and new lines + return matches.map((link) => link.replace(/^\d+\. /, '').replace(/\n/g, '')); +}; + +const generateFindingsRuleQuery = (benchmarkRule: CspBenchmarkRule['metadata']) => { + const currentTimestamp = new Date().toISOString(); + + return `rule.benchmark.rule_number: "${benchmarkRule.benchmark.rule_number}" + AND rule.benchmark.id: "${benchmarkRule.benchmark.id}" + AND result.evaluation: "failed" + AND event.ingested >= "${currentTimestamp}"`; +}; + +/* + * Creates a detection rule from a Benchmark rule + */ +export const createDetectionRuleFromBenchmark = async ( + http: HttpSetup, + benchmarkRule: CspBenchmarkRule['metadata'] +) => { + return await createDetectionRule({ + http, + rule: { + type: 'query', + language: 'kuery', + license: DEFAULT_RULE_LICENSE, + author: [DEFAULT_RULE_AUTHOR], + filters: [], + false_positives: [], + risk_score: DEFAULT_RULE_RISK_SCORE, + risk_score_mapping: [], + severity: DEFAULT_RULE_SEVERITY, + severity_mapping: [], + threat: [], + interval: '1h', + from: `now-${LATEST_FINDINGS_RETENTION_POLICY}`, + to: 'now', + max_signals: DEFAULT_MAX_ALERTS_PER_RULE, + timestamp_override: ALERT_TIMESTAMP_FIELD, + timestamp_override_fallback_disabled: false, + actions: [], + enabled: DEFAULT_RULE_ENABLED, + alert_suppression: { + group_by: [ALERT_SUPPRESSION_FIELD], + missing_fields_strategy: AlertSuppressionMissingFieldsStrategy.Suppress, + }, + index: [FINDINGS_INDEX_PATTERN], + query: generateFindingsRuleQuery(benchmarkRule), + references: convertReferencesLinksToArray(benchmarkRule.references), + name: benchmarkRule.name, + description: benchmarkRule.rationale, + tags: generateBenchmarkRuleTags(benchmarkRule), + investigation_fields: DEFAULT_INVESTIGATION_FIELDS, + note: benchmarkRule.remediation, + }, + }); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx index 62d1371b01f3..d50a351a0f1b 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx @@ -4,10 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import React, { useState, useMemo } from 'react'; +import React, { useState, useMemo, useEffect } from 'react'; import compareVersions from 'compare-versions'; import { EuiSpacer } from '@elastic/eui'; -import { useParams } from 'react-router-dom'; +import { useParams, useHistory, generatePath } from 'react-router-dom'; +import { benchmarksNavigation } from '../../common/navigation/constants'; import { buildRuleKey } from '../../../common/utils/rules_states'; import { extractErrorMessage } from '../../../common/utils/helpers'; import { RulesTable } from './rules_table'; @@ -41,7 +42,10 @@ interface RulesPageData { export type RulesState = RulesPageData & RulesQuery; -const getRulesPage = ( +const getPage = (data: CspBenchmarkRulesWithStates[], { page, perPage }: RulesQuery) => + data.slice(page * perPage, (page + 1) * perPage); + +const getRulesPageData = ( data: CspBenchmarkRulesWithStates[], status: string, error: unknown, @@ -59,17 +63,45 @@ const getRulesPage = ( }; }; -const getPage = (data: CspBenchmarkRulesWithStates[], { page, perPage }: RulesQuery) => - data.slice(page * perPage, (page + 1) * perPage); - const MAX_ITEMS_PER_PAGE = 10000; export const RulesContainer = () => { const params = useParams(); - const [selectedRuleId, setSelectedRuleId] = useState(null); + const history = useHistory(); const [enabledDisabledItemsFilter, setEnabledDisabledItemsFilter] = useState('no-filter'); const { pageSize, setPageSize } = usePageSize(LOCAL_STORAGE_PAGE_SIZE_RULES_KEY); + const navToRuleFlyout = (ruleId: string) => { + history.push( + generatePath(benchmarksNavigation.rules.path, { + benchmarkVersion: params.benchmarkVersion, + benchmarkId: params.benchmarkId, + ruleId, + }) + ); + }; + + const navToRulePage = () => { + history.push( + generatePath(benchmarksNavigation.rules.path, { + benchmarkVersion: params.benchmarkVersion, + benchmarkId: params.benchmarkId, + }) + ); + }; + + // We need to make this call without filters. this way the section list is always full + const allRules = useFindCspBenchmarkRule( + { + page: 1, + perPage: MAX_ITEMS_PER_PAGE, + sortField: 'metadata.benchmark.rule_number', + sortOrder: 'asc', + }, + params.benchmarkId, + params.benchmarkVersion + ); + const [rulesQuery, setRulesQuery] = useState({ section: undefined, ruleNumber: undefined, @@ -80,6 +112,30 @@ export const RulesContainer = () => { sortOrder: 'asc', }); + // This useEffect is in charge of auto paginating to the correct page of a rule from the url params + useEffect(() => { + const getPageByRuleId = () => { + if (params.ruleId && allRules.data?.items) { + const ruleIndex = allRules.data.items.findIndex( + (rule) => rule.metadata.id === params.ruleId + ); + + if (ruleIndex !== -1) { + // Calculate the page based on the rule index and page size + const rulePage = Math.floor(ruleIndex / pageSize); + return rulePage; + } + } + return 0; + }; + + setRulesQuery({ + ...rulesQuery, + page: getPageByRuleId(), + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [allRules.data?.items]); + const { data, status, error } = useFindCspBenchmarkRule( { section: rulesQuery.section, @@ -94,27 +150,9 @@ export const RulesContainer = () => { params.benchmarkVersion ); - // We need to make this call again without the filters. this way the section list is always full - const allRules = useFindCspBenchmarkRule( - { - page: 1, - perPage: MAX_ITEMS_PER_PAGE, - sortField: 'metadata.benchmark.rule_number', - sortOrder: 'asc', - }, - params.benchmarkId, - params.benchmarkVersion - ); - const rulesStates = useCspGetRulesStates(); const arrayRulesStates: RuleStateAttributes[] = Object.values(rulesStates.data || {}); - const filteredRulesStates: RuleStateAttributes[] = arrayRulesStates.filter( - (ruleState: RuleStateAttributes) => - ruleState.benchmark_id === params.benchmarkId && - ruleState.benchmark_version === 'v' + params.benchmarkVersion - ); - const rulesWithStates: CspBenchmarkRulesWithStates[] = useMemo(() => { if (!data) return []; @@ -162,7 +200,7 @@ export const RulesContainer = () => { const cleanedRuleNumberList = [...new Set(ruleNumberList)].sort(compareVersions); const rulesPageData = useMemo( - () => getRulesPage(filteredRulesWithStates, status, error, rulesQuery), + () => getRulesPageData(filteredRulesWithStates, status, error, rulesQuery), [filteredRulesWithStates, status, error, rulesQuery] ); @@ -175,13 +213,14 @@ export const RulesContainer = () => { const rulesFlyoutData: CspBenchmarkRulesWithStates = { ...{ state: - filteredRulesStates.find( - (filteredRuleState) => filteredRuleState.rule_id === selectedRuleId - )?.muted === true + arrayRulesStates.find((filteredRuleState) => filteredRuleState.rule_id === params.ruleId) + ?.muted === true ? 'muted' : 'unmuted', }, - ...{ metadata: rulesPageData.rules_map.get(selectedRuleId!)?.metadata! }, + ...{ + metadata: allRules.data?.items.find((rule) => rule.metadata.id === params.ruleId)?.metadata!, + }, }; return ( @@ -227,16 +266,16 @@ export const RulesContainer = () => { setPageSize(paginationQuery.perPage); setRulesQuery((currentQuery) => ({ ...currentQuery, ...paginationQuery })); }} - setSelectedRuleId={setSelectedRuleId} - selectedRuleId={selectedRuleId} + selectedRuleId={params.ruleId} + onRuleClick={navToRuleFlyout} refetchRulesStates={rulesStates.refetch} selectedRules={selectedRules} setSelectedRules={setSelectedRules} /> - {selectedRuleId && ( + {params.ruleId && rulesFlyoutData.metadata && ( setSelectedRuleId(null)} + onClose={navToRulePage} refetchRulesStates={rulesStates.refetch} /> )} diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_detection_rule_counter.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_detection_rule_counter.tsx new file mode 100644 index 000000000000..04b6a4ab8359 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_detection_rule_counter.tsx @@ -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 type { HttpSetup } from '@kbn/core/public'; +import React from 'react'; +import { CspBenchmarkRule } from '../../../common/types/latest'; +import { getFindingsDetectionRuleSearchTags } from '../../../common/utils/detection_rules'; +import { DetectionRuleCounter } from '../../components/detection_rule_counter'; +import { createDetectionRuleFromBenchmark } from '../configurations/utils/create_detection_rule_from_benchmark'; + +export const RulesDetectionRuleCounter = ({ + benchmarkRule, +}: { + benchmarkRule: CspBenchmarkRule['metadata']; +}) => { + const createBenchmarkRuleFn = async (http: HttpSetup) => + await createDetectionRuleFromBenchmark(http, benchmarkRule); + + return ( + + ); +}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx index dbfcb6df75a9..333f958de6fb 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx @@ -17,9 +17,12 @@ import { EuiFlexGroup, EuiSwitch, EuiFlyoutFooter, + EuiIcon, + EuiToolTip, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; import { CspBenchmarkRuleMetadata } from '../../../common/types/latest'; import { getRuleList } from '../configurations/findings_flyout/rule_tab'; import { getRemediationList } from '../configurations/findings_flyout/overview_tab'; @@ -73,6 +76,7 @@ export const RuleFlyout = ({ onClose, rule, refetchRulesStates }: RuleFlyoutProp await refetchRulesStates(); } }; + return ( @@ -144,9 +148,32 @@ const RuleOverviewTab = ({ const ruleState = (rule: CspBenchmarkRulesWithStates, switchRuleStates: () => Promise) => [ { - title: i18n.translate('xpack.csp.rules.rulesFlyout.ruleState', { - defaultMessage: 'Enabled', - }), + title: ( + + + + + + + + + + + ), description: ( <> & { setPagination(pagination: Pick): void; - setSelectedRuleId(id: string | null): void; - selectedRuleId: string | null; + onRuleClick: (ruleID: string) => void; + selectedRuleId?: string; refetchRulesStates: () => void; selectedRules: CspBenchmarkRulesWithStates[]; setSelectedRules: (rules: CspBenchmarkRulesWithStates[]) => void; @@ -42,7 +43,7 @@ type RulesTableProps = Pick< type GetColumnProps = Pick< RulesTableProps, - 'setSelectedRuleId' | 'refetchRulesStates' | 'selectedRules' | 'setSelectedRules' + 'onRuleClick' | 'refetchRulesStates' | 'selectedRules' | 'setSelectedRules' > & { postRequestChangeRulesStates: ( actionOnRule: 'mute' | 'unmute', @@ -59,7 +60,6 @@ type GetColumnProps = Pick< export const RulesTable = ({ setPagination, - setSelectedRuleId, perPage: pageSize, rules_page: items, page, @@ -70,6 +70,7 @@ export const RulesTable = ({ refetchRulesStates, selectedRules, setSelectedRules, + onRuleClick, onSortChange, }: RulesTableProps) => { const { euiTheme } = useEuiTheme(); @@ -133,7 +134,6 @@ export const RulesTable = ({ const columns = useMemo( () => getColumns({ - setSelectedRuleId, refetchRulesStates, postRequestChangeRulesStates, selectedRules, @@ -142,15 +142,16 @@ export const RulesTable = ({ setIsAllRulesSelectedThisPage, isAllRulesSelectedThisPage, isCurrentPageRulesASubset, + onRuleClick, }), [ - setSelectedRuleId, refetchRulesStates, postRequestChangeRulesStates, selectedRules, setSelectedRules, items, isAllRulesSelectedThisPage, + onRuleClick, ] ); @@ -173,7 +174,6 @@ export const RulesTable = ({ }; const getColumns = ({ - setSelectedRuleId, refetchRulesStates, postRequestChangeRulesStates, selectedRules, @@ -181,6 +181,7 @@ const getColumns = ({ items, isAllRulesSelectedThisPage, isCurrentPageRulesASubset, + onRuleClick, }: GetColumnProps): Array> => [ { field: 'action', @@ -255,7 +256,7 @@ const getColumns = ({ title={name} onClick={(e: React.MouseEvent) => { e.stopPropagation(); - setSelectedRuleId(rule.metadata.id); + onRuleClick(rule.metadata.id); }} data-test-subj={TEST_SUBJECTS.CSP_RULES_TABLE_ROW_ITEM_NAME} > @@ -272,9 +273,16 @@ const getColumns = ({ }, { field: 'metadata.name', - name: i18n.translate('xpack.csp.rules.rulesTable.mutedColumnLabel', { - defaultMessage: 'Enabled', - }), + name: ( + + ), align: 'right', width: '100px', truncateText: true, diff --git a/x-pack/plugins/ecs_data_quality_dashboard/kibana.jsonc b/x-pack/plugins/ecs_data_quality_dashboard/kibana.jsonc index 265018478306..5adbe3eeee83 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/kibana.jsonc +++ b/x-pack/plugins/ecs_data_quality_dashboard/kibana.jsonc @@ -1,7 +1,7 @@ { "type": "plugin", "id": "@kbn/ecs-data-quality-dashboard-plugin", - "owner": "@elastic/security-threat-hunting-investigations", + "owner": "@elastic/security-threat-hunting-explore", "description": "APIs used to assess the quality of data in Elasticsearch indexes", "plugin": { "id": "ecsDataQualityDashboard", diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/lib/data_stream/results_field_map.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/lib/data_stream/results_field_map.ts index 59f8ade6cb83..c0b929ec6deb 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/lib/data_stream/results_field_map.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/lib/data_stream/results_field_map.ts @@ -8,33 +8,23 @@ import type { FieldMap } from '@kbn/data-stream-adapter'; export const resultsFieldMap: FieldMap = { - 'meta.batchId': { type: 'keyword', required: true }, - 'meta.ecsVersion': { type: 'keyword', required: true }, - 'meta.errorCount': { type: 'long', required: true }, - 'meta.ilmPhase': { type: 'keyword', required: true }, - 'meta.indexId': { type: 'keyword', required: true }, - 'meta.indexName': { type: 'keyword', required: true }, - 'meta.isCheckAll': { type: 'boolean', required: true }, - 'meta.numberOfDocuments': { type: 'long', required: true }, - 'meta.numberOfFields': { type: 'long', required: true }, - 'meta.numberOfIncompatibleFields': { type: 'long', required: true }, - 'meta.numberOfEcsFields': { type: 'long', required: true }, - 'meta.numberOfCustomFields': { type: 'long', required: true }, - 'meta.numberOfIndices': { type: 'long', required: true }, - 'meta.numberOfIndicesChecked': { type: 'long', required: true }, - 'meta.numberOfSameFamily': { type: 'long', required: true }, - 'meta.sameFamilyFields': { type: 'keyword', required: true, array: true }, - 'meta.sizeInBytes': { type: 'long', required: true }, - 'meta.timeConsumedMs': { type: 'long', required: true }, - 'meta.unallowedMappingFields': { type: 'keyword', required: true, array: true }, - 'meta.unallowedValueFields': { type: 'keyword', required: true, array: true }, - 'rollup.docsCount': { type: 'long', required: true }, - 'rollup.error': { type: 'text', required: false }, - 'rollup.ilmExplainPhaseCounts': { type: 'object', required: false }, - 'rollup.indices': { type: 'long', required: true }, - 'rollup.pattern': { type: 'keyword', required: true }, - 'rollup.sizeInBytes': { type: 'long', required: true }, - 'rollup.ilmExplain': { type: 'object', required: true, array: true }, - 'rollup.stats': { type: 'object', required: true, array: true }, - 'rollup.results': { type: 'object', required: true, array: true }, + batchId: { type: 'keyword', required: true }, + indexName: { type: 'keyword', required: true }, + isCheckAll: { type: 'boolean', required: true }, + checkedAt: { type: 'date', required: true }, + docsCount: { type: 'long', required: true }, + totalFieldCount: { type: 'long', required: true }, + ecsFieldCount: { type: 'long', required: true }, + customFieldCount: { type: 'long', required: true }, + incompatibleFieldCount: { type: 'long', required: true }, + sameFamilyFieldCount: { type: 'long', required: true }, + sameFamilyFields: { type: 'keyword', required: true, array: true }, + unallowedMappingFields: { type: 'keyword', required: true, array: true }, + unallowedValueFields: { type: 'keyword', required: true, array: true }, + sizeInBytes: { type: 'long', required: true }, + ilmPhase: { type: 'keyword', required: true }, + markdownComments: { type: 'text', required: true, array: true }, + ecsVersion: { type: 'keyword', required: true }, + indexId: { type: 'keyword', required: true }, + error: { type: 'text', required: false }, }; diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/plugin.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/plugin.ts index 19c6f1247969..cb6fe9da7c27 100755 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/plugin.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/plugin.ts @@ -48,14 +48,13 @@ export class EcsDataQualityDashboardPlugin public setup(core: CoreSetup, plugins: PluginSetupDependencies) { this.logger.debug('ecsDataQualityDashboard: Setup'); - // TODO: Uncomment https://github.com/elastic/kibana/pull/173185#issuecomment-1908034302 - // this.resultsDataStream.install({ - // esClient: core - // .getStartServices() - // .then(([{ elasticsearch }]) => elasticsearch.client.asInternalUser), - // logger: this.logger, - // pluginStop$: this.pluginStop$, - // }); + this.resultsDataStream.install({ + esClient: core + .getStartServices() + .then(([{ elasticsearch }]) => elasticsearch.client.asInternalUser), + logger: this.logger, + pluginStop$: this.pluginStop$, + }); core.http.registerRouteHandlerContext< DataQualityDashboardRequestHandlerContext, diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_ilm_explain.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_ilm_explain.ts index 73282d11e3d7..31202adffed2 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_ilm_explain.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_ilm_explain.ts @@ -19,6 +19,7 @@ export const getILMExplainRoute = (router: IRouter, logger: Logger) => { .get({ path: GET_ILM_EXPLAIN, access: 'internal', + options: { tags: ['access:securitySolution'] }, }) .addVersion( { diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_index_mappings.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_index_mappings.ts index e593320933f7..f3c59ccf9f3e 100755 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_index_mappings.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_index_mappings.ts @@ -19,6 +19,7 @@ export const getIndexMappingsRoute = (router: IRouter, logger: Logger) => { .get({ path: GET_INDEX_MAPPINGS, access: 'internal', + options: { tags: ['access:securitySolution'] }, }) .addVersion( { diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_index_stats.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_index_stats.ts index cbaf7940a4b5..69d49b861110 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_index_stats.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/get_index_stats.ts @@ -20,6 +20,7 @@ export const getIndexStatsRoute = (router: IRouter, logger: Logger) => { .get({ path: GET_INDEX_STATS, access: 'internal', + options: { tags: ['access:securitySolution'] }, }) .addVersion( { diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/get_results.test.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/get_results.test.ts index 44f7a97abf0d..05a714a27275 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/get_results.test.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/get_results.test.ts @@ -12,19 +12,17 @@ import { requestContextMock } from '../../__mocks__/request_context'; import type { LatestAggResponseBucket } from './get_results'; import { getResultsRoute, getQuery } from './get_results'; import { loggerMock, type MockedLogger } from '@kbn/logging-mocks'; -import { resultBody, resultDocument } from './results.mock'; -import type { - SearchResponse, - SecurityHasPrivilegesResponse, -} from '@elastic/elasticsearch/lib/api/types'; +import { resultDocument } from './results.mock'; +import type { SearchResponse } from '@elastic/elasticsearch/lib/api/types'; import type { ResultDocument } from '../../schemas/result'; +import type { CheckIndicesPrivilegesParam } from './privileges'; const searchResponse = { aggregations: { latest: { buckets: [ { - key: 'logs-*', + key: resultDocument.indexName, latest_doc: { hits: { hits: [{ _source: resultDocument }] } }, }, ], @@ -35,8 +33,15 @@ const searchResponse = { Record >; -// TODO: https://github.com/elastic/kibana/pull/173185#issuecomment-1908034302 -describe.skip('getResultsRoute route', () => { +const mockCheckIndicesPrivileges = jest.fn(({ indices }: CheckIndicesPrivilegesParam) => + Promise.resolve(Object.fromEntries(indices.map((index) => [index, true]))) +); +jest.mock('./privileges', () => ({ + checkIndicesPrivileges: (params: CheckIndicesPrivilegesParam) => + mockCheckIndicesPrivileges(params), +})); + +describe('getResultsRoute route', () => { describe('querying', () => { let server: ReturnType; let { context } = requestContextMock.createTools(); @@ -45,7 +50,7 @@ describe.skip('getResultsRoute route', () => { const req = requestMock.create({ method: 'get', path: RESULTS_ROUTE_PATH, - query: { patterns: 'logs-*,alerts-*' }, + query: { pattern: 'logs-*' }, }); beforeEach(() => { @@ -56,9 +61,9 @@ describe.skip('getResultsRoute route', () => { ({ context } = requestContextMock.createTools()); - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResolvedValue({ - index: { 'logs-*': { all: true }, 'alerts-*': { all: true } }, - } as unknown as SecurityHasPrivilegesResponse); + context.core.elasticsearch.client.asInternalUser.indices.get.mockResolvedValue({ + [resultDocument.indexName]: {}, + }); getResultsRoute(server.router, logger); }); @@ -68,10 +73,13 @@ describe.skip('getResultsRoute route', () => { mockSearch.mockResolvedValueOnce(searchResponse); const response = await server.inject(req, requestContextMock.convertContext(context)); - expect(mockSearch).toHaveBeenCalled(); + expect(mockSearch).toHaveBeenCalledWith({ + index: expect.any(String), + ...getQuery([resultDocument.indexName]), + }); expect(response.status).toEqual(200); - expect(response.body).toEqual([{ '@timestamp': expect.any(Number), ...resultBody }]); + expect(response.body).toEqual([resultDocument]); }); it('handles results data stream error', async () => { @@ -99,7 +107,7 @@ describe.skip('getResultsRoute route', () => { }); }); - describe('request pattern authorization', () => { + describe('request indices authorization', () => { let server: ReturnType; let { context } = requestContextMock.createTools(); let logger: MockedLogger; @@ -107,7 +115,7 @@ describe.skip('getResultsRoute route', () => { const req = requestMock.create({ method: 'get', path: RESULTS_ROUTE_PATH, - query: { patterns: 'logs-*,alerts-*' }, + query: { pattern: 'logs-*' }, }); beforeEach(() => { @@ -120,54 +128,69 @@ describe.skip('getResultsRoute route', () => { context.core.elasticsearch.client.asInternalUser.search.mockResolvedValue(searchResponse); - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResolvedValue({ - index: { 'logs-*': { all: true }, 'alerts-*': { all: true } }, - } as unknown as SecurityHasPrivilegesResponse); + context.core.elasticsearch.client.asInternalUser.indices.get.mockResolvedValue({ + [resultDocument.indexName]: {}, + }); getResultsRoute(server.router, logger); }); - it('should authorize pattern', async () => { - const mockHasPrivileges = - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges; - mockHasPrivileges.mockResolvedValueOnce({ - index: { 'logs-*': { all: true }, 'alerts-*': { all: true } }, - } as unknown as SecurityHasPrivilegesResponse); + it('should authorize indices from pattern', async () => { + const mockGetIndices = context.core.elasticsearch.client.asInternalUser.indices.get; + mockGetIndices.mockResolvedValueOnce({ [resultDocument.indexName]: {} }); const response = await server.inject(req, requestContextMock.convertContext(context)); - expect(mockHasPrivileges).toHaveBeenCalledWith({ - index: [ - { names: ['logs-*', 'alerts-*'], privileges: ['all', 'read', 'view_index_metadata'] }, - ], - }); + expect(mockGetIndices).toHaveBeenCalledWith({ index: 'logs-*', features: 'aliases' }); + expect(mockCheckIndicesPrivileges).toHaveBeenCalledWith( + expect.objectContaining({ indices: [resultDocument.indexName] }) + ); expect(context.core.elasticsearch.client.asInternalUser.search).toHaveBeenCalled(); expect(response.status).toEqual(200); - expect(response.body).toEqual([{ '@timestamp': expect.any(Number), ...resultBody }]); + expect(response.body).toEqual([resultDocument]); }); - it('should search authorized patterns only', async () => { - const mockHasPrivileges = - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges; - mockHasPrivileges.mockResolvedValueOnce({ - index: { 'logs-*': { all: false }, 'alerts-*': { all: true } }, - } as unknown as SecurityHasPrivilegesResponse); + it('should authorize data streams from pattern', async () => { + const dataStreamName = 'test_data_stream_name'; + const resultIndexNameTwo = `${resultDocument.indexName}_2`; + const resultIndexNameThree = `${resultDocument.indexName}_3`; + const mockGetIndices = context.core.elasticsearch.client.asInternalUser.indices.get; + mockGetIndices.mockResolvedValueOnce({ + [resultDocument.indexName]: {}, + [resultIndexNameTwo]: { data_stream: dataStreamName }, + [resultIndexNameThree]: { data_stream: dataStreamName }, + }); const response = await server.inject(req, requestContextMock.convertContext(context)); + + expect(mockGetIndices).toHaveBeenCalledWith({ index: 'logs-*', features: 'aliases' }); + expect(mockCheckIndicesPrivileges).toHaveBeenCalledWith( + expect.objectContaining({ indices: [resultDocument.indexName, dataStreamName] }) + ); expect(context.core.elasticsearch.client.asInternalUser.search).toHaveBeenCalledWith({ index: expect.any(String), - ...getQuery(['alerts-*']), + ...getQuery([resultDocument.indexName, resultIndexNameTwo, resultIndexNameThree]), }); expect(response.status).toEqual(200); + expect(response.body).toEqual([resultDocument]); + }); + + it('should not search unknown indices', async () => { + const mockGetIndices = context.core.elasticsearch.client.asInternalUser.indices.get; + mockGetIndices.mockResolvedValueOnce({}); // empty object means no index is found + + const response = await server.inject(req, requestContextMock.convertContext(context)); + + expect(mockCheckIndicesPrivileges).not.toHaveBeenCalled(); + expect(context.core.elasticsearch.client.asInternalUser.search).not.toHaveBeenCalled(); + + expect(response.status).toEqual(200); + expect(response.body).toEqual([]); }); - it('should not search unauthorized patterns', async () => { - const mockHasPrivileges = - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges; - mockHasPrivileges.mockResolvedValueOnce({ - index: { 'logs-*': { all: false }, 'alerts-*': { all: false } }, - } as unknown as SecurityHasPrivilegesResponse); + it('should not search unauthorized indices', async () => { + mockCheckIndicesPrivileges.mockResolvedValueOnce({}); // empty object means no index is authorized const response = await server.inject(req, requestContextMock.convertContext(context)); expect(context.core.elasticsearch.client.asInternalUser.search).not.toHaveBeenCalled(); @@ -176,11 +199,19 @@ describe.skip('getResultsRoute route', () => { expect(response.body).toEqual([]); }); - it('handles pattern authorization error', async () => { + it('handles index discovery error', async () => { + const errorMessage = 'Error!'; + const mockGetIndices = context.core.elasticsearch.client.asInternalUser.indices.get; + mockGetIndices.mockRejectedValueOnce({ message: errorMessage }); + + const response = await server.inject(req, requestContextMock.convertContext(context)); + expect(response.status).toEqual(500); + expect(response.body).toEqual({ message: errorMessage, status_code: 500 }); + }); + + it('handles index authorization error', async () => { const errorMessage = 'Error!'; - const mockHasPrivileges = - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges; - mockHasPrivileges.mockRejectedValueOnce({ message: errorMessage }); + mockCheckIndicesPrivileges.mockRejectedValueOnce({ message: errorMessage }); const response = await server.inject(req, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/get_results.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/get_results.ts index 56729c7a40ab..6c410e88f362 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/get_results.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/get_results.ts @@ -11,20 +11,18 @@ import { RESULTS_ROUTE_PATH, INTERNAL_API_VERSION } from '../../../common/consta import { buildResponse } from '../../lib/build_response'; import { buildRouteValidation } from '../../schemas/common'; import { GetResultQuery } from '../../schemas/result'; -import type { Result, ResultDocument } from '../../schemas/result'; +import type { ResultDocument } from '../../schemas/result'; import { API_DEFAULT_ERROR_MESSAGE } from '../../translations'; import type { DataQualityDashboardRequestHandlerContext } from '../../types'; -import { createResultFromDocument } from './parser'; import { API_RESULTS_INDEX_NOT_AVAILABLE } from './translations'; +import { checkIndicesPrivileges } from './privileges'; -export const getQuery = (patterns: string[]) => ({ +export const getQuery = (indexName: string[]) => ({ size: 0, - query: { - bool: { filter: [{ terms: { 'rollup.pattern': patterns } }] }, - }, + query: { bool: { filter: [{ terms: { indexName } }] } }, aggs: { latest: { - terms: { field: 'rollup.pattern', size: 10000 }, // big enough to get all patterns, but under `index.max_terms_count` (default 65536) + terms: { field: 'indexName', size: 10000 }, // big enough to get all indexNames, but under `index.max_terms_count` (default 65536) aggs: { latest_doc: { top_hits: { size: 1, sort: [{ '@timestamp': { order: 'desc' } }] } } }, }, }, @@ -51,10 +49,6 @@ export const getResultsRoute = ( validate: { request: { query: buildRouteValidation(GetResultQuery) } }, }, async (context, request, response) => { - // TODO: https://github.com/elastic/kibana/pull/173185#issuecomment-1908034302 - return response.ok({ body: [] }); - - // eslint-disable-next-line no-unreachable const services = await context.resolve(['core', 'dataQualityDashboard']); const resp = buildResponse(response); @@ -70,38 +64,71 @@ export const getResultsRoute = ( } try { - // Confirm user has authorization for the requested patterns - const { patterns } = request.query; - const userEsClient = services.core.elasticsearch.client.asCurrentUser; - const privileges = await userEsClient.security.hasPrivileges({ - index: [ - { names: patterns.split(','), privileges: ['all', 'read', 'view_index_metadata'] }, - ], + const { client } = services.core.elasticsearch; + const { pattern } = request.query; + + // Discover all indices for the pattern using internal user + const indicesResponse = await client.asInternalUser.indices.get({ + index: pattern, + features: 'aliases', // omit 'settings' and 'mappings' to reduce response size }); - const authorizedPatterns = Object.keys(privileges.index).filter((pattern) => - Object.values(privileges.index[pattern]).some((v) => v === true) - ); - if (authorizedPatterns.length === 0) { + + // map data streams to their backing indices and collect indices to authorize + const indicesToAuthorize: string[] = []; + const dataStreamIndices: Record = {}; + Object.entries(indicesResponse).forEach(([indexName, { data_stream: dataStream }]) => { + if (dataStream) { + if (!dataStreamIndices[dataStream]) { + dataStreamIndices[dataStream] = []; + } + dataStreamIndices[dataStream].push(indexName); + } else { + indicesToAuthorize.push(indexName); + } + }); + indicesToAuthorize.push(...Object.keys(dataStreamIndices)); + if (indicesToAuthorize.length === 0) { return response.ok({ body: [] }); } - // Get the latest result of each pattern - const query = { index, ...getQuery(authorizedPatterns) }; - const internalEsClient = services.core.elasticsearch.client.asInternalUser; + // check privileges for indices or data streams + const hasIndexPrivileges = await checkIndicesPrivileges({ + client, + indices: indicesToAuthorize, + }); + + // filter out unauthorized indices, and expand data streams backing indices + const authorizedIndexNames = Object.entries(hasIndexPrivileges).reduce( + (acc, [indexName, authorized]) => { + if (authorized) { + if (dataStreamIndices[indexName]) { + acc.push(...dataStreamIndices[indexName]); + } else { + acc.push(indexName); + } + } + return acc; + }, + [] + ); + if (authorizedIndexNames.length === 0) { + return response.ok({ body: [] }); + } - const { aggregations } = await internalEsClient.search< + // Get the latest result for each indexName + const query = { index, ...getQuery(authorizedIndexNames) }; + const { aggregations } = await client.asInternalUser.search< ResultDocument, Record >(query); - const results: Result[] = - aggregations?.latest?.buckets.map((bucket) => - createResultFromDocument(bucket.latest_doc.hits.hits[0]._source) - ) ?? []; + const results: ResultDocument[] = + aggregations?.latest?.buckets.map((bucket) => bucket.latest_doc.hits.hits[0]._source) ?? + []; return response.ok({ body: results }); } catch (err) { - logger.error(JSON.stringify(err)); + logger.error(err.message); return resp.error({ body: err.message ?? API_DEFAULT_ERROR_MESSAGE, diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/parser.test.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/parser.test.ts deleted file mode 100644 index 56800801ffc8..000000000000 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/parser.test.ts +++ /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 { createDocumentFromResult, createResultFromDocument } from './parser'; -import { resultBody, resultDocument } from './results.mock'; - -describe('createDocumentFromResult', () => { - it('should create document from result', () => { - const document = createDocumentFromResult(resultBody); - expect(document).toEqual({ ...resultDocument, '@timestamp': expect.any(Number) }); - }); -}); - -describe('createResultFromDocument', () => { - it('should create document from result', () => { - const result = createResultFromDocument(resultDocument); - expect(result).toEqual({ ...resultBody, '@timestamp': expect.any(Number) }); - }); -}); diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/parser.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/parser.ts deleted file mode 100644 index 198d5522839e..000000000000 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/parser.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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import type { Result, ResultDocument, IndexArray, IndexObject } from '../../schemas/result'; - -export const createDocumentFromResult = (result: Result): ResultDocument => { - const { rollup } = result; - const document: ResultDocument = { - ...result, - '@timestamp': Date.now(), - rollup: { - ...rollup, - ilmExplain: indexObjectToIndexArray(rollup.ilmExplain), - stats: indexObjectToIndexArray(rollup.stats), - results: indexObjectToIndexArray(rollup.results), - }, - }; - - return document; -}; - -export const createResultFromDocument = (document: ResultDocument): Result => { - const { rollup } = document; - const result = { - ...document, - rollup: { - ...rollup, - ilmExplain: indexArrayToIndexObject(rollup.ilmExplain), - stats: indexArrayToIndexObject(rollup.stats), - results: indexArrayToIndexObject(rollup.results), - }, - }; - - return result; -}; - -// ES parses object keys containing `.` as nested dot-separated field names (e.g. `event.name`). -// we need to convert documents containing objects with "indexName" keys (e.g. `.index-name-checked`) -// to object arrays so they can be stored correctly, we keep the key in the `_indexName` field. -const indexObjectToIndexArray = (obj: IndexObject): IndexArray => - Object.entries(obj).map(([key, value]) => ({ ...value, _indexName: key })); - -// convert index arrays back to objects with indexName as key -const indexArrayToIndexObject = (arr: IndexArray): IndexObject => - Object.fromEntries(arr.map(({ _indexName, ...value }) => [_indexName, value])); diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/post_results.test.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/post_results.test.ts index 98eb67ecbaaa..f3175a737ee5 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/post_results.test.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/post_results.test.ts @@ -11,20 +11,29 @@ import { requestMock } from '../../__mocks__/request'; import { requestContextMock } from '../../__mocks__/request_context'; import { postResultsRoute } from './post_results'; import { loggerMock, type MockedLogger } from '@kbn/logging-mocks'; -import type { - SecurityHasPrivilegesResponse, - WriteResponseBase, -} from '@elastic/elasticsearch/lib/api/types'; -import { resultBody, resultDocument } from './results.mock'; - -// TODO: https://github.com/elastic/kibana/pull/173185#issuecomment-1908034302 -describe.skip('postResultsRoute route', () => { +import type { WriteResponseBase } from '@elastic/elasticsearch/lib/api/types'; +import { resultDocument } from './results.mock'; +import type { CheckIndicesPrivilegesParam } from './privileges'; + +const mockCheckIndicesPrivileges = jest.fn(({ indices }: CheckIndicesPrivilegesParam) => + Promise.resolve(Object.fromEntries(indices.map((index) => [index, true]))) +); +jest.mock('./privileges', () => ({ + checkIndicesPrivileges: (params: CheckIndicesPrivilegesParam) => + mockCheckIndicesPrivileges(params), +})); + +describe('postResultsRoute route', () => { describe('indexation', () => { let server: ReturnType; let { context } = requestContextMock.createTools(); let logger: MockedLogger; - const req = requestMock.create({ method: 'post', path: RESULTS_ROUTE_PATH, body: resultBody }); + const req = requestMock.create({ + method: 'post', + path: RESULTS_ROUTE_PATH, + body: resultDocument, + }); beforeEach(() => { jest.clearAllMocks(); @@ -34,10 +43,9 @@ describe.skip('postResultsRoute route', () => { ({ context } = requestContextMock.createTools()); - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResolvedValue({ - has_all_requested: true, - } as unknown as SecurityHasPrivilegesResponse); - + context.core.elasticsearch.client.asInternalUser.indices.get.mockResolvedValue({ + [resultDocument.indexName]: {}, + }); postResultsRoute(server.router, logger); }); @@ -80,12 +88,16 @@ describe.skip('postResultsRoute route', () => { }); }); - describe('request pattern authorization', () => { + describe('request index authorization', () => { let server: ReturnType; let { context } = requestContextMock.createTools(); let logger: MockedLogger; - const req = requestMock.create({ method: 'post', path: RESULTS_ROUTE_PATH, body: resultBody }); + const req = requestMock.create({ + method: 'post', + path: RESULTS_ROUTE_PATH, + body: resultDocument, + }); beforeEach(() => { jest.clearAllMocks(); @@ -95,6 +107,9 @@ describe.skip('postResultsRoute route', () => { ({ context } = requestContextMock.createTools()); + context.core.elasticsearch.client.asInternalUser.indices.get.mockResolvedValue({ + [resultDocument.indexName]: {}, + }); context.core.elasticsearch.client.asInternalUser.index.mockResolvedValueOnce({ result: 'created', } as WriteResponseBase); @@ -102,42 +117,41 @@ describe.skip('postResultsRoute route', () => { postResultsRoute(server.router, logger); }); - it('should authorize pattern', async () => { - const mockHasPrivileges = - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges; - mockHasPrivileges.mockResolvedValueOnce({ - has_all_requested: true, - } as unknown as SecurityHasPrivilegesResponse); + it('should authorize index', async () => { + const response = await server.inject(req, requestContextMock.convertContext(context)); + expect(mockCheckIndicesPrivileges).toHaveBeenCalledWith({ + client: context.core.elasticsearch.client, + indices: [resultDocument.indexName], + }); + expect(context.core.elasticsearch.client.asInternalUser.index).toHaveBeenCalled(); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ result: 'created' }); + }); + + it('should authorize data stream', async () => { + const dataStreamName = 'test_data_stream_name'; + context.core.elasticsearch.client.asInternalUser.indices.get.mockResolvedValue({ + [resultDocument.indexName]: { data_stream: dataStreamName }, + }); + mockCheckIndicesPrivileges.mockResolvedValueOnce({ [dataStreamName]: true }); const response = await server.inject(req, requestContextMock.convertContext(context)); - expect(mockHasPrivileges).toHaveBeenCalledWith({ - index: [ - { - names: [resultBody.rollup.pattern], - privileges: ['all', 'read', 'view_index_metadata'], - }, - ], + expect(mockCheckIndicesPrivileges).toHaveBeenCalledWith({ + client: context.core.elasticsearch.client, + indices: [dataStreamName], }); expect(context.core.elasticsearch.client.asInternalUser.index).toHaveBeenCalled(); expect(response.status).toEqual(200); expect(response.body).toEqual({ result: 'created' }); }); - it('should not index unauthorized pattern', async () => { - const mockHasPrivileges = - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges; - mockHasPrivileges.mockResolvedValueOnce({ - has_all_requested: false, - } as unknown as SecurityHasPrivilegesResponse); + it('should not index unauthorized index', async () => { + mockCheckIndicesPrivileges.mockResolvedValueOnce({ [resultDocument.indexName]: false }); const response = await server.inject(req, requestContextMock.convertContext(context)); - expect(mockHasPrivileges).toHaveBeenCalledWith({ - index: [ - { - names: [resultBody.rollup.pattern], - privileges: ['all', 'read', 'view_index_metadata'], - }, - ], + expect(mockCheckIndicesPrivileges).toHaveBeenCalledWith({ + client: context.core.elasticsearch.client, + indices: [resultDocument.indexName], }); expect(context.core.elasticsearch.client.asInternalUser.index).not.toHaveBeenCalled(); @@ -145,11 +159,9 @@ describe.skip('postResultsRoute route', () => { expect(response.body).toEqual({ result: 'noop' }); }); - it('handles pattern authorization error', async () => { + it('handles index authorization error', async () => { const errorMessage = 'Error!'; - const mockHasPrivileges = - context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges; - mockHasPrivileges.mockRejectedValueOnce({ message: errorMessage }); + mockCheckIndicesPrivileges.mockRejectedValueOnce(Error(errorMessage)); const response = await server.inject(req, requestContextMock.convertContext(context)); expect(response.status).toEqual(500); @@ -170,7 +182,7 @@ describe.skip('postResultsRoute route', () => { const req = requestMock.create({ method: 'post', path: RESULTS_ROUTE_PATH, - body: { rollup: resultBody.rollup }, + body: { indexName: 'invalid body' }, }); const result = server.validate(req); diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/post_results.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/post_results.ts index 1162d23f1dfa..b4b2e4b219bc 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/post_results.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/post_results.ts @@ -13,7 +13,7 @@ import { buildRouteValidation } from '../../schemas/common'; import { PostResultBody } from '../../schemas/result'; import { API_DEFAULT_ERROR_MESSAGE } from '../../translations'; import type { DataQualityDashboardRequestHandlerContext } from '../../types'; -import { createDocumentFromResult } from './parser'; +import { checkIndicesPrivileges } from './privileges'; import { API_RESULTS_INDEX_NOT_AVAILABLE } from './translations'; export const postResultsRoute = ( @@ -32,10 +32,6 @@ export const postResultsRoute = ( validate: { request: { body: buildRouteValidation(PostResultBody) } }, }, async (context, request, response) => { - // TODO: https://github.com/elastic/kibana/pull/173185#issuecomment-1908034302 - return response.ok({ body: { result: 'noop' } }); - - // eslint-disable-next-line no-unreachable const services = await context.resolve(['core', 'dataQualityDashboard']); const resp = buildResponse(response); @@ -51,24 +47,35 @@ export const postResultsRoute = ( } try { - // Confirm user has authorization for the pattern payload - const { pattern } = request.body.rollup; - const userEsClient = services.core.elasticsearch.client.asCurrentUser; - const privileges = await userEsClient.security.hasPrivileges({ - index: [{ names: [pattern], privileges: ['all', 'read', 'view_index_metadata'] }], + const { client } = services.core.elasticsearch; + const { indexName } = request.body; + + // Confirm index exists and get the data stream name if it's a data stream + const indicesResponse = await client.asInternalUser.indices.get({ + index: indexName, + features: 'aliases', + }); + if (!indicesResponse[indexName]) { + return response.ok({ body: { result: 'noop' } }); + } + const indexOrDataStream = indicesResponse[indexName].data_stream ?? indexName; + + // Confirm user has authorization for the index name or data stream + const hasIndexPrivileges = await checkIndicesPrivileges({ + client, + indices: [indexOrDataStream], }); - if (!privileges.has_all_requested) { + if (!hasIndexPrivileges[indexOrDataStream]) { return response.ok({ body: { result: 'noop' } }); } // Index the result - const document = createDocumentFromResult(request.body); - const esClient = services.core.elasticsearch.client.asInternalUser; - const outcome = await esClient.index({ index, body: document }); + const body = { '@timestamp': Date.now(), ...request.body }; + const outcome = await client.asInternalUser.index({ index, body }); return response.ok({ body: { result: outcome.result } }); } catch (err) { - logger.error(JSON.stringify(err)); + logger.error(err.message); return resp.error({ body: err.message ?? API_DEFAULT_ERROR_MESSAGE, diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/privileges.test.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/privileges.test.ts new file mode 100644 index 000000000000..2833e3f030fd --- /dev/null +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/privileges.test.ts @@ -0,0 +1,129 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SecurityHasPrivilegesResponse } from '@elastic/elasticsearch/lib/api/types'; +import { requestContextMock } from '../../__mocks__/request_context'; +import { checkIndicesPrivileges } from './privileges'; + +// const mockHasPrivileges = +// context.core.elasticsearch.client.asCurrentUser.security.hasPrivileges; +// mockHasPrivileges.mockResolvedValueOnce({ +// has_all_requested: true, +// } as unknown as SecurityHasPrivilegesResponse); + +describe('checkIndicesPrivileges', () => { + const { context } = requestContextMock.createTools(); + const { client } = context.core.elasticsearch; + + beforeEach(() => { + client.asCurrentUser.security.hasPrivileges.mockResolvedValue({ + index: { + index1: { + read: true, + view_index_metadata: true, + manage: true, + monitor: true, + }, + index2: { + read: true, + view_index_metadata: true, + manage: true, + monitor: true, + }, + }, + } as unknown as SecurityHasPrivilegesResponse); + }); + + it('should return true if user has required privileges', async () => { + const result = await checkIndicesPrivileges({ client, indices: ['index1', 'index2'] }); + expect(result).toEqual({ index1: true, index2: true }); + }); + + it('should return true if only monitor privileges is missing', async () => { + client.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce({ + index: { + index1: { + read: true, + view_index_metadata: true, + manage: true, + monitor: false, + }, + }, + } as unknown as SecurityHasPrivilegesResponse); + const result = await checkIndicesPrivileges({ client, indices: ['index1'] }); + + expect(result).toEqual({ index1: true }); + }); + + it('should return true if only manage privileges is missing', async () => { + client.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce({ + index: { + index1: { + read: true, + view_index_metadata: true, + manage: false, + monitor: true, + }, + }, + } as unknown as SecurityHasPrivilegesResponse); + + const result = await checkIndicesPrivileges({ client, indices: ['index1'] }); + + expect(result).toEqual({ index1: true }); + }); + + it('should return false if both manage and monitor privileges is missing', async () => { + client.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce({ + index: { + index1: { + read: true, + view_index_metadata: true, + manage: false, + monitor: false, + }, + }, + } as unknown as SecurityHasPrivilegesResponse); + + const result = await checkIndicesPrivileges({ client, indices: ['index1'] }); + + expect(result).toEqual({ index1: false }); + }); + + it('should return false if only read privilege is missing', async () => { + client.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce({ + index: { + index1: { + read: false, + view_index_metadata: true, + manage: true, + monitor: true, + }, + }, + } as unknown as SecurityHasPrivilegesResponse); + + const result = await checkIndicesPrivileges({ client, indices: ['index1'] }); + + expect(result).toEqual({ index1: false }); + }); + + it('should return false if only view_index_metadata privilege is missing', async () => { + client.asCurrentUser.security.hasPrivileges.mockResolvedValueOnce({ + index: { + index1: { + read: true, + view_index_metadata: false, + manage: true, + monitor: true, + }, + }, + } as unknown as SecurityHasPrivilegesResponse); + + const result = await checkIndicesPrivileges({ client, indices: ['index1'] }); + + expect(result).toEqual({ index1: false }); + }); +}); diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/privileges.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/privileges.ts new file mode 100644 index 000000000000..ebda2f54e16e --- /dev/null +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/privileges.ts @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; + +export interface CheckIndicesPrivilegesParam { + client: IScopedClusterClient; + indices: string[]; +} + +/** + * Checks user has the required privileges to do a results check for the given indices. + * In order to be allowed to do a result check user needs: + * `read`, `view_index_metadata` and (`monitor` or `manage`) index privileges. + */ +export const checkIndicesPrivileges = async ({ client, indices }: CheckIndicesPrivilegesParam) => { + const privileges = await client.asCurrentUser.security.hasPrivileges({ + index: [{ names: indices, privileges: ['read', 'view_index_metadata', 'monitor', 'manage'] }], + }); + + const hasRequiredIndexPrivilege: Record = {}; + Object.entries(privileges.index).forEach( + ([indexName, { read, view_index_metadata: viewMetadata, monitor, manage }]) => { + hasRequiredIndexPrivilege[indexName] = read && viewMetadata && (monitor || manage); + } + ); + + return hasRequiredIndexPrivilege; +}; diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/results.mock.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/results.mock.ts index 1d0b15a4c24c..36ca3d2dc4e6 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/results.mock.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/routes/results/results.mock.ts @@ -8,195 +8,29 @@ import type { ResultDocument } from '../../schemas/result'; export const resultDocument: ResultDocument = { - '@timestamp': 1622767273955, - meta: { - batchId: 'aae36cd8-3825-4ad1-baa4-79bdf4617f8a', - ecsVersion: '8.6.1', - errorCount: 0, - ilmPhase: 'hot', - indexId: 'aO29KOwtQ3Snf-Pit5Wf4w', - indexName: '.internal.alerts-security.alerts-default-000001', - isCheckAll: true, - numberOfDocuments: 20, - numberOfFields: 1726, - numberOfIncompatibleFields: 2, - numberOfEcsFields: 1440, - numberOfCustomFields: 284, - numberOfIndices: 1, - numberOfIndicesChecked: 1, - numberOfSameFamily: 0, - sameFamilyFields: [], - sizeInBytes: 506471, - timeConsumedMs: 85, - unallowedMappingFields: [], - unallowedValueFields: ['event.category', 'event.outcome'], - }, - rollup: { - docsCount: 20, - error: null, - ilmExplain: [ - { - _indexName: '.internal.alerts-security.alerts-default-000001', - index: '.internal.alerts-security.alerts-default-000001', - managed: true, - policy: '.alerts-ilm-policy', - index_creation_date_millis: 1700757268526, - time_since_index_creation: '20.99d', - lifecycle_date_millis: 1700757268526, - age: '20.99d', - phase: 'hot', - phase_time_millis: 1700757270294, - action: 'rollover', - action_time_millis: 1700757273955, - step: 'check-rollover-ready', - step_time_millis: 1700757273955, - phase_execution: { - policy: '.alerts-ilm-policy', - phase_definition: { - min_age: '0ms', - actions: { - rollover: { - max_age: '30d', - max_primary_shard_size: '50gb', - }, - }, - }, - version: 1, - modified_date_in_millis: 1700757266723, - }, - }, - ], - ilmExplainPhaseCounts: { - hot: 1, - warm: 0, - cold: 0, - frozen: 0, - unmanaged: 0, - }, - indices: 1, - pattern: '.alerts-security.alerts-default', - results: [ - { - _indexName: '.internal.alerts-security.alerts-default-000001', - docsCount: 20, - error: null, - ilmPhase: 'hot', - incompatible: 2, - indexName: '.internal.alerts-security.alerts-default-000001', - markdownComments: [ - '### .internal.alerts-security.alerts-default-000001\n', - '| Result | Index | Docs | Incompatible fields | ILM Phase | Size |\n|--------|-------|------|---------------------|-----------|------|\n| ❌ | .internal.alerts-security.alerts-default-000001 | 20 (100,0 %) | 2 | `hot` | 494.6KB |\n\n', - '### **Incompatible fields** `2` **Same family** `0` **Custom fields** `284` **ECS compliant fields** `1440` **All fields** `1726`\n', - "#### 2 incompatible fields\n\nFields are incompatible with ECS when index mappings, or the values of the fields in the index, don't conform to the Elastic Common Schema (ECS), version 8.6.1.\n\n❌ Detection engine rules referencing these fields may not match them correctly\n❌ Pages may not display some events or fields due to unexpected field mappings or values\n❌ Mappings or field values that don't comply with ECS are not supported\n", - '\n\n#### Incompatible field values - .internal.alerts-security.alerts-default-000001\n\n\n| Field | ECS values (expected) | Document values (actual) | \n|-------|-----------------------|--------------------------|\n| event.category | `authentication`, `configuration`, `database`, `driver`, `email`, `file`, `host`, `iam`, `intrusion_detection`, `malware`, `network`, `package`, `process`, `registry`, `session`, `threat`, `vulnerability`, `web` | `behavior` (1) |\n| event.outcome | `failure`, `success`, `unknown` | `` (12) |\n\n', - ], - pattern: '.alerts-security.alerts-default', - sameFamily: 0, - }, - ], - sizeInBytes: 506471, - stats: [ - { - _indexName: '.internal.alerts-security.alerts-default-000001', - uuid: 'aO29KOwtQ3Snf-Pit5Wf4w', - health: 'green', - status: 'open', - }, - ], - }, -}; - -export const resultBody = { - meta: { - batchId: 'aae36cd8-3825-4ad1-baa4-79bdf4617f8a', - ecsVersion: '8.6.1', - errorCount: 0, - ilmPhase: 'hot', - indexId: 'aO29KOwtQ3Snf-Pit5Wf4w', - indexName: '.internal.alerts-security.alerts-default-000001', - isCheckAll: true, - numberOfDocuments: 20, - numberOfFields: 1726, - numberOfIncompatibleFields: 2, - numberOfEcsFields: 1440, - numberOfCustomFields: 284, - numberOfIndices: 1, - numberOfIndicesChecked: 1, - numberOfSameFamily: 0, - sameFamilyFields: [], - sizeInBytes: 506471, - timeConsumedMs: 85, - unallowedMappingFields: [], - unallowedValueFields: ['event.category', 'event.outcome'], - }, - rollup: { - docsCount: 20, - error: null, - ilmExplain: { - '.internal.alerts-security.alerts-default-000001': { - index: '.internal.alerts-security.alerts-default-000001', - managed: true, - policy: '.alerts-ilm-policy', - index_creation_date_millis: 1700757268526, - time_since_index_creation: '20.99d', - lifecycle_date_millis: 1700757268526, - age: '20.99d', - phase: 'hot', - phase_time_millis: 1700757270294, - action: 'rollover', - action_time_millis: 1700757273955, - step: 'check-rollover-ready', - step_time_millis: 1700757273955, - phase_execution: { - policy: '.alerts-ilm-policy', - phase_definition: { - min_age: '0ms', - actions: { - rollover: { - max_age: '30d', - max_primary_shard_size: '50gb', - }, - }, - }, - version: 1, - modified_date_in_millis: 1700757266723, - }, - }, - }, - ilmExplainPhaseCounts: { - hot: 1, - warm: 0, - cold: 0, - frozen: 0, - unmanaged: 0, - }, - indices: 1, - pattern: '.alerts-security.alerts-default', - results: { - '.internal.alerts-security.alerts-default-000001': { - docsCount: 20, - error: null, - ilmPhase: 'hot', - incompatible: 2, - indexName: '.internal.alerts-security.alerts-default-000001', - markdownComments: [ - '### .internal.alerts-security.alerts-default-000001\n', - '| Result | Index | Docs | Incompatible fields | ILM Phase | Size |\n|--------|-------|------|---------------------|-----------|------|\n| ❌ | .internal.alerts-security.alerts-default-000001 | 20 (100,0 %) | 2 | `hot` | 494.6KB |\n\n', - '### **Incompatible fields** `2` **Same family** `0` **Custom fields** `284` **ECS compliant fields** `1440` **All fields** `1726`\n', - "#### 2 incompatible fields\n\nFields are incompatible with ECS when index mappings, or the values of the fields in the index, don't conform to the Elastic Common Schema (ECS), version 8.6.1.\n\n❌ Detection engine rules referencing these fields may not match them correctly\n❌ Pages may not display some events or fields due to unexpected field mappings or values\n❌ Mappings or field values that don't comply with ECS are not supported\n", - '\n\n#### Incompatible field values - .internal.alerts-security.alerts-default-000001\n\n\n| Field | ECS values (expected) | Document values (actual) | \n|-------|-----------------------|--------------------------|\n| event.category | `authentication`, `configuration`, `database`, `driver`, `email`, `file`, `host`, `iam`, `intrusion_detection`, `malware`, `network`, `package`, `process`, `registry`, `session`, `threat`, `vulnerability`, `web` | `behavior` (1) |\n| event.outcome | `failure`, `success`, `unknown` | `` (12) |\n\n', - ], - pattern: '.alerts-security.alerts-default', - sameFamily: 0, - }, - }, - sizeInBytes: 506471, - stats: { - '.internal.alerts-security.alerts-default-000001': { - uuid: 'aO29KOwtQ3Snf-Pit5Wf4w', - health: 'green', - status: 'open', - }, - }, - }, + batchId: '33d95427-1fd3-43c3-bdeb-74324533a31e', + indexName: '.ds-logs-endpoint.alerts-default-2023.11.23-000001', + isCheckAll: false, + checkedAt: 1706526408000, + docsCount: 100, + totalFieldCount: 1582, + ecsFieldCount: 677, + customFieldCount: 904, + incompatibleFieldCount: 1, + sameFamilyFieldCount: 0, + sameFamilyFields: [], + unallowedMappingFields: [], + unallowedValueFields: ['event.category'], + sizeInBytes: 173796, + ilmPhase: 'hot', + markdownComments: [ + '### .ds-logs-endpoint.alerts-default-2023.11.23-000001\n', + '| Result | Index | Docs | Incompatible fields | ILM Phase | Size |\n|--------|-------|------|---------------------|-----------|------|\n| ❌ | .ds-logs-endpoint.alerts-default-2023.11.23-000001 | 100 (64,1 %) | 1 | `hot` | 274.6KB |\n\n', + '### **Incompatible fields** `1` **Same family** `0` **Custom fields** `904` **ECS compliant fields** `677` **All fields** `1582`\n', + "#### 1 incompatible field\n\nFields are incompatible with ECS when index mappings, or the values of the fields in the index, don't conform to the Elastic Common Schema (ECS), version 8.6.1.\n\n❌ Detection engine rules referencing these fields may not match them correctly\n❌ Pages may not display some events or fields due to unexpected field mappings or values\n❌ Mappings or field values that don't comply with ECS are not supported\n", + '\n\n#### Incompatible field values - .ds-logs-endpoint.alerts-default-2023.11.23-000001\n\n\n| Field | ECS values (expected) | Document values (actual) | \n|-------|-----------------------|--------------------------|\n| event.category | `authentication`, `configuration`, `database`, `driver`, `email`, `file`, `host`, `iam`, `intrusion_detection`, `malware`, `network`, `package`, `process`, `registry`, `session`, `threat`, `vulnerability`, `web` | `behavior` (6) |\n\n', + ], + ecsVersion: '8.6.1', + indexId: 'PMhntcuPQ_yhPoNsXiM_hg', + error: null, }; diff --git a/x-pack/plugins/ecs_data_quality_dashboard/server/schemas/result.ts b/x-pack/plugins/ecs_data_quality_dashboard/server/schemas/result.ts index 09851c9b8dc8..69387ea6fd8c 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/server/schemas/result.ts +++ b/x-pack/plugins/ecs_data_quality_dashboard/server/schemas/result.ts @@ -7,64 +7,30 @@ import * as t from 'io-ts'; -export const ResultMeta = t.type({ +export const ResultDocument = t.type({ batchId: t.string, - ecsVersion: t.string, - errorCount: t.number, - ilmPhase: t.string, - indexId: t.string, indexName: t.string, isCheckAll: t.boolean, - numberOfDocuments: t.number, - numberOfFields: t.number, - numberOfIncompatibleFields: t.number, - numberOfEcsFields: t.number, - numberOfCustomFields: t.number, - numberOfIndices: t.number, - numberOfIndicesChecked: t.number, - numberOfSameFamily: t.number, + checkedAt: t.number, + docsCount: t.number, + totalFieldCount: t.number, + ecsFieldCount: t.number, + customFieldCount: t.number, + incompatibleFieldCount: t.number, + sameFamilyFieldCount: t.number, sameFamilyFields: t.array(t.string), - sizeInBytes: t.number, - timeConsumedMs: t.number, unallowedMappingFields: t.array(t.string), unallowedValueFields: t.array(t.string), -}); -export type ResultMeta = t.TypeOf; - -export const ResultRollup = t.type({ - docsCount: t.number, - error: t.union([t.string, t.null]), - indices: t.number, - pattern: t.string, sizeInBytes: t.number, - ilmExplainPhaseCounts: t.record(t.string, t.number), - ilmExplain: t.record(t.string, t.UnknownRecord), - stats: t.record(t.string, t.UnknownRecord), - results: t.record(t.string, t.UnknownRecord), -}); -export type ResultRollup = t.TypeOf; - -export const Result = t.type({ - meta: ResultMeta, - rollup: ResultRollup, + ilmPhase: t.string, + markdownComments: t.array(t.string), + ecsVersion: t.string, + indexId: t.string, + error: t.union([t.string, t.null]), }); -export type Result = t.TypeOf; - -export type IndexArray = Array<{ _indexName: string } & Record>; -export type IndexObject = Record>; +export type ResultDocument = t.TypeOf; -export type ResultDocument = Omit & { - '@timestamp': number; - rollup: Omit & { - stats: IndexArray; - results: IndexArray; - ilmExplain: IndexArray; - }; -}; +export const PostResultBody = ResultDocument; -// Routes validation schemas - -export const GetResultQuery = t.type({ patterns: t.string }); +export const GetResultQuery = t.type({ pattern: t.string }); export type GetResultQuery = t.TypeOf; - -export const PostResultBody = Result; diff --git a/x-pack/plugins/ecs_data_quality_dashboard/tsconfig.json b/x-pack/plugins/ecs_data_quality_dashboard/tsconfig.json index 04a7d2bf092f..b725beec802b 100644 --- a/x-pack/plugins/ecs_data_quality_dashboard/tsconfig.json +++ b/x-pack/plugins/ecs_data_quality_dashboard/tsconfig.json @@ -24,6 +24,7 @@ "@kbn/data-stream-adapter", "@kbn/spaces-plugin", "@kbn/core-elasticsearch-server-mocks", + "@kbn/core-elasticsearch-server", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/fetch_connector_by_id_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/fetch_connector_by_id_logic.ts new file mode 100644 index 000000000000..320760e49ee7 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/api/connector/fetch_connector_by_id_logic.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 { Connector } from '@kbn/search-connectors'; + +import { createApiLogic, Actions } from '../../../shared/api_logic/create_api_logic'; +import { HttpLogic } from '../../../shared/http'; + +export interface FetchConnectorByIdApiLogicArgs { + connectorId: string; +} +export interface FetchConnectorByIdApiLogicResponse { + connector: Connector | undefined; +} + +export const fetchConnectorById = async ({ + connectorId, +}: FetchConnectorByIdApiLogicArgs): Promise => { + const route = `/internal/enterprise_search/connectors/${connectorId}`; + const response = await HttpLogic.values.http.get(route); + return response; +}; + +export const FetchConnectorByIdApiLogic = createApiLogic( + ['fetch_connector_by_id_api_logic'], + fetchConnectorById +); + +export type FetchConnectorByIdApiLogicActions = Actions< + FetchConnectorByIdApiLogicArgs, + FetchConnectorByIdApiLogicResponse +>; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_detail.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_detail.tsx new file mode 100644 index 000000000000..a3f77406750e --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_detail.tsx @@ -0,0 +1,236 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect } from 'react'; +import { useParams } from 'react-router-dom'; + +import { useActions, useValues } from 'kea'; + +import { i18n } from '@kbn/i18n'; + +import { generateEncodedPath } from '../../../shared/encode_path_params'; +import { KibanaLogic } from '../../../shared/kibana'; +import { CONNECTOR_DETAIL_TAB_PATH } from '../../routes'; +import { baseBreadcrumbs } from '../connectors/connectors'; +import { EnterpriseSearchContentPageTemplate } from '../layout/page_template'; + +import { getHeaderActions } from '../search_index/components/header_actions/header_actions'; +import { ConnectorConfiguration } from '../search_index/connector/connector_configuration'; +import { ConnectorSchedulingComponent } from '../search_index/connector/connector_scheduling'; +import { ConnectorSyncRules } from '../search_index/connector/sync_rules/connector_rules'; +import { SearchIndexDocuments } from '../search_index/documents'; +import { SearchIndexIndexMappings } from '../search_index/index_mappings'; +import { SearchIndexPipelines } from '../search_index/pipelines/pipelines'; + +import { ConnectorViewLogic } from './connector_view_logic'; +import { ConnectorDetailOverview } from './overview'; + +export enum ConnectorDetailTabId { + // all indices + OVERVIEW = 'overview', + DOCUMENTS = 'documents', + INDEX_MAPPINGS = 'index_mappings', + PIPELINES = 'pipelines', + // connector indices + CONFIGURATION = 'configuration', + SYNC_RULES = 'sync_rules', + SCHEDULING = 'scheduling', +} + +export const ConnectorDetail: React.FC = () => { + const connectorId = decodeURIComponent(useParams<{ connectorId: string }>().connectorId); + const { hasFilteringFeature, isLoading, index, connector } = useValues(ConnectorViewLogic); + const { fetchConnector } = useActions(ConnectorViewLogic); + useEffect(() => { + fetchConnector({ connectorId }); + }, []); + + const { tabId = ConnectorDetailTabId.OVERVIEW } = useParams<{ + tabId?: string; + }>(); + + const { + productAccess: { hasAppSearchAccess }, + productFeatures: { hasDefaultIngestPipeline }, + } = useValues(KibanaLogic); + + const ALL_INDICES_TABS = [ + { + content: , + id: ConnectorDetailTabId.OVERVIEW, + isSelected: tabId === ConnectorDetailTabId.OVERVIEW, + label: i18n.translate( + 'xpack.enterpriseSearch.content.connectors.connectorDetail.overviewTabLabel', + { + defaultMessage: 'Overview', + } + ), + onClick: () => + KibanaLogic.values.navigateToUrl( + generateEncodedPath(CONNECTOR_DETAIL_TAB_PATH, { + connectorId, + tabId: ConnectorDetailTabId.OVERVIEW, + }) + ), + }, + { + content: , + disabled: !index, + id: ConnectorDetailTabId.DOCUMENTS, + isSelected: tabId === ConnectorDetailTabId.DOCUMENTS, + label: i18n.translate( + 'xpack.enterpriseSearch.content.connectors.connectorDetail.documentsTabLabel', + { + defaultMessage: 'Documents', + } + ), + onClick: () => + KibanaLogic.values.navigateToUrl( + generateEncodedPath(CONNECTOR_DETAIL_TAB_PATH, { + connectorId, + tabId: ConnectorDetailTabId.DOCUMENTS, + }) + ), + }, + { + content: , + disabled: !index, + id: ConnectorDetailTabId.INDEX_MAPPINGS, + isSelected: tabId === ConnectorDetailTabId.INDEX_MAPPINGS, + label: i18n.translate( + 'xpack.enterpriseSearch.content.connectors.connectorDetail.indexMappingsTabLabel', + { + defaultMessage: 'Index mappings', + } + ), + onClick: () => + KibanaLogic.values.navigateToUrl( + generateEncodedPath(CONNECTOR_DETAIL_TAB_PATH, { + connectorId, + tabId: ConnectorDetailTabId.INDEX_MAPPINGS, + }) + ), + }, + ]; + + const CONNECTOR_TABS = [ + { + content: , + id: ConnectorDetailTabId.CONFIGURATION, + isSelected: tabId === ConnectorDetailTabId.CONFIGURATION, + label: i18n.translate( + 'xpack.enterpriseSearch.content.connectors.connectorDetail.configurationTabLabel', + { + defaultMessage: 'Configuration', + } + ), + onClick: () => + KibanaLogic.values.navigateToUrl( + generateEncodedPath(CONNECTOR_DETAIL_TAB_PATH, { + connectorId, + tabId: ConnectorDetailTabId.CONFIGURATION, + }) + ), + }, + ...(hasFilteringFeature + ? [ + { + content: , + disabled: !index, + id: ConnectorDetailTabId.SYNC_RULES, + isSelected: tabId === ConnectorDetailTabId.SYNC_RULES, + label: i18n.translate( + 'xpack.enterpriseSearch.content.connectors.connectorDetail.syncRulesTabLabel', + { + defaultMessage: 'Sync rules', + } + ), + onClick: () => + KibanaLogic.values.navigateToUrl( + generateEncodedPath(CONNECTOR_DETAIL_TAB_PATH, { + connectorId, + tabId: ConnectorDetailTabId.SYNC_RULES, + }) + ), + }, + ] + : []), + { + content: , + disabled: !index, + id: ConnectorDetailTabId.SCHEDULING, + isSelected: tabId === ConnectorDetailTabId.SCHEDULING, + label: i18n.translate( + 'xpack.enterpriseSearch.content.connectors.connectorDetail.schedulingTabLabel', + { + defaultMessage: 'Scheduling', + } + ), + onClick: () => + KibanaLogic.values.navigateToUrl( + generateEncodedPath(CONNECTOR_DETAIL_TAB_PATH, { + connectorId, + tabId: ConnectorDetailTabId.SCHEDULING, + }) + ), + }, + ]; + + const PIPELINES_TAB = { + content: , + disabled: !index, + id: ConnectorDetailTabId.PIPELINES, + isSelected: tabId === ConnectorDetailTabId.PIPELINES, + label: i18n.translate( + 'xpack.enterpriseSearch.content.connectors.connectorDetail.pipelinesTabLabel', + { + defaultMessage: 'Pipelines', + } + ), + onClick: () => + KibanaLogic.values.navigateToUrl( + generateEncodedPath(CONNECTOR_DETAIL_TAB_PATH, { + connectorId, + tabId: ConnectorDetailTabId.PIPELINES, + }) + ), + }; + + interface TabMenuItem { + content: JSX.Element; + disabled?: boolean; + id: string; + label: string; + onClick?: () => void; + prepend?: React.ReactNode; + route?: string; + testSubj?: string; + } + + const tabs: TabMenuItem[] = [ + ...ALL_INDICES_TABS, + ...CONNECTOR_TABS, + ...(hasDefaultIngestPipeline ? [PIPELINES_TAB] : []), + ]; + + const selectedTab = tabs.find((tab) => tab.id === tabId); + + return ( + + {selectedTab?.content || null} + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_detail_router.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_detail_router.tsx new file mode 100644 index 000000000000..539d549f2bd5 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_detail_router.tsx @@ -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 React, { useEffect } from 'react'; + +import { useActions } from 'kea'; + +import { Routes, Route } from '@kbn/shared-ux-router'; + +import { CONNECTOR_DETAIL_PATH, CONNECTOR_DETAIL_TAB_PATH } from '../../routes'; + +import { IndexNameLogic } from '../search_index/index_name_logic'; + +import { IndexViewLogic } from '../search_index/index_view_logic'; + +import { ConnectorDetail } from './connector_detail'; +import { ConnectorViewLogic } from './connector_view_logic'; + +export const ConnectorDetailRouter: React.FC = () => { + const { stopFetchIndexPoll } = useActions(IndexViewLogic); + useEffect(() => { + const unmountName = IndexNameLogic.mount(); + const unmountView = ConnectorViewLogic.mount(); + const unmountIndexView = IndexViewLogic.mount(); + return () => { + stopFetchIndexPoll(); + unmountName(); + unmountView(); + unmountIndexView(); + }; + }, []); + return ( + + + + + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_stats.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_stats.tsx new file mode 100644 index 000000000000..89f75d979984 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_stats.tsx @@ -0,0 +1,235 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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, { ReactNode } from 'react'; + +import { + EuiBadge, + EuiFlexGrid, + EuiFlexGroup, + EuiFlexItem, + EuiHealth, + EuiIcon, + EuiSplitPanel, + EuiText, + EuiTitle, +} from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { Connector } from '@kbn/search-connectors'; + +import { ConnectorIndex } from '../../../../../common/types/indices'; + +import { generateEncodedPath } from '../../../shared/encode_path_params'; +import { EuiLinkTo } from '../../../shared/react_router_helpers'; +import { CONNECTOR_DETAIL_TAB_PATH } from '../../routes'; +import { + connectorStatusToColor, + connectorStatusToText, +} from '../../utils/connector_status_helpers'; + +import { CONNECTORS } from '../search_index/connector/constants'; + +import { ConnectorDetailTabId } from './connector_detail'; + +export interface ConnectorStatsProps { + connector: Connector; + indexData?: ConnectorIndex; +} + +export interface StatCardProps { + content: ReactNode; + footer: ReactNode; + title: string; +} + +export const StatCard: React.FC = ({ title, content, footer }) => { + return ( + + + + + +

{title}

+
+
+ {content} +
+
+ + {footer} + +
+ ); +}; + +export const ConnectorStats: React.FC = ({ connector, indexData }) => { + const connectorDefinition = CONNECTORS.find((c) => c.serviceType === connector.service_type); + return ( + + + + + + {connectorDefinition && connectorDefinition.icon && ( + + + + )} + + +

{connectorDefinition?.name ?? '-'}

+
+
+
+
+ + + {connectorStatusToText(connector?.status)} + + + + } + footer={ + + + + + + + + +

+ {i18n.translate( + 'xpack.enterpriseSearch.connectors.connectorStats.p.DocumentsLabel', + { + defaultMessage: '{documentAmount} Documents', + values: { + documentAmount: indexData?.total.docs.count ?? '-', + }, + } + )} +

+
+
+
+
+ + + + {i18n.translate( + 'xpack.enterpriseSearch.connectors.connectorStats.seeDocumentsTextLabel', + { + defaultMessage: 'See documents', + } + )} + + + +
+ } + /> +
+ + + + {connector.index_name} + + + + + + ) : ( + i18n.translate('xpack.enterpriseSearch.connectors.connectorStats.noIndex', { + defaultMessage: 'No index related', + }) + ) + } + footer={ + + + + + {i18n.translate( + 'xpack.enterpriseSearch.connectors.connectorStats.configureLink', + { + defaultMessage: 'Configure', + } + )} + + + + + } + /> + + + + + {connector.pipeline.name} + + + ) : ( + i18n.translate('xpack.enterpriseSearch.connectors.connectorStats.noPipelineText', { + defaultMessage: 'None', + }) + ) + } + footer={ + + + + + {i18n.translate( + 'xpack.enterpriseSearch.connectors.connectorStats.managePipelines', + { + defaultMessage: 'Manage pipelines', + } + )} + + + + + } + /> + +
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_view_logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_view_logic.ts new file mode 100644 index 000000000000..31e41eef9c96 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/connector_view_logic.ts @@ -0,0 +1,176 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { kea, MakeLogicType } from 'kea'; + +import { Connector, FeatureName, IngestPipelineParams } from '@kbn/search-connectors'; + +import { Status } from '../../../../../common/types/api'; + +import { + FetchConnectorByIdApiLogic, + FetchConnectorByIdApiLogicActions, +} from '../../api/connector/fetch_connector_by_id_logic'; + +import { FetchIndexActions, FetchIndexApiLogic } from '../../api/index/fetch_index_api_logic'; +import { ElasticsearchViewIndex, IngestionMethod, IngestionStatus } from '../../types'; +import { IndexNameActions, IndexNameLogic } from '../search_index/index_name_logic'; + +export interface ConnectorViewActions { + fetchConnector: FetchConnectorByIdApiLogicActions['makeRequest']; + fetchConnectorApiError: FetchConnectorByIdApiLogicActions['apiError']; + fetchConnectorApiSuccess: FetchConnectorByIdApiLogicActions['apiSuccess']; + fetchIndex: FetchIndexActions['makeRequest']; + fetchIndexApiError: FetchIndexActions['apiError']; + fetchIndexApiSuccess: FetchIndexActions['apiSuccess']; + setIndexName: IndexNameActions['setIndexName']; +} + +// TODO UPDATE +export interface ConnectorViewValues { + connector: Connector | undefined; + connectorData: typeof FetchConnectorByIdApiLogic.values.data; + connectorError: string | undefined; + connectorId: string | null; + connectorName: string | null; + error: string | undefined; + fetchConnectorApiStatus: Status; + fetchIndexApiStatus: Status; + hasAdvancedFilteringFeature: boolean; + hasBasicFilteringFeature: boolean; + hasDocumentLevelSecurityFeature: boolean; + hasFilteringFeature: boolean; + hasIncrementalSyncFeature: boolean; + htmlExtraction: boolean | undefined; + index: ElasticsearchViewIndex | undefined; + indexName: string; + ingestionMethod: IngestionMethod; + ingestionStatus: IngestionStatus; + isCanceling: boolean; + isHiddenIndex: boolean; + isLoading: boolean; + isSyncing: boolean; + isWaitingForSync: boolean; + lastUpdated: string | null; + pipelineData: IngestPipelineParams | undefined; + recheckIndexLoading: boolean; + syncTriggeredLocally: boolean; // holds local value after update so UI updates correctly +} + +export const ConnectorViewLogic = kea>({ + actions: {}, + connect: { + actions: [ + IndexNameLogic, + ['setIndexName'], + FetchConnectorByIdApiLogic, + [ + 'makeRequest as fetchConnector', + 'apiSuccess as fetchConnectorApiSuccess', + 'apiError as fetchConnectorApiError', + ], + FetchIndexApiLogic, + [ + 'makeRequest as fetchIndex', + 'apiSuccess as fetchIndexApiSuccess', + 'apiError as fetchIndexApiError', + ], + ], + values: [ + FetchConnectorByIdApiLogic, + ['status as fetchConnectorApiStatus', 'data as connectorData'], + FetchIndexApiLogic, + ['data as index', 'status as fetchIndexApiStatus'], + ], + }, + listeners: ({ actions, values }) => ({ + fetchConnectorApiSuccess: () => { + if (values.indexName) { + actions.fetchIndex({ indexName: values.indexName }); + actions.setIndexName(values.indexName); + } + }, + }), + path: ['enterprise_search', 'content', 'connector_view_logic'], + reducers: { + syncTriggeredLocally: [ + false, + { + fetchIndexApiSuccess: () => false, + startSyncApiSuccess: () => true, + }, + ], + }, + selectors: ({ selectors }) => ({ + connector: [ + () => [selectors.connectorData], + (connectorData) => { + return connectorData?.connector; + }, + ], + indexName: [ + () => [selectors.connector], + (connector: Connector | undefined) => { + return connector?.index_name || undefined; + }, + ], + isLoading: [ + () => [selectors.fetchConnectorApiStatus, selectors.fetchIndexApiStatus], + (fetchConnectorApiStatus: Status, fetchIndexApiStatus: Status) => + [Status.IDLE && Status.LOADING].includes(fetchConnectorApiStatus) || + [Status.IDLE && Status.LOADING].includes(fetchIndexApiStatus), + ], + connectorId: [() => [selectors.connector], (connector) => connector?.id], + connectorError: [ + () => [selectors.connector], + (connector: Connector | undefined) => connector?.error, + ], + error: [ + () => [selectors.connector], + (connector: Connector | undefined) => connector?.error || connector?.last_sync_error || null, + ], + hasAdvancedFilteringFeature: [ + () => [selectors.connector], + (connector?: Connector) => + connector?.features + ? connector.features[FeatureName.SYNC_RULES]?.advanced?.enabled ?? + connector.features[FeatureName.FILTERING_ADVANCED_CONFIG] + : false, + ], + hasBasicFilteringFeature: [ + () => [selectors.connector], + (connector?: Connector) => + connector?.features + ? connector.features[FeatureName.SYNC_RULES]?.basic?.enabled ?? + connector.features[FeatureName.FILTERING_RULES] + : false, + ], + hasDocumentLevelSecurityFeature: [ + () => [selectors.connector], + (connector?: Connector) => + connector?.features?.[FeatureName.DOCUMENT_LEVEL_SECURITY]?.enabled || false, + ], + hasFilteringFeature: [ + () => [selectors.hasAdvancedFilteringFeature, selectors.hasBasicFilteringFeature], + (advancedFeature: boolean, basicFeature: boolean) => advancedFeature || basicFeature, + ], + hasIncrementalSyncFeature: [ + () => [selectors.connector], + (connector?: Connector) => + connector?.features?.[FeatureName.INCREMENTAL_SYNC]?.enabled || false, + ], + htmlExtraction: [ + () => [selectors.connector], + (connector: Connector | undefined) => + connector?.configuration.extract_full_html?.value ?? undefined, + ], + pipelineData: [ + () => [selectors.connector], + (connector: Connector | undefined) => connector?.pipeline ?? undefined, + ], + }), +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.logic.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.logic.ts new file mode 100644 index 000000000000..790cd87f9b4e --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.logic.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { kea, MakeLogicType } from 'kea'; + +import { Status } from '../../../../../common/types/api'; +import { KibanaLogic } from '../../../shared/kibana'; + +import { + CachedFetchIndexApiLogic, + CachedFetchIndexApiLogicActions, +} from '../../api/index/cached_fetch_index_api_logic'; + +import { CONNECTORS_PATH } from '../../routes'; + +interface OverviewLogicActions { + apiError: CachedFetchIndexApiLogicActions['apiError']; +} + +interface OverviewLogicValues { + apiKey: string; + indexData: typeof CachedFetchIndexApiLogic.values.indexData; + isError: boolean; + isLoading: boolean; + isManageKeysPopoverOpen: boolean; + status: typeof CachedFetchIndexApiLogic.values.status; +} + +export const OverviewLogic = kea>({ + connect: { + actions: [CachedFetchIndexApiLogic, ['apiError']], + values: [CachedFetchIndexApiLogic, ['indexData', 'status']], + }, + listeners: () => ({ + apiError: async (_, breakpoint) => { + // show error for a second before navigating away + await breakpoint(1000); + KibanaLogic.values.navigateToUrl(CONNECTORS_PATH); + }, + }), + path: ['enterprise_search', 'connector_detail', 'overview'], + selectors: ({ selectors }) => ({ + isError: [() => [selectors.status], (status) => status === Status.ERROR], + }), +}); 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 new file mode 100644 index 000000000000..3e9a4af5ee3a --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/overview.tsx @@ -0,0 +1,114 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useActions, useValues } from 'kea'; + +import { EuiButton, EuiCallOut, EuiLink, EuiSpacer, EuiText } from '@elastic/eui'; + +import { i18n } from '@kbn/i18n'; + +import { FormattedMessage } from '@kbn/i18n-react'; + +import { docLinks } from '../../../shared/doc_links'; +import { KibanaLogic } from '../../../shared/kibana'; +import { isConnectorIndex } from '../../utils/indices'; + +import { ConvertConnectorLogic } from '../search_index/connector/native_connector_configuration/convert_connector_logic'; +import { SyncJobs } from '../search_index/sync_jobs/sync_jobs'; + +import { ConvertConnectorModal } from '../shared/convert_connector_modal/convert_connector_modal'; + +import { ConnectorStats } from './connector_stats'; +import { ConnectorViewLogic } from './connector_view_logic'; +import { OverviewLogic } from './overview.logic'; + +export const ConnectorDetailOverview: React.FC = () => { + const { indexData } = useValues(OverviewLogic); + const { connector } = useValues(ConnectorViewLogic); + const error = null; + const { isCloud } = useValues(KibanaLogic); + const { showModal } = useActions(ConvertConnectorLogic); + const { isModalVisible } = useValues(ConvertConnectorLogic); + + return ( + <> + + {isConnectorIndex(indexData) && error && ( + <> + + + {error} + + + + )} + {isConnectorIndex(indexData) && indexData.connector.is_native && !isCloud && ( + <> + {isModalVisible && } + + + +

+ + {i18n.translate( + 'xpack.enterpriseSearch.content.connectors.overview.nativeCloudCallout.connectorClient', + { defaultMessage: 'connector client' } + )} + + ), + }} + /> +

+
+ + showModal()}> + {i18n.translate( + 'xpack.enterpriseSearch.content.indices.connectors.overview.convertConnector.buttonLabel', + { defaultMessage: 'Convert connector' } + )} + +
+ + + )} + {isConnectorIndex(indexData) && connector && ( + + )} + {isConnectorIndex(indexData) && ( + <> + + + + )} + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors_table.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors_table.tsx index 2c675c362b00..f7ba555a3d2f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connectors/connectors_table.tsx @@ -27,7 +27,7 @@ import { Meta } from '../../../../../common/types/pagination'; import { generateEncodedPath } from '../../../shared/encode_path_params'; import { KibanaLogic } from '../../../shared/kibana'; import { EuiLinkTo } from '../../../shared/react_router_helpers/eui_components'; -import { SEARCH_INDEX_PATH } from '../../routes'; +import { CONNECTOR_DETAIL_PATH, SEARCH_INDEX_PATH } from '../../routes'; import { connectorStatusToColor, connectorStatusToText, @@ -59,13 +59,17 @@ export const ConnectorsTable: React.FC = ({ const { navigateToUrl } = useValues(KibanaLogic); const columns: Array> = [ { - field: 'name', name: i18n.translate( 'xpack.enterpriseSearch.content.connectors.connectorTable.columns.connectorName', { defaultMessage: 'Connector name', } ), + render: (connector: Connector) => ( + + {connector.name} + + ), width: '25%', }, { @@ -161,8 +165,8 @@ export const ConnectorsTable: React.FC = ({ ), onClick: (connector) => { navigateToUrl( - generateEncodedPath(SEARCH_INDEX_PATH, { - indexName: connector.index_name || '', + generateEncodedPath(CONNECTOR_DETAIL_PATH, { + connectorId: connector.id, }) ); }, diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx index 93566c21fe99..e338b7d1f193 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/connector/connector_configuration.tsx @@ -120,31 +120,10 @@ export const ConnectorConfiguration: React.FC = () => { { children: ( <> - - - {i18n.translate( - 'xpack.enterpriseSearch.content.indices.configurationConnector.connectorPackage.clientExamplesLink', - { defaultMessage: 'connector client examples' } - )} - - ), - }} - /> - - { title: i18n.translate( 'xpack.enterpriseSearch.content.indices.configurationConnector.steps.deployConnector.title', { - defaultMessage: 'Deploy connector', + defaultMessage: 'Deploy connector service', } ), titleSize: 'xs', @@ -270,7 +249,7 @@ export const ConnectorConfiguration: React.FC = () => { title: i18n.translate( 'xpack.enterpriseSearch.content.indices.configurationConnector.steps.enhance.title', { - defaultMessage: 'Enhance your connector client', + defaultMessage: 'Configure your connector client', } ), titleSize: 'xs', 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 53fbd691476c..cd99649bcc88 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 @@ -20,12 +20,14 @@ import { HttpLogic } from '../shared/http'; import { KibanaLogic } from '../shared/kibana'; import { VersionMismatchPage } from '../shared/version_mismatch'; +import { ConnectorDetailRouter } from './components/connector_detail/connector_detail_router'; import { Connectors } from './components/connectors/connectors'; import { NotFound } from './components/not_found'; import { SearchIndicesRouter } from './components/search_indices'; import { Settings } from './components/settings'; import { CONNECTORS_PATH, + CONNECTOR_DETAIL_PATH, CRAWLERS_PATH, ERROR_STATE_PATH, ROOT_PATH, @@ -77,6 +79,9 @@ export const EnterpriseSearchContentConfigured: React.FC + + + diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts index 9cf8628780a2..1b9445b7fa75 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/routes.ts @@ -34,3 +34,6 @@ export const ML_MANAGE_TRAINED_MODELS_PATH = '/app/ml/trained_models'; export const ML_NOTIFICATIONS_PATH = '/app/ml/notifications'; export const DEV_TOOLS_CONSOLE_PATH = '/app/dev_tools#/console'; + +export const CONNECTOR_DETAIL_PATH = `${CONNECTORS_PATH}/:connectorId`; +export const CONNECTOR_DETAIL_TAB_PATH = `${CONNECTOR_DETAIL_PATH}/:tabId`; 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 91899c88d73f..39657c97c620 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 @@ -545,7 +545,32 @@ export function registerConnectorRoutes({ router, log }: RouteDependencies) { }); }) ); + router.get( + { + path: '/internal/enterprise_search/connectors/{connectorId}', + validate: { + params: schema.object({ + connectorId: schema.string(), + }), + }, + }, + elasticsearchErrorHandler(log, async (context, request, response) => { + const { client } = (await context.core).elasticsearch; + const { connectorId } = request.params; + let connectorResult; + try { + connectorResult = await fetchConnectorById(client.asCurrentUser, connectorId); + } catch (error) { + throw error; + } + return response.ok({ + body: { + connector: connectorResult?.value, + }, + }); + }) + ); router.delete( { path: '/internal/enterprise_search/connectors/{connectorId}', diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.test.tsx index 4352a3a6b824..2e17153ee34e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.test.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.test.tsx @@ -142,6 +142,13 @@ describe('Output form validation', () => { expect(res).toBeUndefined(); }); + + it('should work with hostnames using uppercase letters', () => { + const res = validateLogstashHosts(['tEsT.fr:9200', 'TEST2.fr:9200', 'teSt.fR:9999']); + + expect(res).toBeUndefined(); + }); + it('should throw for invalid hosts starting with http', () => { const res = validateLogstashHosts(['https://test.fr:5044']); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.tsx index 330d5c5d2012..116e9f4abf15 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/output_form_validators.tsx @@ -166,7 +166,7 @@ export function validateLogstashHosts(value: string[]) { const url = new URL(`http://${val}`); - if (url.host !== val) { + if (url.host !== val.toLowerCase()) { throw new Error('Invalid host'); } } catch (error) { diff --git a/x-pack/plugins/fleet/server/mocks/index.ts b/x-pack/plugins/fleet/server/mocks/index.ts index fb6dd7d075ce..857882c57525 100644 --- a/x-pack/plugins/fleet/server/mocks/index.ts +++ b/x-pack/plugins/fleet/server/mocks/index.ts @@ -31,6 +31,8 @@ import { packageServiceMock } from '../services/epm/package_service.mock'; import type { UninstallTokenServiceInterface } from '../services/security/uninstall_token_service'; import type { MessageSigningServiceInterface } from '../services/security'; +import { PackagePolicyMocks } from './package_policy.mocks'; + // Export all mocks from artifacts export * from '../services/artifacts/mocks'; @@ -40,6 +42,8 @@ export * from '../services/files/mocks'; // export all mocks from fleet actions client export * from '../services/actions/mocks'; +export * from './package_policy.mocks'; + export interface MockedFleetAppContext extends FleetAppContext { elasticsearch: ReturnType; data: ReturnType; @@ -144,6 +148,22 @@ export const createPackagePolicyServiceMock = (): jest.Mocked { + return { + async *[Symbol.asyncIterator]() { + yield Promise.resolve([PackagePolicyMocks.generatePackagePolicy({ id: '111' })]); + yield Promise.resolve([PackagePolicyMocks.generatePackagePolicy({ id: '222' })]); + }, + }; + }), + fetchAllItemIds: jest.fn((..._) => { + return { + async *[Symbol.asyncIterator]() { + yield Promise.resolve(['111']); + yield Promise.resolve(['222']); + }, + }; + }), }; }; diff --git a/x-pack/plugins/fleet/server/mocks/package_policy.mocks.ts b/x-pack/plugins/fleet/server/mocks/package_policy.mocks.ts new file mode 100644 index 000000000000..a159917cb5e1 --- /dev/null +++ b/x-pack/plugins/fleet/server/mocks/package_policy.mocks.ts @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObjectsFindResponse } from '@kbn/core-saved-objects-api-server'; + +import type { SavedObjectsFindResult } from '@kbn/core-saved-objects-api-server'; + +import { mapPackagePolicySavedObjectToPackagePolicy } from '../services/package_policies'; + +import type { PackagePolicy } from '../../common'; +import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../../common'; + +import type { PackagePolicySOAttributes } from '../types'; + +const generatePackagePolicySOAttributesMock = ( + overrides: Partial = {} +): PackagePolicySOAttributes => { + return { + name: `Package Policy 1`, + description: 'Policy for things', + created_at: '2024-01-24T15:21:13.389Z', + created_by: 'elastic', + updated_at: '2024-01-25T15:21:13.389Z', + updated_by: 'user-a', + policy_id: '444-555-666', + enabled: true, + inputs: [], + namespace: 'default', + package: { + name: 'endpoint', + title: 'Elastic Endpoint', + version: '1.0.0', + }, + revision: 1, + is_managed: false, + secret_references: [], + vars: {}, + elasticsearch: { + privileges: { + cluster: [], + }, + }, + agents: 2, + + ...overrides, + }; +}; + +const generatePackagePolicyMock = (overrides: Partial = {}) => { + return { + ...mapPackagePolicySavedObjectToPackagePolicy(generatePackagePolicySavedObjectMock()), + ...overrides, + }; +}; + +const generatePackagePolicySavedObjectMock = ( + soAttributes: PackagePolicySOAttributes = generatePackagePolicySOAttributesMock() +): SavedObjectsFindResult => { + return { + score: 1, + id: 'so-123', + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + version: 'abc', + created_at: soAttributes.created_at, + updated_at: soAttributes.updated_at, + attributes: soAttributes, + references: [], + sort: ['created_at'], + }; +}; + +const generatePackagePolicySavedObjectFindResponseMock = ( + soResults?: PackagePolicySOAttributes[] +): SavedObjectsFindResponse => { + const soList = soResults ?? [ + generatePackagePolicySOAttributesMock(), + generatePackagePolicySOAttributesMock(), + ]; + + return { + saved_objects: soList.map((soAttributes) => { + return { + score: 1, + id: 'so-123', + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + version: 'abc', + created_at: soAttributes.created_at, + updated_at: soAttributes.updated_at, + attributes: soAttributes, + references: [], + sort: ['created_at'], + }; + }), + total: soList.length, + per_page: 10, + page: 1, + pit_id: 'pit-id-1', + }; +}; + +export const PackagePolicyMocks = Object.freeze({ + generatePackagePolicySOAttributes: generatePackagePolicySOAttributesMock, + generatePackagePolicySavedObjectFindResponse: generatePackagePolicySavedObjectFindResponseMock, + generatePackagePolicy: generatePackagePolicyMock, +}); diff --git a/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts b/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts index f3b332a5930f..782b044a8469 100644 --- a/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts +++ b/x-pack/plugins/fleet/server/services/artifacts/artifacts.test.ts @@ -11,6 +11,8 @@ import { errors } from '@elastic/elasticsearch'; import type { TransportResult } from '@elastic/elasticsearch'; +import { set } from '@kbn/safer-lodash-set'; + import { FLEET_SERVER_ARTIFACTS_INDEX } from '../../../common'; import { ArtifactsElasticsearchError } from '../../errors'; @@ -33,12 +35,14 @@ import { createArtifact, deleteArtifact, encodeArtifactContent, + fetchAllArtifacts, generateArtifactContentHash, getArtifact, listArtifacts, } from './artifacts'; import type { NewArtifact } from './types'; +import type { FetchAllArtifactsOptions } from './types'; describe('When using the artifacts services', () => { let esClientMock: ReturnType; @@ -324,8 +328,28 @@ describe('When using the artifacts services', () => { newArtifact, ]); - expect(responseErrors).toEqual([new Error('error')]); - expect(artifacts).toBeUndefined(); + expect(responseErrors).toEqual([ + new Error( + 'Create of artifact id [undefined] returned: result [undefined], status [400], reason [{"reason":"error"}]' + ), + ]); + expect(artifacts).toEqual([ + { + body: 'eJyrVkrNKynKTC1WsoqOrQUAJxkFKQ==', + compressionAlgorithm: 'zlib', + created: expect.any(String), + decodedSha256: 'd801aa1fb', + decodedSize: 14, + encodedSha256: 'd29238d40', + encodedSize: 22, + encryptionAlgorithm: 'none', + id: 'endpoint:trustlist-v1-d801aa1fb', + identifier: 'trustlist-v1', + packageName: 'endpoint', + relative_url: '/api/fleet/artifacts/trustlist-v1/d801aa1fb', + type: 'trustlist', + }, + ]); }); }); @@ -488,4 +512,113 @@ describe('When using the artifacts services', () => { }); }); }); + + describe('and calling `fetchAll()`', () => { + beforeEach(() => { + esClientMock.search + .mockResolvedValueOnce(generateArtifactEsSearchResultHitsMock()) + .mockResolvedValueOnce(generateArtifactEsSearchResultHitsMock()) + .mockResolvedValueOnce(set(generateArtifactEsSearchResultHitsMock(), 'hits.hits', [])); + }); + + it('should return an iterator', async () => { + expect(fetchAllArtifacts(esClientMock)).toEqual({ + [Symbol.asyncIterator]: expect.any(Function), + }); + }); + + it('should provide artifacts on each iteration', async () => { + for await (const artifacts of fetchAllArtifacts(esClientMock)) { + expect(artifacts[0]).toEqual({ + body: expect.anything(), + compressionAlgorithm: expect.anything(), + created: expect.anything(), + decodedSha256: expect.anything(), + decodedSize: expect.anything(), + encodedSha256: expect.anything(), + encodedSize: expect.anything(), + encryptionAlgorithm: expect.anything(), + id: expect.anything(), + identifier: expect.anything(), + packageName: expect.anything(), + relative_url: expect.anything(), + type: expect.anything(), + }); + } + + expect(esClientMock.search).toHaveBeenCalledTimes(3); + }); + + it('should use defaults if no `options` were provided', async () => { + for await (const artifacts of fetchAllArtifacts(esClientMock)) { + expect(artifacts.length).toBeGreaterThan(0); + } + + expect(esClientMock.search).toHaveBeenLastCalledWith( + expect.objectContaining({ + q: '', + size: 1000, + sort: [{ created: { order: 'asc' } }], + _source_excludes: undefined, + }) + ); + }); + + it('should use custom options when provided', async () => { + const options: FetchAllArtifactsOptions = { + kuery: 'foo: something', + sortOrder: 'desc', + perPage: 500, + sortField: 'someField', + includeArtifactBody: false, + }; + + for await (const artifacts of fetchAllArtifacts(esClientMock, options)) { + expect(artifacts.length).toBeGreaterThan(0); + } + + expect(esClientMock.search).toHaveBeenCalledWith( + expect.objectContaining({ + q: options.kuery, + size: options.perPage, + sort: [{ [options.sortField!]: { order: options.sortOrder } }], + _source_excludes: 'body', + }) + ); + }); + + it('should set `done` to true if loop `break`s out', async () => { + const iterator = fetchAllArtifacts(esClientMock); + + for await (const _ of iterator) { + break; + } + + await expect(iterator[Symbol.asyncIterator]().next()).resolves.toEqual({ + done: true, + value: expect.any(Array), + }); + + expect(esClientMock.search).toHaveBeenCalledTimes(1); + }); + + it('should handle throwing in loop by setting `done` to `true`', async () => { + const iterator = fetchAllArtifacts(esClientMock); + + try { + for await (const _ of iterator) { + throw new Error('test'); + } + } catch (e) { + expect(e); // just to silence eslint + } + + await expect(iterator[Symbol.asyncIterator]().next()).resolves.toEqual({ + done: true, + value: expect.any(Array), + }); + + expect(esClientMock.search).toHaveBeenCalledTimes(1); + }); + }); }); diff --git a/x-pack/plugins/fleet/server/services/artifacts/artifacts.ts b/x-pack/plugins/fleet/server/services/artifacts/artifacts.ts index 5516ab6f70e2..43cf3f745cc6 100644 --- a/x-pack/plugins/fleet/server/services/artifacts/artifacts.ts +++ b/x-pack/plugins/fleet/server/services/artifacts/artifacts.ts @@ -15,6 +15,8 @@ import { isEmpty, sortBy } from 'lodash'; import type { ElasticsearchClient } from '@kbn/core/server'; +import { createEsSearchIterable } from '../utils/create_es_search_iterable'; + import type { ListResult } from '../../../common/types'; import { FLEET_SERVER_ARTIFACTS_INDEX } from '../../../common'; @@ -34,6 +36,7 @@ import type { ArtifactsClientCreateOptions, ListArtifactsProps, NewArtifact, + FetchAllArtifactsOptions, } from './types'; import { esSearchHitToArtifact, @@ -137,10 +140,10 @@ export const bulkCreateArtifacts = async ( artifacts, appContextService.getConfig()?.createArtifactsBulkBatchSize ); - const logger = appContextService.getLogger(); const nonConflictErrors = []; logger.debug(`Number of batches generated for fleet artifacts: ${batches.length}`); + for (let batchN = 0; batchN < batches.length; batchN++) { logger.debug( `Creating artifacts for batch ${batchN + 1} with ${batches[batchN].length / 2} artifacts` @@ -154,12 +157,22 @@ export const bulkCreateArtifacts = async ( refresh, }) ); + // Track errors of the bulk create action if (res.errors) { nonConflictErrors.push( ...res.items.reduce((acc, item) => { - if (item.create?.status !== 409) { - acc.push(new Error(item.create?.error?.reason)); + // 409's (conflict - record already exists) are ignored since the artifact already exists + if (item.create && item.create.status !== 409) { + acc.push( + new Error( + `Create of artifact id [${item.create._id}] returned: result [${ + item.create.result + }], status [${item.create.status}], reason [${JSON.stringify( + item.create?.error || '' + )}]` + ) + ); } return acc; }, []) @@ -167,11 +180,6 @@ export const bulkCreateArtifacts = async ( } } - // If any non conflict error, it returns only the errors - if (nonConflictErrors.length > 0) { - return { errors: nonConflictErrors }; - } - // Use non sorted artifacts array to preserve the artifacts order in the response const nonSortedEsArtifactsResponse: Artifact[] = artifacts.map((artifact) => { return esSearchHitToArtifact({ @@ -182,6 +190,7 @@ export const bulkCreateArtifacts = async ( return { artifacts: nonSortedEsArtifactsResponse, + errors: nonConflictErrors.length ? nonConflictErrors : undefined, }; }; @@ -281,3 +290,66 @@ export const encodeArtifactContent = async ( return encodedArtifact; }; + +/** + * Returns an iterator that loops through all the artifacts stored in the index + * + * @param esClient + * @param options + * + * @example + * + * async () => { + * for await (const value of fetchAllArtifactsIterator()) { + * // process page of data here + * } + * } + */ +export const fetchAllArtifacts = ( + esClient: ElasticsearchClient, + options: FetchAllArtifactsOptions = {} +): AsyncIterable => { + const { kuery = '', perPage = 1000, sortField, sortOrder, includeArtifactBody = true } = options; + + return createEsSearchIterable({ + esClient, + searchRequest: { + index: FLEET_SERVER_ARTIFACTS_INDEX, + rest_total_hits_as_int: true, + track_total_hits: false, + q: kuery, + size: perPage, + sort: [ + { + // MUST have a sort field and sort order + [sortField || 'created']: { + order: sortOrder || 'asc', + }, + }, + ], + _source_excludes: includeArtifactBody ? undefined : 'body', + }, + resultsMapper: (data): Artifact[] => { + return data.hits.hits.map((hit) => { + // @ts-expect-error @elastic/elasticsearch _source is optional + const artifact = esSearchHitToArtifact(hit); + + // If not body attribute is included, still create the property in the object (since the + // return type is `Artifact` and `body` is required), but throw an error is caller attempts + // to still access it. + if (!includeArtifactBody) { + Object.defineProperty(artifact, 'body', { + enumerable: false, + get(): string { + throw new Error( + `'body' attribute not included due to request to 'fetchAllArtifacts()' having options 'includeArtifactBody' set to 'false'` + ); + }, + }); + } + + return artifact; + }); + }, + }); +}; diff --git a/x-pack/plugins/fleet/server/services/artifacts/client.ts b/x-pack/plugins/fleet/server/services/artifacts/client.ts index 7ba2452e83fe..0b40a7acdcc8 100644 --- a/x-pack/plugins/fleet/server/services/artifacts/client.ts +++ b/x-pack/plugins/fleet/server/services/artifacts/client.ts @@ -17,6 +17,7 @@ import type { ArtifactsClientInterface, NewArtifact, ListArtifactsProps, + FetchAllArtifactsOptions, } from './types'; import { relativeDownloadUrlFromArtifact, uniqueIdFromId } from './mappings'; @@ -29,6 +30,7 @@ import { listArtifacts, bulkCreateArtifacts, bulkDeleteArtifacts, + fetchAllArtifacts, } from './artifacts'; /** @@ -49,6 +51,15 @@ export class FleetArtifactsClient implements ArtifactsClientInterface { return artifact; } + /** + * Creates a `kuery` string using the provided value on input that is bound to the integration package + * @param kuery + * @private + */ + private buildFilter(kuery: string): string { + return `(package_name: "${this.packageName}")${kuery ? ` AND ${kuery}` : ''}`; + } + async getArtifact(id: string): Promise { const artifact = await getArtifact(this.esClient, id); return artifact ? this.validate(artifact) : undefined; @@ -119,20 +130,37 @@ export class FleetArtifactsClient implements ArtifactsClientInterface { } /** - * Get a list of artifacts. - * NOTE that when using the `kuery` filtering param, that all filters property names should - * match the internal attribute names of the index + * Get a list of artifacts. A few things to note: + * - if wanting to get ALL artifacts, consider using instead the `fetchAll()` method instead + * as it will property return data past the 10k ES limitation + * - when using the `kuery` filtering param, all filters property names should match the + * internal attribute names in the index */ async listArtifacts({ kuery, ...options }: ListArtifactsProps = {}): Promise< ListResult > { - // All filtering for artifacts should be bound to the `packageName`, so we insert - // that into the KQL value and use `AND` to add the defined `kuery` (if any) to it. - const filter = `(package_name: "${this.packageName}")${kuery ? ` AND ${kuery}` : ''}`; - return listArtifacts(this.esClient, { ...options, - kuery: filter, + kuery: this.buildFilter(kuery), + }); + } + + /** + * Returns an `AsyncIterable` object that can be used to iterate over all artifacts + * + * @param options + * + * @example + * async () => { + * for await (const artifacts of fleetArtifactsClient.fetchAll()) { + * // artifacts === first page of items + * } + * } + */ + fetchAll({ kuery, ...options }: FetchAllArtifactsOptions = {}): AsyncIterable { + return fetchAllArtifacts(this.esClient, { + ...options, + kuery: this.buildFilter(kuery), }); } diff --git a/x-pack/plugins/fleet/server/services/artifacts/mocks.ts b/x-pack/plugins/fleet/server/services/artifacts/mocks.ts index dc831558cb7b..4e5d8c93f064 100644 --- a/x-pack/plugins/fleet/server/services/artifacts/mocks.ts +++ b/x-pack/plugins/fleet/server/services/artifacts/mocks.ts @@ -44,6 +44,34 @@ export const createArtifactsClientMock = (): jest.Mocked { + return createFetchAllArtifactsIterableMock(); + }), + }; +}; + +export const createFetchAllArtifactsIterableMock = (artifactPages: Artifact[][] = []) => { + const totalPagesOfResults = artifactPages.length; + let nextResults = 0; + + return { + [Symbol.asyncIterator]() { + return { + async next() { + return { + value: artifactPages[nextResults++] ?? [], + done: nextResults > totalPagesOfResults, + }; + }, + + async return() { + return { + value: [], + done: true, + }; + }, + }; + }, }; }; @@ -100,6 +128,7 @@ export const generateArtifactEsGetSingleHitMock = ( _version: 1, _score: 1, _source, + sort: ['abc'], }; }; diff --git a/x-pack/plugins/fleet/server/services/artifacts/types.ts b/x-pack/plugins/fleet/server/services/artifacts/types.ts index 4b0aacd92bc2..697815a593fd 100644 --- a/x-pack/plugins/fleet/server/services/artifacts/types.ts +++ b/x-pack/plugins/fleet/server/services/artifacts/types.ts @@ -72,6 +72,12 @@ export type ListArtifactsProps = Pick & { + sortField?: string | keyof ArtifactElasticsearchProperties; + /** If false, then the `body` property of the Artifact will be excluded from the results. Default is `true` */ + includeArtifactBody?: boolean; +}; + /** * The interface exposed out of Fleet's Artifact service via the client class */ @@ -93,4 +99,6 @@ export interface ArtifactsClientInterface { encodeContent(content: ArtifactsClientCreateOptions['content']): Promise; generateHash(content: string): string; + + fetchAll(options?: FetchAllArtifactsOptions): AsyncIterable; } diff --git a/x-pack/plugins/fleet/server/services/epm/registry/index.ts b/x-pack/plugins/fleet/server/services/epm/registry/index.ts index 97402447be71..9dfd30772594 100644 --- a/x-pack/plugins/fleet/server/services/epm/registry/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/registry/index.ts @@ -94,16 +94,8 @@ async function _fetchFindLatestPackage( const bundledPackage = await getBundledPackageByName(packageName); - // temporary workaround to allow synthetics package beta version until there is a GA available - // needed because synthetics is installed by default on kibana startup - const prereleaseAllowedExceptions = ['synthetics']; - - const prereleaseEnabled = prerelease || prereleaseAllowedExceptions.includes(packageName); - const registryUrl = getRegistryUrl(); - const url = new URL( - `${registryUrl}/search?package=${packageName}&prerelease=${prereleaseEnabled}` - ); + const url = new URL(`${registryUrl}/search?package=${packageName}&prerelease=${prerelease}`); if (!ignoreConstraints) { setConstraints(url); diff --git a/x-pack/plugins/fleet/server/services/package_policies/index.ts b/x-pack/plugins/fleet/server/services/package_policies/index.ts index d0d4fa4aae82..a7eacdc76a3a 100644 --- a/x-pack/plugins/fleet/server/services/package_policies/index.ts +++ b/x-pack/plugins/fleet/server/services/package_policies/index.ts @@ -7,3 +7,4 @@ export * from './experimental_datastream_features'; export * from './package_policy_name_helper'; +export * from './utils'; diff --git a/x-pack/plugins/fleet/server/services/package_policies/utils.test.ts b/x-pack/plugins/fleet/server/services/package_policies/utils.test.ts new file mode 100644 index 000000000000..363ffe9c38fa --- /dev/null +++ b/x-pack/plugins/fleet/server/services/package_policies/utils.test.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { PackagePolicyMocks } from '../../mocks'; + +import { mapPackagePolicySavedObjectToPackagePolicy } from './utils'; + +describe('Package Policy Utils', () => { + describe('mapPackagePolicySavedObjectToPackagePolicy()', () => { + it('should return only exposed SO properties', () => { + const soItem = + PackagePolicyMocks.generatePackagePolicySavedObjectFindResponse().saved_objects.at(0)!; + + expect(mapPackagePolicySavedObjectToPackagePolicy(soItem)).toEqual({ + agents: 2, + created_at: '2024-01-24T15:21:13.389Z', + created_by: 'elastic', + description: 'Policy for things', + elasticsearch: { + privileges: { + cluster: [], + }, + }, + enabled: true, + id: 'so-123', + inputs: [], + is_managed: false, + name: 'Package Policy 1', + namespace: 'default', + package: { + name: 'endpoint', + title: 'Elastic Endpoint', + version: '1.0.0', + }, + policy_id: '444-555-666', + revision: 1, + secret_references: [], + updated_at: '2024-01-25T15:21:13.389Z', + updated_by: 'user-a', + vars: {}, + version: 'abc', + }); + }); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/package_policies/utils.ts b/x-pack/plugins/fleet/server/services/package_policies/utils.ts new file mode 100644 index 000000000000..309db211bbf1 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/package_policies/utils.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { SavedObject } from '@kbn/core-saved-objects-common/src/server_types'; + +import type { PackagePolicy, PackagePolicySOAttributes } from '../../types'; + +export const mapPackagePolicySavedObjectToPackagePolicy = ({ + /* eslint-disable @typescript-eslint/naming-convention */ + id, + version, + attributes: { + name, + description, + namespace, + enabled, + is_managed, + policy_id, + // `package` is a reserved keyword + package: packageInfo, + inputs, + vars, + elasticsearch, + agents, + revision, + secret_references, + updated_at, + updated_by, + created_at, + created_by, + /* eslint-enable @typescript-eslint/naming-convention */ + }, +}: SavedObject): PackagePolicy => { + return { + id, + name, + description, + namespace, + enabled, + is_managed, + policy_id, + package: packageInfo, + inputs, + vars, + elasticsearch, + version, + agents, + revision, + secret_references, + updated_at, + updated_by, + created_at, + created_by, + }; +}; diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts index 24483be93a9f..cc605900c3a5 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts @@ -19,6 +19,8 @@ import type { } from '@kbn/core/server'; import { SavedObjectsErrorHelpers } from '@kbn/core/server'; +import { PackagePolicyMocks } from '../mocks/package_policy.mocks'; + import type { PackageInfo, PackagePolicySOAttributes, @@ -53,6 +55,8 @@ import { import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../constants'; +import { mapPackagePolicySavedObjectToPackagePolicy } from './package_policies'; + import { preconfigurePackageInputs, updatePackageInputs, @@ -4918,6 +4922,149 @@ describe('Package policy service', () => { ).rejects.toEqual(new FleetError('Package notinstalled is not installed')); }); }); + + describe('fetchAllItemIds()', () => { + let soClientMock: ReturnType; + + beforeEach(() => { + soClientMock = savedObjectsClientMock.create(); + + soClientMock.find + .mockResolvedValueOnce(PackagePolicyMocks.generatePackagePolicySavedObjectFindResponse()) + .mockResolvedValueOnce(PackagePolicyMocks.generatePackagePolicySavedObjectFindResponse()) + .mockResolvedValueOnce( + Object.assign(PackagePolicyMocks.generatePackagePolicySavedObjectFindResponse(), { + saved_objects: [], + }) + ); + }); + + it('should return an iterator', async () => { + expect(packagePolicyService.fetchAllItemIds(soClientMock)).toEqual({ + [Symbol.asyncIterator]: expect.any(Function), + }); + }); + + it('should provide item ids on every iteration', async () => { + for await (const ids of packagePolicyService.fetchAllItemIds(soClientMock)) { + expect(ids).toEqual(['so-123', 'so-123']); + } + + expect(soClientMock.find).toHaveBeenCalledTimes(3); + }); + + it('should use default options', async () => { + for await (const ids of packagePolicyService.fetchAllItemIds(soClientMock)) { + expect(ids); + } + + expect(soClientMock.find).toHaveBeenCalledWith( + expect.objectContaining({ + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + perPage: 1000, + sortField: 'created_at', + sortOrder: 'asc', + fields: [], + filter: undefined, + }) + ); + }); + + it('should use custom options when defined', async () => { + for await (const ids of packagePolicyService.fetchAllItemIds(soClientMock, { + perPage: 13, + kuery: 'one=two', + })) { + expect(ids); + } + + expect(soClientMock.find).toHaveBeenCalledWith( + expect.objectContaining({ + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + perPage: 13, + sortField: 'created_at', + sortOrder: 'asc', + fields: [], + filter: 'one=two', + }) + ); + }); + }); + + describe('fetchAllItems()', () => { + let soClientMock: ReturnType; + + beforeEach(() => { + soClientMock = savedObjectsClientMock.create(); + + soClientMock.find + .mockResolvedValueOnce(PackagePolicyMocks.generatePackagePolicySavedObjectFindResponse()) + .mockResolvedValueOnce(PackagePolicyMocks.generatePackagePolicySavedObjectFindResponse()) + .mockResolvedValueOnce( + Object.assign(PackagePolicyMocks.generatePackagePolicySavedObjectFindResponse(), { + saved_objects: [], + }) + ); + }); + + it('should return an iterator', async () => { + expect(packagePolicyService.fetchAllItems(soClientMock)).toEqual({ + [Symbol.asyncIterator]: expect.any(Function), + }); + }); + + it('should provide items on every iteration', async () => { + for await (const items of packagePolicyService.fetchAllItems(soClientMock)) { + expect(items).toEqual( + PackagePolicyMocks.generatePackagePolicySavedObjectFindResponse().saved_objects.map( + (soItem) => { + return mapPackagePolicySavedObjectToPackagePolicy(soItem); + } + ) + ); + } + + expect(soClientMock.find).toHaveBeenCalledTimes(3); + }); + + it('should use default options', async () => { + for await (const ids of packagePolicyService.fetchAllItemIds(soClientMock)) { + expect(ids); + } + + expect(soClientMock.find).toHaveBeenCalledWith( + expect.objectContaining({ + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + perPage: 1000, + sortField: 'created_at', + sortOrder: 'asc', + fields: [], + filter: undefined, + }) + ); + }); + + it('should use custom options when defined', async () => { + for await (const ids of packagePolicyService.fetchAllItems(soClientMock, { + kuery: 'one=two', + perPage: 12, + sortOrder: 'desc', + sortField: 'updated_by', + })) { + expect(ids); + } + + expect(soClientMock.find).toHaveBeenCalledWith( + expect.objectContaining({ + type: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + perPage: 12, + sortField: 'updated_by', + sortOrder: 'desc', + filter: 'one=two', + }) + ); + }); + }); }); describe('getUpgradeDryRunDiff', () => { diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index e89ac0160f62..45753540af25 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -95,6 +95,8 @@ import type { } from '../types'; import type { ExternalCallback } from '..'; +import { createSoFindIterable } from './utils/create_so_find_iterable'; + import type { FleetAuthzRouteConfig } from './security'; import { getAuthzFromRequest, doesNotHaveRequiredFleetAuthz } from './security'; @@ -109,9 +111,16 @@ import { appContextService } from '.'; import { removeOldAssets } from './epm/packages/cleanup'; import type { PackageUpdateEvent, UpdateEventType } from './upgrade_sender'; import { sendTelemetryEvents } from './upgrade_sender'; -import { handleExperimentalDatastreamFeatureOptIn } from './package_policies'; +import { + handleExperimentalDatastreamFeatureOptIn, + mapPackagePolicySavedObjectToPackagePolicy, +} from './package_policies'; import { updateDatastreamExperimentalFeatures } from './epm/packages/update'; -import type { PackagePolicyClient, PackagePolicyService } from './package_policy_service'; +import type { + PackagePolicyClient, + PackagePolicyClientFetchAllItemsOptions, + PackagePolicyService, +} from './package_policy_service'; import { installAssetsForInputPackagePolicy } from './epm/packages/install'; import { auditLoggingService } from './audit_logging'; import { @@ -122,6 +131,7 @@ import { } from './secrets'; import { getPackageAssetsMap } from './epm/packages/get'; import { validateOutputForNewPackagePolicy } from './agent_policies/outputs_helpers'; +import type { PackagePolicyClientFetchAllItemIdsOptions } from './package_policy_service'; export type InputsOverride = Partial & { vars?: Array; @@ -1886,6 +1896,60 @@ class PackagePolicyClientImpl implements PackagePolicyClient { } } } + + fetchAllItemIds( + soClient: SavedObjectsClientContract, + { perPage = 1000, kuery }: PackagePolicyClientFetchAllItemIdsOptions = {} + ): AsyncIterable { + // TODO:PT Question for fleet team: do I need to `auditLoggingService.writeCustomSoAuditLog()` here? Its only IDs + + return createSoFindIterable<{}>({ + soClient, + findRequest: { + type: SAVED_OBJECT_TYPE, + perPage, + sortField: 'created_at', + sortOrder: 'asc', + fields: [], + filter: kuery ? normalizeKuery(SAVED_OBJECT_TYPE, kuery) : undefined, + }, + resultsMapper: (data) => { + return data.saved_objects.map((packagePolicySO) => packagePolicySO.id); + }, + }); + } + + fetchAllItems( + soClient: SavedObjectsClientContract, + { + perPage = 1000, + kuery, + sortOrder = 'asc', + sortField = 'created_at', + }: PackagePolicyClientFetchAllItemsOptions = {} + ): AsyncIterable { + return createSoFindIterable({ + soClient, + findRequest: { + type: SAVED_OBJECT_TYPE, + sortField, + sortOrder, + perPage, + filter: kuery ? normalizeKuery(SAVED_OBJECT_TYPE, kuery) : undefined, + }, + resultsMapper(data) { + return data.saved_objects.map((packagePolicySO) => { + auditLoggingService.writeCustomSoAuditLog({ + action: 'find', + id: packagePolicySO.id, + savedObjectType: PACKAGE_POLICY_SAVED_OBJECT_TYPE, + }); + + return mapPackagePolicySavedObjectToPackagePolicy(packagePolicySO); + }); + }, + }); + } } export class PackagePolicyServiceImpl diff --git a/x-pack/plugins/fleet/server/services/package_policy_service.ts b/x-pack/plugins/fleet/server/services/package_policy_service.ts index 9519cafbc6a7..de960c44b787 100644 --- a/x-pack/plugins/fleet/server/services/package_policy_service.ts +++ b/x-pack/plugins/fleet/server/services/package_policy_service.ts @@ -213,4 +213,31 @@ export interface PackagePolicyClient { packageInfo: PackageInfo; experimentalDataStreamFeatures: ExperimentalDataStreamFeature[]; }>; + + /** + * Returns an `AsyncIterable` for retrieving all integration policy IDs + * @param soClient + * @param options + */ + fetchAllItemIds( + soClient: SavedObjectsClientContract, + options?: PackagePolicyClientFetchAllItemIdsOptions + ): AsyncIterable; + + /** + * Returns an `AsyncIterable` for retrieving all integration policies + * @param soClient + * @param options + */ + fetchAllItems( + soClient: SavedObjectsClientContract, + options?: PackagePolicyClientFetchAllItemsOptions + ): AsyncIterable; } + +export type PackagePolicyClientFetchAllItemIdsOptions = Pick; + +export type PackagePolicyClientFetchAllItemsOptions = Pick< + ListWithKuery, + 'perPage' | 'kuery' | 'sortField' | 'sortOrder' +>; diff --git a/x-pack/plugins/fleet/server/services/utils/create_es_search_iterable.ts b/x-pack/plugins/fleet/server/services/utils/create_es_search_iterable.ts new file mode 100644 index 000000000000..ae4cb9551bc8 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/utils/create_es_search_iterable.ts @@ -0,0 +1,165 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 type * as estypes from '@kbn/es-types'; + +import type { SearchRequest, SearchResponse } from '@elastic/elasticsearch/lib/api/types'; + +export interface CreateEsSearchIterableOptions { + esClient: ElasticsearchClient; + searchRequest: Omit & + Pick, 'sort' | 'index'>; + /** + * An optional callback for mapping the results retrieved from ES. If defined, the iterator + * `value` will be set to the data returned by this mapping function. + * + * @param data + */ + resultsMapper?: (data: SearchResponse) => any; + /** If a Point in Time should be used while executing the search. Defaults to `true` */ + usePointInTime?: boolean; +} + +export type InferEsSearchIteratorResultValue = + CreateEsSearchIterableOptions['resultsMapper'] extends undefined + ? SearchResponse + : ReturnType>['resultsMapper']>; + +/** + * Creates an `AsyncIterable` that can be used to iterate (ex. via `for..await..of`) over all the data + * matching the search query. The search request to ES will use `search_after`, thus can iterate over + * datasets above 10k items as well. + * + * @param options + * + * @example + * + * const yourFn = async () => { + * const dataIterable = createEsSearchIterable({ + * esClient, + * searchRequest: { + * index: 'some-index', + * sort: [ + * { + * created: { order: 'asc' } + * } + * ] + * } + * }); + * + * for await (const data of dataIterable) { + * // data === your search results + * } + * } + */ +export const createEsSearchIterable = ({ + esClient, + searchRequest: { size = 1000, index, ...searchOptions }, + resultsMapper, + usePointInTime = true, +}: CreateEsSearchIterableOptions): AsyncIterable< + InferEsSearchIteratorResultValue +> => { + const keepAliveValue = '5m'; + let done = false; + let value: SearchResponse; + let searchAfterValue: estypes.SearchHit['sort'] | undefined; + let pointInTime: Promise<{ id: string }> = usePointInTime + ? esClient.openPointInTime({ + index, + ignore_unavailable: true, + keep_alive: keepAliveValue, + }) + : Promise.resolve({ id: '' }); + + const createIteratorResult = (): IteratorResult> => { + return { done, value }; + }; + + const setValue = (searchResponse: SearchResponse): void => { + value = resultsMapper ? resultsMapper(searchResponse) : searchResponse; + }; + + const setDone = async (): Promise => { + done = true; + + if (usePointInTime) { + const pitId = (await pointInTime).id; + + if (pitId) { + await esClient.closePointInTime({ id: pitId }); + } + } + }; + + const fetchData = async () => { + const pitId = (await pointInTime).id; + + const searchResult = await esClient + .search({ + ...searchOptions, + size, + ...(usePointInTime + ? { + pit: { + id: pitId, + keep_alive: keepAliveValue, + }, + } + : { index }), + search_after: searchAfterValue, + }) + .catch((e) => { + Error.captureStackTrace(e); + throw e; + }); + + const searchHits = searchResult.hits.hits; + const lastSearchHit = searchHits[searchHits.length - 1]; + + if (searchHits.length === 0) { + await setDone(); + return; + } + + searchAfterValue = lastSearchHit.sort; + pointInTime = Promise.resolve({ id: searchResult.pit_id ?? '' }); + setValue(searchResult); + + // If (for some reason) we don't have a `searchAfterValue`, + // then throw an error, or else we'll keep looping forever + if (!searchAfterValue) { + await setDone(); + throw new Error( + `Unable to store 'search_after' value. Last 'SearchHit' did not include a 'sort' property \n(did you forget to set the 'sort' attribute on your SearchRequest?)':\n${JSON.stringify( + lastSearchHit + )}` + ); + } + }; + + return { + [Symbol.asyncIterator]() { + return { + async next() { + if (!done) { + await fetchData(); + } + + return createIteratorResult(); + }, + + async return() { + done = true; + return createIteratorResult(); + }, + }; + }, + }; +}; diff --git a/x-pack/plugins/fleet/server/services/utils/create_so_find_iterable.ts b/x-pack/plugins/fleet/server/services/utils/create_so_find_iterable.ts new file mode 100644 index 000000000000..6b17b3ba9804 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/utils/create_so_find_iterable.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 type { + SavedObjectsClientContract, + SavedObjectsFindOptions, + SavedObjectsFindResponse, + SavedObjectsFindResult, +} from '@kbn/core-saved-objects-api-server'; + +export interface CreateSoFindIterableOptions { + soClient: SavedObjectsClientContract; + findRequest: Omit & + // sortField is required + Pick, 'sortField'>; + /** + * An optional callback for mapping the results retrieved from SavedObjects. If defined, the iterator + * `value` will be set to the data returned by this mapping function. + * + * @param data + */ + resultsMapper?: (data: SavedObjectsFindResponse) => any; + /** If a Point in Time should be used while executing the search. Defaults to `true` */ + usePointInTime?: boolean; +} + +export type InferSoFindIteratorResultValue = + CreateSoFindIterableOptions['resultsMapper'] extends undefined + ? SavedObjectsFindResponse + : ReturnType>['resultsMapper']>; + +/** + * Creates an `AsyncIterable` that can be used to iterate (ex. via `for..await..of`) over all the data + * matching the search query. The search request to Saved Object will use `searchAfter`, thus can iterate over + * datasets above 10k items as well. + * + * @param options + */ +export const createSoFindIterable = ({ + soClient, + findRequest: { perPage = 1000, ...findOptions }, + resultsMapper, + usePointInTime = true, +}: CreateSoFindIterableOptions): AsyncIterable< + InferSoFindIteratorResultValue +> => { + const keepAliveValue = '5m'; + let done = false; + let value: SavedObjectsFindResponse; + let searchAfterValue: SavedObjectsFindResult['sort'] | undefined; + let pointInTime: Promise<{ id: string }> = usePointInTime + ? soClient.openPointInTimeForType(findOptions.type, { keepAlive: keepAliveValue }) + : Promise.resolve({ id: '' }); + + const setValue = (findResponse: SavedObjectsFindResponse): void => { + value = resultsMapper ? resultsMapper(findResponse) : findResponse; + }; + + const setDone = async (): Promise => { + done = true; + + if (usePointInTime) { + const pitId = (await pointInTime).id; + + if (pitId) { + await soClient.closePointInTime(pitId); + } + } + }; + + const fetchData = async () => { + const findResult = await soClient + .find({ + ...findOptions, + ...(usePointInTime + ? { + pit: { + id: (await pointInTime).id, + keepAlive: keepAliveValue, + }, + } + : {}), + perPage, + searchAfter: searchAfterValue, + }) + .catch((e) => { + Error.captureStackTrace(e); + throw e; + }); + + const soItems = findResult.saved_objects; + const lastSearchHit = soItems[soItems.length - 1]; + + if (soItems.length === 0) { + setValue(findResult); + await setDone(); + return; + } + + searchAfterValue = lastSearchHit.sort; + pointInTime = Promise.resolve({ id: findResult.pit_id ?? '' }); + setValue(findResult); + + // If (for some reason) we don't have a `searchAfterValue`, + // then throw an error, or else we'll keep looping forever + if (!searchAfterValue) { + await setDone(); + throw new Error( + `Unable to store 'searchAfter' value. Last 'SavedObjectsFindResult' did not include a 'sort' property \n(did you forget to set the 'sortField' attribute on your SavedObjectsFindOptions?)':\n${JSON.stringify( + lastSearchHit + )}` + ); + } + }; + + const createIteratorResult = (): IteratorResult> => { + return { done, value }; + }; + + return { + [Symbol.asyncIterator]() { + return { + async next() { + if (!done) { + await fetchData(); + } + + return createIteratorResult(); + }, + + async return() { + done = true; + return createIteratorResult(); + }, + }; + }, + }; +}; diff --git a/x-pack/plugins/fleet/server/types/models/output.test.ts b/x-pack/plugins/fleet/server/types/models/output.test.ts index 06edd900fec2..9c850766b9ba 100644 --- a/x-pack/plugins/fleet/server/types/models/output.test.ts +++ b/x-pack/plugins/fleet/server/types/models/output.test.ts @@ -13,6 +13,10 @@ describe('Output model', () => { expect(validateLogstashHost('test.fr:5044')).toBeUndefined(); }); + it('should support valid host with uppercase letters', () => { + expect(validateLogstashHost('tEsT.fr:5044')).toBeUndefined(); + }); + it('should return an error for an invalid host', () => { expect(validateLogstashHost('!@#%&!#!@')).toMatchInlineSnapshot(`"Invalid Logstash host"`); }); diff --git a/x-pack/plugins/fleet/server/types/models/output.ts b/x-pack/plugins/fleet/server/types/models/output.ts index 730ec512f5a0..765018f3ac88 100644 --- a/x-pack/plugins/fleet/server/types/models/output.ts +++ b/x-pack/plugins/fleet/server/types/models/output.ts @@ -26,7 +26,7 @@ export function validateLogstashHost(val: string) { try { const url = new URL(`http://${val}`); - if (url.host !== val) { + if (url.host !== val.toLowerCase()) { return 'Invalid host'; } } catch (err) { diff --git a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_shift.tsx b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_shift.tsx index 8bf26114416d..fe69c9d76d45 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_shift.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/dimension_panel/time_shift.tsx @@ -155,7 +155,7 @@ export function TimeShift({ ); })} selectedOptions={getSelectedOption()} - singleSelection={{ asPlainText: true }} + singleSelection={{ asPlainText: false }} isInvalid={isLocalValueInvalid} onCreateOption={(val) => { const parsedVal = parseTimeShift(val); diff --git a/x-pack/plugins/lists/server/routes/list/import_list_item_route.ts b/x-pack/plugins/lists/server/routes/list/import_list_item_route.ts index 822a18fd13cf..9e64fe59404c 100644 --- a/x-pack/plugins/lists/server/routes/list/import_list_item_route.ts +++ b/x-pack/plugins/lists/server/routes/list/import_list_item_route.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { extname } from 'path'; + import { schema } from '@kbn/config-schema'; import { validate } from '@kbn/securitysolution-io-ts-utils'; import { transformError } from '@kbn/securitysolution-es-utils'; @@ -17,6 +19,8 @@ import { buildRouteValidation, buildSiemResponse } from '../utils'; import { createStreamFromBuffer } from '../utils/create_stream_from_buffer'; import { getListClient } from '..'; +const validFileExtensions = ['.csv', '.txt']; + export const importListItemRoute = (router: ListsPluginRouter, config: ConfigType): void => { router.versioned .post({ @@ -47,10 +51,29 @@ export const importListItemRoute = (router: ListsPluginRouter, config: ConfigTyp async (context, request, response) => { const siemResponse = buildSiemResponse(response); try { - const stream = createStreamFromBuffer(request.body); const { deserializer, list_id: listId, serializer, type } = request.query; const lists = await getListClient(context); + const filename = await lists.getImportFilename({ + stream: createStreamFromBuffer(request.body), + }); + if (!filename) { + return siemResponse.error({ + body: 'To import a list item, the file name must be specified', + statusCode: 400, + }); + } + const fileExtension = extname(filename).toLowerCase(); + if (!validFileExtensions.includes(fileExtension)) { + return siemResponse.error({ + body: `Unsupported media type. File must be one of the following types: [${validFileExtensions.join( + ', ' + )}]`, + statusCode: 415, + }); + } + + const stream = createStreamFromBuffer(request.body); const listDataExists = await lists.getListDataStreamExists(); if (!listDataExists) { const listIndexExists = await lists.getListIndexExists(); diff --git a/x-pack/plugins/lists/server/services/lists/list_client.ts b/x-pack/plugins/lists/server/services/lists/list_client.ts index 826e4a545d80..d1d5c585c3f8 100644 --- a/x-pack/plugins/lists/server/services/lists/list_client.ts +++ b/x-pack/plugins/lists/server/services/lists/list_client.ts @@ -37,6 +37,7 @@ import type { import type { ConfigType } from '../../config'; import { + BufferLines, createListItem, deleteListItem, deleteListItemByValue, @@ -69,6 +70,7 @@ import type { FindAllListItemsOptions, FindListItemOptions, FindListOptions, + GetImportFilename, GetListItemByValueOptions, GetListItemOptions, GetListItemsByValueOptions, @@ -715,6 +717,33 @@ export class ListClient { }); }; + /** + * Gets the filename of the imported file + * @param options + * @param options.stream The stream to pull the import from + * @returns + */ + public getImportFilename = ({ stream }: GetImportFilename): Promise => { + return new Promise((resolve, reject) => { + const { config } = this; + const readBuffer = new BufferLines({ bufferSize: config.importBufferSize, input: stream }); + let fileName: string | undefined; + readBuffer.on('fileName', async (fileNameEmitted: string) => { + try { + readBuffer.pause(); + fileName = decodeURIComponent(fileNameEmitted); + readBuffer.resume(); + } catch (err) { + reject(err); + } + }); + + readBuffer.on('close', () => { + resolve(fileName); + }); + }); + }; + /** * Imports list items to a stream. If the list already exists, this will append the list items to the existing list. * If the list does not exist, this will auto-create the list and then add the items to that list. diff --git a/x-pack/plugins/lists/server/services/lists/list_client_types.ts b/x-pack/plugins/lists/server/services/lists/list_client_types.ts index 7509eeb91424..4c64e8e94016 100644 --- a/x-pack/plugins/lists/server/services/lists/list_client_types.ts +++ b/x-pack/plugins/lists/server/services/lists/list_client_types.ts @@ -335,3 +335,12 @@ export interface SearchListItemByValuesOptions { /** The value to search for list items based off. */ value: unknown[]; } + +/** + * ListClient.getImportFilename + * {@link ListClient.getImportFilename} + */ +export interface GetImportFilename { + /** The stream to pull the import from */ + stream: Readable; +} diff --git a/x-pack/plugins/ml/public/application/components/anomalies_table/anomalies_table.js b/x-pack/plugins/ml/public/application/components/anomalies_table/anomalies_table.js index 9b023ae640c1..0edb008184aa 100644 --- a/x-pack/plugins/ml/public/application/components/anomalies_table/anomalies_table.js +++ b/x-pack/plugins/ml/public/application/components/anomalies_table/anomalies_table.js @@ -144,9 +144,8 @@ export class AnomaliesTableInternal extends Component { }; unsetShowRuleEditorFlyoutFunction = () => { - const showRuleEditorFlyout = () => {}; this.setState({ - showRuleEditorFlyout, + showRuleEditorFlyout: () => {}, }); }; diff --git a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js index 0e21de91dbbb..abb7055b41a8 100644 --- a/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js +++ b/x-pack/plugins/ml/public/application/components/rule_editor/rule_editor_flyout.js @@ -83,11 +83,13 @@ class RuleEditorFlyoutUI extends Component { } componentDidMount() { - this.toastNotificationService = toastNotificationServiceProvider( - this.props.kibana.services.notifications.toasts - ); - if (typeof this.props.setShowFunction === 'function') { - this.props.setShowFunction(this.showFlyout); + if (this.props.kibana.services.notifications) { + this.toastNotificationService = toastNotificationServiceProvider( + this.props.kibana.services.notifications.toasts + ); + if (typeof this.props.setShowFunction === 'function') { + this.props.setShowFunction(this.showFlyout); + } } } @@ -480,7 +482,7 @@ class RuleEditorFlyoutUI extends Component { }; render() { - const docsUrl = this.props.kibana.services.docLinks.links.ml.customRules; + const docsUrl = this.props.kibana.services.docLinks?.links.ml.customRules; const { isFlyoutVisible, job, diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer.scss b/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer.scss index 6160db3b940c..e47e69c741a9 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer.scss +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/_timeseriesexplorer.scss @@ -74,6 +74,11 @@ pointer-events: none; } + .values-dots circle { + fill: $euiColorPrimary; + stroke-width: 0; + } + .metric-value { opacity: 1; fill: transparent; diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js index a66a5f0efece..b459f0bffcee 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js @@ -17,6 +17,8 @@ import { isEqual, reduce, each, get } from 'lodash'; import d3 from 'd3'; import moment from 'moment'; +import { EuiPopover } from '@elastic/eui'; + import { i18n } from '@kbn/i18n'; import { getFormattedSeverityScore, getSeverityWithLow } from '@kbn/ml-anomaly-utils'; import { formatHumanReadableDateTimeSeconds } from '@kbn/ml-date-utils'; @@ -52,6 +54,9 @@ import { } from './timeseries_chart_annotations'; import { MlAnnotationUpdatesContext } from '../../../contexts/ml/ml_annotation_updates_context'; +import { LinksMenuUI } from '../../../components/anomalies_table/links_menu'; +import { RuleEditorFlyout } from '../../../components/rule_editor'; + const focusZoomPanelHeight = 25; const focusChartHeight = 310; const focusHeight = focusZoomPanelHeight + focusChartHeight; @@ -60,6 +65,7 @@ const contextChartLineTopMargin = 3; const chartSpacing = 25; const swimlaneHeight = 30; const ctxAnnotationMargin = 2; +const popoverMenuOffset = 28; const annotationHeight = ANNOTATION_SYMBOL_HEIGHT + ctxAnnotationMargin * 2; const margin = { top: 10, right: 10, bottom: 15, left: 40 }; @@ -123,11 +129,18 @@ class TimeseriesChartIntl extends Component { zoomFromFocusLoaded: PropTypes.object, zoomToFocusLoaded: PropTypes.object, tooltipService: PropTypes.object.isRequired, + tableData: PropTypes.object, + sourceIndicesWithGeoFields: PropTypes.object.isRequired, }; rowMouseenterSubscriber = null; rowMouseleaveSubscriber = null; + constructor(props) { + super(props); + this.state = { popoverData: null, popoverCoords: [0, 0], showRuleEditorFlyout: () => {} }; + } + componentWillUnmount() { const element = d3.select(this.rootNode); element.html(''); @@ -206,7 +219,10 @@ class TimeseriesChartIntl extends Component { const highlightFocusChartAnomaly = this.highlightFocusChartAnomaly.bind(this); const boundHighlightFocusChartAnnotation = highlightFocusChartAnnotation.bind(this); function tableRecordMousenterListener({ record, type = 'anomaly' }) { - if (type === 'anomaly') { + // do not display tooltips if the action popover is active + if (this.state.popoverData !== null) { + return; + } else if (type === 'anomaly') { highlightFocusChartAnomaly(record); } else if (type === 'annotation') { boundHighlightFocusChartAnnotation(record); @@ -217,7 +233,7 @@ class TimeseriesChartIntl extends Component { const boundUnhighlightFocusChartAnnotation = unhighlightFocusChartAnnotation.bind(this); function tableRecordMouseleaveListener({ record, type = 'anomaly' }) { if (type === 'anomaly') { - unhighlightFocusChartAnomaly(record); + unhighlightFocusChartAnomaly(); } else { boundUnhighlightFocusChartAnnotation(record); } @@ -594,8 +610,8 @@ class TimeseriesChartIntl extends Component { const data = focusChartData; const contextYScale = this.contextYScale; + const showAnomalyPopover = this.showAnomalyPopover.bind(this); const showFocusChartTooltip = this.showFocusChartTooltip.bind(this); - const hideFocusChartTooltip = this.props.tooltipService.hide.bind(this.props.tooltipService); const focusChart = d3.select('.focus-chart'); @@ -766,6 +782,8 @@ class TimeseriesChartIntl extends Component { ) ); + const that = this; + // Remove dots that are no longer needed i.e. if number of chart points has decreased. dots.exit().remove(); // Create any new dots that are needed i.e. if number of chart points has increased. @@ -773,8 +791,16 @@ class TimeseriesChartIntl extends Component { .enter() .append('circle') .attr('r', LINE_CHART_ANOMALY_RADIUS) + .on('click', function (d) { + d3.event.preventDefault(); + if (d.anomalyScore === undefined) return; + showAnomalyPopover(d, this); + }) .on('mouseover', function (d) { - showFocusChartTooltip(d, this); + // Show the tooltip only if the actions menu isn't active + if (that.state.popoverData === null) { + showFocusChartTooltip(d, this); + } }) .on('mouseout', () => this.props.tooltipService.hide()); @@ -786,6 +812,7 @@ class TimeseriesChartIntl extends Component { .attr('cy', (d) => { return this.focusYScale(d.value); }) + .attr('data-test-subj', (d) => (d.anomalyScore !== undefined ? 'mlAnomalyMarker' : undefined)) .attr('class', (d) => { let markerClass = 'metric-value'; if (d.anomalyScore !== undefined) { @@ -810,6 +837,11 @@ class TimeseriesChartIntl extends Component { .enter() .append('path') .attr('d', d3.svg.symbol().size(MULTI_BUCKET_SYMBOL_SIZE).type('cross')) + .on('click', function (d) { + d3.event.preventDefault(); + if (d.anomalyScore === undefined) return; + showAnomalyPopover(d, this); + }) .on('mouseover', function (d) { showFocusChartTooltip(d, this); }) @@ -821,6 +853,7 @@ class TimeseriesChartIntl extends Component { 'transform', (d) => `translate(${this.focusXScale(d.date)}, ${this.focusYScale(d.value)})` ) + .attr('data-test-subj', 'mlAnomalyMarker') .attr('class', (d) => `anomaly-marker multi-bucket ${getSeverityWithLow(d.anomalyScore).id}`); // Add rectangular markers for any scheduled events. @@ -1479,6 +1512,37 @@ class TimeseriesChartIntl extends Component { this.setContextBrushExtent(new Date(from), new Date(to)); } + showAnomalyPopover(marker, circle) { + const anomalyTime = marker.date.getTime(); + + // The table items could be aggregated, so we have to find the item + // that has the closest timestamp to the selected anomaly from the chart. + const tableItem = this.props.tableData.anomalies.reduce((closestItem, currentItem) => { + const closestItemDelta = Math.abs(anomalyTime - closestItem.source.timestamp); + const currentItemDelta = Math.abs(anomalyTime - currentItem.source.timestamp); + return currentItemDelta < closestItemDelta ? currentItem : closestItem; + }, this.props.tableData.anomalies[0]); + + if (tableItem) { + // Overwrite the timestamp of the possibly aggregated table item with the + // timestamp of the anomaly clicked in the chart so we're able to pick + // the right baseline and deviation time ranges for Log Rate Analysis. + tableItem.source.timestamp = anomalyTime; + + // Calculate the relative coordinates of the clicked anomaly marker + // so we're able to position the popover actions menu above it. + const dotRect = circle.getBoundingClientRect(); + const rootRect = this.rootNode.getBoundingClientRect(); + const x = Math.round(dotRect.x + dotRect.width / 2 - rootRect.x); + const y = Math.round(dotRect.y + dotRect.height / 2 - rootRect.y) - popoverMenuOffset; + + // Hide any active tooltip + this.props.tooltipService.hide(); + // Set the popover state to enable the actions menu + this.setState({ popoverData: tableItem, popoverCoords: [x, y] }); + } + } + showFocusChartTooltip(marker, circle) { const { modelPlotEnabled } = this.props; @@ -1818,6 +1882,7 @@ class TimeseriesChartIntl extends Component { .append('path') .attr('d', d3.svg.symbol().size(MULTI_BUCKET_SYMBOL_SIZE).type('cross')) .attr('transform', (d) => `translate(${focusXScale(d.date)}, ${focusYScale(d.value)})`) + .attr('data-test-subj', 'mlAnomalyMarker') .attr( 'class', (d) => @@ -1830,6 +1895,7 @@ class TimeseriesChartIntl extends Component { .attr('r', LINE_CHART_ANOMALY_RADIUS) .attr('cx', (d) => focusXScale(d.date)) .attr('cy', (d) => focusYScale(d.value)) + .attr('data-test-subj', 'mlAnomalyMarker') .attr( 'class', (d) => @@ -1862,8 +1928,60 @@ class TimeseriesChartIntl extends Component { this.rootNode = componentNode; } + closePopover() { + this.setState({ popoverData: null, popoverCoords: [0, 0] }); + } + + setShowRuleEditorFlyoutFunction = (func) => { + this.setState({ + showRuleEditorFlyout: func, + }); + }; + + unsetShowRuleEditorFlyoutFunction = () => { + this.setState({ + showRuleEditorFlyout: () => {}, + }); + }; + render() { - return
; + return ( + <> + + {this.state.popoverData !== null && ( +
+ this.closePopover()} + panelPaddingSize="none" + anchorPosition="upLeft" + > + this.closePopover()} + sourceIndicesWithGeoFields={this.props.sourceIndicesWithGeoFields} + /> + +
+ )} +
+ + ); } } @@ -1874,6 +1992,7 @@ export const TimeseriesChart = (props) => { if (annotationProp === undefined) { return null; } + return ( { const wrapper = mountWithIntl(); - expect(wrapper.html()).toBe(`
`); + expect(wrapper.html()).toBe('
'); }); }); diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx index af42229d8ac7..66da1e422288 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/components/timeseries_chart/timeseries_chart_with_tooltip.tsx @@ -8,6 +8,7 @@ import React, { FC, useEffect, useState, useCallback, useContext } from 'react'; import { i18n } from '@kbn/i18n'; import { extractErrorMessage } from '@kbn/ml-error-utils'; +import type { MlAnomaliesTableRecord } from '@kbn/ml-anomaly-utils'; import { MlTooltipComponent } from '../../../components/chart_tooltip'; import { TimeseriesChart } from './timeseries_chart'; import { CombinedJob } from '../../../../../common/types/anomaly_detection_jobs'; @@ -17,6 +18,7 @@ import { useMlKibana, useNotifications } from '../../../contexts/kibana'; import { getBoundsRoundedToInterval } from '../../../util/time_buckets'; import { getControlsForDetector } from '../../get_controls_for_detector'; import { MlAnnotationUpdatesContext } from '../../../contexts/ml/ml_annotation_updates_context'; +import { SourceIndicesWithGeoFields } from '../../../explorer/explorer_utils'; interface TimeSeriesChartWithTooltipsProps { bounds: any; @@ -30,6 +32,11 @@ interface TimeSeriesChartWithTooltipsProps { chartProps: any; lastRefresh: number; contextAggregationInterval: any; + tableData?: { + anomalies: MlAnomaliesTableRecord[]; + interval: string; + }; + sourceIndicesWithGeoFields: SourceIndicesWithGeoFields; } export const TimeSeriesChartWithTooltips: FC = ({ bounds, @@ -43,6 +50,11 @@ export const TimeSeriesChartWithTooltips: FC = chartProps, lastRefresh, contextAggregationInterval, + tableData = { + anomalies: [], + interval: 'second', + }, + sourceIndicesWithGeoFields, }) => { const { toasts: toastNotifications } = useNotifications(); const { @@ -132,6 +144,8 @@ export const TimeSeriesChartWithTooltips: FC = showForecast={showForecast} showModelBounds={showModelBounds} tooltipService={tooltipService} + tableData={tableData} + sourceIndicesWithGeoFields={sourceIndicesWithGeoFields} /> )} diff --git a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js index b7b8b7fe6e77..757f4cb06543 100644 --- a/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js +++ b/x-pack/plugins/ml/public/application/timeseriesexplorer/timeseriesexplorer.js @@ -1218,6 +1218,8 @@ export class TimeSeriesExplorer extends React.Component { showForecast={showForecast} showModelBounds={showModelBounds} lastRefresh={lastRefresh} + tableData={tableData} + sourceIndicesWithGeoFields={sourceIndicesWithGeoFields} /> {focusAnnotationError !== undefined && ( <> @@ -1316,7 +1318,7 @@ export class TimeSeriesExplorer extends React.Component { bounds={bounds} tableData={tableData} filter={this.tableFilter} - sourceIndicesWithGeoFields={sourceIndicesWithGeoFields} + sourceIndicesWithGeoFields={this.state.sourceIndicesWithGeoFields} selectedJobs={[ { id: selectedJob.job_id, diff --git a/x-pack/plugins/observability/public/components/burn_rate_rule_editor/burn_rate_rule_editor.tsx b/x-pack/plugins/observability/public/components/burn_rate_rule_editor/burn_rate_rule_editor.tsx index 4579640c6a5e..70451de2cc9e 100644 --- a/x-pack/plugins/observability/public/components/burn_rate_rule_editor/burn_rate_rule_editor.tsx +++ b/x-pack/plugins/observability/public/components/burn_rate_rule_editor/burn_rate_rule_editor.tsx @@ -16,12 +16,6 @@ import { BurnRateRuleParams, WindowSchema } from '../../typings'; import { SloSelector } from './slo_selector'; import { ValidationBurnRateRuleResult } from './validation'; import { createNewWindow, Windows } from './windows'; -import { - ALERT_ACTION, - HIGH_PRIORITY_ACTION, - LOW_PRIORITY_ACTION, - MEDIUM_PRIORITY_ACTION, -} from '../../../common/constants'; import { BURN_RATE_DEFAULTS } from './constants'; import { AlertTimeTable } from './alert_time_table'; @@ -38,54 +32,25 @@ export function BurnRateRuleEditor(props: Props) { }); const [selectedSlo, setSelectedSlo] = useState(undefined); + const [windowDefs, setWindowDefs] = useState(ruleParams?.windows || []); useEffect(() => { setSelectedSlo(initialSlo); + setWindowDefs((previous) => { + if (previous.length > 0) { + return previous; + } + return createDefaultWindows(initialSlo); + }); }, [initialSlo]); const onSelectedSlo = (slo: SLOResponse | undefined) => { setSelectedSlo(slo); - setRuleParams('sloId', slo?.id); - }; - - const [windowDefs, setWindowDefs] = useState( - ruleParams?.windows || [ - createNewWindow(selectedSlo, { - burnRateThreshold: 14.4, - longWindow: { value: 1, unit: 'h' }, - shortWindow: { value: 5, unit: 'm' }, - actionGroup: ALERT_ACTION.id, - }), - createNewWindow(selectedSlo, { - burnRateThreshold: 6, - longWindow: { value: 6, unit: 'h' }, - shortWindow: { value: 30, unit: 'm' }, - actionGroup: HIGH_PRIORITY_ACTION.id, - }), - createNewWindow(selectedSlo, { - burnRateThreshold: 3, - longWindow: { value: 24, unit: 'h' }, - shortWindow: { value: 120, unit: 'm' }, - actionGroup: MEDIUM_PRIORITY_ACTION.id, - }), - createNewWindow(selectedSlo, { - burnRateThreshold: 1, - longWindow: { value: 72, unit: 'h' }, - shortWindow: { value: 360, unit: 'm' }, - actionGroup: LOW_PRIORITY_ACTION.id, - }), - ] - ); - - // When the SLO changes, recalculate the max burn rates - useEffect(() => { setWindowDefs(() => { - const burnRateDefaults = selectedSlo - ? BURN_RATE_DEFAULTS[selectedSlo?.timeWindow.duration] - : BURN_RATE_DEFAULTS['30d']; - return burnRateDefaults.map((partialWindow) => createNewWindow(selectedSlo, partialWindow)); + return createDefaultWindows(slo); }); - }, [selectedSlo]); + setRuleParams('sloId', slo?.id); + }; useEffect(() => { setRuleParams('windows', windowDefs); @@ -131,3 +96,8 @@ export function BurnRateRuleEditor(props: Props) { ); } + +function createDefaultWindows(slo: SLOResponse | undefined) { + const burnRateDefaults = slo ? BURN_RATE_DEFAULTS[slo.timeWindow.duration] : []; + return burnRateDefaults.map((partialWindow) => createNewWindow(slo, partialWindow)); +} diff --git a/x-pack/plugins/observability/public/components/burn_rate_rule_editor/windows.tsx b/x-pack/plugins/observability/public/components/burn_rate_rule_editor/windows.tsx index 125361940c1f..69e05a4537d7 100644 --- a/x-pack/plugins/observability/public/components/burn_rate_rule_editor/windows.tsx +++ b/x-pack/plugins/observability/public/components/burn_rate_rule_editor/windows.tsx @@ -17,7 +17,7 @@ import { EuiTitle, EuiSwitch, } from '@elastic/eui'; -import { SLOResponse } from '@kbn/slo-schema'; +import { CreateSLOInput, SLOResponse } from '@kbn/slo-schema'; import { i18n } from '@kbn/i18n'; import numeral from '@elastic/numeral'; import { v4 } from 'uuid'; @@ -51,7 +51,10 @@ const ACTION_GROUP_OPTIONS = [ { value: LOW_PRIORITY_ACTION.id, text: LOW_PRIORITY_ACTION.name }, ]; -export const calculateMaxBurnRateThreshold = (longWindow: Duration, slo?: SLOResponse) => { +export const calculateMaxBurnRateThreshold = ( + longWindow: Duration, + slo?: SLOResponse | CreateSLOInput +) => { return slo ? Math.floor(toMinutes(toDuration(slo.timeWindow.duration)) / toMinutes(longWindow)) : Infinity; @@ -244,7 +247,7 @@ const getErrorBudgetExhaustionText = ( }); export const createNewWindow = ( - slo?: SLOResponse, + slo?: SLOResponse | CreateSLOInput, partialWindow: Partial = {} ): WindowSchema => { const longWindow = partialWindow.longWindow || { value: 1, unit: 'h' }; diff --git a/x-pack/plugins/observability/public/hooks/use_create_rule.ts b/x-pack/plugins/observability/public/hooks/use_create_rule.ts new file mode 100644 index 000000000000..7c30544105aa --- /dev/null +++ b/x-pack/plugins/observability/public/hooks/use_create_rule.ts @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useMutation } from '@tanstack/react-query'; +import { i18n } from '@kbn/i18n'; +import { BASE_ALERTING_API_PATH, RuleTypeParams } from '@kbn/alerting-plugin/common'; +import { v4 } from 'uuid'; +import { + CreateRuleRequestBody, + CreateRuleResponse, +} from '@kbn/alerting-plugin/common/routes/rule/apis/create'; +import { useKibana } from '../utils/kibana_react'; + +export function useCreateRule() { + const { + http, + notifications: { toasts }, + } = useKibana().services; + + const createRule = useMutation< + CreateRuleResponse, + Error, + { rule: CreateRuleRequestBody } + >( + ['createRule'], + ({ rule }) => { + try { + const ruleId = v4(); + const body = JSON.stringify(rule); + return http.post(`${BASE_ALERTING_API_PATH}/rule/${ruleId}`, { + body, + }); + } catch (e) { + throw new Error(`Unable to create rule: ${e}`); + } + }, + { + onError: (_err) => { + toasts.addDanger( + i18n.translate('xpack.observability.rules.createRule.errorNotification.descriptionText', { + defaultMessage: 'Failed to create rule', + }) + ); + }, + + onSuccess: () => { + toasts.addSuccess( + i18n.translate( + 'xpack.observability.rules.createRule.successNotification.descriptionText', + { + defaultMessage: 'Rule created', + } + ) + ); + }, + } + ); + + return createRule; +} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx index bf3253511829..dfc5fb1a6f56 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/slo_edit_form.tsx @@ -5,25 +5,15 @@ * 2.0. */ -import { - EuiButton, - EuiButtonEmpty, - EuiCheckbox, - EuiFlexGroup, - EuiIconTip, - EuiSpacer, - EuiSteps, -} from '@elastic/eui'; +import { EuiButton, EuiButtonEmpty, EuiFlexGroup, EuiSpacer, EuiSteps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { GetSLOResponse } from '@kbn/slo-schema'; -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback } from 'react'; import { FormProvider, useForm } from 'react-hook-form'; import { InspectSLOPortal } from './common/inspect_slo_portal'; import { EquivalentApiRequest } from './common/equivalent_api_request'; -import { BurnRateRuleFlyout } from '../../slos/components/common/burn_rate_rule_flyout'; import { paths } from '../../../../common/locators/paths'; import { useCreateSlo } from '../../../hooks/slo/use_create_slo'; -import { useFetchRulesForSlo } from '../../../hooks/slo/use_fetch_rules_for_slo'; import { useUpdateSlo } from '../../../hooks/slo/use_update_slo'; import { useKibana } from '../../../utils/kibana_react'; import { SLO_EDIT_FORM_DEFAULT_VALUES } from '../constants'; @@ -32,10 +22,6 @@ import { transformSloResponseToCreateSloForm, transformValuesToUpdateSLOInput, } from '../helpers/process_slo_form_values'; -import { - CREATE_RULE_SEARCH_PARAM, - useAddRuleFlyoutState, -} from '../hooks/use_add_rule_flyout_state'; import { useParseUrlState } from '../hooks/use_parse_url_state'; import { useSectionFormValidation } from '../hooks/use_section_form_validation'; import { useShowSections } from '../hooks/use_show_sections'; @@ -43,6 +29,9 @@ import { CreateSLOForm } from '../types'; import { SloEditFormDescriptionSection } from './slo_edit_form_description_section'; import { SloEditFormIndicatorSection } from './slo_edit_form_indicator_section'; import { SloEditFormObjectiveSection } from './slo_edit_form_objective_section'; +import { useCreateRule } from '../../../hooks/use_create_rule'; +import { createBurnRateRuleRequestBody } from '../helpers/create_burn_rate_rule_request_body'; +import { BurnRateRuleParams } from '../../../typings'; export interface Props { slo?: GetSLOResponse; @@ -57,22 +46,9 @@ export function SloEditForm({ slo }: Props) { } = useKibana().services; const isEditMode = slo !== undefined; - const { data: rules, isInitialLoading } = useFetchRulesForSlo({ - sloIds: slo?.id ? [slo.id] : undefined, - }); - const sloFormValuesFromUrlState = useParseUrlState(); const sloFormValuesFromSloResponse = transformSloResponseToCreateSloForm(slo); - const isAddRuleFlyoutOpen = useAddRuleFlyoutState(isEditMode); - const [isCreateRuleCheckboxChecked, setIsCreateRuleCheckboxChecked] = useState(true); - - useEffect(() => { - if (isEditMode && rules && rules[slo.id].length) { - setIsCreateRuleCheckboxChecked(false); - } - }, [isEditMode, rules, slo]); - const methods = useForm({ defaultValues: SLO_EDIT_FORM_DEFAULT_VALUES, values: sloFormValuesFromUrlState ? sloFormValuesFromUrlState : sloFormValuesFromSloResponse, @@ -97,6 +73,8 @@ export function SloEditForm({ slo }: Props) { const { mutateAsync: createSlo, isLoading: isCreateSloLoading } = useCreateSlo(); const { mutateAsync: updateSlo, isLoading: isUpdateSloLoading } = useUpdateSlo(); + const { mutateAsync: createBurnRateRule, isLoading: isCreateBurnRateRuleLoading } = + useCreateRule(); const handleSubmit = async () => { const isValid = await trigger(); @@ -108,30 +86,15 @@ export function SloEditForm({ slo }: Props) { if (isEditMode) { const processedValues = transformValuesToUpdateSLOInput(values); - - if (isCreateRuleCheckboxChecked) { - await updateSlo({ sloId: slo.id, slo: processedValues }); - navigate( - basePath.prepend( - `${paths.observability.sloEdit(slo.id)}?${CREATE_RULE_SEARCH_PARAM}=true` - ) - ); - } else { - updateSlo({ sloId: slo.id, slo: processedValues }); - navigate(basePath.prepend(paths.observability.slos)); - } + updateSlo({ sloId: slo.id, slo: processedValues }); + navigate(basePath.prepend(paths.observability.slos)); } else { const processedValues = transformCreateSLOFormToCreateSLOInput(values); - - if (isCreateRuleCheckboxChecked) { - const { id } = await createSlo({ slo: processedValues }); - navigate( - basePath.prepend(`${paths.observability.sloEdit(id)}?${CREATE_RULE_SEARCH_PARAM}=true`) - ); - } else { - createSlo({ slo: processedValues }); - navigate(basePath.prepend(paths.observability.slos)); - } + const resp = await createSlo({ slo: processedValues }); + await createBurnRateRule({ + rule: createBurnRateRuleRequestBody({ ...processedValues, id: resp.id }), + }); + navigate(basePath.prepend(paths.observability.slos)); } }; @@ -140,10 +103,6 @@ export function SloEditForm({ slo }: Props) { [navigateToUrl] ); - const handleChangeCheckbox = () => { - setIsCreateRuleCheckboxChecked(!isCreateRuleCheckboxChecked); - }; - return ( <> @@ -175,36 +134,6 @@ export function SloEditForm({ slo }: Props) { ]} /> - - - - {i18n.translate('xpack.observability.slo.sloEdit.createAlert.title', { - defaultMessage: 'Create an', - })}{' '} - - {i18n.translate('xpack.observability.slo.sloEdit.createAlert.ruleName', { - defaultMessage: 'SLO burn rate alert rule', - })} - - - - - } - onChange={handleChangeCheckbox} - /> - - @@ -212,7 +141,7 @@ export function SloEditForm({ slo }: Props) { color="primary" data-test-subj="sloFormSubmitButton" fill - isLoading={isCreateSloLoading || isUpdateSloLoading} + isLoading={isCreateSloLoading || isUpdateSloLoading || isCreateBurnRateRuleLoading} onClick={handleSubmit} > {isEditMode @@ -243,12 +172,6 @@ export function SloEditForm({ slo }: Props) { - - ); } diff --git a/x-pack/plugins/observability/public/pages/slo_edit/components/timeslice_metric/metric_indicator.tsx b/x-pack/plugins/observability/public/pages/slo_edit/components/timeslice_metric/metric_indicator.tsx index b8105814b852..d3098208fa6c 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/components/timeslice_metric/metric_indicator.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/components/timeslice_metric/metric_indicator.tsx @@ -270,10 +270,11 @@ export function MetricIndicator({ indexFields, isLoadingIndex }: MetricIndicator defaultValue={0} render={({ field: { ref, ...field }, fieldState }) => ( field.onChange(Number(event.target.value))} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/helpers/create_burn_rate_rule_request_body.ts b/x-pack/plugins/observability/public/pages/slo_edit/helpers/create_burn_rate_rule_request_body.ts new file mode 100644 index 000000000000..0128d6c7d636 --- /dev/null +++ b/x-pack/plugins/observability/public/pages/slo_edit/helpers/create_burn_rate_rule_request_body.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CreateSLOInput } from '@kbn/slo-schema'; +import { i18n } from '@kbn/i18n'; +import { CreateRuleRequestBody } from '@kbn/alerting-plugin/common/routes/rule/apis/create'; +import { BURN_RATE_DEFAULTS } from '../../../components/burn_rate_rule_editor/constants'; +import { createNewWindow } from '../../../components/burn_rate_rule_editor/windows'; +import { BurnRateRuleParams } from '../../../typings'; + +function createBurnRateWindowsFromSLO(slo: CreateSLOInput) { + const burnRateDefaults = slo + ? BURN_RATE_DEFAULTS[slo?.timeWindow.duration] + : BURN_RATE_DEFAULTS['30d']; + return burnRateDefaults.map((partialWindow) => createNewWindow(slo, partialWindow)); +} + +export function createBurnRateRuleRequestBody( + slo: CreateSLOInput & { id: string } +): CreateRuleRequestBody { + return { + params: { + sloId: slo.id, + windows: createBurnRateWindowsFromSLO(slo), + }, + consumer: 'slo', + schedule: { interval: '1m' }, + tags: [], + name: i18n.translate('xpack.observability.slo.burnRateRule.name', { + defaultMessage: '{name} Burn Rate rule', + values: { name: slo.name }, + }), + rule_type_id: 'slo.rules.burnRate', + actions: [], + enabled: true, + }; +} diff --git a/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.test.tsx b/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.test.tsx index 9ef10ea1d928..f843109f5354 100644 --- a/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.test.tsx +++ b/x-pack/plugins/observability/public/pages/slo_edit/slo_edit.test.tsx @@ -20,6 +20,7 @@ import { useCreateSlo } from '../../hooks/slo/use_create_slo'; import { useFetchApmSuggestions } from '../../hooks/slo/use_fetch_apm_suggestions'; import { useFetchSloDetails } from '../../hooks/slo/use_fetch_slo_details'; import { useUpdateSlo } from '../../hooks/slo/use_update_slo'; +import { useCreateRule } from '../../hooks/use_create_rule'; import { useFetchDataViews } from '../../hooks/use_fetch_data_views'; import { useFetchIndices } from '../../hooks/use_fetch_indices'; import { useKibana } from '../../utils/kibana_react'; @@ -39,6 +40,7 @@ jest.mock('../../hooks/use_fetch_data_views'); jest.mock('../../hooks/slo/use_fetch_slo_details'); jest.mock('../../hooks/slo/use_create_slo'); jest.mock('../../hooks/slo/use_update_slo'); +jest.mock('../../hooks/use_create_rule'); jest.mock('../../hooks/slo/use_fetch_apm_suggestions'); jest.mock('../../hooks/slo/use_capabilities'); @@ -54,6 +56,7 @@ const useFetchDataViewsMock = useFetchDataViews as jest.Mock; const useFetchSloMock = useFetchSloDetails as jest.Mock; const useCreateSloMock = useCreateSlo as jest.Mock; const useUpdateSloMock = useUpdateSlo as jest.Mock; +const useCreateRuleMock = useCreateRule as jest.Mock; const useFetchApmSuggestionsMock = useFetchApmSuggestions as jest.Mock; const useCapabilitiesMock = useCapabilities as jest.Mock; @@ -131,8 +134,9 @@ const mockKibana = (license: ILicense | null = licenseMock) => { }; describe('SLO Edit Page', () => { - const mockCreate = jest.fn(); + const mockCreate = jest.fn(() => Promise.resolve({ id: 'mock-slo-id' })); const mockUpdate = jest.fn(); + const mockCreateRule = jest.fn(); const history = createBrowserHistory(); @@ -163,6 +167,13 @@ describe('SLO Edit Page', () => { mutateAsync: mockCreate, }); + useCreateRuleMock.mockReturnValue({ + isLoading: false, + isSuccess: false, + isError: false, + mutateAsync: mockCreateRule, + }); + useUpdateSloMock.mockReturnValue({ isLoading: false, isSuccess: false, @@ -393,7 +404,7 @@ describe('SLO Edit Page', () => { }); describe('when submitting has completed successfully', () => { - it('navigates to the SLO List page when checkbox to create new rule is not checked', async () => { + it('navigates to the SLO List page', async () => { const slo = buildSlo(); jest.spyOn(Router, 'useParams').mockReturnValue({ sloId: '123' }); @@ -414,52 +425,6 @@ describe('SLO Edit Page', () => { expect(mockNavigate).toBeCalledWith(mockBasePathPrepend(paths.observability.slos)); }); }); - - it('navigates to the SLO Edit page when checkbox to create new rule is checked', async () => { - const slo = buildSlo(); - - jest.spyOn(Router, 'useParams').mockReturnValue({ sloId: '123' }); - jest - .spyOn(Router, 'useLocation') - .mockReturnValue({ pathname: '/slos/123/edit', search: '', state: '', hash: '' }); - - useFetchSloMock.mockReturnValue({ isLoading: false, data: slo }); - - const { getByTestId } = render(); - - expect(getByTestId('sloFormSubmitButton')).toBeEnabled(); - - await waitFor(() => { - fireEvent.click(getByTestId('createNewRuleCheckbox')); - fireEvent.click(getByTestId('sloFormSubmitButton')); - }); - - await waitFor(() => { - expect(mockNavigate).toBeCalledWith( - mockBasePathPrepend(`${paths.observability.sloEdit(slo.id)}?create-rule=true`) - ); - }); - }); - - it('opens the Add Rule Flyout when visiting an existing SLO with search params set', async () => { - const slo = buildSlo(); - - jest.spyOn(Router, 'useParams').mockReturnValue({ sloId: '123' }); - jest.spyOn(Router, 'useLocation').mockReturnValue({ - pathname: '/slos/123/edit', - search: 'create-rule=true', - state: '', - hash: '', - }); - - useFetchSloMock.mockReturnValue({ isLoading: false, data: slo }); - - const { getByTestId } = render(); - - await waitFor(() => { - expect(getByTestId('add-rule-flyout')).toBeTruthy(); - }); - }); }); }); }); diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.test.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.test.ts index afed418ec8d3..2367167b4969 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.test.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.test.ts @@ -208,6 +208,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -216,6 +217,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -358,6 +360,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -366,6 +369,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -490,6 +494,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -498,6 +503,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -732,6 +738,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -740,6 +747,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -850,6 +858,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -858,6 +867,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlerts: {}, @@ -963,6 +973,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -971,6 +982,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -1077,6 +1089,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: { @@ -1087,6 +1100,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, }, @@ -1258,6 +1272,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -1266,6 +1281,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -1388,6 +1404,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -1396,6 +1413,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -1570,6 +1588,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: flapping, flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -1578,6 +1597,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [false, false], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_2: { alertId: 'TEST_ALERT_2', @@ -1586,6 +1606,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: flapping, flapping: true, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_3: { alertId: 'TEST_ALERT_3', @@ -1594,6 +1615,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [false, false], flapping: true, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -1604,6 +1626,7 @@ describe('createLifecycleExecutor', () => { expect(serializedAlerts.state.trackedAlerts).toEqual({ TEST_ALERT_0: { + activeCount: 1, alertId: 'TEST_ALERT_0', alertUuid: 'TEST_ALERT_0_UUID', flapping: true, @@ -1612,6 +1635,7 @@ describe('createLifecycleExecutor', () => { started: '2020-01-01T12:00:00.000Z', }, TEST_ALERT_1: { + activeCount: 1, alertId: 'TEST_ALERT_1', alertUuid: 'TEST_ALERT_1_UUID', flapping: false, @@ -1620,6 +1644,7 @@ describe('createLifecycleExecutor', () => { started: '2020-01-02T12:00:00.000Z', }, TEST_ALERT_2: { + activeCount: 1, alertId: 'TEST_ALERT_2', alertUuid: 'TEST_ALERT_2_UUID', flapping: true, @@ -1628,6 +1653,7 @@ describe('createLifecycleExecutor', () => { started: '2020-01-01T12:00:00.000Z', }, TEST_ALERT_3: { + activeCount: 1, alertId: 'TEST_ALERT_3', alertUuid: 'TEST_ALERT_3_UUID', flapping: true, @@ -1786,6 +1812,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [true, true, true, true], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_1: { alertId: 'TEST_ALERT_1', @@ -1794,6 +1821,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: notFlapping, flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_2: { alertId: 'TEST_ALERT_2', @@ -1802,6 +1830,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: [true, true], flapping: true, pendingRecoveredCount: 0, + activeCount: 0, }, TEST_ALERT_3: { alertId: 'TEST_ALERT_3', @@ -1810,6 +1839,7 @@ describe('createLifecycleExecutor', () => { flappingHistory: notFlapping, flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -1820,6 +1850,7 @@ describe('createLifecycleExecutor', () => { expect(serializedAlerts.state.trackedAlerts).toEqual({ TEST_ALERT_2: { + activeCount: 0, alertId: 'TEST_ALERT_2', alertUuid: 'TEST_ALERT_2_UUID', flapping: true, @@ -1831,6 +1862,7 @@ describe('createLifecycleExecutor', () => { expect(serializedAlerts.state.trackedAlertsRecovered).toEqual({ TEST_ALERT_0: { + activeCount: 0, alertId: 'TEST_ALERT_0', alertUuid: 'TEST_ALERT_0_UUID', flapping: true, @@ -1839,6 +1871,7 @@ describe('createLifecycleExecutor', () => { started: '2020-01-01T12:00:00.000Z', }, TEST_ALERT_1: { + activeCount: 0, alertId: 'TEST_ALERT_1', alertUuid: 'TEST_ALERT_1_UUID', flapping: false, @@ -1847,6 +1880,7 @@ describe('createLifecycleExecutor', () => { started: '2020-01-02T12:00:00.000Z', }, TEST_ALERT_3: { + activeCount: 0, alertId: 'TEST_ALERT_3', alertUuid: 'TEST_ALERT_3_UUID', flapping: false, diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts index 91d30fae7b3d..4bd3b912ae67 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts @@ -290,7 +290,7 @@ export const createLifecycleExecutor = trackedAlertRecoveredIds ); - const { alertUuid, started, flapping, pendingRecoveredCount } = !isNew + const { alertUuid, started, flapping, pendingRecoveredCount, activeCount } = !isNew ? state.trackedAlerts[alertId] : { alertUuid: lifecycleAlertServices.getAlertUuid(alertId), @@ -299,6 +299,7 @@ export const createLifecycleExecutor = ? state.trackedAlertsRecovered[alertId].flapping : false, pendingRecoveredCount: 0, + activeCount: 0, }; const event: ParsedTechnicalFields & ParsedExperimentalFields = { @@ -342,16 +343,20 @@ export const createLifecycleExecutor = flappingHistory, flapping, pendingRecoveredCount, + activeCount, }; }); const trackedEventsToIndex = makeEventsDataMapFor(trackedAlertIds); const newEventsToIndex = makeEventsDataMapFor(newAlertIds); const trackedRecoveredEventsToIndex = makeEventsDataMapFor(trackedAlertRecoveredIds); - const allEventsToIndex = [ - ...getAlertsForNotification(flappingSettings, trackedEventsToIndex), - ...newEventsToIndex, - ]; + const allEventsToIndex = getAlertsForNotification( + flappingSettings, + rule.alertDelay?.active ?? 0, + trackedEventsToIndex, + newEventsToIndex, + { maintenanceWindowIds, timestamp: commonRuleFields[TIMESTAMP] } + ); // Only write alerts if: // - writing is enabled @@ -392,18 +397,34 @@ export const createLifecycleExecutor = } const nextTrackedAlerts = Object.fromEntries( - allEventsToIndex + [...newEventsToIndex, ...trackedEventsToIndex] .filter(({ event }) => event[ALERT_STATUS] !== ALERT_STATUS_RECOVERED) - .map(({ event, flappingHistory, flapping: isCurrentlyFlapping, pendingRecoveredCount }) => { - const alertId = event[ALERT_INSTANCE_ID]!; - const alertUuid = event[ALERT_UUID]!; - const started = new Date(event[ALERT_START]!).toISOString(); - const flapping = isFlapping(flappingSettings, flappingHistory, isCurrentlyFlapping); - return [ - alertId, - { alertId, alertUuid, started, flappingHistory, flapping, pendingRecoveredCount }, - ]; - }) + .map( + ({ + event, + flappingHistory, + flapping: isCurrentlyFlapping, + pendingRecoveredCount, + activeCount, + }) => { + const alertId = event[ALERT_INSTANCE_ID]!; + const alertUuid = event[ALERT_UUID]!; + const started = new Date(event[ALERT_START]!).toISOString(); + const flapping = isFlapping(flappingSettings, flappingHistory, isCurrentlyFlapping); + return [ + alertId, + { + alertId, + alertUuid, + started, + flappingHistory, + flapping, + pendingRecoveredCount, + activeCount, + }, + ]; + } + ) ); const nextTrackedAlertsRecovered = Object.fromEntries( @@ -416,16 +437,32 @@ export const createLifecycleExecutor = event[ALERT_STATUS] === ALERT_STATUS_RECOVERED && (flapping || flappingHistory.filter((f: boolean) => f).length > 0) ) - .map(({ event, flappingHistory, flapping: isCurrentlyFlapping, pendingRecoveredCount }) => { - const alertId = event[ALERT_INSTANCE_ID]!; - const alertUuid = event[ALERT_UUID]!; - const started = new Date(event[ALERT_START]!).toISOString(); - const flapping = isFlapping(flappingSettings, flappingHistory, isCurrentlyFlapping); - return [ - alertId, - { alertId, alertUuid, started, flappingHistory, flapping, pendingRecoveredCount }, - ]; - }) + .map( + ({ + event, + flappingHistory, + flapping: isCurrentlyFlapping, + pendingRecoveredCount, + activeCount, + }) => { + const alertId = event[ALERT_INSTANCE_ID]!; + const alertUuid = event[ALERT_UUID]!; + const started = new Date(event[ALERT_START]!).toISOString(); + const flapping = isFlapping(flappingSettings, flappingHistory, isCurrentlyFlapping); + return [ + alertId, + { + alertId, + alertUuid, + started, + flappingHistory, + flapping, + pendingRecoveredCount, + activeCount, + }, + ]; + } + ) ); return { diff --git a/x-pack/plugins/rule_registry/server/utils/get_alerts_for_notification.test.ts b/x-pack/plugins/rule_registry/server/utils/get_alerts_for_notification.test.ts index b3047303bcb0..abb9ebba6d01 100644 --- a/x-pack/plugins/rule_registry/server/utils/get_alerts_for_notification.test.ts +++ b/x-pack/plugins/rule_registry/server/utils/get_alerts_for_notification.test.ts @@ -14,12 +14,17 @@ import { cloneDeep } from 'lodash'; import { getAlertsForNotification } from './get_alerts_for_notification'; describe('getAlertsForNotification', () => { + const newEventParams = { + maintenanceWindowIds: ['maintenance-window-id'], + timestamp: 'timestamp', + }; const alert1 = { event: { 'kibana.alert.status': ALERT_STATUS_RECOVERED, }, flapping: true, pendingRecoveredCount: 3, + activeCount: 3, }; const alert2 = { event: { @@ -40,13 +45,38 @@ describe('getAlertsForNotification', () => { pendingRecoveredCount: 4, flappingHistory: [true, true], }; + const alert5 = { + event: { + 'kibana.alert.status': ALERT_STATUS_ACTIVE, + }, + activeCount: 1, + pendingRecoveredCount: 0, + flappingHistory: [], + }; test('should set pendingRecoveredCount to zero for all active alerts', () => { - const trackedEvents = [alert4]; - expect(getAlertsForNotification(DEFAULT_FLAPPING_SETTINGS, trackedEvents)) - .toMatchInlineSnapshot(` + const trackedEvents = cloneDeep([alert4]); + const newEvents = cloneDeep([alert5]); + expect( + getAlertsForNotification( + DEFAULT_FLAPPING_SETTINGS, + 0, + trackedEvents, + newEvents, + newEventParams + ) + ).toMatchInlineSnapshot(` Array [ Object { + "activeCount": 2, + "event": Object { + "kibana.alert.status": "active", + }, + "flappingHistory": Array [], + "pendingRecoveredCount": 0, + }, + Object { + "activeCount": 1, "event": Object { "kibana.alert.status": "active", }, @@ -62,10 +92,12 @@ describe('getAlertsForNotification', () => { test('should not remove alerts if the num of recovered alerts is not at the limit', () => { const trackedEvents = cloneDeep([alert1, alert2, alert3]); - expect(getAlertsForNotification(DEFAULT_FLAPPING_SETTINGS, trackedEvents)) - .toMatchInlineSnapshot(` + expect( + getAlertsForNotification(DEFAULT_FLAPPING_SETTINGS, 0, trackedEvents, [], newEventParams) + ).toMatchInlineSnapshot(` Array [ Object { + "activeCount": 0, "event": Object { "kibana.alert.status": "recovered", }, @@ -73,12 +105,14 @@ describe('getAlertsForNotification', () => { "pendingRecoveredCount": 0, }, Object { + "activeCount": 0, "event": Object { "kibana.alert.status": "recovered", }, "flapping": false, }, Object { + "activeCount": 0, "event": Object { "event.action": "active", "kibana.alert.status": "active", @@ -92,10 +126,12 @@ describe('getAlertsForNotification', () => { test('should reset counts and not modify alerts if flapping is disabled', () => { const trackedEvents = cloneDeep([alert1, alert2, alert3]); - expect(getAlertsForNotification(DISABLE_FLAPPING_SETTINGS, trackedEvents)) - .toMatchInlineSnapshot(` + expect( + getAlertsForNotification(DISABLE_FLAPPING_SETTINGS, 0, trackedEvents, [], newEventParams) + ).toMatchInlineSnapshot(` Array [ Object { + "activeCount": 0, "event": Object { "kibana.alert.status": "recovered", }, @@ -103,6 +139,7 @@ describe('getAlertsForNotification', () => { "pendingRecoveredCount": 0, }, Object { + "activeCount": 0, "event": Object { "kibana.alert.status": "recovered", }, @@ -110,6 +147,7 @@ describe('getAlertsForNotification', () => { "pendingRecoveredCount": 0, }, Object { + "activeCount": 0, "event": Object { "kibana.alert.status": "recovered", }, @@ -119,4 +157,106 @@ describe('getAlertsForNotification', () => { ] `); }); + + test('should increment activeCount for all active alerts', () => { + const trackedEvents = cloneDeep([alert4]); + const newEvents = cloneDeep([alert5]); + expect( + getAlertsForNotification( + DEFAULT_FLAPPING_SETTINGS, + 0, + trackedEvents, + newEvents, + newEventParams + ) + ).toMatchInlineSnapshot(` + Array [ + Object { + "activeCount": 2, + "event": Object { + "kibana.alert.status": "active", + }, + "flappingHistory": Array [], + "pendingRecoveredCount": 0, + }, + Object { + "activeCount": 1, + "event": Object { + "kibana.alert.status": "active", + }, + "flappingHistory": Array [ + true, + true, + ], + "pendingRecoveredCount": 0, + }, + ] + `); + }); + + test('should reset activeCount for all recovered alerts', () => { + const trackedEvents = cloneDeep([alert1, alert2]); + expect( + getAlertsForNotification(DEFAULT_FLAPPING_SETTINGS, 0, trackedEvents, [], newEventParams) + ).toMatchInlineSnapshot(` + Array [ + Object { + "activeCount": 0, + "event": Object { + "kibana.alert.status": "recovered", + }, + "flapping": true, + "pendingRecoveredCount": 0, + }, + Object { + "activeCount": 0, + "event": Object { + "kibana.alert.status": "recovered", + }, + "flapping": false, + }, + ] + `); + }); + + test('should not return active alerts if the activeCount is less than the rule alertDelay', () => { + const trackedEvents = cloneDeep([alert4]); + const newEvents = cloneDeep([alert5]); + expect( + getAlertsForNotification( + DEFAULT_FLAPPING_SETTINGS, + 5, + trackedEvents, + newEvents, + newEventParams + ) + ).toMatchInlineSnapshot(`Array []`); + }); + + test('should update active alert to look like a new alert if the activeCount is equal to the rule alertDelay', () => { + const trackedEvents = cloneDeep([alert5]); + expect( + getAlertsForNotification(DEFAULT_FLAPPING_SETTINGS, 2, trackedEvents, [], newEventParams) + ).toMatchInlineSnapshot(` + Array [ + Object { + "activeCount": 2, + "event": Object { + "event.action": "open", + "kibana.alert.duration.us": 0, + "kibana.alert.maintenance_window_ids": Array [ + "maintenance-window-id", + ], + "kibana.alert.start": "timestamp", + "kibana.alert.status": "active", + "kibana.alert.time_range": Object { + "gte": "timestamp", + }, + }, + "flappingHistory": Array [], + "pendingRecoveredCount": 0, + }, + ] + `); + }); }); diff --git a/x-pack/plugins/rule_registry/server/utils/get_alerts_for_notification.ts b/x-pack/plugins/rule_registry/server/utils/get_alerts_for_notification.ts index 878db2a91802..5ec0e5b835ee 100644 --- a/x-pack/plugins/rule_registry/server/utils/get_alerts_for_notification.ts +++ b/x-pack/plugins/rule_registry/server/utils/get_alerts_for_notification.ts @@ -11,32 +11,68 @@ import { ALERT_STATUS, ALERT_STATUS_ACTIVE, ALERT_STATUS_RECOVERED, + ALERT_START, + ALERT_DURATION, EVENT_ACTION, + ALERT_TIME_RANGE, + ALERT_MAINTENANCE_WINDOW_IDS, } from '@kbn/rule-data-utils'; export function getAlertsForNotification( flappingSettings: RulesSettingsFlappingProperties, - trackedEventsToIndex: any[] + alertDelay: number, + trackedEventsToIndex: any[], + newEventsToIndex: any[], + newEventParams: { + // values used to create a new event + maintenanceWindowIds?: string[]; + timestamp: string; + } ) { - return trackedEventsToIndex.map((trackedEvent) => { - if (!flappingSettings.enabled || trackedEvent.event[ALERT_STATUS] === ALERT_STATUS_ACTIVE) { + const events: any[] = []; + for (const trackedEvent of [...newEventsToIndex, ...trackedEventsToIndex]) { + if (trackedEvent.event[ALERT_STATUS] === ALERT_STATUS_ACTIVE) { + const count = trackedEvent.activeCount || 0; + trackedEvent.activeCount = count + 1; trackedEvent.pendingRecoveredCount = 0; - } else if ( - flappingSettings.enabled && - trackedEvent.event[ALERT_STATUS] === ALERT_STATUS_RECOVERED - ) { - if (trackedEvent.flapping) { - const count = trackedEvent.pendingRecoveredCount || 0; - trackedEvent.pendingRecoveredCount = count + 1; - if (trackedEvent.pendingRecoveredCount < flappingSettings.statusChangeThreshold) { - trackedEvent.event[ALERT_STATUS] = ALERT_STATUS_ACTIVE; - trackedEvent.event[EVENT_ACTION] = 'active'; - delete trackedEvent.event[ALERT_END]; - } else { - trackedEvent.pendingRecoveredCount = 0; + // do not index the event if the number of consecutive + // active alerts is less than the rule alertDelay threshold + if (trackedEvent.activeCount < alertDelay) { + // remove from array of events to index + continue; + } else { + const { timestamp, maintenanceWindowIds } = newEventParams; + // if the active count is equal to the alertDelay it is considered a new event + if (trackedEvent.activeCount === alertDelay) { + // update the event to look like a new event + trackedEvent.event[ALERT_DURATION] = 0; + trackedEvent.event[ALERT_START] = timestamp; + trackedEvent.event[ALERT_TIME_RANGE] = { gte: timestamp }; + trackedEvent.event[EVENT_ACTION] = 'open'; + if (maintenanceWindowIds?.length) { + trackedEvent.event[ALERT_MAINTENANCE_WINDOW_IDS] = maintenanceWindowIds; + } } } + } else if (trackedEvent.event[ALERT_STATUS] === ALERT_STATUS_RECOVERED) { + trackedEvent.activeCount = 0; + if (flappingSettings.enabled) { + if (trackedEvent.flapping) { + const count = trackedEvent.pendingRecoveredCount || 0; + trackedEvent.pendingRecoveredCount = count + 1; + if (trackedEvent.pendingRecoveredCount < flappingSettings.statusChangeThreshold) { + trackedEvent.event[ALERT_STATUS] = ALERT_STATUS_ACTIVE; + trackedEvent.event[EVENT_ACTION] = 'active'; + delete trackedEvent.event[ALERT_END]; + } else { + trackedEvent.pendingRecoveredCount = 0; + } + } + } else { + trackedEvent.pendingRecoveredCount = 0; + } } - return trackedEvent; - }); + events.push(trackedEvent); + } + return events; } diff --git a/x-pack/plugins/rule_registry/server/utils/get_updated_flapping_history.test.ts b/x-pack/plugins/rule_registry/server/utils/get_updated_flapping_history.test.ts index 52467f168e64..84685779186d 100644 --- a/x-pack/plugins/rule_registry/server/utils/get_updated_flapping_history.test.ts +++ b/x-pack/plugins/rule_registry/server/utils/get_updated_flapping_history.test.ts @@ -49,6 +49,7 @@ describe('getUpdatedFlappingHistory', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -81,6 +82,7 @@ describe('getUpdatedFlappingHistory', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlerts: {}, @@ -115,6 +117,7 @@ describe('getUpdatedFlappingHistory', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, trackedAlertsRecovered: {}, @@ -150,6 +153,7 @@ describe('getUpdatedFlappingHistory', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, }; @@ -184,6 +188,7 @@ describe('getUpdatedFlappingHistory', () => { flappingHistory: [], flapping: false, pendingRecoveredCount: 0, + activeCount: 0, }, }, }; diff --git a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/integration_tests/pdfmaker.test.ts b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/integration_tests/pdfmaker.test.ts index 2243f68b7ad7..9643a3bbcd4a 100644 --- a/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/integration_tests/pdfmaker.test.ts +++ b/x-pack/plugins/screenshotting/server/formats/pdf/pdf_maker/integration_tests/pdfmaker.test.ts @@ -33,6 +33,7 @@ describe('PdfMaker', () => { branch: 'screenshot-test', buildNum: 567891011, buildSha: 'screenshot-dfdfed0a', + buildShaShort: 'scr-dfdfed0a', dist: false, version: '1000.0.0', buildDate: new Date('2023-05-15T23:12:09.000Z'), diff --git a/x-pack/plugins/screenshotting/server/screenshots/index.test.ts b/x-pack/plugins/screenshotting/server/screenshots/index.test.ts index 4a177a94a147..3c6540f28770 100644 --- a/x-pack/plugins/screenshotting/server/screenshots/index.test.ts +++ b/x-pack/plugins/screenshotting/server/screenshots/index.test.ts @@ -56,6 +56,7 @@ describe('Screenshot Observable Pipeline', () => { branch: 'screenshot-test', buildNum: 567891011, buildSha: 'screenshot-dfdfed0a', + buildShaShort: 'scrn-dfdfed0a', dist: false, version: '5000.0.0', buildDate: new Date('2023-05-15T23:12:09.000Z'), diff --git a/x-pack/plugins/security/server/__snapshots__/prompt_page.test.tsx.snap b/x-pack/plugins/security/server/__snapshots__/prompt_page.test.tsx.snap index f24357ae373f..b6bb95e80744 100644 --- a/x-pack/plugins/security/server/__snapshots__/prompt_page.test.tsx.snap +++ b/x-pack/plugins/security/server/__snapshots__/prompt_page.test.tsx.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`PromptPage renders as expected with additional scripts 1`] = `"ElasticMockedFonts

Some Title

Some Body
Action#1
Action#2
"`; +exports[`PromptPage renders as expected with additional scripts 1`] = `"ElasticMockedFonts

Some Title

Some Body
Action#1
Action#2
"`; -exports[`PromptPage renders as expected without additional scripts 1`] = `"ElasticMockedFonts

Some Title

Some Body
Action#1
Action#2
"`; +exports[`PromptPage renders as expected without additional scripts 1`] = `"ElasticMockedFonts

Some Title

Some Body
Action#1
Action#2
"`; diff --git a/x-pack/plugins/security/server/authentication/__snapshots__/unauthenticated_page.test.tsx.snap b/x-pack/plugins/security/server/authentication/__snapshots__/unauthenticated_page.test.tsx.snap index fb377c8a0b92..8b78fb132c3f 100644 --- a/x-pack/plugins/security/server/authentication/__snapshots__/unauthenticated_page.test.tsx.snap +++ b/x-pack/plugins/security/server/authentication/__snapshots__/unauthenticated_page.test.tsx.snap @@ -1,5 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`UnauthenticatedPage renders as expected 1`] = `"ElasticMockedFonts

We hit an authentication error

Try logging in again, and if the problem persists, contact your system administrator.

"`; +exports[`UnauthenticatedPage renders as expected 1`] = `"ElasticMockedFonts

We hit an authentication error

Try logging in again, and if the problem persists, contact your system administrator.

"`; -exports[`UnauthenticatedPage renders as expected with custom title 1`] = `"My Company NameMockedFonts

We hit an authentication error

Try logging in again, and if the problem persists, contact your system administrator.

"`; +exports[`UnauthenticatedPage renders as expected with custom title 1`] = `"My Company NameMockedFonts

We hit an authentication error

Try logging in again, and if the problem persists, contact your system administrator.

"`; diff --git a/x-pack/plugins/security/server/authentication/authentication_service.test.ts b/x-pack/plugins/security/server/authentication/authentication_service.test.ts index a779d30891b8..3f985df49cef 100644 --- a/x-pack/plugins/security/server/authentication/authentication_service.test.ts +++ b/x-pack/plugins/security/server/authentication/authentication_service.test.ts @@ -19,6 +19,7 @@ import type { ElasticsearchServiceSetup, HttpServiceSetup, HttpServiceStart, + IStaticAssets, KibanaRequest, Logger, LoggerFactory, @@ -63,7 +64,7 @@ describe('AuthenticationService', () => { elasticsearch: jest.Mocked; config: ConfigType; license: jest.Mocked; - buildNumber: number; + staticAssets: IStaticAssets; customBranding: jest.Mocked; }; let mockStartAuthenticationParams: { @@ -96,7 +97,7 @@ describe('AuthenticationService', () => { isTLSEnabled: false, }), license: licenseMock.create(), - buildNumber: 100500, + staticAssets: coreSetupMock.http.staticAssets, customBranding: customBrandingServiceMock.createSetupContract(), }; mockCanRedirectRequest.mockReturnValue(false); @@ -983,7 +984,7 @@ describe('AuthenticationService', () => { expect(mockRenderUnauthorizedPage).toHaveBeenCalledWith({ basePath: mockSetupAuthenticationParams.http.basePath, - buildNumber: 100500, + staticAssets: expect.any(Object), originalURL: '/mock-server-basepath/app/some', }); }); @@ -1015,7 +1016,7 @@ describe('AuthenticationService', () => { expect(mockRenderUnauthorizedPage).toHaveBeenCalledWith({ basePath: mockSetupAuthenticationParams.http.basePath, - buildNumber: 100500, + staticAssets: expect.any(Object), originalURL: '/mock-server-basepath/app/some', }); }); @@ -1050,7 +1051,7 @@ describe('AuthenticationService', () => { expect(mockRenderUnauthorizedPage).toHaveBeenCalledWith({ basePath: mockSetupAuthenticationParams.http.basePath, - buildNumber: 100500, + staticAssets: expect.any(Object), originalURL: '/mock-server-basepath/', }); }); diff --git a/x-pack/plugins/security/server/authentication/authentication_service.ts b/x-pack/plugins/security/server/authentication/authentication_service.ts index d6f955b8b455..cbe4e5f96569 100644 --- a/x-pack/plugins/security/server/authentication/authentication_service.ts +++ b/x-pack/plugins/security/server/authentication/authentication_service.ts @@ -40,12 +40,14 @@ import type { Session } from '../session_management'; import type { UserProfileServiceStartInternal } from '../user_profile'; interface AuthenticationServiceSetupParams { - http: Pick; + http: Pick< + HttpServiceSetup, + 'basePath' | 'csp' | 'registerAuth' | 'registerOnPreResponse' | 'staticAssets' + >; customBranding: CustomBrandingSetup; elasticsearch: Pick; config: ConfigType; license: SecurityLicense; - buildNumber: number; } interface AuthenticationServiceStartParams { @@ -92,7 +94,6 @@ export class AuthenticationService { config, http, license, - buildNumber, elasticsearch, customBranding, }: AuthenticationServiceSetupParams) { @@ -204,8 +205,8 @@ export class AuthenticationService { }); return toolkit.render({ body: renderUnauthenticatedPage({ - buildNumber, basePath: http.basePath, + staticAssets: http.staticAssets, originalURL, customBranding: customBrandingValue, }), diff --git a/x-pack/plugins/security/server/authentication/unauthenticated_page.test.tsx b/x-pack/plugins/security/server/authentication/unauthenticated_page.test.tsx index d65c032911a0..0abd444f8036 100644 --- a/x-pack/plugins/security/server/authentication/unauthenticated_page.test.tsx +++ b/x-pack/plugins/security/server/authentication/unauthenticated_page.test.tsx @@ -26,7 +26,7 @@ describe('UnauthenticatedPage', () => { const body = renderToStaticMarkup( @@ -44,7 +44,7 @@ describe('UnauthenticatedPage', () => { const body = renderToStaticMarkup( diff --git a/x-pack/plugins/security/server/authentication/unauthenticated_page.tsx b/x-pack/plugins/security/server/authentication/unauthenticated_page.tsx index fce29bbe89bc..694f8f16bba0 100644 --- a/x-pack/plugins/security/server/authentication/unauthenticated_page.tsx +++ b/x-pack/plugins/security/server/authentication/unauthenticated_page.tsx @@ -11,6 +11,7 @@ import { renderToStaticMarkup } from 'react-dom/server'; import type { IBasePath } from '@kbn/core/server'; import type { CustomBranding } from '@kbn/core-custom-branding-common'; +import type { IStaticAssets } from '@kbn/core-http-server'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -18,16 +19,21 @@ import { PromptPage } from '../prompt_page'; interface Props { originalURL: string; - buildNumber: number; basePath: IBasePath; + staticAssets: IStaticAssets; customBranding: CustomBranding; } -export function UnauthenticatedPage({ basePath, originalURL, buildNumber, customBranding }: Props) { +export function UnauthenticatedPage({ + basePath, + originalURL, + staticAssets, + customBranding, +}: Props) { return ( ElasticMockedFonts

You do not have permission to access the requested page

Either go back to the previous page or log in as a different user.

"`; +exports[`ResetSessionPage renders as expected 1`] = `"ElasticMockedFonts

You do not have permission to access the requested page

Either go back to the previous page or log in as a different user.

"`; -exports[`ResetSessionPage renders as expected with custom page title 1`] = `"My Company NameMockedFonts

You do not have permission to access the requested page

Either go back to the previous page or log in as a different user.

"`; +exports[`ResetSessionPage renders as expected with custom page title 1`] = `"My Company NameMockedFonts

You do not have permission to access the requested page

Either go back to the previous page or log in as a different user.

"`; diff --git a/x-pack/plugins/security/server/authorization/authorization_service.test.ts b/x-pack/plugins/security/server/authorization/authorization_service.test.ts index a052d6753248..ddc5e26903c2 100644 --- a/x-pack/plugins/security/server/authorization/authorization_service.test.ts +++ b/x-pack/plugins/security/server/authorization/authorization_service.test.ts @@ -76,7 +76,6 @@ it(`#setup returns exposed services`, () => { loggers: loggingSystemMock.create(), kibanaIndexName, packageVersion: 'some-version', - buildNumber: 42, features: mockFeaturesSetup, getSpacesService: mockGetSpacesService, getCurrentUser: jest.fn(), @@ -138,7 +137,6 @@ describe('#start', () => { loggers: loggingSystemMock.create(), kibanaIndexName, packageVersion: 'some-version', - buildNumber: 42, features: featuresPluginMock.createSetup(), getSpacesService: jest .fn() @@ -211,7 +209,6 @@ it('#stop unsubscribes from license and ES updates.', async () => { loggers: loggingSystemMock.create(), kibanaIndexName, packageVersion: 'some-version', - buildNumber: 42, features: featuresPluginMock.createSetup(), getSpacesService: jest .fn() diff --git a/x-pack/plugins/security/server/authorization/authorization_service.tsx b/x-pack/plugins/security/server/authorization/authorization_service.tsx index 16f2ed3b446e..795016874dc9 100644 --- a/x-pack/plugins/security/server/authorization/authorization_service.tsx +++ b/x-pack/plugins/security/server/authorization/authorization_service.tsx @@ -57,7 +57,6 @@ export { Actions } from './actions'; interface AuthorizationServiceSetupParams { packageVersion: string; - buildNumber: number; http: HttpServiceSetup; capabilities: CapabilitiesSetup; getClusterClient: () => Promise; @@ -100,7 +99,6 @@ export class AuthorizationService { http, capabilities, packageVersion, - buildNumber, getClusterClient, license, loggers, @@ -179,7 +177,7 @@ export class AuthorizationService { const next = `${http.basePath.get(request)}${request.url.pathname}${request.url.search}`; const body = renderToString( { const body = renderToStaticMarkup( @@ -44,7 +44,7 @@ describe('ResetSessionPage', () => { const body = renderToStaticMarkup( diff --git a/x-pack/plugins/security/server/authorization/reset_session_page.tsx b/x-pack/plugins/security/server/authorization/reset_session_page.tsx index 85c78ddfcbae..27af66a8a404 100644 --- a/x-pack/plugins/security/server/authorization/reset_session_page.tsx +++ b/x-pack/plugins/security/server/authorization/reset_session_page.tsx @@ -10,6 +10,7 @@ import React from 'react'; import type { IBasePath } from '@kbn/core/server'; import type { CustomBranding } from '@kbn/core-custom-branding-common'; +import type { IStaticAssets } from '@kbn/core-http-server'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -22,18 +23,18 @@ import { PromptPage } from '../prompt_page'; */ export function ResetSessionPage({ logoutUrl, - buildNumber, + staticAssets, basePath, customBranding, }: { logoutUrl: string; - buildNumber: number; + staticAssets: IStaticAssets; basePath: IBasePath; customBranding: CustomBranding; }) { return ( spaces?.spacesService, features, getCurrentUser: (request) => this.getAuthentication().getCurrentUser(request), diff --git a/x-pack/plugins/security/server/prompt_page.test.tsx b/x-pack/plugins/security/server/prompt_page.test.tsx index 268a7ac640e7..754584284035 100644 --- a/x-pack/plugins/security/server/prompt_page.test.tsx +++ b/x-pack/plugins/security/server/prompt_page.test.tsx @@ -25,7 +25,7 @@ describe('PromptPage', () => { const body = renderToStaticMarkup( Some Body
} @@ -45,7 +45,7 @@ describe('PromptPage', () => { const body = renderToStaticMarkup( extends Error { super(message); // For debugging - capture name of subclasses this.name = this.constructor.name; + + if (meta instanceof Error) { + this.stack += `\n----- original error -----\n${meta.stack}`; + } } } diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.test.tsx index b1a838ba7459..1153cced85ba 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.test.tsx @@ -529,4 +529,41 @@ describe('GroupedAlertsTable', () => { } }); }); + + it('sends telemetry data when selected group changes', () => { + jest + .spyOn(window.localStorage, 'getItem') + .mockReturnValue(getMockStorageState(['kibana.alert.rule.name'])); + store = createMockStore({ + ...mockGlobalState, + groups: { + [testProps.tableId]: { + options: mockOptions, + activeGroups: ['kibana.alert.rule.name'], + }, + }, + }); + + const { getByTestId } = render( + + + + ); + + fireEvent.click(getByTestId('group-selector-dropdown')); + fireEvent.click(getByTestId('panel-user.name')); + + expect(mockedTelemetry.reportAlertsGroupingChanged).toHaveBeenCalledWith({ + groupByField: 'user.name', + tableId: testProps.tableId, + }); + + fireEvent.click(getByTestId('group-selector-dropdown')); + fireEvent.click(getByTestId('panel-host.name')); + + expect(mockedTelemetry.reportAlertsGroupingChanged).toHaveBeenCalledWith({ + groupByField: 'host.name', + tableId: testProps.tableId, + }); + }); }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.tsx index f48a288dad64..3382a94d6c70 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/alerts_grouping.tsx @@ -76,8 +76,8 @@ const GroupedAlertsTableComponent: React.FC = (props) const { onGroupChange, onGroupToggle } = useMemo( () => ({ - onGroupChange: (param: { groupByField: string; tableId: string }) => { - telemetry.reportAlertsGroupingChanged(param); + onGroupChange: ({ groupByField, tableId }: { groupByField: string; tableId: string }) => { + telemetry.reportAlertsGroupingChanged({ groupByField, tableId }); }, onGroupToggle: (param: { isOpen: boolean; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/mitre_attack.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/mitre_attack.test.tsx index 4768be2ad278..41a7e7b0e3da 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/mitre_attack.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/mitre_attack.test.tsx @@ -19,7 +19,8 @@ const renderMitreAttack = (contextValue: RightPanelContext) => ); -describe('', () => { +// FLAKY: https://github.com/elastic/kibana/issues/176002 +describe.skip('', () => { it('should render mitre attack information', async () => { const contextValue = { searchHit: mockSearchHit } as unknown as RightPanelContext; diff --git a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts index f3a7070aa7e3..a80b0d9ce15a 100644 --- a/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts +++ b/x-pack/plugins/security_solution/scripts/run_cypress/parallel_serverless.ts @@ -33,10 +33,22 @@ interface ProductType { product_tier: string; } +interface OverrideEntry { + docker_image: string; +} + +interface ProductOverrides { + kibana?: OverrideEntry; + elasticsearch?: OverrideEntry; + fleet?: OverrideEntry; + cluster?: OverrideEntry; +} + interface CreateProjectRequestBody { name: string; region_id: string; product_types?: ProductType[]; + overrides?: ProductOverrides; } interface Project { @@ -61,7 +73,7 @@ const DEFAULT_CONFIGURATION: Readonly = [ const DEFAULT_REGION = 'aws-eu-west-1'; const PROJECT_NAME_PREFIX = 'kibana-cypress-security-solution-ephemeral'; -const BASE_ENV_URL = 'https://console.qa.cld.elstc.co'; +const BASE_ENV_URL = `${process.env.QA_CONSOLE_URL}`; let log: ToolingLog; const API_HEADERS = Object.freeze({ 'kbn-xsrf': 'cypress-creds', @@ -96,6 +108,22 @@ async function createSecurityProject( product_types: productTypes, }; + log.info(`Kibana override flag equals to ${process.env.KIBANA_MKI_USE_LATEST_COMMIT}!`); + if ( + process.env.KIBANA_MKI_USE_LATEST_COMMIT && + process.env.KIBANA_MKI_USE_LATEST_COMMIT === '1' + ) { + const kibanaOverrideImage = `${process.env.BUILDKITE_COMMIT?.substring(0, 12)}`; + log.info( + `Overriding Kibana image in the MKI with docker.elastic.co/kibana-ci/kibana-serverless:sec-sol-qg-${kibanaOverrideImage}` + ); + body.overrides = { + kibana: { + docker_image: `docker.elastic.co/kibana-ci/kibana-serverless:sec-sol-qg-${kibanaOverrideImage}`, + }, + }; + } + try { const response = await axios.post(`${BASE_ENV_URL}/api/v1/serverless/projects/security`, body, { headers: { @@ -570,8 +598,11 @@ ${JSON.stringify(cypressConfigFile, null, 2)} KIBANA_USERNAME: credentials.username, KIBANA_PASSWORD: credentials.password, + // Both CLOUD_SERVERLESS and IS_SERVERLESS are used by the cypress tests. CLOUD_SERVERLESS: true, IS_SERVERLESS: true, + // TEST_CLOUD is used by SvlUserManagerProvider to define if testing against cloud. + TEST_CLOUD: 1, }; if (process.env.DEBUG && !process.env.CI) { diff --git a/x-pack/plugins/security_solution/server/config.mock.ts b/x-pack/plugins/security_solution/server/config.mock.ts index 855cec11ab16..9f61523dbbe8 100644 --- a/x-pack/plugins/security_solution/server/config.mock.ts +++ b/x-pack/plugins/security_solution/server/config.mock.ts @@ -22,6 +22,7 @@ export const createMockConfig = (): ConfigType => { maxTimelineImportPayloadBytes: 10485760, enableExperimental, packagerTaskInterval: '60s', + packagerTaskTimeout: '5m', packagerTaskPackagePolicyUpdateBatchSize: 10, prebuiltRulesPackageVersion: '', alertMergeStrategy: 'missingFields', diff --git a/x-pack/plugins/security_solution/server/config.ts b/x-pack/plugins/security_solution/server/config.ts index adc8fbfb1174..4cb9ff479fff 100644 --- a/x-pack/plugins/security_solution/server/config.ts +++ b/x-pack/plugins/security_solution/server/config.ts @@ -92,14 +92,20 @@ export const configSchema = schema.object({ }), /** - * Artifacts Configuration + * Endpoint Artifacts Configuration: the interval between runs of the task that builds the + * artifacts and associated manifest. */ packagerTaskInterval: schema.string({ defaultValue: '60s' }), + /** + * Endpoint Artifacts Configuration: timeout value for how long the task should run. + */ + packagerTaskTimeout: schema.string({ defaultValue: '20m' }), + /** * Artifacts Configuration for package policy update concurrency */ - packagerTaskPackagePolicyUpdateBatchSize: schema.number({ defaultValue: 10, max: 50, min: 1 }), + packagerTaskPackagePolicyUpdateBatchSize: schema.number({ defaultValue: 25, max: 50, min: 1 }), /** * For internal use. Specify which version of the Detection Rules fleet package to install diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts index a0ad1f9712be..a1988cb7a13a 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.test.ts @@ -19,7 +19,7 @@ import { getMockArtifacts } from './mocks'; import { InvalidInternalManifestError } from '../../services/artifacts/errors'; import { loggingSystemMock } from '@kbn/core/server/mocks'; -describe('task', () => { +describe('Endpoint artifact packager task', () => { const MOCK_TASK_INSTANCE = { id: `${ManifestTaskConstants.TYPE}:1.0.0`, runAt: new Date(), @@ -170,7 +170,7 @@ describe('task', () => { await runTask(manifestManager); - expect(logger.info).toHaveBeenCalledWith('recovering from invalid internal manifest'); + expect(logger.warn).toHaveBeenCalledWith('recovering from invalid internal manifest'); expect(logger.error).toHaveBeenNthCalledWith(1, expect.any(InvalidInternalManifestError)); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts index dafa13141a0c..8547eb6dca11 100644 --- a/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts +++ b/x-pack/plugins/security_solution/server/endpoint/lib/artifacts/task.ts @@ -22,6 +22,10 @@ import { wrapErrorIfNeeded } from '../../utils'; import { EndpointError } from '../../../../common/endpoint/errors'; export const ManifestTaskConstants = { + /** + * No longer used. Timeout value now comes from `xpack.securitySolution.packagerTaskTimeout` + * @deprecated + */ TIMEOUT: '1m', TYPE: 'endpoint:user-artifact-packager', VERSION: '1.0.0', @@ -44,22 +48,37 @@ export class ManifestTask { constructor(setupContract: ManifestTaskSetupContract) { this.endpointAppContext = setupContract.endpointAppContext; this.logger = this.endpointAppContext.logFactory.get(this.getTaskId()); + const { packagerTaskInterval, packagerTaskTimeout, packagerTaskPackagePolicyUpdateBatchSize } = + this.endpointAppContext.serverConfig; + + this.logger.info( + `Registering ${ManifestTaskConstants.TYPE} task with timeout of [${packagerTaskTimeout}], interval of [${packagerTaskInterval}] and policy update batch size of [${packagerTaskPackagePolicyUpdateBatchSize}]` + ); setupContract.taskManager.registerTaskDefinitions({ [ManifestTaskConstants.TYPE]: { title: 'Security Solution Endpoint Exceptions Handler', - timeout: ManifestTaskConstants.TIMEOUT, + timeout: packagerTaskTimeout, createTaskRunner: ({ taskInstance }: { taskInstance: ConcreteTaskInstance }) => { return { run: async () => { - const taskInterval = (await this.endpointAppContext.config()).packagerTaskInterval; - const startTime = new Date().getTime(); + const taskInterval = packagerTaskInterval; + const startTime = new Date(); + + this.logger.info(`Started. Checking for changes to endpoint artifacts`); + await this.runTask(taskInstance.id); + const endTime = new Date().getTime(); - this.logger.debug( - `${ManifestTaskConstants.TYPE} task run took ${endTime - startTime}ms` + + this.logger.info( + `Complete. Task run took ${ + endTime - startTime.getTime() + }ms [ stated: ${startTime.toISOString()} ]` ); + const nextRun = new Date(); + if (taskInterval.endsWith('s')) { const seconds = parseInt(taskInterval.slice(0, -1), 10); nextRun.setSeconds(nextRun.getSeconds() + seconds); @@ -70,12 +89,20 @@ export class ManifestTask { this.logger.error(`Invalid task interval: ${taskInterval}`); return; } + return { state: {}, runAt: nextRun, }; }, - cancel: async () => {}, + cancel: async () => { + // TODO:PT add support for AbortController to Task manager + this.logger.warn( + 'Task run was canceled. Packaging of endpoint artifacts may be taking longer due to the ' + + 'amount of policies/artifacts. Consider increasing the `xpack.securitySolution.packagerTaskTimeout` ' + + 'server configuration setting if this continues' + ); + }, }; }, }, @@ -91,7 +118,7 @@ export class ManifestTask { taskType: ManifestTaskConstants.TYPE, scope: ['securitySolution'], schedule: { - interval: (await this.endpointAppContext.config()).packagerTaskInterval, + interval: this.endpointAppContext.serverConfig.packagerTaskInterval, }, state: {}, params: { version: ManifestTaskConstants.VERSION }, @@ -127,23 +154,29 @@ export class ManifestTask { } try { - let oldManifest: Manifest | null; + let oldManifest: Manifest | null = null; try { // Last manifest we computed, which was saved to ES oldManifest = await manifestManager.getLastComputedManifest(); } catch (e) { + this.logger.error(e); + // Lets recover from a failure in getting the internal manifest map by creating an empty default manifest if (e instanceof InvalidInternalManifestError) { - this.logger.error(e); - this.logger.info('recovering from invalid internal manifest'); + this.logger.warn('recovering from invalid internal manifest'); oldManifest = ManifestManager.createDefaultManifest(); + } else { + this.logger.error( + `unable to recover from error while attempting to retrieve last computed manifest` + ); + + return; } } - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (oldManifest! == null) { - this.logger.debug('Last computed manifest not available yet'); + if (!oldManifest) { + this.logger.info('Last computed manifest not available yet'); return; } @@ -152,10 +185,17 @@ export class ManifestTask { const diff = newManifest.diff(oldManifest); + this.logger.debug( + `New -vs- old manifest diff counts: ${Object.entries(diff).map( + ([diffType, diffItems]) => `${diffType}: ${diffItems.length}` + )}` + ); + const persistErrors = await manifestManager.pushArtifacts( diff.additions as InternalArtifactCompleteSchema[], newManifest ); + if (persistErrors.length) { reportErrors(this.logger, persistErrors); throw new Error('Unable to persist new artifacts.'); @@ -167,8 +207,9 @@ export class ManifestTask { await manifestManager.commit(newManifest); } - // Try dispatching to ingest-manager package policies + // Dispatch updates to Fleet integration policies with new manifest info const dispatchErrors = await manifestManager.tryDispatch(newManifest); + if (dispatchErrors.length) { reportErrors(this.logger, dispatchErrors); throw new Error('Error dispatching manifest.'); @@ -178,9 +219,11 @@ export class ManifestTask { const deleteErrors = await manifestManager.deleteArtifacts( diff.removals.map((artifact) => getArtifactId(artifact)) ); + if (deleteErrors.length) { reportErrors(this.logger, deleteErrors); } + await manifestManager.cleanup(newManifest); } catch (err) { this.logger.error(wrapErrorIfNeeded(err)); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/artifact_client.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/artifact_client.ts index 3e00310a5bb6..24c04ee881b8 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/artifact_client.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/artifact_client.ts @@ -11,9 +11,11 @@ import type { ListArtifactsProps, } from '@kbn/fleet-plugin/server'; import type { ListResult } from '@kbn/fleet-plugin/common'; +import type { FetchAllArtifactsOptions } from '@kbn/fleet-plugin/server/services'; import type { InternalArtifactCompleteSchema } from '../../schemas/artifacts'; -export interface EndpointArtifactClientInterface { +export interface EndpointArtifactClientInterface + extends Pick { getArtifact(id: string): Promise; createArtifact(artifact: InternalArtifactCompleteSchema): Promise; @@ -67,6 +69,15 @@ export class EndpointArtifactClient implements EndpointArtifactClientInterface { return this.fleetArtifacts.listArtifacts(options); } + fetchAll({ + // Our default, unlike the Fleet service, is to NOT include the body of + // the artifact, since we really don't need it when processing all artifacts + includeArtifactBody = false, + ...options + }: FetchAllArtifactsOptions = {}): AsyncIterable { + return this.fleetArtifacts.fetchAll({ ...options, includeArtifactBody }); + } + async createArtifact( artifact: InternalArtifactCompleteSchema ): Promise { diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.test.ts index 9ff37c67e613..1d935ccb905d 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.test.ts @@ -39,6 +39,10 @@ import { EndpointError } from '../../../../../common/endpoint/errors'; import type { Artifact } from '@kbn/fleet-plugin/server'; import { AppFeatureSecurityKey } from '@kbn/security-solution-features/keys'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types/src/response/exception_list_item_schema'; +import { + createFetchAllArtifactsIterableMock, + generateArtifactMock, +} from '@kbn/fleet-plugin/server/services/artifacts/mocks'; const getArtifactObject = (artifact: InternalArtifactSchema) => JSON.parse(Buffer.from(artifact.body!, 'base64').toString()); @@ -76,12 +80,9 @@ describe('ManifestManager', () => { const ARTIFACT_NAME_BLOCKLISTS_WINDOWS = 'endpoint-blocklist-windows-v1'; const ARTIFACT_NAME_BLOCKLISTS_LINUX = 'endpoint-blocklist-linux-v1'; - const mockPolicyListIdsResponse = (items: string[]) => - jest.fn().mockResolvedValue({ - items, - page: 1, - per_page: 100, - total: items.length, + const getMockPolicyFetchAllItemIds = (items: string[]) => + jest.fn(async function* () { + yield items; }); let ARTIFACTS: InternalArtifactCompleteSchema[] = []; @@ -200,9 +201,7 @@ describe('ManifestManager', () => { ( manifestManagerContext.artifactClient as jest.Mocked - ).listArtifacts.mockImplementation(async () => { - return { items: ARTIFACTS as Artifact[], total: 100, page: 1, perPage: 100 }; - }); + ).fetchAll.mockReturnValue(createFetchAllArtifactsIterableMock([ARTIFACTS as Artifact[]])); const manifest = await manifestManager.getLastComputedManifest(); @@ -259,33 +258,26 @@ describe('ManifestManager', () => { ( manifestManagerContext.artifactClient as jest.Mocked - ).listArtifacts.mockImplementation(async () => { - // report the MACOS Exceptions artifact as not found - return { - items: [ + ).fetchAll.mockReturnValue( + createFetchAllArtifactsIterableMock([ + // report the MACOS Exceptions artifact as not found + [ ARTIFACT_TRUSTED_APPS_MACOS, ARTIFACT_EXCEPTIONS_WINDOWS, ARTIFACT_TRUSTED_APPS_WINDOWS, ARTIFACTS_BY_ID[ARTIFACT_ID_EXCEPTIONS_LINUX], ] as Artifact[], - total: 100, - page: 1, - perPage: 100, - }; - }); + ]) + ); const manifest = await manifestManager.getLastComputedManifest(); expect(manifest?.getAllArtifacts()).toStrictEqual(ARTIFACTS.slice(1, 5)); - expect(manifestManagerContext.logger.error).toHaveBeenCalledWith( - new InvalidInternalManifestError( - `artifact id [${ARTIFACT_ID_EXCEPTIONS_MACOS}] not found!`, - { - entry: ARTIFACTS_BY_ID[ARTIFACT_ID_EXCEPTIONS_MACOS], - action: 'removed from internal ManifestManger tracking map', - } - ) + expect(manifestManagerContext.logger.warn).toHaveBeenCalledWith( + "Missing artifacts detected! Internal artifact manifest (SavedObject version [2.0.0]) references [1] artifact IDs that don't exist.\n" + + "First 10 below (run with logging set to 'debug' to see all):\n" + + 'endpoint-exceptionlist-macos-v1-96b76a1a911662053a1562ac14c4ff1e87c2ff550d6fe52e1e0b3790526597d3' ); }); }); @@ -327,7 +319,9 @@ describe('ManifestManager', () => { const manifestManager = new ManifestManager(context); context.exceptionListClient.findExceptionListItem = mockFindExceptionListItemResponses({}); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); context.savedObjectsClient.create = jest .fn() @@ -389,7 +383,9 @@ describe('ManifestManager', () => { .mockImplementation((_type: string, object: InternalManifestSchema) => ({ attributes: object, })); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); const manifest = await manifestManager.buildNewManifest(); @@ -460,7 +456,9 @@ describe('ManifestManager', () => { context.exceptionListClient.findExceptionListItem = mockFindExceptionListItemResponses({ [ENDPOINT_LIST_ID]: { macos: [exceptionListItem] }, }); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); context.savedObjectsClient.create = jest .fn() .mockImplementation((_type: string, object: InternalManifestSchema) => ({ @@ -576,7 +574,7 @@ describe('ManifestManager', () => { .mockImplementation((_type: string, object: InternalManifestSchema) => ({ attributes: object, })); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([ + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ TEST_POLICY_ID_1, TEST_POLICY_ID_2, ]); @@ -679,7 +677,7 @@ describe('ManifestManager', () => { linux: [trustedAppListItem, trustedAppListItemPolicy2], }, }); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([ + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ TEST_POLICY_ID_1, TEST_POLICY_ID_2, ]); @@ -795,7 +793,9 @@ describe('ManifestManager', () => { .mockImplementation((_type: string, object: InternalManifestSchema) => ({ attributes: object, })); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); const manifest = await manifestManager.buildNewManifest(); @@ -878,7 +878,9 @@ describe('ManifestManager', () => { .mockImplementation((_type: string, object: InternalManifestSchema) => ({ attributes: object, })); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); const manifest = await manifestManager.buildNewManifest(); @@ -960,7 +962,9 @@ describe('ManifestManager', () => { .mockImplementation((_type: string, object: InternalManifestSchema) => ({ attributes: object, })); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); const manifest = await manifestManager.buildNewManifest(); @@ -1026,7 +1030,9 @@ describe('ManifestManager', () => { .mockImplementation((_type: string, object: InternalManifestSchema) => ({ attributes: object, })); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); const manifest = await manifestManager.buildNewManifest(); @@ -1068,7 +1074,9 @@ describe('ManifestManager', () => { .mockImplementation((_type: string, object: InternalManifestSchema) => ({ attributes: object, })); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); const manifest = await manifestManager.buildNewManifest(); @@ -1299,12 +1307,9 @@ describe('ManifestManager', () => { }); describe('tryDispatch', () => { - const mockPolicyListResponse = (items: PackagePolicy[]) => - jest.fn().mockResolvedValue({ - items, - page: 1, - per_page: 100, - total: items.length, + const getMockPolicyFetchAllItems = (items: PackagePolicy[]) => + jest.fn(async function* () { + yield items; }); test('Should not dispatch if no policies', async () => { @@ -1313,8 +1318,7 @@ describe('ManifestManager', () => { const manifest = new Manifest({ soVersion: '1.0.0' }); manifest.addEntry(ARTIFACT_EXCEPTIONS_MACOS); - - context.packagePolicyService.list = mockPolicyListResponse([]); + context.packagePolicyService.fetchAllItems = getMockPolicyFetchAllItems([]); await expect(manifestManager.tryDispatch(manifest)).resolves.toStrictEqual([]); @@ -1328,7 +1332,7 @@ describe('ManifestManager', () => { const manifest = new Manifest({ soVersion: '1.0.0' }); manifest.addEntry(ARTIFACT_EXCEPTIONS_MACOS); - context.packagePolicyService.list = mockPolicyListResponse([ + context.packagePolicyService.fetchAllItems = getMockPolicyFetchAllItems([ createPackagePolicyWithConfigMock({ id: TEST_POLICY_ID_1 }), ]); @@ -1346,7 +1350,7 @@ describe('ManifestManager', () => { const manifest = new Manifest({ soVersion: '1.0.0' }); manifest.addEntry(ARTIFACT_EXCEPTIONS_MACOS); - context.packagePolicyService.list = mockPolicyListResponse([ + context.packagePolicyService.fetchAllItems = getMockPolicyFetchAllItems([ createPackagePolicyWithConfigMock({ id: TEST_POLICY_ID_1, config: { @@ -1378,7 +1382,7 @@ describe('ManifestManager', () => { manifest.addEntry(ARTIFACT_EXCEPTIONS_WINDOWS, TEST_POLICY_ID_2); manifest.addEntry(ARTIFACT_TRUSTED_APPS_MACOS, TEST_POLICY_ID_2); - context.packagePolicyService.list = mockPolicyListResponse([ + context.packagePolicyService.fetchAllItems = getMockPolicyFetchAllItems([ createPackagePolicyWithConfigMock({ id: TEST_POLICY_ID_1, config: { @@ -1446,7 +1450,7 @@ describe('ManifestManager', () => { manifest.addEntry(ARTIFACT_EXCEPTIONS_WINDOWS, TEST_POLICY_ID_2); manifest.addEntry(ARTIFACT_TRUSTED_APPS_MACOS, TEST_POLICY_ID_2); - context.packagePolicyService.list = mockPolicyListResponse([ + context.packagePolicyService.fetchAllItems = getMockPolicyFetchAllItems([ createPackagePolicyWithConfigMock({ id: TEST_POLICY_ID_1, config: { @@ -1516,7 +1520,7 @@ describe('ManifestManager', () => { const manifest = new Manifest({ soVersion: '1.0.0', semanticVersion: '1.0.1' }); manifest.addEntry(ARTIFACT_EXCEPTIONS_MACOS); - context.packagePolicyService.list = mockPolicyListResponse([ + context.packagePolicyService.fetchAllItems = getMockPolicyFetchAllItems([ createPackagePolicyWithConfigMock({ id: TEST_POLICY_ID_1, config: { @@ -1557,8 +1561,14 @@ describe('ManifestManager', () => { const context = buildManifestManagerContextMock({}); const manifestManager = new ManifestManager(context); + (context.artifactClient.fetchAll as jest.Mock).mockReturnValue( + createFetchAllArtifactsIterableMock([[generateArtifactMock()]]) + ); + context.exceptionListClient.findExceptionListItem = mockFindExceptionListItemResponses({}); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); context.savedObjectsClient.create = jest .fn() @@ -1581,7 +1591,9 @@ describe('ManifestManager', () => { const manifestManager = new ManifestManager(context); context.exceptionListClient.findExceptionListItem = mockFindExceptionListItemResponses({}); - context.packagePolicyService.listIds = mockPolicyListIdsResponse([TEST_POLICY_ID_1]); + context.packagePolicyService.fetchAllItemIds = getMockPolicyFetchAllItemIds([ + TEST_POLICY_ID_1, + ]); context.savedObjectsClient.create = jest .fn() diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts index 27f528aba271..a1ec74bc57b0 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/manifest_manager/manifest_manager.ts @@ -6,15 +6,17 @@ */ import semver from 'semver'; -import { chunk, isEmpty, isEqual, keyBy } from 'lodash'; +import { isEmpty, isEqual, keyBy } from 'lodash'; import type { ElasticsearchClient } from '@kbn/core/server'; import { type Logger, type SavedObjectsClientContract } from '@kbn/core/server'; import { ENDPOINT_LIST_ID, ENDPOINT_ARTIFACT_LISTS } from '@kbn/securitysolution-list-constants'; -import type { ListResult, PackagePolicy } from '@kbn/fleet-plugin/common'; +import type { PackagePolicy } from '@kbn/fleet-plugin/common'; import type { Artifact, PackagePolicyClient } from '@kbn/fleet-plugin/server'; import type { ExceptionListClient } from '@kbn/lists-plugin/server'; import type { ExceptionListItemSchema } from '@kbn/securitysolution-io-ts-list-types'; import { AppFeatureKey } from '@kbn/security-solution-features/keys'; +import { stringify } from '../../../utils/stringify'; +import { QueueProcessor } from '../../../utils/queue_processor'; import type { AppFeaturesService } from '../../../../lib/app_features_service/app_features_service'; import type { ExperimentalFeatures } from '../../../../../common'; import type { ManifestSchemaVersion } from '../../../../../common/endpoint/schema/common'; @@ -70,24 +72,6 @@ const iterateArtifactsBuildResult = ( } }; -const iterateAllListItems = async ( - pageSupplier: (page: number, perPage: number) => Promise>, - itemCallback: (items: T[]) => void -) => { - let paging = true; - let page = 1; - const perPage = 1000; - - while (paging) { - const { items, total } = await pageSupplier(page, perPage); - - itemCallback(items); - - paging = (page - 1) * perPage + items.length < total; - page++; - } -}; - export interface ManifestManagerContext { savedObjectsClient: SavedObjectsClientContract; artifactClient: EndpointArtifactClientInterface; @@ -407,7 +391,7 @@ export class ManifestManager { } /** - * Writes new artifact SOs. + * Writes new artifact to Fleet * * @param artifacts An InternalArtifactCompleteSchema array representing the artifacts. * @param newManifest A Manifest representing the new manifest @@ -418,7 +402,6 @@ export class ManifestManager { newManifest: Manifest ): Promise { const errors: Error[] = []; - const artifactsToCreate: InternalArtifactCompleteSchema[] = []; for (const artifact of artifacts) { @@ -433,28 +416,58 @@ export class ManifestManager { return errors; } + this.logger.debug(`Creating [${artifactsToCreate.length}] artifacts`); + const { artifacts: fleetArtifacts, errors: createErrors } = await this.artifactClient.bulkCreateArtifacts(artifactsToCreate); + this.logger.info(`Count of artifacts created: ${fleetArtifacts?.length ?? 0}`); + if (createErrors) { errors.push(...createErrors); } + const newArtifactsAddedToManifest: string[] = []; + const artifactsNotCreated: string[] = []; + if (fleetArtifacts) { - const fleetArtfactsByIdentifier: { [key: string]: InternalArtifactCompleteSchema } = {}; + const fleetArtifactsByIdentifier: { [key: string]: InternalArtifactCompleteSchema } = {}; + fleetArtifacts.forEach((fleetArtifact) => { - fleetArtfactsByIdentifier[getArtifactId(fleetArtifact)] = fleetArtifact; + fleetArtifactsByIdentifier[getArtifactId(fleetArtifact)] = fleetArtifact; }); + artifactsToCreate.forEach((artifact) => { const artifactId = getArtifactId(artifact); - const fleetArtifact = fleetArtfactsByIdentifier[artifactId]; + const fleetArtifact = fleetArtifactsByIdentifier[artifactId]; + + if (!fleetArtifact) { + artifactsNotCreated.push(artifactId); + + return; + } - if (!fleetArtifact) return; newManifest.replaceArtifact(fleetArtifact); - this.logger.debug(`New created artifact ${artifactId} added to the manifest`); + newArtifactsAddedToManifest.push(artifactId); }); } + if (artifactsNotCreated.length) { + this.logger.debug( + `A total of [${ + artifactsNotCreated.length + }] artifacts were not created. Prior version of the artifact will remain in manifest.\n${artifactsNotCreated.join( + '\n' + )}` + ); + } + + if (newArtifactsAddedToManifest.length !== 0) { + this.logger.debug( + `Newly created artifacts added to the manifest:\n${newArtifactsAddedToManifest.join('\n')}` + ); + } + return errors; } @@ -469,15 +482,24 @@ export class ManifestManager { if (isEmpty(artifactIds)) { return []; } + const errors = await this.artifactClient.bulkDeleteArtifacts(artifactIds); + if (!isEmpty(errors)) { return errors; } - for (const artifactId of artifactIds) { - this.logger.info(`Cleaned up artifact ${artifactId}`); + + this.logger.info(`Count of cleaned up artifacts: ${artifactIds.length}`); + + if (artifactIds.length !== 0) { + this.logger.debug(`Deleted artifacts from cleanup:\n${artifactIds.join('\n ')}`); } + return []; } catch (err) { + this.logger.error( + `Attempted to delete [${artifactIds.length}] outdated artifacts failed with: ${err.message}\n${err.stack}` + ); return [err]; } } @@ -508,22 +530,35 @@ export class ManifestManager { const fleetArtifacts = await this.listAllArtifacts(); const fleetArtifactsById = keyBy(fleetArtifacts, (artifact) => getArtifactId(artifact)); + const invalidArtifactIds: string[] = []; + // Ensure that all artifacts currently defined in the Manifest have a valid artifact in fleet, + // and remove any that does not have an actual artifact from the manifest for (const entry of manifestSo.attributes.artifacts) { const artifact = fleetArtifactsById[entry.artifactId]; if (!artifact) { - this.logger.error( - new InvalidInternalManifestError(`artifact id [${entry.artifactId}] not found!`, { - entry, - action: 'removed from internal ManifestManger tracking map', - }) - ); + invalidArtifactIds.push(entry.artifactId); } else { manifest.addEntry(artifact, entry.policyId); } } + if (invalidArtifactIds.length) { + this.logger.warn( + `Missing artifacts detected! Internal artifact manifest (SavedObject version [${ + manifestSo.version + }]) references [${ + invalidArtifactIds.length + }] artifact IDs that don't exist.\nFirst 10 below (run with logging set to 'debug' to see all):\n${invalidArtifactIds + .slice(0, 10) + .join('\n')}` + ); + this.logger.debug( + `Artifact ID references that are missing:\n${stringify(invalidArtifactIds)}` + ); + } + return manifest; } catch (error) { if (!error.output || error.output.statusCode !== 404) { @@ -569,15 +604,10 @@ export class ManifestManager { for (const result of results) { iterateArtifactsBuildResult(result, (artifact, policyId) => { - const artifactToAdd = baselineManifest.getArtifact(getArtifactId(artifact)) || artifact; - if (!internalArtifactCompleteSchema.is(artifactToAdd)) { - throw new EndpointError( - `Incomplete artifact detected: ${getArtifactId(artifactToAdd)}`, - artifactToAdd - ); - } - - manifest.addEntry(artifactToAdd, policyId); + manifest.addEntry( + baselineManifest.getArtifact(getArtifactId(artifact)) || artifact, + policyId + ); }); } @@ -592,81 +622,93 @@ export class ManifestManager { * @returns {Promise} Any errors encountered. */ public async tryDispatch(manifest: Manifest): Promise { - const allPackagePolicies: PackagePolicy[] = []; - await iterateAllListItems( - (page, perPage) => this.listEndpointPolicies(page, perPage), - (packagePoliciesBatch) => { - allPackagePolicies.push(...packagePoliciesBatch); - } - ); + const errors: Error[] = []; + const updatedPolicies: string[] = []; + const unChangedPolicies: string[] = []; + const manifestVersion = manifest.getSemanticVersion(); + const execId = Math.random().toString(32).substring(3, 8); + const policyUpdateBatchProcessor = new QueueProcessor({ + batchSize: this.packagerTaskPackagePolicyUpdateBatchSize, + logger: this.logger, + key: `tryDispatch.${execId}`, + batchHandler: async ({ data: currentBatch }) => { + const response = await this.packagePolicyService.bulkUpdate( + this.savedObjectsClient, + this.esClient, + currentBatch + ); - const packagePoliciesToUpdate: PackagePolicy[] = []; + if (!isEmpty(response.failedPolicies)) { + errors.push( + ...response.failedPolicies.map((failedPolicy) => { + if (failedPolicy.error instanceof Error) { + return failedPolicy.error; + } else { + return new Error(failedPolicy.error.message); + } + }) + ); + } - const errors: Error[] = []; - allPackagePolicies.forEach((packagePolicy) => { - const { id } = packagePolicy; - if (packagePolicy.inputs.length > 0 && packagePolicy.inputs[0].config !== undefined) { - const oldManifest = packagePolicy.inputs[0].config.artifact_manifest ?? { - value: {}, - }; - - const newManifestVersion = manifest.getSemanticVersion(); - if (semver.gt(newManifestVersion, oldManifest.value.manifest_version)) { - const serializedManifest = manifest.toPackagePolicyManifest(id); - - if (!manifestDispatchSchema.is(serializedManifest)) { - errors.push(new EndpointError(`Invalid manifest for policy ${id}`, serializedManifest)); - } else if (!manifestsEqual(serializedManifest, oldManifest.value)) { - packagePolicy.inputs[0].config.artifact_manifest = { value: serializedManifest }; - packagePoliciesToUpdate.push(packagePolicy); + if (response.updatedPolicies) { + updatedPolicies.push( + ...response.updatedPolicies.map((policy) => { + return `[${policy.id}][${policy.name}] updated with manifest version: [${manifestVersion}]`; + }) + ); + } + }, + }); + + for await (const policies of this.fetchAllPolicies()) { + for (const packagePolicy of policies) { + const { id, name } = packagePolicy; + + if (packagePolicy.inputs.length > 0 && packagePolicy.inputs[0].config !== undefined) { + const oldManifest = packagePolicy.inputs[0].config.artifact_manifest ?? { + value: {}, + }; + + const newManifestVersion = manifest.getSemanticVersion(); + + if (semver.gt(newManifestVersion, oldManifest.value.manifest_version)) { + const serializedManifest = manifest.toPackagePolicyManifest(id); + + if (!manifestDispatchSchema.is(serializedManifest)) { + errors.push( + new EndpointError(`Invalid manifest for policy ${id}`, serializedManifest) + ); + } else if (!manifestsEqual(serializedManifest, oldManifest.value)) { + packagePolicy.inputs[0].config.artifact_manifest = { value: serializedManifest }; + policyUpdateBatchProcessor.addToQueue(packagePolicy); + } else { + unChangedPolicies.push(`[${id}][${name}] No change in manifest content`); + } } else { - this.logger.debug( - `No change in manifest content for package policy: ${id}. Staying on old version` - ); + unChangedPolicies.push(`[${id}][${name}] No change in manifest version`); } } else { - this.logger.debug(`No change in manifest version for package policy: ${id}`); + errors.push( + new EndpointError(`Package Policy ${id} has no 'inputs[0].config'`, packagePolicy) + ); } - } else { - errors.push( - new EndpointError(`Package Policy ${id} has no 'inputs[0].config'`, packagePolicy) - ); } - }); + } - // Split updates in batches with batch size: packagerTaskPackagePolicyUpdateBatchSize - const updateBatches = chunk( - packagePoliciesToUpdate, - this.packagerTaskPackagePolicyUpdateBatchSize + await policyUpdateBatchProcessor.complete(); + + this.logger.info( + `Processed [${updatedPolicies.length + unChangedPolicies.length}] Policies: updated: [${ + updatedPolicies.length + }], un-changed: [${unChangedPolicies.length}]` ); - for (const currentBatch of updateBatches) { - const response = await this.packagePolicyService.bulkUpdate( - this.savedObjectsClient, - this.esClient, - currentBatch - ); + if (updatedPolicies.length) { + this.logger.debug(`Updated Policies:\n ${updatedPolicies.join('\n ')}`); + } - // Update errors - if (!isEmpty(response.failedPolicies)) { - errors.push( - ...response.failedPolicies.map((failedPolicy) => { - if (failedPolicy.error instanceof Error) { - return failedPolicy.error; - } else { - return new Error(failedPolicy.error.message); - } - }) - ); - } - // Log success updates - for (const updatedPolicy of response.updatedPolicies || []) { - this.logger.debug( - `Updated package policy ${ - updatedPolicy.id - } with manifest version ${manifest.getSemanticVersion()}` - ); - } + if (unChangedPolicies.length) { + this.logger.debug(`Un-changed Policies:\n ${unChangedPolicies.join('\n ')}`); } return errors; @@ -696,31 +738,24 @@ export class ManifestManager { this.logger.info(`Committed manifest ${manifest.getSemanticVersion()}`); } - private async listEndpointPolicies( - page: number, - perPage: number - ): Promise> { - return this.packagePolicyService.list(this.savedObjectsClient, { - page, - perPage, + private fetchAllPolicies(): AsyncIterable { + return this.packagePolicyService.fetchAllItems(this.savedObjectsClient, { kuery: 'ingest-package-policies.package.name:endpoint', }); } private async listEndpointPolicyIds(): Promise { const allPolicyIds: string[] = []; - await iterateAllListItems( - (page, perPage) => { - return this.packagePolicyService.listIds(this.savedObjectsClient, { - page, - perPage, - kuery: 'ingest-package-policies.package.name:endpoint', - }); - }, - (packagePolicyIdsBatch) => { - allPolicyIds.push(...packagePolicyIdsBatch); - } - ); + const idFetcher = this.packagePolicyService.fetchAllItemIds(this.savedObjectsClient, { + kuery: 'ingest-package-policies.package.name:endpoint', + }); + + for await (const itemIds of idFetcher) { + allPolicyIds.push(...itemIds); + } + + this.logger.debug(`Retrieved [${allPolicyIds.length}] endpoint integration policy IDs`); + return allPolicyIds; } @@ -733,70 +768,68 @@ export class ManifestManager { * @returns Artifact[] */ private async listAllArtifacts(): Promise { - const fleetArtifacts = []; - const perPage = 100; - let page = 1; + const fleetArtifacts: Artifact[] = []; + let total = 0; - let fleetArtifactsResponse = await this.artifactClient.listArtifacts({ - perPage, - page, - }); - fleetArtifacts.push(...fleetArtifactsResponse.items); - - while ( - fleetArtifactsResponse.total > fleetArtifacts.length && - !isEmpty(fleetArtifactsResponse.items) - ) { - page += 1; - fleetArtifactsResponse = await this.artifactClient.listArtifacts({ - perPage, - page, - }); - fleetArtifacts.push(...fleetArtifactsResponse.items); + for await (const artifacts of this.artifactClient.fetchAll()) { + fleetArtifacts.push(...artifacts); + total += artifacts.length; } + + this.logger.info(`Count of current stored artifacts: ${total}`); + return fleetArtifacts; } /** - * Cleanup .fleet-artifacts index if there are some orphan artifacts + * Pulls in all artifacts from Fleet and checks to ensure they are all being referenced + * by the Manifest. If any are found to not be in the current Manifest (orphan), they + * are cleaned up (deleted) */ public async cleanup(manifest: Manifest) { - try { - const fleetArtifacts = await this.listAllArtifacts(); - if (isEmpty(fleetArtifacts)) { - return; - } - - const badArtifacts = []; - const badArtifactIds = []; + const badArtifactIds: string[] = []; + const errors: string[] = []; + const artifactDeletionProcess = new QueueProcessor({ + batchSize: this.packagerTaskPackagePolicyUpdateBatchSize, + logger: this.logger, + key: 'cleanup', + batchHandler: async ({ batch, data }) => { + const deleteErrors = await this.artifactClient.bulkDeleteArtifacts(data); + + badArtifactIds.push(...data); + + if (deleteErrors.length) { + errors.push( + `Delete batch #[${batch}] with [${data.length}] items:\n${stringify(deleteErrors)}` + ); + } + }, + }); - const manifestArtifactsIds = manifest - .getAllArtifacts() - .map((artifact) => getArtifactId(artifact)); + const validArtifactIds = manifest.getAllArtifacts().map((artifact) => getArtifactId(artifact)); - for (const fleetArtifact of fleetArtifacts) { - const artifactId = getArtifactId(fleetArtifact); - const isArtifactInManifest = manifestArtifactsIds.includes(artifactId); + for await (const artifacts of this.artifactClient.fetchAll()) { + for (const artifact of artifacts) { + const artifactId = getArtifactId(artifact); + const isArtifactInManifest = validArtifactIds.includes(artifactId); if (!isArtifactInManifest) { - badArtifacts.push(fleetArtifact); - badArtifactIds.push(artifactId); + artifactDeletionProcess.addToQueue(artifactId); } } + } - if (isEmpty(badArtifacts)) { - return; - } + await artifactDeletionProcess.complete(); + if (errors.length > 0) { this.logger.error( - new EndpointError(`Cleaning up ${badArtifacts.length} orphan artifacts`, badArtifacts) + `The following errors were encountered while attempting to delete [${ + badArtifactIds.length + }] orphaned artifacts:\n${stringify(errors)}` ); - - await this.artifactClient.bulkDeleteArtifacts(badArtifactIds); - - this.logger.info(`All orphan artifacts has been removed successfully`); - } catch (error) { - this.logger.error(new EndpointError('There was an error cleaning orphan artifacts', error)); + } else if (badArtifactIds.length > 0) { + this.logger.info(`Count of orphan artifacts cleaned up: ${badArtifactIds.length}`); + this.logger.debug(`Orphan artifacts deleted from Fleet:\n${stringify(badArtifactIds)}`); } } } diff --git a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/mocks.ts b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/mocks.ts index 2acfa7b7b479..1a1dd701e980 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/artifacts/mocks.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/artifacts/mocks.ts @@ -65,6 +65,7 @@ export const createEndpointArtifactClientMock = ( bulkDeleteArtifacts: jest.fn(async (...args) => endpointArtifactClientMocked.bulkDeleteArtifacts(...args) ), + fetchAll: jest.fn((...args) => endpointArtifactClientMocked.fetchAll(...args)), _esClient: esClient, }; }; diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/queue_processor.ts b/x-pack/plugins/security_solution/server/endpoint/utils/queue_processor.ts new file mode 100644 index 000000000000..f4f3e4ac7685 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/utils/queue_processor.ts @@ -0,0 +1,152 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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'; + +export interface QueueProcessorOptions { + batchHandler: (batch: { batch: number; data: T[] }) => Promise; + batchSize?: number; + logger?: Logger; + /** + * Used when `logger` is passed. It will be used to define the logging messages context path. + * Defaults to the name of the callback provided in `batchHandler` + */ + key?: string; +} + +/** + * Process an un-bound amount of items in batches. Each batch is process once the queued reach the + * `batchSize`, thus processing is gradually executed ensuring that data is not held in memory + * for too long. Once all items are added to the Queue, calling + * `.complete()` will ensure they are all processed. + * + * @example + * const processor = new QueueProcessor<{ id: string }>({ + * batchHandler: ({ data, batch }) => { + * // data === array of `{ id: string }` + * // batch === batch number + * } + * }); + * + * const myIdList = [ .... ]; // Array with 50 string + * + * for (const id of myIdList) { + * batchHandler.addToQueue({ id: id}); + * } + * + * await processor.complete(); + */ +export class QueueProcessor { + private readonly batchSize: number; + private readonly batchHandler: QueueProcessorOptions['batchHandler']; + private readonly logger: Logger | undefined = undefined; + + private queue: T[] = []; + private processingPromise: Promise | undefined = undefined; + private batchCount = 0; + private itemsProcessedCount = 0; + + constructor({ + batchHandler, + batchSize = 10, + logger, + key = 'QueueProcessor', + }: QueueProcessorOptions) { + if (batchSize < 1 || !Number.isFinite(batchSize)) { + throw new Error(`batchSize must be a number greater than zero`); + } + + this.batchSize = batchSize; + this.batchHandler = batchHandler; + this.logger = logger ? logger.get(key) : undefined; + } + + protected log( + message: string, + output: keyof Pick = 'info' + ): void { + if (this.logger) { + this.logger[output](message); + } + } + + protected async processQueue(all: boolean = false) { + if (this.processingPromise || this.queue.length === 0) { + return; + } + + const runThroughQueue = async () => { + let hasMoreData = true; + + while (hasMoreData) { + try { + if (all || this.queue.length >= this.batchSize) { + const batchPage = this.queue.splice(0, this.batchSize); + const batchPageSize = batchPage.length; + const remainingItemsSize = this.queue.length; + + hasMoreData = (all && remainingItemsSize > 0) || remainingItemsSize >= this.batchSize; + this.itemsProcessedCount += batchPageSize; + this.batchCount++; + + try { + this.log( + `Processing batch [${this.batchCount}] with [${batchPageSize}] items. Items remaining in queue: [${remainingItemsSize}]`, + 'debug' + ); + await this.batchHandler({ batch: this.batchCount, data: batchPage }); + } catch (err) { + this.log( + `batchHandler threw error (below). Will continue on to next batch page:\n${err}`, + 'debug' + ); + // ignore errors in the batch page processing and keep going to process others. + // callback should have handled errors that its process might throw + } + } else { + hasMoreData = false; + } + } catch (err) { + hasMoreData = false; + throw err; + } + } + }; + + this.processingPromise = runThroughQueue().finally(() => { + this.processingPromise = undefined; + }); + + return this.processingPromise; + } + + /** + * Adds an update to the queue + */ + public addToQueue(...data: T[]) { + this.queue.push(...data); + this.processQueue(); + } + + /** + * Flushes the queue and awaits processing of all remaining updates. + * + * **IMPORTANT**: Always make sure `complete()` is called to ensure no items are left in the queue + */ + public async complete(): Promise { + if (this.processingPromise) { + await this.processingPromise.finally(() => {}); + } + + await this.processQueue(true); + + this.log( + `Processed [${this.batchCount}] batches and a total of [${this.itemsProcessedCount}] items`, + 'debug' + ); + } +} diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index aaa104533e08..0bc81fc0b17f 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -532,7 +532,7 @@ export class Plugin implements ISecuritySolutionPlugin { artifactClient, exceptionListClient, packagePolicyService: plugins.fleet.packagePolicyService, - logger, + logger: this.pluginContext.logger.get('ManifestManager'), experimentalFeatures: config.experimentalFeatures, packagerTaskPackagePolicyUpdateBatchSize: config.packagerTaskPackagePolicyUpdateBatchSize, esClient: core.elasticsearch.client.asInternalUser, diff --git a/x-pack/plugins/task_manager/server/polling_lifecycle.ts b/x-pack/plugins/task_manager/server/polling_lifecycle.ts index 20a63377b41e..475895639fc1 100644 --- a/x-pack/plugins/task_manager/server/polling_lifecycle.ts +++ b/x-pack/plugins/task_manager/server/polling_lifecycle.ts @@ -173,7 +173,7 @@ export class TaskPollingLifecycle implements ITaskEventEmitter { + it('should generate expected events with a alertDelay', async () => { + const ACTIVE_PATH = 'kibana.alert.rule.execution.metrics.alert_counts.active'; + const NEW_PATH = 'kibana.alert.rule.execution.metrics.alert_counts.new'; + const RECOVERED_PATH = 'kibana.alert.rule.execution.metrics.alert_counts.recovered'; + const ACTION_PATH = 'kibana.alert.rule.execution.metrics.number_of_triggered_actions'; + const { body: createdAction } = await supertest .post(`${getUrlPrefix(space.id)}/api/actions/connector`) .set('kbn-xsrf', 'foo') @@ -1863,7 +1869,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) { // pattern of when the alert should fire const pattern = { - instance: [true, true, true, false, true], + instance: [true, true, true, true, false, true], }; const response = await supertest @@ -1874,6 +1880,7 @@ export default function eventLogTests({ getService }: FtrProviderContext) { rule_type_id: 'test.patternFiring', schedule: { interval: '1s' }, throttle: null, + notify_when: null, params: { pattern, }, @@ -1882,9 +1889,14 @@ export default function eventLogTests({ getService }: FtrProviderContext) { id: createdAction.id, group: 'default', params: {}, + frequency: { + summary: false, + throttle: null, + notify_when: RuleNotifyWhen.CHANGE, + }, }, ], - notification_delay: { + alert_delay: { active: 3, }, }) @@ -1904,101 +1916,48 @@ export default function eventLogTests({ getService }: FtrProviderContext) { provider: 'alerting', actions: new Map([ // make sure the counts of the # of events per type are as expected - ['execute-start', { gte: 5 }], - ['execute', { gte: 5 }], - ['new-instance', { equal: 2 }], - ['active-instance', { gte: 1 }], + ['execute-start', { equal: 6 }], + ['execute', { equal: 6 }], + ['new-instance', { equal: 1 }], + ['active-instance', { equal: 2 }], ['recovered-instance', { equal: 1 }], ]), }); }); - const actualTriggeredActions = events - .filter((event) => event?.event?.action === 'execute') - .reduce( - (acc, event) => - acc + - (event?.kibana?.alert?.rule?.execution?.metrics - ?.number_of_triggered_actions as number), - 0 - ); - expect(actualTriggeredActions).to.eql(1); - }); - - it('should generate expected events with a notificationDelay with AAD', 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); - - // pattern of when the alert should fire - const pattern = { - instance: [true, true, true, false, true], - }; - - const response = await supertest - .post(`${getUrlPrefix(space.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - rule_type_id: 'test.patternFiringAad', - schedule: { interval: '1s' }, - throttle: null, - params: { - pattern, - }, - actions: [ - { - id: createdAction.id, - group: 'default', - params: {}, - }, - ], - notification_delay: { - active: 3, - }, - }) - ); - - expect(response.status).to.eql(200); - const alertId = response.body.id; - objectRemover.add(space.id, alertId, 'rule', 'alerting'); + const executeEvents = events.filter((event) => event?.event?.action === 'execute'); - // get the events we're expecting - const events = await retry.try(async () => { - return await getEventLog({ - getService, - spaceId: space.id, - type: 'alert', - id: alertId, - provider: 'alerting', - actions: new Map([ - // make sure the counts of the # of events per type are as expected - ['execute-start', { gte: 5 }], - ['execute', { gte: 5 }], - ['new-instance', { equal: 2 }], - ['active-instance', { gte: 1 }], - ['recovered-instance', { equal: 1 }], - ]), - }); + // first two executions do not create the active alert + executeEvents.slice(0, 1).forEach((event) => { + expect(get(event, ACTIVE_PATH)).to.be(0); + expect(get(event, NEW_PATH)).to.be(0); + expect(get(event, RECOVERED_PATH)).to.be(0); + expect(get(event, ACTION_PATH)).to.be(0); }); - const actualTriggeredActions = events - .filter((event) => event?.event?.action === 'execute') - .reduce( - (acc, event) => - acc + - (event?.kibana?.alert?.rule?.execution?.metrics - ?.number_of_triggered_actions as number), - 0 - ); - expect(actualTriggeredActions).to.eql(1); + // third executions creates the delayed active alert and triggers actions + expect(get(executeEvents[2], ACTIVE_PATH)).to.be(1); + expect(get(executeEvents[2], NEW_PATH)).to.be(1); + expect(get(executeEvents[2], RECOVERED_PATH)).to.be(0); + expect(get(executeEvents[2], ACTION_PATH)).to.be(1); + + // fourth execution + expect(get(executeEvents[3], ACTIVE_PATH)).to.be(1); + expect(get(executeEvents[3], NEW_PATH)).to.be(0); + expect(get(executeEvents[3], RECOVERED_PATH)).to.be(0); + expect(get(executeEvents[3], ACTION_PATH)).to.be(0); + + // fifth recovered execution + expect(get(executeEvents[4], ACTIVE_PATH)).to.be(0); + expect(get(executeEvents[4], NEW_PATH)).to.be(0); + expect(get(executeEvents[4], RECOVERED_PATH)).to.be(1); + expect(get(executeEvents[4], ACTION_PATH)).to.be(0); + + // sixth execution does not create the active alert + expect(get(executeEvents[5], ACTIVE_PATH)).to.be(0); + expect(get(executeEvents[5], NEW_PATH)).to.be(0); + expect(get(executeEvents[5], RECOVERED_PATH)).to.be(0); + expect(get(executeEvents[5], ACTION_PATH)).to.be(0); }); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/notification_delay.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alert_delay.ts similarity index 82% rename from x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/notification_delay.ts rename to x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alert_delay.ts index 2b632686d579..7062c1c65fd9 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/notification_delay.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alert_delay.ts @@ -12,7 +12,7 @@ import { getUrlPrefix, getTestRuleData, ObjectRemover } from '../../../../common import { Spaces } from '../../../scenarios'; // eslint-disable-next-line import/no-default-export -export default function createNotificationDelayTests({ getService }: FtrProviderContext) { +export default function createAlertDelayTests({ getService }: FtrProviderContext) { const es = getService('es'); const supertestWithoutAuth = getService('supertestWithoutAuth'); const retry = getService('retry'); @@ -22,7 +22,7 @@ export default function createNotificationDelayTests({ getService }: FtrProvider const ACTIVE_PATH = 'alertInstances.instance.meta.activeCount'; const RECOVERED_PATH = 'alertRecoveredInstances.instance.meta.activeCount'; - describe('Notification Delay', () => { + describe('Alert Delay', () => { let actionId: string; const objectRemover = new ObjectRemover(supertestWithoutAuth); @@ -37,20 +37,7 @@ export default function createNotificationDelayTests({ getService }: FtrProvider afterEach(() => objectRemover.removeAll()); - it('should clear the activeCount if the notificationDelay is not configured for the rule', async () => { - const start = new Date().toISOString(); - const pattern = { - instance: [true], - }; - - const ruleId = await createRule(actionId, pattern); - objectRemover.add(space.id, ruleId, 'rule', 'alerting'); - - const state = await getAlertState(start, ruleId, 0); - expect(get(state, ACTIVE_PATH)).to.eql(0); - }); - - it('should update the activeCount when alert is active and clear when recovered if the notificationDelay is configured for the rule', async () => { + it('should update the activeCount when alert is active and clear when recovered', async () => { let start = new Date().toISOString(); const pattern = { instance: [true, true, true, false, true], @@ -79,7 +66,7 @@ export default function createNotificationDelayTests({ getService }: FtrProvider expect(get(state, ACTIVE_PATH)).to.eql(1); }); - it('should reset the activeCount when count of consecutive active alerts exceeds the notificationDelay count', async () => { + it('should continue incrementing the activeCount when count of consecutive active alerts exceeds the alertDelay count', async () => { let start = new Date().toISOString(); const pattern = { instance: [true, true, true, true, true], @@ -96,16 +83,16 @@ export default function createNotificationDelayTests({ getService }: FtrProvider expect(get(state, ACTIVE_PATH)).to.eql(2); start = new Date().toISOString(); - state = await getAlertState(start, ruleId, 0, true); - expect(get(state, ACTIVE_PATH)).to.eql(0); + state = await getAlertState(start, ruleId, 3, true); + expect(get(state, ACTIVE_PATH)).to.eql(3); start = new Date().toISOString(); - state = await getAlertState(start, ruleId, 1, true); - expect(get(state, ACTIVE_PATH)).to.eql(1); + state = await getAlertState(start, ruleId, 4, true); + expect(get(state, ACTIVE_PATH)).to.eql(4); start = new Date().toISOString(); - state = await getAlertState(start, ruleId, 2, true); - expect(get(state, ACTIVE_PATH)).to.eql(2); + state = await getAlertState(start, ruleId, 5, true); + expect(get(state, ACTIVE_PATH)).to.eql(5); }); }); @@ -187,7 +174,7 @@ export default function createNotificationDelayTests({ getService }: FtrProvider params: {}, }, ], - ...(activeCount ? { notification_delay: { active: activeCount } } : {}), + ...(activeCount ? { alert_delay: { active: activeCount } } : {}), }) ) .expect(200); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_alert_delay.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_alert_delay.ts new file mode 100644 index 000000000000..f7e2876e9775 --- /dev/null +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_alert_delay.ts @@ -0,0 +1,665 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { get } from 'lodash'; +import { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { IValidatedEvent } from '@kbn/event-log-plugin/server'; +import type { Alert } from '@kbn/alerts-as-data-utils'; +import { + ALERT_ACTION_GROUP, + ALERT_DURATION, + ALERT_END, + ALERT_RULE_CATEGORY, + ALERT_RULE_CONSUMER, + ALERT_RULE_EXECUTION_UUID, + ALERT_RULE_NAME, + ALERT_RULE_PARAMETERS, + ALERT_RULE_PRODUCER, + ALERT_RULE_TAGS, + ALERT_RULE_TYPE_ID, + ALERT_RULE_UUID, + ALERT_START, + ALERT_STATUS, + ALERT_TIME_RANGE, + ALERT_UUID, + ALERT_WORKFLOW_STATUS, + EVENT_ACTION, + EVENT_KIND, + SPACE_IDS, +} from '@kbn/rule-data-utils'; +import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; +import { ES_TEST_INDEX_NAME, ESTestIndexTool } from '@kbn/alerting-api-integration-helpers'; +import { FtrProviderContext } from '../../../../../common/ftr_provider_context'; +import { Spaces } from '../../../../scenarios'; +import { + getEventLog, + getTestRuleData, + getUrlPrefix, + ObjectRemover, + TaskManagerDoc, +} from '../../../../../common/lib'; + +// eslint-disable-next-line import/no-default-export +export default function createAlertsAsDataAlertDelayInstallResourcesTest({ + getService, +}: FtrProviderContext) { + const ACTIVE_PATH = 'kibana.alert.rule.execution.metrics.alert_counts.active'; + const NEW_PATH = 'kibana.alert.rule.execution.metrics.alert_counts.new'; + const RECOVERED_PATH = 'kibana.alert.rule.execution.metrics.alert_counts.recovered'; + const ACTION_PATH = 'kibana.alert.rule.execution.metrics.number_of_triggered_actions'; + const UUID_PATH = 'kibana.alert.rule.execution.uuid'; + + const es = getService('es'); + const retry = getService('retry'); + const supertestWithoutAuth = getService('supertestWithoutAuth'); + const objectRemover = new ObjectRemover(supertestWithoutAuth); + const esTestIndexTool = new ESTestIndexTool(es, retry); + + type PatternFiringAlert = Alert & { patternIndex: number; instancePattern: boolean[] }; + // type AlwaysFiringAlert = Alert & { patternIndex: number; instancePattern: boolean[] }; + + const alertsAsDataIndex = '.alerts-test.patternfiring.alerts-default'; + const alwaysFiringAlertsAsDataIndex = + '.internal.alerts-observability.test.alerts.alerts-default-000001'; + const timestampPattern = /\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z/; + + describe('alerts as data', () => { + before(async () => { + await esTestIndexTool.destroy(); + await esTestIndexTool.setup(); + await es.deleteByQuery({ + index: [alertsAsDataIndex, alwaysFiringAlertsAsDataIndex], + query: { match_all: {} }, + conflicts: 'proceed', + }); + }); + afterEach(() => objectRemover.removeAll()); + after(async () => { + await objectRemover.removeAll(); + await esTestIndexTool.destroy(); + await es.deleteByQuery({ + index: [alertsAsDataIndex, alwaysFiringAlertsAsDataIndex], + query: { match_all: {} }, + conflicts: 'proceed', + }); + }); + + it('should generate expected events with a alertDelay with AAD', async () => { + const { body: createdAction } = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'MY action', + connector_type_id: 'test.noop', + config: {}, + secrets: {}, + }) + .expect(200); + + // pattern of when the alert should fire + const pattern = { + instance: [true, true, true, true, false, true], + }; + + const response = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + rule_type_id: 'test.patternFiringAad', + schedule: { interval: '1d' }, + throttle: null, + notify_when: null, + params: { + pattern, + }, + actions: [ + { + id: createdAction.id, + group: 'default', + params: {}, + frequency: { + summary: false, + throttle: null, + notify_when: RuleNotifyWhen.CHANGE, + }, + }, + ], + alert_delay: { + active: 3, + }, + }) + ); + + expect(response.status).to.eql(200); + const ruleId = response.body.id; + objectRemover.add(Spaces.space1.id, ruleId, 'rule', 'alerting'); + + // -------------------------- + // RUN 1 - 0 new alerts + // -------------------------- + let events: IValidatedEvent[] = await waitForEventLogDocs( + ruleId, + new Map([['execute', { equal: 1 }]]) + ); + let executeEvent = events[0]; + expect(get(executeEvent, ACTIVE_PATH)).to.be(0); + expect(get(executeEvent, NEW_PATH)).to.be(0); + expect(get(executeEvent, RECOVERED_PATH)).to.be(0); + expect(get(executeEvent, ACTION_PATH)).to.be(0); + + // Query for alerts + const alertDocsRun1 = await queryForAlertDocs(); + + // Get alert state from task document + let state: any = await getTaskState(ruleId); + expect(state.alertInstances.instance.meta.activeCount).to.equal(1); + expect(state.alertInstances.instance.state.patternIndex).to.equal(0); + + // After the first run, we should have 0 alert docs for the 0 active alerts + expect(alertDocsRun1.length).to.equal(0); + + // -------------------------- + // RUN 2 - 0 new alerts + // -------------------------- + let runSoon = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${ruleId}/_run_soon`) + .set('kbn-xsrf', 'foo'); + expect(runSoon.status).to.eql(204); + + events = await waitForEventLogDocs(ruleId, new Map([['execute', { equal: 2 }]])); + executeEvent = events[1]; + expect(get(executeEvent, ACTIVE_PATH)).to.be(0); + expect(get(executeEvent, NEW_PATH)).to.be(0); + expect(get(executeEvent, RECOVERED_PATH)).to.be(0); + expect(get(executeEvent, ACTION_PATH)).to.be(0); + + // Query for alerts + const alertDocsRun2 = await queryForAlertDocs(); + + // Get alert state from task document + state = await getTaskState(ruleId); + expect(state.alertInstances.instance.meta.activeCount).to.equal(2); + expect(state.alertInstances.instance.state.patternIndex).to.equal(1); + + // After the second run, we should have 0 alert docs for the 0 active alerts + expect(alertDocsRun2.length).to.equal(0); + + // -------------------------- + // RUN 3 - 1 new alert + // -------------------------- + runSoon = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${ruleId}/_run_soon`) + .set('kbn-xsrf', 'foo'); + expect(runSoon.status).to.eql(204); + + events = await waitForEventLogDocs(ruleId, new Map([['execute', { equal: 3 }]])); + executeEvent = events[2]; + let executionUuid = get(executeEvent, UUID_PATH); + expect(get(executeEvent, ACTIVE_PATH)).to.be(1); + expect(get(executeEvent, NEW_PATH)).to.be(1); + expect(get(executeEvent, RECOVERED_PATH)).to.be(0); + expect(get(executeEvent, ACTION_PATH)).to.be(1); + + // Query for alerts + const alertDocsRun3 = await queryForAlertDocs(); + + // Get alert state from task document + state = await getTaskState(ruleId); + expect(state.alertInstances.instance.meta.activeCount).to.equal(3); + expect(state.alertInstances.instance.state.patternIndex).to.equal(2); + + // After the third run, we should have 1 alert docs for the 1 active alert + expect(alertDocsRun3.length).to.equal(1); + + testExpectRuleData(alertDocsRun3, ruleId, { pattern }, executionUuid!); + let source: PatternFiringAlert = alertDocsRun3[0]._source!; + + // Each doc should have active status and default action group id + expect(source[ALERT_ACTION_GROUP]).to.equal('default'); + // patternIndex should be 2 for the third run + expect(source.patternIndex).to.equal(2); + // alert UUID should equal doc id + expect(source[ALERT_UUID]).to.equal(alertDocsRun3[0]._id); + // duration should be 0 since this is a new alert + expect(source[ALERT_DURATION]).to.equal(0); + // start should be defined + expect(source[ALERT_START]).to.match(timestampPattern); + // time_range.gte should be same as start + expect(source[ALERT_TIME_RANGE]?.gte).to.equal(source[ALERT_START]); + // timestamp should be defined + expect(source['@timestamp']).to.match(timestampPattern); + // status should be active + expect(source[ALERT_STATUS]).to.equal('active'); + // workflow status should be 'open' + expect(source[ALERT_WORKFLOW_STATUS]).to.equal('open'); + // event.action should be 'open' + expect(source[EVENT_ACTION]).to.equal('open'); + // event.kind should be 'signal' + expect(source[EVENT_KIND]).to.equal('signal'); + // tags should equal rule tags because rule type doesn't set any tags + expect(source.tags).to.eql(['foo']); + + // -------------------------- + // RUN 4 - 1 active alert + // -------------------------- + runSoon = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${ruleId}/_run_soon`) + .set('kbn-xsrf', 'foo'); + expect(runSoon.status).to.eql(204); + + events = await waitForEventLogDocs(ruleId, new Map([['execute', { equal: 4 }]])); + executeEvent = events[3]; + executionUuid = get(executeEvent, UUID_PATH); + expect(get(executeEvent, ACTIVE_PATH)).to.be(1); + expect(get(executeEvent, NEW_PATH)).to.be(0); + expect(get(executeEvent, RECOVERED_PATH)).to.be(0); + expect(get(executeEvent, ACTION_PATH)).to.be(0); + + // Query for alerts + const alertDocsRun4 = await queryForAlertDocs(); + + // Get alert state from task document + state = await getTaskState(ruleId); + expect(state.alertInstances.instance.meta.activeCount).to.equal(4); + expect(state.alertInstances.instance.state.patternIndex).to.equal(3); + + // After the fourth run, we should have 1 alert docs for the 1 active alert + expect(alertDocsRun4.length).to.equal(1); + + testExpectRuleData(alertDocsRun4, ruleId, { pattern }, executionUuid!); + source = alertDocsRun4[0]._source!; + const run3Source = alertDocsRun3[0]._source!; + + expect(source[ALERT_UUID]).to.equal(run3Source[ALERT_UUID]); + // patternIndex should be 3 for the fourth run + expect(source.patternIndex).to.equal(3); + expect(source[ALERT_ACTION_GROUP]).to.equal('default'); + // start time should be defined and the same as prior run + expect(source[ALERT_START]).to.match(timestampPattern); + expect(source[ALERT_START]).to.equal(run3Source[ALERT_START]); + // timestamp should be defined and not the same as prior run + expect(source['@timestamp']).to.match(timestampPattern); + expect(source['@timestamp']).not.to.equal(run3Source['@timestamp']); + // status should still be active + expect(source[ALERT_STATUS]).to.equal('active'); + // event.action set to active + expect(source[EVENT_ACTION]).to.eql('active'); + expect(source.tags).to.eql(['foo']); + // these values should be the same as previous run + expect(source[EVENT_KIND]).to.eql(run3Source[EVENT_KIND]); + expect(source[ALERT_WORKFLOW_STATUS]).to.eql(run3Source[ALERT_WORKFLOW_STATUS]); + expect(source[ALERT_TIME_RANGE]?.gte).to.equal(run3Source[ALERT_TIME_RANGE]?.gte); + + // -------------------------- + // RUN 5 - 1 recovered alert + // -------------------------- + runSoon = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${ruleId}/_run_soon`) + .set('kbn-xsrf', 'foo'); + expect(runSoon.status).to.eql(204); + + events = await waitForEventLogDocs(ruleId, new Map([['execute', { equal: 5 }]])); + executeEvent = events[4]; + executionUuid = get(executeEvent, UUID_PATH); + expect(get(executeEvent, ACTIVE_PATH)).to.be(0); + expect(get(executeEvent, NEW_PATH)).to.be(0); + expect(get(executeEvent, RECOVERED_PATH)).to.be(1); + expect(get(executeEvent, ACTION_PATH)).to.be(0); + + // Query for alerts + const alertDocsRun5 = await queryForAlertDocs(); + + // Get alert state from task document + state = await getTaskState(ruleId); + expect(state.alertRecoveredInstances.instance.meta.activeCount).to.equal(0); + + // After the fourth run, we should have 1 alert docs for the 1 recovered alert + expect(alertDocsRun5.length).to.equal(1); + + testExpectRuleData(alertDocsRun5, ruleId, { pattern }, executionUuid!); + source = alertDocsRun5[0]._source!; + + // action group should be set to recovered + expect(source[ALERT_ACTION_GROUP]).to.be('recovered'); + // rule type AAD payload should be set to recovery values + expect(source.instancePattern).to.eql([]); + expect(source.patternIndex).to.eql(-1); + // uuid is the same + expect(source[ALERT_UUID]).to.equal(run3Source[ALERT_UUID]); + // start time should be defined and the same as before + expect(source[ALERT_START]).to.match(timestampPattern); + expect(source[ALERT_START]).to.equal(run3Source[ALERT_START]); + // timestamp should be defined and not the same as prior run + expect(source['@timestamp']).to.match(timestampPattern); + expect(source['@timestamp']).not.to.equal(run3Source['@timestamp']); + // end time should be defined + expect(source[ALERT_END]).to.match(timestampPattern); + // status should be set to recovered + expect(source[ALERT_STATUS]).to.equal('recovered'); + // event.action set to close + expect(source[EVENT_ACTION]).to.eql('close'); + expect(source.tags).to.eql(['foo']); + // these values should be the same as previous run + expect(source[EVENT_KIND]).to.eql(run3Source[EVENT_KIND]); + expect(source[ALERT_WORKFLOW_STATUS]).to.eql(run3Source[ALERT_WORKFLOW_STATUS]); + expect(source[ALERT_TIME_RANGE]?.gte).to.equal(run3Source[ALERT_TIME_RANGE]?.gte); + // time_range.lte should be set to end time + expect(source[ALERT_TIME_RANGE]?.lte).to.equal(source[ALERT_END]); + + // -------------------------- + // RUN 6 - 0 new alerts + // -------------------------- + runSoon = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${ruleId}/_run_soon`) + .set('kbn-xsrf', 'foo'); + expect(runSoon.status).to.eql(204); + + events = await waitForEventLogDocs(ruleId, new Map([['execute', { equal: 6 }]])); + executeEvent = events[5]; + expect(get(executeEvent, ACTIVE_PATH)).to.be(0); + expect(get(executeEvent, NEW_PATH)).to.be(0); + expect(get(executeEvent, RECOVERED_PATH)).to.be(0); + expect(get(executeEvent, ACTION_PATH)).to.be(0); + + // Query for alerts + const alertDocsRun6 = await queryForAlertDocs(); + + // Get alert state from task document + state = await getTaskState(ruleId); + expect(state.alertInstances.instance.meta.activeCount).to.equal(1); + expect(state.alertInstances.instance.state.patternIndex).to.equal(5); + + // After the sixth run, we should have 1 alert docs for the previously recovered alert + expect(alertDocsRun6.length).to.equal(1); + }); + + it('should generate expected events with a alertDelay with AAD (rule registry)', async () => { + const params = { + index: ES_TEST_INDEX_NAME, + reference: 'test', + }; + const { body: createdAction } = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/api/actions/connector`) + .set('kbn-xsrf', 'foo') + .send({ + name: 'MY action', + connector_type_id: 'test.noop', + config: {}, + secrets: {}, + }) + .expect(200); + + const response = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) + .set('kbn-xsrf', 'foo') + .send( + getTestRuleData({ + rule_type_id: 'test.always-firing-alert-as-data', + schedule: { interval: '1d' }, + throttle: null, + notify_when: null, + params, + actions: [ + { + id: createdAction.id, + group: 'default', + params: {}, + frequency: { + summary: false, + throttle: null, + notify_when: RuleNotifyWhen.CHANGE, + }, + }, + ], + alert_delay: { + active: 3, + }, + }) + ); + + expect(response.status).to.eql(200); + const ruleId = response.body.id; + objectRemover.add(Spaces.space1.id, ruleId, 'rule', 'alerting'); + + // -------------------------- + // RUN 1 - 0 new alerts + // -------------------------- + let events: IValidatedEvent[] = await waitForEventLogDocs( + ruleId, + new Map([['execute', { equal: 1 }]]) + ); + let executeEvent = events[0]; + expect(get(executeEvent, ACTIVE_PATH)).to.be(0); + expect(get(executeEvent, NEW_PATH)).to.be(0); + expect(get(executeEvent, RECOVERED_PATH)).to.be(0); + expect(get(executeEvent, ACTION_PATH)).to.be(0); + + // Query for alerts + const alertDocsRun1 = await queryForAlertDocs(alwaysFiringAlertsAsDataIndex); + + // Get alert state from task document + let state: any = await getTaskState(ruleId); + expect(state.alertInstances['1'].meta.activeCount).to.equal(1); + expect(state.alertTypeState.trackedAlerts['1'].activeCount).to.equal(1); + + // After the first run, we should have 0 alert docs for the 0 active alerts + expect(alertDocsRun1.length).to.equal(0); + + // -------------------------- + // RUN 2 - 0 new alerts + // -------------------------- + let runSoon = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${ruleId}/_run_soon`) + .set('kbn-xsrf', 'foo'); + expect(runSoon.status).to.eql(204); + + events = await waitForEventLogDocs(ruleId, new Map([['execute', { equal: 2 }]])); + executeEvent = events[1]; + expect(get(executeEvent, ACTIVE_PATH)).to.be(0); + expect(get(executeEvent, NEW_PATH)).to.be(0); + expect(get(executeEvent, RECOVERED_PATH)).to.be(0); + expect(get(executeEvent, ACTION_PATH)).to.be(0); + + // Query for alerts + const alertDocsRun2 = await queryForAlertDocs(alwaysFiringAlertsAsDataIndex); + + // Get alert state from task document + state = await getTaskState(ruleId); + expect(state.alertInstances['1'].meta.activeCount).to.equal(2); + expect(state.alertTypeState.trackedAlerts['1'].activeCount).to.equal(2); + + // After the second run, we should have 0 alert docs for the 0 active alerts + expect(alertDocsRun2.length).to.equal(0); + + // -------------------------- + // RUN 3 - 1 new alert + // -------------------------- + runSoon = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${ruleId}/_run_soon`) + .set('kbn-xsrf', 'foo'); + expect(runSoon.status).to.eql(204); + + events = await waitForEventLogDocs(ruleId, new Map([['execute', { equal: 3 }]])); + executeEvent = events[2]; + let executionUuid = get(executeEvent, UUID_PATH); + // Note: the rule creates 2 alerts but we will only look at one + expect(get(executeEvent, ACTIVE_PATH)).to.be(2); + expect(get(executeEvent, NEW_PATH)).to.be(2); + expect(get(executeEvent, RECOVERED_PATH)).to.be(0); + expect(get(executeEvent, ACTION_PATH)).to.be(2); + + // Query for alerts + const alertDocsRun3 = await queryForAlertDocs(alwaysFiringAlertsAsDataIndex); + + // Get alert state from task document + state = await getTaskState(ruleId); + expect(state.alertInstances['1'].meta.activeCount).to.equal(3); + expect(state.alertTypeState.trackedAlerts['1'].activeCount).to.equal(3); + + // After the third run, we should have 2 alert docs for the 2 active alerts but we will only look at one + expect(alertDocsRun3.length).to.equal(2); + + let source: Alert = alertDocsRun3[0]._source!; + + // Each doc should have a copy of the rule data + expect(source[ALERT_RULE_CATEGORY]).to.equal('Test: Always Firing Alert As Data'); + expect(source[ALERT_RULE_CONSUMER]).to.equal('alertsFixture'); + expect(source[ALERT_RULE_NAME]).to.equal('abc'); + expect(source[ALERT_RULE_PRODUCER]).to.equal('alertsFixture'); + expect(source[ALERT_RULE_TAGS]).to.eql(['foo']); + expect(source[ALERT_RULE_TYPE_ID]).to.equal('test.always-firing-alert-as-data'); + expect(source[ALERT_RULE_UUID]).to.equal(ruleId); + expect(source[ALERT_RULE_PARAMETERS]).to.eql(params); + expect(source[SPACE_IDS]).to.eql(['space1']); + expect(source[ALERT_RULE_EXECUTION_UUID]).to.equal(executionUuid); + // alert UUID should equal doc id + expect(source[ALERT_UUID]).to.equal(alertDocsRun3[0]._id); + // duration should be 0 since this is a new alert + expect(source[ALERT_DURATION]).to.equal(0); + // start should be defined + expect(source[ALERT_START]).to.match(timestampPattern); + // time_range.gte should be same as start + expect(source[ALERT_TIME_RANGE]?.gte).to.equal(source[ALERT_START]); + // timestamp should be defined + expect(source['@timestamp']).to.match(timestampPattern); + // status should be active + expect(source[ALERT_STATUS]).to.equal('active'); + // workflow status should be 'open' + expect(source[ALERT_WORKFLOW_STATUS]).to.equal('open'); + // event.action should be 'open' + expect(source[EVENT_ACTION]).to.equal('open'); + // event.kind should be 'signal' + expect(source[EVENT_KIND]).to.equal('signal'); + // tags should equal rule tags because rule type doesn't set any tags + expect(source.tags).to.eql(['foo']); + + // -------------------------- + // RUN 4 - 1 active alert + // -------------------------- + runSoon = await supertestWithoutAuth + .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rule/${ruleId}/_run_soon`) + .set('kbn-xsrf', 'foo'); + expect(runSoon.status).to.eql(204); + + events = await waitForEventLogDocs(ruleId, new Map([['execute', { equal: 4 }]])); + executeEvent = events[3]; + executionUuid = get(executeEvent, UUID_PATH); + // Note: the rule creates 2 alerts but we will only look at one + expect(get(executeEvent, ACTIVE_PATH)).to.be(2); + expect(get(executeEvent, NEW_PATH)).to.be(0); + expect(get(executeEvent, RECOVERED_PATH)).to.be(0); + expect(get(executeEvent, ACTION_PATH)).to.be(0); + + // Query for alerts + const alertDocsRun4 = await queryForAlertDocs(alwaysFiringAlertsAsDataIndex); + + // Get alert state from task document + state = await getTaskState(ruleId); + expect(state.alertInstances['1'].meta.activeCount).to.equal(4); + expect(state.alertTypeState.trackedAlerts['1'].activeCount).to.equal(4); + + // After the fourth run, we should have 2 alert docs for the 2 active alerts but we will only look at one + expect(alertDocsRun4.length).to.equal(2); + + source = alertDocsRun4[0]._source!; + const run3Source = alertDocsRun3[0]._source!; + + // Each doc should have a copy of the rule data + expect(source[ALERT_RULE_CATEGORY]).to.equal('Test: Always Firing Alert As Data'); + expect(source[ALERT_RULE_CONSUMER]).to.equal('alertsFixture'); + expect(source[ALERT_RULE_NAME]).to.equal('abc'); + expect(source[ALERT_RULE_PRODUCER]).to.equal('alertsFixture'); + expect(source[ALERT_RULE_TAGS]).to.eql(['foo']); + expect(source[ALERT_RULE_TYPE_ID]).to.equal('test.always-firing-alert-as-data'); + expect(source[ALERT_RULE_UUID]).to.equal(ruleId); + expect(source[ALERT_RULE_PARAMETERS]).to.eql(params); + expect(source[SPACE_IDS]).to.eql(['space1']); + expect(source[ALERT_RULE_EXECUTION_UUID]).to.equal(executionUuid); + expect(source[ALERT_UUID]).to.equal(run3Source[ALERT_UUID]); + // start time should be defined and the same as prior run + expect(source[ALERT_START]).to.match(timestampPattern); + expect(source[ALERT_START]).to.equal(run3Source[ALERT_START]); + // timestamp should be defined and not the same as prior run + expect(source['@timestamp']).to.match(timestampPattern); + expect(source['@timestamp']).not.to.equal(run3Source['@timestamp']); + // status should still be active + expect(source[ALERT_STATUS]).to.equal('active'); + // event.action set to active + expect(source[EVENT_ACTION]).to.eql('active'); + expect(source.tags).to.eql(['foo']); + // these values should be the same as previous run + expect(source[EVENT_KIND]).to.eql(run3Source[EVENT_KIND]); + expect(source[ALERT_WORKFLOW_STATUS]).to.eql(run3Source[ALERT_WORKFLOW_STATUS]); + expect(source[ALERT_TIME_RANGE]?.gte).to.equal(run3Source[ALERT_TIME_RANGE]?.gte); + }); + }); + + function testExpectRuleData( + alertDocs: Array>, + ruleId: string, + ruleParameters: unknown, + executionUuid?: string + ) { + for (let i = 0; i < alertDocs.length; ++i) { + const source: PatternFiringAlert = alertDocs[i]._source!; + + // Each doc should have a copy of the rule data + expect(source[ALERT_RULE_CATEGORY]).to.equal( + 'Test: Firing on a Pattern and writing Alerts as Data' + ); + expect(source[ALERT_RULE_CONSUMER]).to.equal('alertsFixture'); + expect(source[ALERT_RULE_NAME]).to.equal('abc'); + expect(source[ALERT_RULE_PRODUCER]).to.equal('alertsFixture'); + expect(source[ALERT_RULE_TAGS]).to.eql(['foo']); + expect(source[ALERT_RULE_TYPE_ID]).to.equal('test.patternFiringAad'); + expect(source[ALERT_RULE_UUID]).to.equal(ruleId); + expect(source[ALERT_RULE_PARAMETERS]).to.eql(ruleParameters); + expect(source[SPACE_IDS]).to.eql(['space1']); + + if (executionUuid) { + expect(source[ALERT_RULE_EXECUTION_UUID]).to.equal(executionUuid); + } + } + } + + async function queryForAlertDocs( + index: string = alertsAsDataIndex + ): Promise>> { + const searchResult = await es.search({ + index, + body: { query: { match_all: {} } }, + }); + return searchResult.hits.hits as Array>; + } + + async function getTaskState(ruleId: string) { + const task = await es.get({ + id: `task:${ruleId}`, + index: '.kibana_task_manager', + }); + + return JSON.parse(task._source!.task.state); + } + + async function waitForEventLogDocs( + id: string, + actions: Map + ) { + return await retry.try(async () => { + return await getEventLog({ + getService, + spaceId: Spaces.space1.id, + type: 'alert', + id, + provider: 'alerting', + actions, + }); + }); + } +} diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/index.ts index 20342e053016..e1a29d1c4bf3 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/index.ts @@ -14,5 +14,6 @@ export default function alertsAsDataTests({ loadTestFile }: FtrProviderContext) loadTestFile(require.resolve('./alerts_as_data')); loadTestFile(require.resolve('./alerts_as_data_flapping')); loadTestFile(require.resolve('./alerts_as_data_conflicts')); + loadTestFile(require.resolve('./alerts_as_data_alert_delay')); }); } 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 b73477cf3df3..15084a47f4d8 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 @@ -28,7 +28,7 @@ export default function alertingTests({ loadTestFile, getService }: FtrProviderC loadTestFile(require.resolve('./run_soon')); loadTestFile(require.resolve('./flapping_history')); loadTestFile(require.resolve('./check_registered_rule_types')); - loadTestFile(require.resolve('./notification_delay')); + loadTestFile(require.resolve('./alert_delay')); loadTestFile(require.resolve('./generate_alert_schemas')); // Do not place test files here, due to https://github.com/elastic/kibana/issues/123059 diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/rule_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/rule_page.ts index 8ab9afd81814..3cf0810c7a03 100644 --- a/x-pack/test/cloud_security_posture_functional/page_objects/rule_page.ts +++ b/x-pack/test/cloud_security_posture_functional/page_objects/rule_page.ts @@ -181,6 +181,10 @@ export function RulePagePageProvider({ getService, getPageObjects }: FtrProvider const disabledRulesButton = await testSubjects.find('rules-counters-disabled-rules-button'); await disabledRulesButton.click(); }, + + doesElementExist: async (selector: string) => { + return await testSubjects.exists(selector); + }, }; const navigateToRulePage = async (benchmarkCisId: string, benchmarkCisVersion: string) => { diff --git a/x-pack/test/cloud_security_posture_functional/pages/rules.ts b/x-pack/test/cloud_security_posture_functional/pages/rules.ts index 81629da46439..b734c391bf27 100644 --- a/x-pack/test/cloud_security_posture_functional/pages/rules.ts +++ b/x-pack/test/cloud_security_posture_functional/pages/rules.ts @@ -28,8 +28,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'findings', ]); - // Failing: See https://github.com/elastic/kibana/issues/175905 - describe.skip('Cloud Posture Rules Page', function () { + describe('Cloud Posture Rules Page', function () { this.tags(['cloud_security_posture_rules_page']); let rule: typeof pageObjects.rule; let findings: typeof pageObjects.findings; @@ -72,9 +71,81 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await findings.index.remove(); }); - // FLAKY: https://github.com/elastic/kibana/issues/175614 - describe.skip('Rules Page - Bulk Action buttons', () => { - it('It should disable both Enable and Disable options when there are no rules selected', async () => { + describe('Rules Page - Rules Counters', () => { + it('Shows posture score when there are findings', async () => { + const isEmptyStateVisible = await rule.rulePage.getCountersEmptyState(); + expect(isEmptyStateVisible).to.be(false); + + const postureScoreCounter = await rule.rulePage.getPostureScoreCounter(); + expect((await postureScoreCounter.getVisibleText()).includes('33%')).to.be(true); + }); + + it('Clicking the posture score button leads to the dashboard', async () => { + await rule.rulePage.clickPostureScoreButton(); + await pageObjects.common.waitUntilUrlIncludes('cloud_security_posture/dashboard'); + }); + + it('Shows integrations count when there are findings', async () => { + const integrationsCounter = await rule.rulePage.getIntegrationsEvaluatedCounter(); + expect((await integrationsCounter.getVisibleText()).includes('1')).to.be(true); + }); + + it('Clicking the integrations counter button leads to the integration page', async () => { + await rule.rulePage.clickIntegrationsEvaluatedButton(); + await pageObjects.common.waitUntilUrlIncludes('add-integration/kspm'); + }); + + it('Shows the failed findings counter when there are findings', async () => { + const failedFindingsCounter = await rule.rulePage.getFailedFindingsCounter(); + expect((await failedFindingsCounter.getVisibleText()).includes('2')).to.be(true); + }); + + it('Clicking the failed findings button leads to the findings page', async () => { + await rule.rulePage.clickFailedFindingsButton(); + await pageObjects.common.waitUntilUrlIncludes( + 'cloud_security_posture/findings/configurations' + ); + }); + + it('Shows the disabled rules count', async () => { + const disabledRulesCounter = await rule.rulePage.getDisabledRulesCounter(); + expect((await disabledRulesCounter.getVisibleText()).includes('0')).to.be(true); + + // disable rule 1.1.1 (k8s findings mock contains a findings from that rule) + await rule.rulePage.clickEnableRulesRowSwitchButton(0); + await pageObjects.header.waitUntilLoadingHasFinished(); + expect((await disabledRulesCounter.getVisibleText()).includes('1')).to.be(true); + + const postureScoreCounter = await rule.rulePage.getPostureScoreCounter(); + expect((await postureScoreCounter.getVisibleText()).includes('0%')).to.be(true); + + // enable rule back + await rule.rulePage.clickEnableRulesRowSwitchButton(0); + }); + + it('Clicking the disabled rules button shows enables the disabled filter', async () => { + await rule.rulePage.clickEnableRulesRowSwitchButton(0); + await pageObjects.header.waitUntilLoadingHasFinished(); + + await rule.rulePage.clickDisabledRulesButton(); + await pageObjects.header.waitUntilLoadingHasFinished(); + expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 1).to.be(true); + }); + + it('Shows empty state when there are no findings', async () => { + // Ensure there are no findings initially + await findings.index.remove(); + await rule.navigateToRulePage('cis_k8s', '1.0.1'); + + const isEmptyStateVisible = await rule.rulePage.getCountersEmptyState(); + expect(isEmptyStateVisible).to.be(true); + await rule.rulePage.clickEnableRulesRowSwitchButton(0); + }); + }); + + describe('Rules Page - Bulk Action buttons', () => { + it('It should disable Enable option when there are all rules selected are already enabled ', async () => { + await rule.rulePage.clickSelectAllRules(); await rule.rulePage.toggleBulkActionButton(); expect( (await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) === @@ -83,11 +154,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect( (await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) === 'true' - ).to.be(true); + ).to.be(false); }); - it('It should disable Enable option when there are all rules selected are already enabled ', async () => { - await rule.rulePage.clickSelectAllRules(); + it('It should disable both Enable and Disable options when there are no rules selected', async () => { await rule.rulePage.toggleBulkActionButton(); expect( (await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_ENABLE)) === @@ -96,7 +166,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect( (await rule.rulePage.isBulkActionOptionDisabled(RULES_BULK_ACTION_OPTION_DISABLE)) === 'true' - ).to.be(false); + ).to.be(true); }); it('It should disable Disable option when there are all rules selected are already Disabled', async () => { @@ -178,6 +248,15 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.header.waitUntilLoadingHasFinished(); expect((await rule.rulePage.getEnableSwitchButtonState()) === 'false').to.be(true); }); + it('Alerts section of Rules Flyout shows Disabled text when Rules are disabled', async () => { + await rule.rulePage.clickRulesNames(0); + await pageObjects.header.waitUntilLoadingHasFinished(); + expect( + (await rule.rulePage.doesElementExist( + 'csp:findings-flyout-create-detection-rule-link' + )) === false + ).to.be(true); + }); it('Users are able to Enable/Disable Rule from Take Action on Rule Flyout', async () => { await rule.rulePage.clickRulesNames(0); await rule.rulePage.clickTakeActionButton(); @@ -185,78 +264,14 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { await pageObjects.header.waitUntilLoadingHasFinished(); expect((await rule.rulePage.getEnableSwitchButtonState()) === 'true').to.be(true); }); - }); - - describe('Rules Page - Rules Counters', () => { - it('Shows posture score when there are findings', async () => { - const isEmptyStateVisible = await rule.rulePage.getCountersEmptyState(); - expect(isEmptyStateVisible).to.be(false); - - const postureScoreCounter = await rule.rulePage.getPostureScoreCounter(); - expect((await postureScoreCounter.getVisibleText()).includes('33%')).to.be(true); - }); - - it('Clicking the posture score button leads to the dashboard', async () => { - await rule.rulePage.clickPostureScoreButton(); - await pageObjects.common.waitUntilUrlIncludes('cloud_security_posture/dashboard'); - }); - - it('Shows integrations count when there are findings', async () => { - const integrationsCounter = await rule.rulePage.getIntegrationsEvaluatedCounter(); - expect((await integrationsCounter.getVisibleText()).includes('1')).to.be(true); - }); - - it('Clicking the integrations counter button leads to the integration page', async () => { - await rule.rulePage.clickIntegrationsEvaluatedButton(); - await pageObjects.common.waitUntilUrlIncludes( - 'cloud_security_posture/add-integration/kspm' - ); - }); - - it('Shows the failed findings counter when there are findings', async () => { - const failedFindingsCounter = await rule.rulePage.getFailedFindingsCounter(); - expect((await failedFindingsCounter.getVisibleText()).includes('2')).to.be(true); - }); - - it('Clicking the failed findings button leads to the findings page', async () => { - await rule.rulePage.clickFailedFindingsButton(); - await pageObjects.common.waitUntilUrlIncludes( - 'cloud_security_posture/findings/configurations' - ); - }); - - it('Shows the disabled rules count', async () => { - const disabledRulesCounter = await rule.rulePage.getDisabledRulesCounter(); - expect((await disabledRulesCounter.getVisibleText()).includes('0')).to.be(true); - - // disable rule 1.1.1 (k8s findings mock contains a findings from that rule) - await rule.rulePage.clickEnableRulesRowSwitchButton(0); - await pageObjects.header.waitUntilLoadingHasFinished(); - expect((await disabledRulesCounter.getVisibleText()).includes('1')).to.be(true); - - const postureScoreCounter = await rule.rulePage.getPostureScoreCounter(); - expect((await postureScoreCounter.getVisibleText()).includes('0%')).to.be(true); - - // enable rule back - await rule.rulePage.clickEnableRulesRowSwitchButton(0); - }); - - it('Clicking the disabled rules button shows enables the disabled filter', async () => { - await rule.rulePage.clickEnableRulesRowSwitchButton(0); - await pageObjects.header.waitUntilLoadingHasFinished(); - - await rule.rulePage.clickDisabledRulesButton(); + it('Alerts section of Rules Flyout shows Detection Rule Counter component when Rules are enabled', async () => { + await rule.rulePage.clickRulesNames(0); await pageObjects.header.waitUntilLoadingHasFinished(); - expect((await rule.rulePage.getEnableRulesRowSwitchButton()) === 1).to.be(true); - }); - - it('Shows empty state when there are no findings', async () => { - // Ensure there are no findings initially - await findings.index.remove(); - await rule.navigateToRulePage('cis_k8s', '1.0.1'); - - const isEmptyStateVisible = await rule.rulePage.getCountersEmptyState(); - expect(isEmptyStateVisible).to.be(true); + expect( + (await rule.rulePage.doesElementExist( + 'csp:findings-flyout-create-detection-rule-link' + )) === true + ).to.be(true); }); }); }); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/anomaly_explorer.ts b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/anomaly_explorer.ts index a6e867676d10..76bed212eebd 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/anomaly_explorer.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/anomaly_explorer.ts @@ -543,6 +543,39 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); }); }); + + describe('Use anomaly table action to view in Discover', function () { + beforeEach(async () => { + await ml.navigation.navigateToAnomalyExplorer( + testData.jobConfig.job_id, + { + from: '2016-02-07T00%3A00%3A00.000Z', + to: '2016-02-11T23%3A59%3A54.000Z', + }, + () => elasticChart.setNewChartUiDebugFlag(true) + ); + + await ml.commonUI.waitForMlLoadingIndicatorToDisappear(); + await ml.commonUI.waitForDatePickerIndicatorLoaded(); + await ml.swimLane.waitForSwimLanesToLoad(); + }); + + it('should render the anomaly table', async () => { + await ml.testExecution.logTestStep('displays the anomalies table'); + await ml.anomaliesTable.assertTableExists(); + + await ml.testExecution.logTestStep('anomalies table is not empty'); + await ml.anomaliesTable.assertTableNotEmpty(); + }); + + it('should click the Discover action in the anomaly table', async () => { + await ml.anomaliesTable.assertAnomalyActionsMenuButtonExists(0); + await ml.anomaliesTable.scrollRowIntoView(0); + await ml.anomaliesTable.assertAnomalyActionsMenuButtonEnabled(0, true); + await ml.anomaliesTable.assertAnomalyActionDiscoverButtonExists(0); + await ml.anomaliesTable.ensureAnomalyActionDiscoverButtonClicked(0); + }); + }); }); } }); diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/single_metric_viewer.ts b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/single_metric_viewer.ts index 1779589a5a0c..c9ceb71459e4 100644 --- a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/single_metric_viewer.ts +++ b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/single_metric_viewer.ts @@ -90,6 +90,13 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep('anomalies table is not empty'); await ml.anomaliesTable.assertTableNotEmpty(); }); + + it('should click on an anomaly marker', async () => { + await ml.singleMetricViewer.assertAnomalyMarkerExist(); + await ml.singleMetricViewer.openAnomalyMarkerActionsPopover(); + await ml.anomaliesTable.assertAnomalyActionDiscoverButtonExists(0); + await ml.anomaliesTable.ensureAnomalyActionDiscoverButtonClicked(0); + }); }); describe('with entity fields', function () { @@ -193,7 +200,9 @@ export default function ({ getService }: FtrProviderContext) { // Also sorting by name is enforced because the model plot is enabled // and anomalous only is disabled await ml.singleMetricViewer.assertEntityConfig('day_of_week', false, 'name', 'desc'); + }); + it('should render the singe metric viewer chart and anomaly table', async () => { await ml.testExecution.logTestStep('displays the chart'); await ml.singleMetricViewer.assertChartExist(); @@ -203,6 +212,14 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep('anomalies table is not empty'); await ml.anomaliesTable.assertTableNotEmpty(); }); + + it('should click the Discover action in the anomaly table', async () => { + await ml.anomaliesTable.assertAnomalyActionsMenuButtonExists(0); + await ml.anomaliesTable.scrollRowIntoView(0); + await ml.anomaliesTable.assertAnomalyActionsMenuButtonEnabled(0, true); + await ml.anomaliesTable.assertAnomalyActionDiscoverButtonExists(0); + await ml.anomaliesTable.ensureAnomalyActionDiscoverButtonClicked(0); + }); }); }); } diff --git a/x-pack/test/functional/services/ml/anomalies_table.ts b/x-pack/test/functional/services/ml/anomalies_table.ts index 52eaf5715f67..c59221289f84 100644 --- a/x-pack/test/functional/services/ml/anomalies_table.ts +++ b/x-pack/test/functional/services/ml/anomalies_table.ts @@ -131,6 +131,24 @@ export function MachineLearningAnomaliesTableProvider({ getService }: FtrProvide ); }, + async assertAnomalyActionDiscoverButtonExists(rowIndex: number) { + await this.ensureAnomalyActionsMenuOpen(rowIndex); + await testSubjects.existOrFail('mlAnomaliesListRowAction_viewInDiscoverButton'); + }, + + async assertAnomalyActionDiscoverButtonNotExists(rowIndex: number) { + await this.ensureAnomalyActionsMenuOpen(rowIndex); + await testSubjects.missingOrFail('mlAnomaliesListRowAction_viewInDiscoverButton'); + }, + + async ensureAnomalyActionDiscoverButtonClicked(rowIndex: number) { + await retry.tryForTime(10 * 1000, async () => { + await this.ensureAnomalyActionsMenuOpen(rowIndex); + await testSubjects.click('mlAnomaliesListRowAction_viewInDiscoverButton'); + await testSubjects.existOrFail('discoverLayoutResizableContainer'); + }); + }, + async assertAnomalyActionLogRateAnalysisButtonExists(rowIndex: number) { await this.ensureAnomalyActionsMenuOpen(rowIndex); await testSubjects.existOrFail('mlAnomaliesListRowAction_runLogRateAnalysisButton'); diff --git a/x-pack/test/functional/services/ml/single_metric_viewer.ts b/x-pack/test/functional/services/ml/single_metric_viewer.ts index 29f1ded74deb..05ae2bd20cab 100644 --- a/x-pack/test/functional/services/ml/single_metric_viewer.ts +++ b/x-pack/test/functional/services/ml/single_metric_viewer.ts @@ -73,6 +73,15 @@ export function MachineLearningSingleMetricViewerProvider( await testSubjects.existOrFail('mlSingleMetricViewerChart'); }, + async assertAnomalyMarkerExist() { + await testSubjects.existOrFail('mlAnomalyMarker'); + }, + + async openAnomalyMarkerActionsPopover() { + await testSubjects.click('mlAnomalyMarker'); + await testSubjects.existOrFail('mlAnomaliesListRowActionsMenu'); + }, + async assertAnnotationsExists(state: string) { await testSubjects.existOrFail(`mlAnomalyExplorerAnnotations ${state}`, { timeout: 30 * 1000, diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/alerts/trial_license_complete_tier/alerts_compatibility.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/alerts/trial_license_complete_tier/alerts_compatibility.ts index 5547bf57fb1a..25ef93cafaac 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/alerts/trial_license_complete_tier/alerts_compatibility.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/alerts/trial_license_complete_tier/alerts_compatibility.ts @@ -636,7 +636,8 @@ export default ({ getService }: FtrProviderContext) => { }); }); - describe('Threshold', () => { + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/176359 + describe.skip('Threshold', () => { beforeEach(async () => { await esArchiver.load('x-pack/test/functional/es_archives/security_solution/alerts/7.16.0'); await createAlertsIndex(supertest, log); diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/exceptions/workflows/trial_license_complete_tier/role_based_rule_exceptions_workflows.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/exceptions/workflows/trial_license_complete_tier/role_based_rule_exceptions_workflows.ts index ef78015ef771..e308732db382 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/exceptions/workflows/trial_license_complete_tier/role_based_rule_exceptions_workflows.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/exceptions/workflows/trial_license_complete_tier/role_based_rule_exceptions_workflows.ts @@ -803,7 +803,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no alerts when a value list exception is added for a query rule', async () => { - const valueListId = 'value-list-id'; + const valueListId = 'value-list-id.txt'; await importFile(supertest, log, 'keyword', ['suricata-sensor-amsterdam'], valueListId); const rule: QueryRuleCreateProps = { name: 'Simple Rule Query', @@ -835,7 +835,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no alerts when a value list exception is added for a threat match rule', async () => { - const valueListId = 'value-list-id'; + const valueListId = 'value-list-id.txt'; await importFile(supertest, log, 'keyword', ['zeek-sensor-amsterdam'], valueListId); const rule: ThreatMatchRuleCreateProps = { description: 'Detecting root and admin users', @@ -883,7 +883,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no alerts when a value list exception is added for a threshold rule', async () => { - const valueListId = 'value-list-id'; + const valueListId = 'value-list-id.txt'; await importFile(supertest, log, 'keyword', ['zeek-sensor-amsterdam'], valueListId); const rule: ThresholdRuleCreateProps = { description: 'Detecting root and admin users', @@ -920,7 +920,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no alerts when a value list exception is added for an EQL rule', async () => { - const valueListId = 'value-list-id'; + const valueListId = 'value-list-id.txt'; await importFile(supertest, log, 'keyword', ['zeek-sensor-amsterdam'], valueListId); const rule: EqlRuleCreateProps = { ...getEqlRuleForAlertTesting(['auditbeat-*']), @@ -944,7 +944,7 @@ export default ({ getService }: FtrProviderContext) => { expect(alertsOpen.hits.hits.length).toEqual(0); }); it('should Not allow deleting value list when there are references and ignoreReferences is false', async () => { - const valueListId = 'value-list-id'; + const valueListId = 'value-list-id.txt'; await importFile(supertest, log, 'keyword', ['suricata-sensor-amsterdam'], valueListId); const rule: QueryRuleCreateProps = { ...getSimpleRule(), diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/exceptions/workflows/trial_license_complete_tier/rule_exception_synchronizations.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/exceptions/workflows/trial_license_complete_tier/rule_exception_synchronizations.ts index c584ec46f2ef..5a68270e1220 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/exceptions/workflows/trial_license_complete_tier/rule_exception_synchronizations.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/exceptions/workflows/trial_license_complete_tier/rule_exception_synchronizations.ts @@ -107,7 +107,7 @@ export default ({ getService }: FtrProviderContext) => { it('should Not allow editing an Exception with deleted ValueList', async () => { await createListsIndex(supertest, log); - const valueListId = 'value-list-id'; + const valueListId = 'value-list-id.txt'; await importFile(supertest, log, 'keyword', ['suricata-sensor-amsterdam'], valueListId); const rule: QueryRuleCreateProps = { ...getSimpleRule(), diff --git a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/machine_learning.ts b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/machine_learning.ts index e222f1ddd7cb..60ad53f94937 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/machine_learning.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/detections_response/detection_engine/rule_execution_logic/trial_license_complete_tier/execution_logic/machine_learning.ts @@ -229,7 +229,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('generates no alerts when a value list exception is added for an ML rule', async () => { - const valueListId = 'value-list-id'; + const valueListId = 'value-list-id.txt'; await importFile(supertest, log, 'keyword', ['mothra'], valueListId); const { previewId } = await previewRuleWithExceptionEntries({ supertest, diff --git a/x-pack/test/security_solution_api_integration/test_suites/lists_and_exception_lists/lists_items/trial_license_complete_tier/items/import_list_items.ts b/x-pack/test/security_solution_api_integration/test_suites/lists_and_exception_lists/lists_items/trial_license_complete_tier/items/import_list_items.ts index 99a96ae9052b..7fabd749bc01 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/lists_and_exception_lists/lists_items/trial_license_complete_tier/items/import_list_items.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/lists_and_exception_lists/lists_items/trial_license_complete_tier/items/import_list_items.ts @@ -54,6 +54,39 @@ export default ({ getService }: FtrProviderContext): void => { await deleteListsIndex(supertest, log); }); + it('should not import a list item if the imported file is not .txt or .csv', async () => { + const { body } = await supertest + .post(`${LIST_ITEM_URL}/_import?type=ip`) + .set('kbn-xsrf', 'true') + .attach('file', getImportListItemAsBuffer(['127.0.0.1', '127.0.0.2']), 'list_items.pdf') + .expect('Content-Type', 'application/json; charset=utf-8') + .expect(415); + + expect(body).to.eql({ + status_code: 415, + message: 'Unsupported media type. File must be one of the following types: [.csv, .txt]', + }); + }); + + it('should not import a list item if the imported file exceed the file size limit', async () => { + const { body } = await supertest + .post(`${LIST_ITEM_URL}/_import?type=ip`) + .set('kbn-xsrf', 'true') + .attach( + 'file', + getImportListItemAsBuffer(Array(1000000).fill('127.0.0.1')), + 'list_items.txt' + ) + .expect('Content-Type', 'application/json; charset=utf-8') + .expect(413); + + expect(body).to.eql({ + statusCode: 413, + error: 'Request Entity Too Large', + message: 'Payload content length greater than maximum allowed: 9000000', + }); + }); + it('should set the response content types to be expected when importing two items', async () => { await supertest .post(`${LIST_ITEM_URL}/_import?type=ip`) diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts b/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts index 98866bc50f43..73f582f9aa9c 100644 --- a/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts +++ b/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts @@ -12,7 +12,8 @@ export default function ({ getService }: FtrProviderContext) { const svlCommonApi = getService('svlCommonApi'); const supertest = getService('supertest'); - describe('fleet', function () { + // Failing: See https://github.com/elastic/kibana/issues/176352 + describe.skip('fleet', function () { it('rejects request to create a new fleet server hosts if host url is different from default', async () => { const { body, status } = await supertest .post('/api/fleet/fleet_server_hosts') diff --git a/yarn.lock b/yarn.lock index 099e1b64cf50..5549bf6e05d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26016,13 +26016,6 @@ react-resizable@^3.0.4: prop-types "15.x" react-draggable "^4.0.3" -react-resize-detector@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-7.1.1.tgz#18d5b84909d5ab13abe0a68ddf0fb8e80c553dfc" - integrity sha512-rU54VTstNzFLZAmMNHqt8xINjDWP7SQR05A2HUW0OGvl4vcrXzgaxrrqAY5tZMfkLkoYm5u0i0qGqCjdc2jyAA== - dependencies: - lodash "^4.17.21" - react-reverse-portal@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/react-reverse-portal/-/react-reverse-portal-2.1.0.tgz#3c572e1c0d9e49b8febf4bf2fd43b9819ce6f508"