diff --git a/.buildkite/pipelines/on_merge.yml b/.buildkite/pipelines/on_merge.yml index 5518e1f8ed83c..d5ffcf7067c36 100644 --- a/.buildkite/pipelines/on_merge.yml +++ b/.buildkite/pipelines/on_merge.yml @@ -45,6 +45,20 @@ steps: - exit_status: '-1' limit: 3 + - command: .buildkite/scripts/steps/checks.sh + label: 'Checks' + agents: + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-prod + provider: gcp + machineType: n2-standard-2 + preemptible: true + timeout_in_minutes: 60 + retry: + automatic: + - exit_status: '-1' + limit: 3 + - command: .buildkite/scripts/steps/lint.sh label: 'Linting' agents: @@ -89,6 +103,20 @@ steps: - exit_status: '-1' limit: 3 + - command: .buildkite/scripts/steps/checks/capture_oas_snapshot.sh + label: 'Check OAS Snapshot' + agents: + image: family/kibana-ubuntu-2004 + imageProject: elastic-images-prod + provider: gcp + machineType: n2-standard-4 + preemptible: true + timeout_in_minutes: 60 + retry: + automatic: + - exit_status: '-1' + limit: 3 + - wait - command: .buildkite/scripts/steps/on_merge_api_docs.sh @@ -454,34 +482,6 @@ steps: provider: gcp machineType: n2-standard-2 - - command: .buildkite/scripts/steps/checks.sh - label: 'Checks' - agents: - image: family/kibana-ubuntu-2004 - imageProject: elastic-images-prod - provider: gcp - machineType: n2-standard-2 - preemptible: true - timeout_in_minutes: 60 - retry: - automatic: - - exit_status: '-1' - limit: 3 - - - command: .buildkite/scripts/steps/checks/capture_oas_snapshot.sh - label: 'Check OAS Snapshot' - agents: - image: family/kibana-ubuntu-2004 - imageProject: elastic-images-prod - provider: gcp - machineType: n2-standard-4 - preemptible: true - timeout_in_minutes: 60 - retry: - automatic: - - exit_status: '-1' - limit: 3 - - command: .buildkite/scripts/steps/storybooks/build_and_upload.sh label: 'Build Storybooks' agents: diff --git a/.buildkite/pipelines/pull_request/apm_cypress.yml b/.buildkite/pipelines/pull_request/apm_cypress.yml index c0cb60dbc986b..97935cc3489d1 100644 --- a/.buildkite/pipelines/pull_request/apm_cypress.yml +++ b/.buildkite/pipelines/pull_request/apm_cypress.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 120 parallelism: 1 # TODO: Set parallelism when apm_cypress handles it retry: diff --git a/.buildkite/pipelines/pull_request/base.yml b/.buildkite/pipelines/pull_request/base.yml index fc3e2ce388bf5..e7b593f464b54 100644 --- a/.buildkite/pipelines/pull_request/base.yml +++ b/.buildkite/pipelines/pull_request/base.yml @@ -32,6 +32,18 @@ steps: - exit_status: '-1' limit: 3 + - command: .buildkite/scripts/steps/checks.sh + label: 'Checks' + key: checks + agents: + machineType: n2-standard-2 + preemptible: true + timeout_in_minutes: 60 + retry: + automatic: + - exit_status: '-1' + limit: 3 + - command: .buildkite/scripts/steps/lint.sh label: 'Linting' agents: @@ -56,6 +68,18 @@ steps: - exit_status: '-1' limit: 3 + - command: .buildkite/scripts/steps/checks/capture_oas_snapshot.sh + label: 'Check OAS Snapshot' + agents: + machineType: n2-standard-4 + preemptible: true + key: check_oas_snapshot + timeout_in_minutes: 60 + retry: + automatic: + - exit_status: '-1' + limit: 3 + - command: .buildkite/scripts/steps/check_types.sh label: 'Check Types' agents: @@ -99,29 +123,6 @@ steps: - exit_status: '*' limit: 1 - - command: .buildkite/scripts/steps/checks.sh - label: 'Checks' - key: checks - agents: - machineType: n2-standard-2 - preemptible: true - timeout_in_minutes: 60 - retry: - automatic: - - exit_status: '-1' - limit: 3 - - - command: .buildkite/scripts/steps/checks/capture_oas_snapshot.sh - label: 'Check OAS Snapshot' - agents: - machineType: n2-standard-4 - preemptible: true - timeout_in_minutes: 60 - retry: - automatic: - - exit_status: '-1' - limit: 3 - - command: .buildkite/scripts/steps/api_docs/build_api_docs.sh label: 'Build API Docs' agents: diff --git a/.buildkite/pipelines/pull_request/deploy_cloud.yml b/.buildkite/pipelines/pull_request/deploy_cloud.yml index 6b42037b95953..565c5af3bb0c1 100644 --- a/.buildkite/pipelines/pull_request/deploy_cloud.yml +++ b/.buildkite/pipelines/pull_request/deploy_cloud.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 30 soft_fail: true retry: diff --git a/.buildkite/pipelines/pull_request/exploratory_view_plugin.yml b/.buildkite/pipelines/pull_request/exploratory_view_plugin.yml index c46edb528987a..05fc218080cd4 100644 --- a/.buildkite/pipelines/pull_request/exploratory_view_plugin.yml +++ b/.buildkite/pipelines/pull_request/exploratory_view_plugin.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 artifact_paths: - 'x-pack/plugins/observability_solution/exploratory_view/e2e/.journeys/**/*' diff --git a/.buildkite/pipelines/pull_request/fips.yml b/.buildkite/pipelines/pull_request/fips.yml index 1a759e1288328..4f906e4420c8f 100644 --- a/.buildkite/pipelines/pull_request/fips.yml +++ b/.buildkite/pipelines/pull_request/fips.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 soft_fail: true retry: diff --git a/.buildkite/pipelines/pull_request/fleet_cypress.yml b/.buildkite/pipelines/pull_request/fleet_cypress.yml index d20591728b788..50912cc16e5a8 100644 --- a/.buildkite/pipelines/pull_request/fleet_cypress.yml +++ b/.buildkite/pipelines/pull_request/fleet_cypress.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 50 parallelism: 6 retry: diff --git a/.buildkite/pipelines/pull_request/inventory_cypress.yml b/.buildkite/pipelines/pull_request/inventory_cypress.yml index 7028b55808ca6..3cd96de506288 100644 --- a/.buildkite/pipelines/pull_request/inventory_cypress.yml +++ b/.buildkite/pipelines/pull_request/inventory_cypress.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 120 parallelism: 1 retry: diff --git a/.buildkite/pipelines/pull_request/kbn_handlebars.yml b/.buildkite/pipelines/pull_request/kbn_handlebars.yml index 36901a5d5c552..187058d238682 100644 --- a/.buildkite/pipelines/pull_request/kbn_handlebars.yml +++ b/.buildkite/pipelines/pull_request/kbn_handlebars.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 5 retry: automatic: diff --git a/.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml b/.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml index 8906cc72fa81f..b0d438064d51e 100644 --- a/.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml +++ b/.buildkite/pipelines/pull_request/observability_onboarding_cypress.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 120 retry: automatic: diff --git a/.buildkite/pipelines/pull_request/profiling_cypress.yml b/.buildkite/pipelines/pull_request/profiling_cypress.yml index 100e42206b3a1..8ed98a4fbc736 100644 --- a/.buildkite/pipelines/pull_request/profiling_cypress.yml +++ b/.buildkite/pipelines/pull_request/profiling_cypress.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 120 parallelism: 2 retry: diff --git a/.buildkite/pipelines/pull_request/response_ops.yml b/.buildkite/pipelines/pull_request/response_ops.yml index f09beb168259f..9ac20e86f6660 100644 --- a/.buildkite/pipelines/pull_request/response_ops.yml +++ b/.buildkite/pipelines/pull_request/response_ops.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 120 parallelism: 9 retry: diff --git a/.buildkite/pipelines/pull_request/response_ops_cases.yml b/.buildkite/pipelines/pull_request/response_ops_cases.yml index 5382ab6017fa6..27289c864e2c1 100644 --- a/.buildkite/pipelines/pull_request/response_ops_cases.yml +++ b/.buildkite/pipelines/pull_request/response_ops_cases.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 120 retry: automatic: diff --git a/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml b/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml index e8fa983f5ff63..ca185a684d0c7 100644 --- a/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml +++ b/.buildkite/pipelines/pull_request/security_solution/ai_assistant.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 1 retry: @@ -25,9 +27,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 1 retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/cloud_security_posture.yml b/.buildkite/pipelines/pull_request/security_solution/cloud_security_posture.yml index d2f1571f9d93f..e1ba84bf4f661 100644 --- a/.buildkite/pipelines/pull_request/security_solution/cloud_security_posture.yml +++ b/.buildkite/pipelines/pull_request/security_solution/cloud_security_posture.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 1 retry: @@ -25,9 +27,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 1 retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml b/.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml index 24c7fad53ddd2..90c20eaca256f 100644 --- a/.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml +++ b/.buildkite/pipelines/pull_request/security_solution/cypress_burn.yml @@ -9,9 +9,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 soft_fail: true parallelism: 1 @@ -28,9 +30,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 soft_fail: true parallelism: 1 @@ -45,9 +49,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 1 retry: @@ -62,9 +68,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 50 soft_fail: true retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml b/.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml index ecb07ce4c22a1..0692c26f57176 100644 --- a/.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml +++ b/.buildkite/pipelines/pull_request/security_solution/defend_workflows.yml @@ -9,9 +9,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 20 retry: @@ -29,9 +31,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 14 retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml b/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml index ad3c4dd230cee..91b3ff7e6b7ff 100644 --- a/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml +++ b/.buildkite/pipelines/pull_request/security_solution/detection_engine.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 5 retry: @@ -25,9 +27,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 2 retry: @@ -43,9 +47,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 5 retry: @@ -61,9 +67,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 2 retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml b/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml index 2f1d30ab97d07..d031c8f382a49 100644 --- a/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml +++ b/.buildkite/pipelines/pull_request/security_solution/entity_analytics.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 3 retry: @@ -25,9 +27,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 2 retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/explore.yml b/.buildkite/pipelines/pull_request/security_solution/explore.yml index 5fb3ed443e037..3805c8e37f905 100644 --- a/.buildkite/pipelines/pull_request/security_solution/explore.yml +++ b/.buildkite/pipelines/pull_request/security_solution/explore.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 2 retry: @@ -25,9 +27,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 2 retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/investigations.yml b/.buildkite/pipelines/pull_request/security_solution/investigations.yml index c238c8936ad7f..bcabf31f70e8b 100644 --- a/.buildkite/pipelines/pull_request/security_solution/investigations.yml +++ b/.buildkite/pipelines/pull_request/security_solution/investigations.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 7 retry: @@ -25,9 +27,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 8 retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/osquery_cypress.yml b/.buildkite/pipelines/pull_request/security_solution/osquery_cypress.yml index 790d28ff4c472..c2de20aa5975d 100644 --- a/.buildkite/pipelines/pull_request/security_solution/osquery_cypress.yml +++ b/.buildkite/pipelines/pull_request/security_solution/osquery_cypress.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 8 retry: @@ -25,9 +27,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 8 retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/playwright.yml b/.buildkite/pipelines/pull_request/security_solution/playwright.yml index 213021e02ca06..c92506297ea07 100644 --- a/.buildkite/pipelines/pull_request/security_solution/playwright.yml +++ b/.buildkite/pipelines/pull_request/security_solution/playwright.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 1 retry: @@ -25,9 +27,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 1 retry: diff --git a/.buildkite/pipelines/pull_request/security_solution/rule_management.yml b/.buildkite/pipelines/pull_request/security_solution/rule_management.yml index 8e43f0f4530ef..e247dc2972620 100644 --- a/.buildkite/pipelines/pull_request/security_solution/rule_management.yml +++ b/.buildkite/pipelines/pull_request/security_solution/rule_management.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 5 retry: @@ -25,9 +27,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 1 retry: @@ -43,9 +47,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 4 retry: @@ -61,9 +67,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 parallelism: 2 retry: diff --git a/.buildkite/pipelines/pull_request/slo_plugin_e2e.yml b/.buildkite/pipelines/pull_request/slo_plugin_e2e.yml index 3d1a4f9b46f41..2cf1126cf1f5d 100644 --- a/.buildkite/pipelines/pull_request/slo_plugin_e2e.yml +++ b/.buildkite/pipelines/pull_request/slo_plugin_e2e.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 30 artifact_paths: - 'x-pack/plugins/observability_solution/slo/e2e/.journeys/**/*' diff --git a/.buildkite/pipelines/pull_request/synthetics_plugin.yml b/.buildkite/pipelines/pull_request/synthetics_plugin.yml index f5d6b841a953d..b4079b9fac307 100644 --- a/.buildkite/pipelines/pull_request/synthetics_plugin.yml +++ b/.buildkite/pipelines/pull_request/synthetics_plugin.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 artifact_paths: - 'x-pack/plugins/observability_solution/synthetics/e2e/.journeys/**/*' diff --git a/.buildkite/pipelines/pull_request/uptime_plugin.yml b/.buildkite/pipelines/pull_request/uptime_plugin.yml index a03915ef77099..4c1e05d7476fd 100644 --- a/.buildkite/pipelines/pull_request/uptime_plugin.yml +++ b/.buildkite/pipelines/pull_request/uptime_plugin.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 artifact_paths: - 'x-pack/plugins/observability_solution/synthetics/e2e/.journeys/**/*' diff --git a/.buildkite/pipelines/pull_request/ux_plugin_e2e.yml b/.buildkite/pipelines/pull_request/ux_plugin_e2e.yml index cd95f44fa2e86..4bade14464f35 100644 --- a/.buildkite/pipelines/pull_request/ux_plugin_e2e.yml +++ b/.buildkite/pipelines/pull_request/ux_plugin_e2e.yml @@ -7,9 +7,11 @@ steps: depends_on: - build - quick_checks + - checks - linting - linting_with_types - check_types + - check_oas_snapshot timeout_in_minutes: 60 artifact_paths: - 'x-pack/plugins/observability_solution/ux/e2e/.journeys/**/*' diff --git a/.buildkite/pull_requests.json b/.buildkite/pull_requests.json index cbc0e9df03dc8..e88982ec00d9d 100644 --- a/.buildkite/pull_requests.json +++ b/.buildkite/pull_requests.json @@ -14,6 +14,7 @@ "build_on_commit": true, "build_on_comment": true, "build_drafts": false, + "build_on_ready": true, "trigger_comment_regex": "^(?:(?:buildkite\\W+)?(?:build|test)\\W+(?:this|it))|^\\/ci$", "always_trigger_comment_regex": "^(?:(?:buildkite\\W+)?(?:build|test)\\W+(?:this|it))|^\\/ci$", "skip_ci_labels": ["skip-ci"], diff --git a/.buildkite/scripts/steps/cloud/deploy.json b/.buildkite/scripts/steps/cloud/deploy.json index 3080f083aadfd..5ee605c39ff5c 100644 --- a/.buildkite/scripts/steps/cloud/deploy.json +++ b/.buildkite/scripts/steps/cloud/deploy.json @@ -7,7 +7,7 @@ "plan": { "cluster_topology": [ { - "instance_configuration_id": "gcp.integrationsserver.1", + "instance_configuration_id": "gcp.integrationsserver.n2.68x32x45", "zone_count": 1, "size": { "resource": "memory", @@ -32,7 +32,7 @@ "cluster_topology": [ { "zone_count": 1, - "instance_configuration_id": "gcp.coordinating.1", + "instance_configuration_id": "gcp.es.coordinating.n2.68x16x45", "node_roles": [ "ingest", "remote_cluster_client" @@ -50,7 +50,7 @@ "data": "hot" } }, - "instance_configuration_id": "gcp.data.highio.1", + "instance_configuration_id": "gcp.es.datahot.n2.68x32x45", "node_roles": [ "master", "ingest", @@ -72,7 +72,7 @@ "data": "warm" } }, - "instance_configuration_id": "gcp.data.highstorage.1", + "instance_configuration_id": "gcp.es.datawarm.n2.68x10x190", "node_roles": [ "data_warm", "remote_cluster_client" @@ -90,7 +90,7 @@ "data": "cold" } }, - "instance_configuration_id": "gcp.data.highstorage.1", + "instance_configuration_id": "gcp.es.datacold.n2.68x10x190", "node_roles": [ "data_cold", "remote_cluster_client" @@ -108,7 +108,7 @@ "data": "frozen" } }, - "instance_configuration_id": "gcp.es.datafrozen.n1.64x10x95", + "instance_configuration_id": "gcp.es.datafrozen.n2.68x10x90", "node_roles": [ "data_frozen" ], @@ -120,7 +120,7 @@ }, { "zone_count": 1, - "instance_configuration_id": "gcp.master.1", + "instance_configuration_id": "gcp.es.master.n2.68x32x45", "node_roles": [ "master", "remote_cluster_client" @@ -142,7 +142,7 @@ }, "autoscaling_tier_override": true, "id": "ml", - "instance_configuration_id": "gcp.ml.1", + "instance_configuration_id": "gcp.es.ml.n2.68x32x45", "node_roles": [ "ml", "remote_cluster_client" @@ -155,7 +155,7 @@ "enabled_built_in_plugins": [] }, "deployment_template": { - "id": "gcp-io-optimized-v2" + "id": "gcp-cpu-optimized" } }, "ref_id": "main-elasticsearch" @@ -168,7 +168,7 @@ "plan": { "cluster_topology": [ { - "instance_configuration_id": "gcp.kibana.1", + "instance_configuration_id": "gcp.kibana.n2.68x32x45", "zone_count": 1, "size": { "value": 2048, diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 10250b18541c8..523e860db1491 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -793,7 +793,6 @@ x-pack/packages/security/plugin_types_common @elastic/kibana-security x-pack/packages/security/plugin_types_public @elastic/kibana-security x-pack/packages/security/plugin_types_server @elastic/kibana-security x-pack/packages/security/role_management_model @elastic/kibana-security -x-pack/packages/security-solution/common @elastic/security-threat-hunting-investigations x-pack/packages/security-solution/distribution_bar @elastic/kibana-cloud-security-posture x-pack/plugins/security_solution_ess @elastic/security-solution x-pack/packages/security-solution/features @elastic/security-threat-hunting-explore @@ -955,7 +954,7 @@ packages/kbn-triggers-actions-ui-types @elastic/response-ops packages/kbn-try-in-console @elastic/search-kibana packages/kbn-ts-projects @elastic/kibana-operations packages/kbn-ts-type-check-cli @elastic/kibana-operations -packages/kbn-typed-react-router-config @elastic/obs-knowledge-team @elastic/obs-ux-management-team +packages/kbn-typed-react-router-config @elastic/obs-knowledge-team @elastic/obs-ux-infra_services-team packages/kbn-ui-actions-browser @elastic/appex-sharedux x-pack/examples/ui_actions_enhanced_examples @elastic/appex-sharedux src/plugins/ui_actions_enhanced @elastic/appex-sharedux @@ -1146,8 +1145,12 @@ packages/kbn-monaco/src/esql @elastic/kibana-esql #CC# /x-pack/plugins/reporting/ @elastic/appex-sharedux #CC# /x-pack/plugins/security_solution_serverless/ @elastic/appex-sharedux -### Observability Plugins +# Observability UI +/x-pack/test_serverless/api_integration/test_suites/observability/config.ts @elastic/observability-ui @elastic/appex-qa +/x-pack/test_serverless/api_integration/test_suites/observability/index.ts @elastic/observability-ui + +### Observability Plugins # Observability AI Assistant x-pack/test/observability_ai_assistant_api_integration @elastic/obs-ai-assistant @@ -1238,6 +1241,7 @@ x-pack/test_serverless/**/test_suites/observability/ai_assistant @elastic/obs-ai /x-pack/test/accessibility/apps/group3/stack_monitoring.ts @elastic/stack-monitoring # Fleet +/x-pack/test_serverless/api_integration/test_suites/security/fleet @elastic/fleet /x-pack/test/fleet_packages @elastic/fleet /x-pack/test/fleet_api_integration @elastic/fleet /x-pack/test/fleet_cypress @elastic/fleet @@ -1514,8 +1518,6 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib /x-pack/test/rule_registry @elastic/response-ops @elastic/obs-ux-management-team /x-pack/test/accessibility/apps/group3/rules_connectors.ts @elastic/response-ops /x-pack/test/functional/es_archives/cases/default @elastic/response-ops -/x-pack/test_serverless/api_integration/test_suites/observability/config.ts @elastic/response-ops -/x-pack/test_serverless/api_integration/test_suites/observability/index.ts @elastic/response-ops /x-pack/test_serverless/functional/page_objects/svl_triggers_actions_ui_page.ts @elastic/response-ops /x-pack/test_serverless/functional/page_objects/svl_rule_details_ui_page.ts @elastic/response-ops /x-pack/test_serverless/functional/page_objects/svl_oblt_overview_page.ts @elastic/response-ops @@ -1619,6 +1621,7 @@ x-pack/test/api_integration/apis/management/index_management/inference_endpoints # Security Solution /x-pack/test/common/services/security_solution @elastic/security-solution /x-pack/test/api_integration/services/security_solution_*.gen.ts @elastic/security-solution +/x-pack/test_serverless/functional/test_suites/security/index.feature_flags.ts @elastic/security-solution /x-pack/test/accessibility/apps/group3/security_solution.ts @elastic/security-solution /x-pack/test_serverless/functional/test_suites/security/config.ts @elastic/security-solution @elastic/appex-qa /x-pack/test_serverless/functional/test_suites/security/config.feature_flags.ts @elastic/security-solution diff --git a/docs/settings/alert-action-settings.asciidoc b/docs/settings/alert-action-settings.asciidoc index db36248ef194f..e0fa3f0aab860 100644 --- a/docs/settings/alert-action-settings.asciidoc +++ b/docs/settings/alert-action-settings.asciidoc @@ -112,11 +112,6 @@ A boolean value indicating that TLS must be used for this connection. The options `smtp.ignoreTLS` and `smtp.requireTLS` can not both be set to true. Default: `false`. -`xpack.actions.customHostSettings[n].ssl.rejectUnauthorized`:: -deprecated:[8.0.0] Use <> instead. A boolean value indicating whether to bypass server certificate validation. -Overrides the general `xpack.actions.rejectUnauthorized` configuration -for requests made for this hostname/port. - [[action-config-custom-host-verification-mode]] `xpack.actions.customHostSettings[n].ssl.verificationMode` {ess-icon}:: Controls the verification of the server certificate that {kib} receives when making an outbound SSL/TLS connection to the host server. Valid values are `full`, `certificate`, and `none`. Use `full` to perform hostname verification, `certificate` to skip hostname verification, and `none` to skip verification. Default: `full`. <>. Overrides the general `xpack.actions.ssl.verificationMode` configuration @@ -198,19 +193,10 @@ By default, no hosts will use the proxy, but if an action's hostname is in this `xpack.actions.proxyHeaders` {ess-icon}:: Specifies HTTP headers for the proxy, if using a proxy for actions. Default: {}. -`xpack.actions.proxyRejectUnauthorizedCertificates` {ess-icon}:: -deprecated:[8.0.0] Use <> instead. Set to `false` to bypass certificate validation for the proxy, if using a proxy for actions. Default: `true`. - [[action-config-proxy-verification-mode]]`xpack.actions.ssl.proxyVerificationMode` {ess-icon}:: Controls the verification for the proxy server certificate that Kibana receives when making an outbound SSL/TLS connection to the proxy server. Valid values are `full`, `certificate`, and `none`. Use `full` to perform hostname verification, `certificate` to skip hostname verification, and `none` to skip verification. Default: `full`. <>. -`xpack.actions.rejectUnauthorized` {ess-icon}:: -deprecated:[8.0.0] Use <> instead. Set to `false` to bypass certificate validation for actions. Default: `true`. -+ -As an alternative to setting `xpack.actions.rejectUnauthorized`, you can use the setting -`xpack.actions.customHostSettings` to set SSL options for specific servers. - [[action-config-verification-mode]] `xpack.actions.ssl.verificationMode` {ess-icon}:: Controls the verification for the server certificate that {hosted-ems} receives when making an outbound SSL/TLS connection for actions. Valid values are `full`, `certificate`, and `none`. Use `full` to perform hostname verification, `certificate` to skip hostname verification, and `none` to skip verification. Default: `full`. <>. diff --git a/oas_docs/bundle.json b/oas_docs/bundle.json index fd2a7bbe22de0..743d6ae6e422a 100644 --- a/oas_docs/bundle.json +++ b/oas_docs/bundle.json @@ -40775,7 +40775,7 @@ }, "/api/spaces/_copy_saved_objects": { "post": { - "description": "It also allows you to automatically copy related objects, so when you copy a dashboard, this can automatically copy over the associated visualizations, data views, and saved searches, as required. You can request to overwrite any objects that already exist in the target space if they share an identifier or you can use the resolve copy saved objects conflicts API to do this on a per-object basis.", + "description": "It also allows you to automatically copy related objects, so when you copy a dashboard, this can automatically copy over the associated visualizations, data views, and saved searches, as required. You can request to overwrite any objects that already exist in the target space if they share an identifier or you can use the resolve copy saved objects conflicts API to do this on a per-object basis.

[Required authorization] Route required privileges: ALL of [copySavedObjectsToSpaces].", "operationId": "post-spaces-copy-saved-objects", "parameters": [ { @@ -41018,7 +41018,7 @@ }, "/api/spaces/_resolve_copy_saved_objects_errors": { "post": { - "description": "Overwrite saved objects that are returned as errors from the copy saved objects to space API.", + "description": "Overwrite saved objects that are returned as errors from the copy saved objects to space API.

[Required authorization] Route required privileges: ALL of [copySavedObjectsToSpaces].", "operationId": "post-spaces-resolve-copy-saved-objects-errors", "parameters": [ { diff --git a/oas_docs/output/kibana.yaml b/oas_docs/output/kibana.yaml index 5bbc65ad80bc4..6122607df925f 100644 --- a/oas_docs/output/kibana.yaml +++ b/oas_docs/output/kibana.yaml @@ -41050,7 +41050,9 @@ paths: visualizations, data views, and saved searches, as required. You can request to overwrite any objects that already exist in the target space if they share an identifier or you can use the resolve copy saved - objects conflicts API to do this on a per-object basis. + objects conflicts API to do this on a per-object + basis.

[Required authorization] Route required privileges: ALL + of [copySavedObjectsToSpaces]. operationId: post-spaces-copy-saved-objects parameters: - description: The version of the API to use @@ -41239,7 +41241,8 @@ paths: post: description: >- Overwrite saved objects that are returned as errors from the copy saved - objects to space API. + objects to space API.

[Required authorization] Route required + privileges: ALL of [copySavedObjectsToSpaces]. operationId: post-spaces-resolve-copy-saved-objects-errors parameters: - description: The version of the API to use diff --git a/package.json b/package.json index 4a91266058ccb..17e873a89c7be 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "resolutions": { "**/@bazel/typescript/protobufjs": "6.11.4", "**/@hello-pangea/dnd": "16.6.0", - "**/@langchain/core": "^0.2.18", + "**/@langchain/core": "^0.3.16", "**/@langchain/google-common": "^0.1.1", "**/@types/node": "20.10.5", "**/@typescript-eslint/utils": "5.62.0", @@ -90,7 +90,7 @@ "**/globule/minimatch": "^3.1.2", "**/hoist-non-react-statics": "^3.3.2", "**/isomorphic-fetch/node-fetch": "^2.6.7", - "**/langchain": "^0.2.11", + "**/langchain": "^0.3.5", "**/remark-parse/trim": "1.0.1", "**/sharp": "0.32.6", "**/typescript": "5.1.6", @@ -810,7 +810,6 @@ "@kbn/security-plugin-types-public": "link:x-pack/packages/security/plugin_types_public", "@kbn/security-plugin-types-server": "link:x-pack/packages/security/plugin_types_server", "@kbn/security-role-management-model": "link:x-pack/packages/security/role_management_model", - "@kbn/security-solution-common": "link:x-pack/packages/security-solution/common", "@kbn/security-solution-distribution-bar": "link:x-pack/packages/security-solution/distribution_bar", "@kbn/security-solution-ess": "link:x-pack/plugins/security_solution_ess", "@kbn/security-solution-features": "link:x-pack/packages/security-solution/features", @@ -1010,13 +1009,13 @@ "@kbn/xstate-utils": "link:packages/kbn-xstate-utils", "@kbn/zod": "link:packages/kbn-zod", "@kbn/zod-helpers": "link:packages/kbn-zod-helpers", - "@langchain/community": "0.2.18", - "@langchain/core": "^0.2.18", + "@langchain/community": "0.3.11", + "@langchain/core": "^0.3.16", "@langchain/google-common": "^0.1.1", - "@langchain/google-genai": "^0.1.0", + "@langchain/google-genai": "^0.1.2", "@langchain/google-vertexai": "^0.1.0", - "@langchain/langgraph": "0.0.34", - "@langchain/openai": "^0.1.3", + "@langchain/langgraph": "0.2.19", + "@langchain/openai": "^0.3.11", "@langtrase/trace-attributes": "^3.0.8", "@launchdarkly/node-server-sdk": "^9.7.0", "@launchdarkly/openfeature-node-server": "^1.0.0", @@ -1159,8 +1158,8 @@ "jsonwebtoken": "^9.0.2", "jsts": "^1.6.2", "kea": "^2.6.0", - "langchain": "^0.2.11", - "langsmith": "^0.1.55", + "langchain": "^0.3.5", + "langsmith": "^0.2.3", "launchdarkly-js-client-sdk": "^3.5.0", "load-json-file": "^6.2.0", "lodash": "^4.17.21", @@ -1189,7 +1188,7 @@ "nunjucks": "^3.2.4", "object-hash": "^1.3.1", "object-path-immutable": "^3.1.1", - "openai": "^4.24.1", + "openai": "^4.68.0", "openpgp": "5.10.1", "ora": "^4.0.4", "p-limit": "^3.0.1", diff --git a/packages/kbn-alerts-ui-shared/src/rule_type_modal/components/rule_type_list.test.tsx b/packages/kbn-alerts-ui-shared/src/rule_type_modal/components/rule_type_list.test.tsx index 175d90924586c..7003b06875659 100644 --- a/packages/kbn-alerts-ui-shared/src/rule_type_modal/components/rule_type_list.test.tsx +++ b/packages/kbn-alerts-ui-shared/src/rule_type_modal/components/rule_type_list.test.tsx @@ -9,6 +9,7 @@ import React from 'react'; import { render, screen, within } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { RuleTypeList } from './rule_type_list'; import { RuleTypeWithDescription } from '../types'; @@ -93,5 +94,8 @@ describe('RuleTypeList', () => { expect(secondRuleInList).not.toBeDisabled(); const thirdRuleInList = within(ruleListEl[2]).getByRole('button', { name: 'Rule Type 2' }); expect(thirdRuleInList).toBeDisabled(); + + await userEvent.hover(ruleListEl[2]); + expect(await screen.findByText('This rule requires a platinum license.')).toBeInTheDocument(); }); }); diff --git a/packages/kbn-alerts-ui-shared/src/rule_type_modal/components/rule_type_list.tsx b/packages/kbn-alerts-ui-shared/src/rule_type_modal/components/rule_type_list.tsx index 4e21e428f3c5c..91710dbdfade5 100644 --- a/packages/kbn-alerts-ui-shared/src/rule_type_modal/components/rule_type_list.tsx +++ b/packages/kbn-alerts-ui-shared/src/rule_type_modal/components/rule_type_list.tsx @@ -20,6 +20,7 @@ import { EuiEmptyPrompt, EuiButton, useEuiTheme, + EuiToolTip, } from '@elastic/eui'; import { omit } from 'lodash'; import { PRODUCER_DISPLAY_NAMES } from '../../common/i18n'; @@ -86,6 +87,28 @@ export const RuleTypeList: React.FC = ({ const onClickAll = useCallback(() => onFilterByProducer(null), [onFilterByProducer]); + const ruleCard = (rule: RuleTypeWithDescription) => ( + onSelectRuleType(rule.id)} + description={rule.description} + style={{ marginRight: '8px', flexGrow: 0 }} + data-test-subj={`${rule.id}-SelectOption`} + isDisabled={!rule.enabledInLicense} + > + + {producerToDisplayName(rule.producer)} + + + ); + return ( = ({ )} {ruleTypesList.map((rule) => ( - onSelectRuleType(rule.id)} - description={rule.description} - style={{ marginRight: '8px', flexGrow: 0 }} - data-test-subj={`${rule.id}-SelectOption`} - isDisabled={rule.enabledInLicense === false} - > - - {producerToDisplayName(rule.producer)} - - + <>{ruleCard(rule)} + + )} ))} diff --git a/packages/kbn-apm-synthtrace-client/src/lib/entities/kubernetes/index.ts b/packages/kbn-apm-synthtrace-client/src/lib/entities/kubernetes/index.ts index 36d7f8caf9601..db95dcf4155bc 100644 --- a/packages/kbn-apm-synthtrace-client/src/lib/entities/kubernetes/index.ts +++ b/packages/kbn-apm-synthtrace-client/src/lib/entities/kubernetes/index.ts @@ -55,9 +55,9 @@ export class K8sEntity extends Serializable { super({ ...fields, 'entity.type': entityTypeWithSchema, - 'entity.definitionId': `builtin_${entityTypeWithSchema}`, - 'entity.identityFields': identityFields, - 'entity.displayName': getDisplayName({ identityFields, fields }), + 'entity.definition_id': `builtin_${entityTypeWithSchema}`, + 'entity.identity_fields': identityFields, + 'entity.display_name': getDisplayName({ identityFields, fields }), }); } } diff --git a/packages/kbn-apm-synthtrace-client/src/types/agent_names.ts b/packages/kbn-apm-synthtrace-client/src/types/agent_names.ts index d181a437fb73d..5953331bf5aa8 100644 --- a/packages/kbn-apm-synthtrace-client/src/types/agent_names.ts +++ b/packages/kbn-apm-synthtrace-client/src/types/agent_names.ts @@ -24,6 +24,8 @@ type OpenTelemetryAgentName = | 'otlp' | 'opentelemetry/cpp' | 'opentelemetry/dotnet' + | 'opentelemetry/dotnet/opentelemetry-dotnet-instrumentation' + | 'opentelemetry/dotnet/elastic' | 'opentelemetry/erlang' | 'opentelemetry/go' | 'opentelemetry/java' diff --git a/packages/kbn-router-to-openapispec/src/extract_authz_description.test.ts b/packages/kbn-router-to-openapispec/src/extract_authz_description.test.ts index 8da2324e68f02..308f0a7686597 100644 --- a/packages/kbn-router-to-openapispec/src/extract_authz_description.test.ts +++ b/packages/kbn-router-to-openapispec/src/extract_authz_description.test.ts @@ -33,7 +33,9 @@ describe('extractAuthzDescription', () => { }, }; const description = extractAuthzDescription(routeSecurity); - expect(description).toBe('[Authz] Route required privileges: ALL of [manage_spaces].'); + expect(description).toBe( + '[Required authorization] Route required privileges: ALL of [manage_spaces].' + ); }); it('should return route authz description for privilege groups', () => { @@ -44,7 +46,9 @@ describe('extractAuthzDescription', () => { }, }; const description = extractAuthzDescription(routeSecurity); - expect(description).toBe('[Authz] Route required privileges: ALL of [console].'); + expect(description).toBe( + '[Required authorization] Route required privileges: ALL of [console].' + ); } { const routeSecurity: RouteSecurity = { @@ -58,7 +62,7 @@ describe('extractAuthzDescription', () => { }; const description = extractAuthzDescription(routeSecurity); expect(description).toBe( - '[Authz] Route required privileges: ANY of [manage_spaces OR taskmanager].' + '[Required authorization] Route required privileges: ANY of [manage_spaces OR taskmanager].' ); } { @@ -74,7 +78,7 @@ describe('extractAuthzDescription', () => { }; const description = extractAuthzDescription(routeSecurity); expect(description).toBe( - '[Authz] Route required privileges: ALL of [console, filesManagement] AND ANY of [manage_spaces OR taskmanager].' + '[Required authorization] Route required privileges: ALL of [console, filesManagement] AND ANY of [manage_spaces OR taskmanager].' ); } }); diff --git a/packages/kbn-router-to-openapispec/src/extract_authz_description.ts b/packages/kbn-router-to-openapispec/src/extract_authz_description.ts index 4cd6875913780..7979188f2641e 100644 --- a/packages/kbn-router-to-openapispec/src/extract_authz_description.ts +++ b/packages/kbn-router-to-openapispec/src/extract_authz_description.ts @@ -56,5 +56,5 @@ export const extractAuthzDescription = (routeSecurity: InternalRouteSecurity | u return `Route required privileges: ${getPrivilegesDescription(allRequired, anyRequired)}.`; }; - return `[Authz] ${getDescriptionForRoute()}`; + return `[Required authorization] ${getDescriptionForRoute()}`; }; diff --git a/packages/kbn-router-to-openapispec/src/process_router.test.ts b/packages/kbn-router-to-openapispec/src/process_router.test.ts index 17191e7ab1b1c..2ce135a378789 100644 --- a/packages/kbn-router-to-openapispec/src/process_router.test.ts +++ b/packages/kbn-router-to-openapispec/src/process_router.test.ts @@ -124,6 +124,26 @@ describe('processRouter', () => { }, }, }, + { + path: '/quux', + method: 'post', + options: { + description: 'This a test route description.', + }, + handler: jest.fn(), + validationSchemas: { request: { body: schema.object({}) } }, + security: { + authz: { + requiredPrivileges: [ + 'manage_spaces', + { + allRequired: ['taskmanager'], + anyRequired: ['console'], + }, + ], + }, + }, + }, ], } as unknown as Router; @@ -132,7 +152,7 @@ describe('processRouter', () => { version: '2023-10-31', }); - expect(Object.keys(result1.paths!)).toHaveLength(4); + expect(Object.keys(result1.paths!)).toHaveLength(5); const result2 = processRouter(testRouter, new OasConverter(), createOpIdGenerator(), { version: '2024-10-31', @@ -148,7 +168,11 @@ describe('processRouter', () => { expect(result.paths['/qux']?.post).toBeDefined(); expect(result.paths['/qux']?.post?.description).toEqual( - '[Authz] Route required privileges: ALL of [manage_spaces, taskmanager] AND ANY of [console].' + '[Required authorization] Route required privileges: ALL of [manage_spaces, taskmanager] AND ANY of [console].' + ); + + expect(result.paths['/quux']?.post?.description).toEqual( + 'This a test route description.

[Required authorization] Route required privileges: ALL of [manage_spaces, taskmanager] AND ANY of [console].' ); }); }); diff --git a/packages/kbn-router-to-openapispec/src/process_router.ts b/packages/kbn-router-to-openapispec/src/process_router.ts index e11c4057a05b8..b808f9bed84d5 100644 --- a/packages/kbn-router-to-openapispec/src/process_router.ts +++ b/packages/kbn-router-to-openapispec/src/process_router.ts @@ -64,11 +64,13 @@ export const processRouter = ( parameters.push(...pathObjects, ...queryObjects); } - let description = ''; + let description = `${route.options.description ?? ''}`; if (route.security) { const authzDescription = extractAuthzDescription(route.security); - description = `${route.options.description ?? ''}${authzDescription ?? ''}`; + description += `${route.options.description && authzDescription ? `

` : ''}${ + authzDescription ?? '' + }`; } const hasDeprecations = !!route.options.deprecated; @@ -77,7 +79,6 @@ export const processRouter = ( summary: route.options.summary ?? '', tags: route.options.tags ? extractTags(route.options.tags) : [], ...(description ? { description } : {}), - ...(route.options.description ? { description: route.options.description } : {}), ...(hasDeprecations ? { deprecated: true } : {}), ...(route.options.discontinued ? { 'x-discontinued': route.options.discontinued } : {}), requestBody: !!validationSchemas?.body diff --git a/packages/kbn-router-to-openapispec/src/process_versioned_router.test.ts b/packages/kbn-router-to-openapispec/src/process_versioned_router.test.ts index 839ba5f298134..b7a4827e4f365 100644 --- a/packages/kbn-router-to-openapispec/src/process_versioned_router.test.ts +++ b/packages/kbn-router-to-openapispec/src/process_versioned_router.test.ts @@ -157,7 +157,7 @@ describe('processVersionedRouter', () => { expect(results.paths['/foo']!.get).toBeDefined(); expect(results.paths['/foo']!.get!.description).toBe( - '[Authz] Route required privileges: ALL of [manage_spaces].' + 'This is a test route description.

[Required authorization] Route required privileges: ALL of [manage_spaces].' ); }); }); @@ -176,6 +176,7 @@ const createTestRoute: () => VersionedRouterRoute = () => ({ requiredPrivileges: ['manage_spaces'], }, }, + description: 'This is a test route description.', }, handlers: [ { diff --git a/packages/kbn-router-to-openapispec/src/process_versioned_router.ts b/packages/kbn-router-to-openapispec/src/process_versioned_router.ts index 380bbd2e86c26..eab2dfef78a21 100644 --- a/packages/kbn-router-to-openapispec/src/process_versioned_router.ts +++ b/packages/kbn-router-to-openapispec/src/process_versioned_router.ts @@ -90,12 +90,13 @@ export const processVersionedRouter = ( ...queryObjects, ]; } - - let description = ''; + let description = `${route.options.description ?? ''}`; if (route.options.security) { const authzDescription = extractAuthzDescription(route.options.security); - description = `${route.options.description ?? ''}${authzDescription ?? ''}`; + description += `${route.options.description && authzDescription ? '

' : ''}${ + authzDescription ?? '' + }`; } const hasBody = Boolean(extractValidationSchemaFromVersionedHandler(handler)?.request?.body); @@ -107,7 +108,6 @@ export const processVersionedRouter = ( summary: route.options.summary ?? '', tags: route.options.options?.tags ? extractTags(route.options.options.tags) : [], ...(description ? { description } : {}), - ...(route.options.description ? { description: route.options.description } : {}), ...(hasDeprecations ? { deprecated: true } : {}), ...(route.options.discontinued ? { 'x-discontinued': route.options.discontinued } : {}), requestBody: hasBody diff --git a/packages/kbn-typed-react-router-config/kibana.jsonc b/packages/kbn-typed-react-router-config/kibana.jsonc index 0462d28238890..c004d263a6046 100644 --- a/packages/kbn-typed-react-router-config/kibana.jsonc +++ b/packages/kbn-typed-react-router-config/kibana.jsonc @@ -1,5 +1,5 @@ { "type": "shared-common", "id": "@kbn/typed-react-router-config", - "owner": ["@elastic/obs-knowledge-team", "@elastic/obs-ux-management-team"] + "owner": ["@elastic/obs-knowledge-team", "@elastic/obs-ux-infra_services-team"] } diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker index fbe64258a5704..b814538466d73 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker @@ -221,16 +221,13 @@ kibana_vars=( xpack.actions.proxyBypassHosts xpack.actions.proxyHeaders xpack.actions.proxyOnlyHosts - xpack.actions.proxyRejectUnauthorizedCertificates xpack.actions.proxyUrl - xpack.actions.rejectUnauthorized xpack.actions.responseTimeout xpack.actions.ssl.proxyVerificationMode xpack.actions.ssl.verificationMode xpack.alerting.healthCheck.interval xpack.alerting.invalidateApiKeysTask.interval xpack.alerting.invalidateApiKeysTask.removalDelay - xpack.alerting.defaultRuleTaskTimeout xpack.alerting.rules.run.timeout xpack.alerting.rules.run.ruleTypeOverrides xpack.alerting.cancelAlertsOnRuleTimeout @@ -240,9 +237,6 @@ kibana_vars=( xpack.alerting.rules.run.alerts.max xpack.alerting.rules.run.actions.connectorTypeOverrides xpack.alerting.maxScheduledPerMinute - xpack.alerts.healthCheck.interval - xpack.alerts.invalidateApiKeysTask.interval - xpack.alerts.invalidateApiKeysTask.removalDelay xpack.apm.indices.error xpack.apm.indices.metric xpack.apm.indices.onboarding diff --git a/src/plugins/dashboard/public/dashboard_container/state/dashboard_container_reducers.ts b/src/plugins/dashboard/public/dashboard_container/state/dashboard_container_reducers.ts index 0bb33a05c36ce..c0c39b0ffd284 100644 --- a/src/plugins/dashboard/public/dashboard_container/state/dashboard_container_reducers.ts +++ b/src/plugins/dashboard/public/dashboard_container/state/dashboard_container_reducers.ts @@ -9,6 +9,7 @@ import { PayloadAction } from '@reduxjs/toolkit'; +import { isFilterPinned } from '@kbn/es-query'; import { DashboardReduxState, DashboardStateFromSaveModal, @@ -94,13 +95,20 @@ export const dashboardContainerReducers = { * `timeRestore` is `false`, this causes unecessary data fetches for the control group. * 2) The view mode, since resetting should never impact this - sometimes the Dashboard saved objects * have this saved in and we don't want resetting to cause unexpected view mode changes. + * 3) Pinned filters. */ resetToLastSavedInput: ( state: DashboardReduxState, action: PayloadAction ) => { + const keepPinnedFilters = [ + ...state.explicitInput.filters.filter(isFilterPinned), + ...action.payload.filters, + ]; + state.explicitInput = { ...action.payload, + filters: keepPinnedFilters, ...(!state.explicitInput.timeRestore && { timeRange: state.explicitInput.timeRange }), viewMode: state.explicitInput.viewMode, }; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/security/security_root_profile/profile.tsx b/src/plugins/discover/public/context_awareness/profile_providers/security/security_root_profile/profile.tsx index 238d29302a910..602879125a331 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/security/security_root_profile/profile.tsx +++ b/src/plugins/discover/public/context_awareness/profile_providers/security/security_root_profile/profile.tsx @@ -7,8 +7,6 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import React from 'react'; -import { getDiscoverCellRenderer } from '@kbn/security-solution-common'; import { RootProfileProvider, SolutionType } from '../../../profiles'; import { ProfileProviderServices } from '../../profile_provider_services'; import { SecurityProfileProviderFactory } from '../types'; @@ -21,12 +19,6 @@ export const createSecurityRootProfileProvider: SecurityProfileProviderFactory< profile: { getCellRenderers: (prev) => (params) => ({ ...prev(params), - 'host.name': (props) => { - const CellRenderer = getDiscoverCellRenderer({ - fieldName: 'host.name', - }); - return ; - }, }), }, resolve: (params) => { diff --git a/src/plugins/discover/tsconfig.json b/src/plugins/discover/tsconfig.json index 197d323d7d221..72d5594ba40f0 100644 --- a/src/plugins/discover/tsconfig.json +++ b/src/plugins/discover/tsconfig.json @@ -95,7 +95,6 @@ "@kbn/presentation-containers", "@kbn/observability-ai-assistant-plugin", "@kbn/fields-metadata-plugin", - "@kbn/security-solution-common", "@kbn/logs-data-access-plugin", "@kbn/core-lifecycle-browser", "@kbn/discover-contextual-components", diff --git a/src/plugins/ui_actions_enhanced/.eslintrc.json b/src/plugins/ui_actions_enhanced/.eslintrc.json deleted file mode 100644 index 2aab6c2d9093b..0000000000000 --- a/src/plugins/ui_actions_enhanced/.eslintrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "rules": { - "@typescript-eslint/consistent-type-definitions": 0 - } -} diff --git a/src/plugins/ui_actions_enhanced/common/types.ts b/src/plugins/ui_actions_enhanced/common/types.ts index 5086d0e541e97..ff60a9370c576 100644 --- a/src/plugins/ui_actions_enhanced/common/types.ts +++ b/src/plugins/ui_actions_enhanced/common/types.ts @@ -11,6 +11,7 @@ import type { SerializableRecord } from '@kbn/utility-types'; export type BaseActionConfig = SerializableRecord; +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions export type SerializedAction = { readonly factoryId: string; readonly name: string; @@ -20,12 +21,14 @@ export type SerializedAction /** * Serialized representation of a triggers-action pair, used to persist in storage. */ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions export type SerializedEvent = { eventId: string; triggers: string[]; action: SerializedAction; }; +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions export type DynamicActionsState = { events: SerializedEvent[]; }; diff --git a/src/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx b/src/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx index 2e4fd27948b8e..cfe7784ec99fd 100644 --- a/src/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx +++ b/src/plugins/ui_actions_enhanced/public/components/action_wizard/test_data.tsx @@ -25,6 +25,7 @@ export const dashboards = [ { id: 'dashboard2', title: 'Dashboard 2' }, ]; +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions type DashboardDrilldownConfig = { dashboardId?: string; useCurrentFilters: boolean; @@ -119,6 +120,7 @@ export const dashboardFactory = new ActionFactory(dashboardDrilldownActionFactor getFeatureUsageStart: () => licensingMock.createStart().featureUsage, }); +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions type UrlDrilldownConfig = { url: string; openInNewTab: boolean; diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/url_drilldown_collect_config/i18n.ts b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/url_drilldown_collect_config/i18n.ts index 2c49b497e0c75..d357897c32395 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/url_drilldown_collect_config/i18n.ts +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/components/url_drilldown_collect_config/i18n.ts @@ -9,23 +9,6 @@ import { i18n } from '@kbn/i18n'; -export const txtUrlTemplatePlaceholder = i18n.translate( - 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplatePlaceholderText', - { - defaultMessage: 'Example: {exampleUrl}', - values: { - exampleUrl: 'https://www.my-url.com/?{{event.key}}={{event.value}}', - }, - } -); - -export const txtUrlPreviewHelpText = i18n.translate( - 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewHelpText', - { - defaultMessage: `Please note that in preview '{{event.*}}' variables are substituted with dummy values.`, - } -); - export const txtUrlTemplateLabel = i18n.translate( 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateLabel', { @@ -33,24 +16,43 @@ export const txtUrlTemplateLabel = i18n.translate( } ); -export const txtUrlTemplateSyntaxHelpLinkText = i18n.translate( - 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateSyntaxHelpLinkText', +export const txtEmptyErrorMessage = i18n.translate( + 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateEmptyErrorMessage', { - defaultMessage: 'Syntax help', + defaultMessage: 'URL template is required.', } ); -export const txtUrlTemplatePreviewLabel = i18n.translate( - 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewLabel', +export const txtInvalidFormatErrorMessage = ({ + error, + example, +}: { + error: string; + example: string; +}) => + i18n.translate( + 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateInvalidFormatErrorMessage', + { + defaultMessage: '{error} Example: {example}', + values: { + error, + example, + }, + } + ); + +export const txtUrlTemplateSyntaxTestingHelpText = i18n.translate( + 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateSyntaxTestingHelpText', { - defaultMessage: 'URL preview:', + defaultMessage: + 'To validate and test the URL template, save the configuration and use this drilldown from the panel.', } ); -export const txtUrlTemplatePreviewLinkText = i18n.translate( - 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewLinkText', +export const txtUrlTemplateSyntaxHelpLinkText = i18n.translate( + 'uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateSyntaxHelpLinkText', { - defaultMessage: 'Preview', + defaultMessage: 'Syntax help', } ); 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 60b8cc33c178f..fd9e78c37d981 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 @@ -17,10 +17,14 @@ import { txtUrlTemplateSyntaxHelpLinkText, txtUrlTemplateLabel, txtUrlTemplateAdditionalOptions, + txtEmptyErrorMessage, + txtInvalidFormatErrorMessage, + txtUrlTemplateSyntaxTestingHelpText, } from './i18n'; import { VariablePopover } from '../variable_popover'; import { UrlDrilldownOptionsComponent } from './lazy'; import { DEFAULT_URL_DRILLDOWN_OPTIONS } from '../../constants'; +import { validateUrl } from '../../url_validation'; export interface UrlDrilldownCollectConfigProps { config: UrlDrilldownConfig; @@ -69,7 +73,16 @@ export const UrlDrilldownCollectConfig: React.FC } } const isEmpty = !urlTemplate; - const isInvalid = !isPristine && isEmpty; + + const isValidUrlFormat = validateUrl(urlTemplate); + const isInvalid = !isPristine && (isEmpty || !isValidUrlFormat.isValid); + + const invalidErrorMessage = isInvalid + ? isEmpty + ? txtEmptyErrorMessage + : txtInvalidFormatErrorMessage({ error: isValidUrlFormat.error!, example: exampleUrl }) + : undefined; + const variablesDropdown = ( - {txtUrlTemplateSyntaxHelpLinkText} - - ) + <> + {txtUrlTemplateSyntaxTestingHelpText}{' '} + {syntaxHelpDocsLink ? ( + + {txtUrlTemplateSyntaxHelpLinkText} + + ) : null} + } labelAppend={variablesDropdown} > diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/types.ts b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/types.ts index 1deafe53db379..973fcb1c8ebbf 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/types.ts +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/types.ts @@ -14,6 +14,7 @@ export type UrlDrilldownConfig = { /** * User-configurable options for URL drilldowns */ +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions export type UrlDrilldownOptions = { openInNewTab: boolean; encodeUrl: boolean; diff --git a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_validation.ts b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_validation.ts index e95c32df56595..d3c3db4772bec 100644 --- a/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_validation.ts +++ b/src/plugins/ui_actions_enhanced/public/drilldowns/url_drilldown/url_validation.ts @@ -14,23 +14,24 @@ import { compile } from './url_template'; const generalFormatError = i18n.translate( 'uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatGeneralErrorMessage', { - defaultMessage: 'Invalid format. Example: {exampleUrl}', - values: { - exampleUrl: 'https://www.my-url.com/?{{event.key}}={{event.value}}', - }, + defaultMessage: 'Invalid URL format.', } ); -const formatError = (message: string) => - i18n.translate('uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatErrorMessage', { - defaultMessage: 'Invalid format: {message}', +const compileError = (message: string) => + i18n.translate('uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlCompileErrorMessage', { + defaultMessage: 'The URL template is not valid in the given context. {message}.', values: { - message, + message: message.replaceAll('[object Object]', 'context'), }, }); const SAFE_URL_PATTERN = /^(?:(?:https?|mailto):|[^&:/?#]*(?:[/?#]|$))/gi; -export function validateUrl(url: string): { isValid: boolean; error?: string } { +export function validateUrl(url: string): { + isValid: boolean; + error?: string; + invalidUrl?: string; +} { if (!url) return { isValid: false, @@ -45,6 +46,7 @@ export function validateUrl(url: string): { isValid: boolean; error?: string } { return { isValid: false, error: generalFormatError, + invalidUrl: url, }; } } @@ -52,20 +54,32 @@ export function validateUrl(url: string): { isValid: boolean; error?: string } { export async function validateUrlTemplate( urlTemplate: UrlDrilldownConfig['url'], scope: UrlDrilldownScope -): Promise<{ isValid: boolean; error?: string }> { +): Promise<{ isValid: boolean; error?: string; invalidUrl?: string }> { if (!urlTemplate.template) return { isValid: false, error: generalFormatError, }; + let compiledUrl: string; + + try { + compiledUrl = await compile(urlTemplate.template, scope); + } catch (e) { + return { + isValid: false, + error: compileError(e.message), + invalidUrl: urlTemplate.template, + }; + } + try { - const compiledUrl = await compile(urlTemplate.template, scope); return validateUrl(compiledUrl); } catch (e) { return { isValid: false, - error: formatError(e.message), + error: generalFormatError + ` ${e.message}.`, + invalidUrl: compiledUrl, }; } } diff --git a/src/plugins/unified_search/public/query_string_input/esql_menu_popover.tsx b/src/plugins/unified_search/public/query_string_input/esql_menu_popover.tsx index 71e54c3376abb..ba978debb73de 100644 --- a/src/plugins/unified_search/public/query_string_input/esql_menu_popover.tsx +++ b/src/plugins/unified_search/public/query_string_input/esql_menu_popover.tsx @@ -145,7 +145,6 @@ export const ESQLMenuPopover: React.FC = ({ }, { id: 1, - initialFocusedItemIndex: 1, title: i18n.translate('unifiedSearch.query.queryBar.esqlMenu.exampleQueries', { defaultMessage: 'Recommended queries', }), diff --git a/tsconfig.base.json b/tsconfig.base.json index 727cb930bc606..7b1bc834fcc28 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -1580,8 +1580,6 @@ "@kbn/security-plugin-types-server/*": ["x-pack/packages/security/plugin_types_server/*"], "@kbn/security-role-management-model": ["x-pack/packages/security/role_management_model"], "@kbn/security-role-management-model/*": ["x-pack/packages/security/role_management_model/*"], - "@kbn/security-solution-common": ["x-pack/packages/security-solution/common"], - "@kbn/security-solution-common/*": ["x-pack/packages/security-solution/common/*"], "@kbn/security-solution-distribution-bar": ["x-pack/packages/security-solution/distribution_bar"], "@kbn/security-solution-distribution-bar/*": ["x-pack/packages/security-solution/distribution_bar/*"], "@kbn/security-solution-ess": ["x-pack/plugins/security_solution_ess"], diff --git a/x-pack/packages/kbn-langchain/server/language_models/mocks/index.ts b/x-pack/packages/kbn-langchain/server/language_models/mocks/index.ts index f40bafca1a469..838f93ca308af 100644 --- a/x-pack/packages/kbn-langchain/server/language_models/mocks/index.ts +++ b/x-pack/packages/kbn-langchain/server/language_models/mocks/index.ts @@ -20,6 +20,7 @@ export const mockChatCompletion: OpenAI.ChatCompletion = { message: { role: 'assistant', content: 'Yes, your name is Andrew. How can I assist you further, Andrew?', + refusal: null, }, finish_reason: 'stop', logprobs: null, diff --git a/x-pack/packages/kbn-langchain/server/language_models/types.ts b/x-pack/packages/kbn-langchain/server/language_models/types.ts index 43dcad34fda3c..35415e8eaf118 100644 --- a/x-pack/packages/kbn-langchain/server/language_models/types.ts +++ b/x-pack/packages/kbn-langchain/server/language_models/types.ts @@ -11,7 +11,10 @@ import type OpenAI from 'openai'; export interface InvokeAIActionParamsSchema { messages: Array<{ role: string; - content: string | OpenAI.ChatCompletionContentPart[]; + content: + | string + | OpenAI.ChatCompletionContentPart[] + | Array; name?: string; function_call?: { arguments: string; diff --git a/x-pack/packages/observability/observability_utils/es/utils/esql_result_to_plain_objects.test.ts b/x-pack/packages/observability/observability_utils/es/utils/esql_result_to_plain_objects.test.ts new file mode 100644 index 0000000000000..4557d0ba0bdd5 --- /dev/null +++ b/x-pack/packages/observability/observability_utils/es/utils/esql_result_to_plain_objects.test.ts @@ -0,0 +1,66 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ESQLSearchResponse } from '@kbn/es-types'; +import { esqlResultToPlainObjects } from './esql_result_to_plain_objects'; + +describe('esqlResultToPlainObjects', () => { + it('should return an empty array for an empty result', () => { + const result: ESQLSearchResponse = { + columns: [], + values: [], + }; + const output = esqlResultToPlainObjects(result); + expect(output).toEqual([]); + }); + + it('should return plain objects', () => { + const result: ESQLSearchResponse = { + columns: [{ name: 'name', type: 'keyword' }], + values: [['Foo Bar']], + }; + const output = esqlResultToPlainObjects(result); + expect(output).toEqual([{ name: 'Foo Bar' }]); + }); + + it('should return columns without "text" or "keyword" in their names', () => { + const result: ESQLSearchResponse = { + columns: [ + { name: 'name.text', type: 'text' }, + { name: 'age', type: 'keyword' }, + ], + values: [ + ['Foo Bar', 30], + ['Foo Qux', 25], + ], + }; + const output = esqlResultToPlainObjects(result); + expect(output).toEqual([ + { name: 'Foo Bar', age: 30 }, + { name: 'Foo Qux', age: 25 }, + ]); + }); + + it('should handle mixed columns correctly', () => { + const result: ESQLSearchResponse = { + columns: [ + { name: 'name', type: 'text' }, + { name: 'name.text', type: 'text' }, + { name: 'age', type: 'keyword' }, + ], + values: [ + ['Foo Bar', 'Foo Bar', 30], + ['Foo Qux', 'Foo Qux', 25], + ], + }; + const output = esqlResultToPlainObjects(result); + expect(output).toEqual([ + { name: 'Foo Bar', age: 30 }, + { name: 'Foo Qux', age: 25 }, + ]); + }); +}); diff --git a/x-pack/packages/observability/observability_utils/es/utils/esql_result_to_plain_objects.ts b/x-pack/packages/observability/observability_utils/es/utils/esql_result_to_plain_objects.ts index ad48bcb311b25..96049f75ef156 100644 --- a/x-pack/packages/observability/observability_utils/es/utils/esql_result_to_plain_objects.ts +++ b/x-pack/packages/observability/observability_utils/es/utils/esql_result_to_plain_objects.ts @@ -13,7 +13,17 @@ export function esqlResultToPlainObjects>( return result.values.map((row) => { return row.reduce>((acc, value, index) => { const column = result.columns[index]; - acc[column.name] = value; + + if (!column) { + return acc; + } + + // Removes the type suffix from the column name + const name = column.name.replace(/\.(text|keyword)$/, ''); + if (!acc[name]) { + acc[name] = value; + } + return acc; }, {}); }) as T[]; diff --git a/x-pack/packages/security-solution/common/index.ts b/x-pack/packages/security-solution/common/index.ts deleted file mode 100644 index ba5d797648f13..0000000000000 --- a/x-pack/packages/security-solution/common/index.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export { HostDetailsButton } from './src/cells/renderers/host'; - -export * from './src/flyout'; -export * from './src/cells/renderers'; diff --git a/x-pack/packages/security-solution/common/jest.config.js b/x-pack/packages/security-solution/common/jest.config.js deleted file mode 100644 index 7047e229df092..0000000000000 --- a/x-pack/packages/security-solution/common/jest.config.js +++ /dev/null @@ -1,12 +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. - */ - -module.exports = { - preset: '@kbn/test', - rootDir: '../../../..', - roots: ['/x-pack/packages/security-solution/common'], -}; diff --git a/x-pack/packages/security-solution/common/kibana.jsonc b/x-pack/packages/security-solution/common/kibana.jsonc deleted file mode 100644 index 708feab435425..0000000000000 --- a/x-pack/packages/security-solution/common/kibana.jsonc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type": "shared-browser", - "id": "@kbn/security-solution-common", - "owner": "@elastic/security-threat-hunting-investigations" -} diff --git a/x-pack/packages/security-solution/common/package.json b/x-pack/packages/security-solution/common/package.json deleted file mode 100644 index ce355e927c3df..0000000000000 --- a/x-pack/packages/security-solution/common/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@kbn/security-solution-common", - "version": "1.0.0", - "description": "security solution common components which can be used in multiple plugins such as custom discover and timeline", - "license": "Elastic License 2.0", - "private": true, - "sideEffects": false -} \ No newline at end of file diff --git a/x-pack/packages/security-solution/common/src/cells/renderers/discover.ts b/x-pack/packages/security-solution/common/src/cells/renderers/discover.ts deleted file mode 100644 index 8d0393a3c6f2b..0000000000000 --- a/x-pack/packages/security-solution/common/src/cells/renderers/discover.ts +++ /dev/null @@ -1,24 +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 { DataGridCellValueElementProps } from '@kbn/unified-data-table'; -import { ComponentType, PropsWithChildren } from 'react'; -import { HostCellWithFlyoutRenderer } from './host'; - -export type DiscoverCellRenderer = ComponentType>; - -const RENDERERS: Record = { - 'host.name': HostCellWithFlyoutRenderer, -}; - -interface GetRendererArgs { - fieldName: string; -} - -export const getDiscoverCellRenderer = ({ fieldName }: GetRendererArgs) => { - return RENDERERS[fieldName]; -}; diff --git a/x-pack/packages/security-solution/common/src/cells/renderers/get.ts b/x-pack/packages/security-solution/common/src/cells/renderers/get.ts deleted file mode 100644 index 3102c520e31db..0000000000000 --- a/x-pack/packages/security-solution/common/src/cells/renderers/get.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export { getDiscoverCellRenderer } from './discover'; -export type { DiscoverCellRenderer } from './discover'; diff --git a/x-pack/packages/security-solution/common/src/cells/renderers/host/button.test.tsx b/x-pack/packages/security-solution/common/src/cells/renderers/host/button.test.tsx deleted file mode 100644 index d49af3ed50518..0000000000000 --- a/x-pack/packages/security-solution/common/src/cells/renderers/host/button.test.tsx +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React from 'react'; -import { HostDetailsButton } from './button'; -import { render, screen } from '@testing-library/react'; - -const onClickMock = jest.fn(); -const TestComponent = () => { - return {'Test'}; -}; - -describe('Host Button', () => { - it('should render as button with link formatting', () => { - render(); - expect(screen.getByTestId('host-details-button')).toBeVisible(); - expect(screen.getByTestId('host-details-button')).toHaveAttribute('type', 'button'); - expect(screen.getByTestId('host-details-button')).toHaveClass('euiLink'); - }); - - it('should perform onClick Correctly', () => { - render(); - screen.getByTestId('host-details-button').click(); - expect(onClickMock).toHaveBeenCalled(); - }); -}); diff --git a/x-pack/packages/security-solution/common/src/cells/renderers/host/button.tsx b/x-pack/packages/security-solution/common/src/cells/renderers/host/button.tsx deleted file mode 100644 index b478ee17bf9d4..0000000000000 --- a/x-pack/packages/security-solution/common/src/cells/renderers/host/button.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { SyntheticEvent } from 'react'; -import { EuiLink } from '@elastic/eui'; - -interface HostDetailsButtonProps { - children?: React.ReactNode; - onClick?: (e: SyntheticEvent) => void; - title?: string; -} - -export const HostDetailsButton: React.FC = ({ - children, - onClick, - title, -}) => { - return ( - - {children} - - ); -}; diff --git a/x-pack/packages/security-solution/common/src/cells/renderers/host/index.tsx b/x-pack/packages/security-solution/common/src/cells/renderers/host/index.tsx deleted file mode 100644 index a39397b233d60..0000000000000 --- a/x-pack/packages/security-solution/common/src/cells/renderers/host/index.tsx +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './button'; -export * from './with_expandable_flyout'; diff --git a/x-pack/packages/security-solution/common/src/cells/renderers/host/with_expandable_flyout.test.tsx b/x-pack/packages/security-solution/common/src/cells/renderers/host/with_expandable_flyout.test.tsx deleted file mode 100644 index 0568c656cdbe5..0000000000000 --- a/x-pack/packages/security-solution/common/src/cells/renderers/host/with_expandable_flyout.test.tsx +++ /dev/null @@ -1,54 +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 { - HostCellWithFlyoutRenderer, - HostCellWithFlyoutRendererProps, -} from './with_expandable_flyout'; -import React from 'react'; -import { render, screen } from '@testing-library/react'; - -const renderTestComponents = (props?: Partial) => { - const finalProps: HostCellWithFlyoutRendererProps = { - rowIndex: 0, - columnId: 'test', - setCellProps: jest.fn(), - isExpandable: false, - isExpanded: true, - isDetails: false, - colIndex: 0, - fieldFormats: {} as HostCellWithFlyoutRendererProps['fieldFormats'], - dataView: {} as HostCellWithFlyoutRendererProps['dataView'], - closePopover: jest.fn(), - row: { - id: '1', - raw: { - _source: { - host: { - name: 'test-host-name', - }, - }, - }, - flattened: { - 'host.name': 'test-host-name', - }, - }, - ...props, - }; - return render(); -}; - -describe('With Expandable Flyout', () => { - it('should open Expandable Flyout on Click', () => { - renderTestComponents(); - - expect(screen.getByTestId('host-details-button')).toBeVisible(); - screen.getByTestId('host-details-button').click(); - expect(screen.getByTestId('host-name-flyout')).toBeVisible(); - expect(screen.getByText('Host Flyout Header - test-host-name')).toBeVisible(); - }); -}); diff --git a/x-pack/packages/security-solution/common/src/cells/renderers/host/with_expandable_flyout.tsx b/x-pack/packages/security-solution/common/src/cells/renderers/host/with_expandable_flyout.tsx deleted file mode 100644 index 5e48d85b0384d..0000000000000 --- a/x-pack/packages/security-solution/common/src/cells/renderers/host/with_expandable_flyout.tsx +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import React, { useCallback, useMemo } from 'react'; -import { getFieldValue } from '@kbn/discover-utils'; -import type { PropsWithChildren } from 'react'; -import type { DataGridCellValueElementProps } from '@kbn/unified-data-table'; -import { - ExpandableFlyout, - type ExpandableFlyoutProps, - useExpandableFlyoutApi, - withExpandableFlyoutProvider, -} from '@kbn/expandable-flyout'; -import { HostRightPanel, HostRightPanelProps } from '../../../flyout/panels'; -import { HostDetailsButton } from './button'; - -export type HostCellWithFlyoutRendererProps = PropsWithChildren; - -const HostCellWithFlyoutRendererComp = React.memo(function HostCellWithFlyoutRendererComp( - props: HostCellWithFlyoutRendererProps -) { - const hostName = getFieldValue(props.row, 'host.name') as string; - - const { openFlyout } = useExpandableFlyoutApi(); - - const onClick = useCallback(() => { - openFlyout({ - right: { - id: `host-panel-${hostName}-${props.rowIndex}`, - params: { - hostName, - }, - } as HostRightPanelProps, - }); - }, [openFlyout, hostName, props.rowIndex]); - - const panels: ExpandableFlyoutProps['registeredPanels'] = useMemo(() => { - return [ - { - key: `host-panel-${hostName}-${props.rowIndex}`, - component: (panelProps) => { - return ; - }, - }, - ]; - }, [hostName, props.rowIndex]); - - return ( - <> - - {hostName} - - ); -}); - -export const HostCellWithFlyoutRenderer = withExpandableFlyoutProvider( - HostCellWithFlyoutRendererComp -); diff --git a/x-pack/packages/security-solution/common/src/cells/renderers/index.ts b/x-pack/packages/security-solution/common/src/cells/renderers/index.ts deleted file mode 100644 index e42333a710c04..0000000000000 --- a/x-pack/packages/security-solution/common/src/cells/renderers/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './get'; diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/index.ts b/x-pack/packages/security-solution/common/src/flyout/common/components/index.ts deleted file mode 100644 index 4624ae2f70c55..0000000000000 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/index.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export { FlyoutFooter } from './flyout_footer'; -export { FlyoutError } from './flyout_error'; -export { FlyoutLoading } from './flyout_loading'; -export { FlyoutNavigation } from './flyout_navigation'; -export { FlyoutTitle } from './flyout_title'; -export { FlyoutBody } from './flyout_body'; -export { FlyoutHeader } from './flyout_header'; -export { FlyoutHeaderTabs } from './flyout_header_tabs'; -export { ExpandablePanel } from './expandable_panel'; diff --git a/x-pack/packages/security-solution/common/src/flyout/index.tsx b/x-pack/packages/security-solution/common/src/flyout/index.tsx deleted file mode 100644 index e919538d497c6..0000000000000 --- a/x-pack/packages/security-solution/common/src/flyout/index.tsx +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './common/components'; -export * from './common/test_ids'; -export { HostRightPanel } from './panels'; diff --git a/x-pack/packages/security-solution/common/src/flyout/panels/host/right/index.tsx b/x-pack/packages/security-solution/common/src/flyout/panels/host/right/index.tsx deleted file mode 100644 index d877695f5b170..0000000000000 --- a/x-pack/packages/security-solution/common/src/flyout/panels/host/right/index.tsx +++ /dev/null @@ -1,37 +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 { FlyoutPanelProps } from '@kbn/expandable-flyout'; -import React from 'react'; -import { - FlyoutBody, - FlyoutFooter, - FlyoutHeader, - FlyoutNavigation, -} from '../../../common/components'; -// import { getEntityTableColumns } from './columns'; -// import type { BasicEntityData, EntityTableRows } from './types'; - -export interface HostRightPanelParamProps extends Record { - hostName: string; -} - -export interface HostRightPanelProps extends FlyoutPanelProps { - key: 'host'; - params: HostRightPanelParamProps; -} - -export const HostRightPanel = (props: HostRightPanelParamProps) => { - return ( - <> - - {`Host Flyout Header - ${props.hostName}`} - {'Host Flyout'} - {'Host Flyout Footer'} - - ); -}; diff --git a/x-pack/packages/security-solution/common/src/flyout/panels/index.ts b/x-pack/packages/security-solution/common/src/flyout/panels/index.ts deleted file mode 100644 index 3134078ebdf7f..0000000000000 --- a/x-pack/packages/security-solution/common/src/flyout/panels/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export * from './host/right'; -export * from './keys'; diff --git a/x-pack/packages/security-solution/common/src/flyout/panels/keys.ts b/x-pack/packages/security-solution/common/src/flyout/panels/keys.ts deleted file mode 100644 index fe06cf652d016..0000000000000 --- a/x-pack/packages/security-solution/common/src/flyout/panels/keys.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const HOST_PANEL = 'host-panel'; diff --git a/x-pack/packages/security-solution/common/tsconfig.json b/x-pack/packages/security-solution/common/tsconfig.json deleted file mode 100644 index fb0d3709961d8..0000000000000 --- a/x-pack/packages/security-solution/common/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "extends": "../../../../tsconfig.base.json", - "compilerOptions": { - "outDir": "target/types", - "types": [ - "jest", - "node", - "react", - "@testing-library/jest-dom", - "@testing-library/react", - "@emotion/react/types/css-prop" - ] - }, - "include": [ - "**/*.ts", - "**/*.tsx" - ], - "kbn_references": [ - "@kbn/unified-data-table", - "@kbn/discover-utils", - "@kbn/expandable-flyout", - "@kbn/i18n", - "@kbn/i18n-react" - ], - "exclude": [ - "target/**/*" - ] -} diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/hooks/use_stored_pattern_results/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/hooks/use_stored_pattern_results/index.test.tsx new file mode 100644 index 0000000000000..d58bf3af39d58 --- /dev/null +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/hooks/use_stored_pattern_results/index.test.tsx @@ -0,0 +1,108 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { notificationServiceMock } from '@kbn/core-notifications-browser-mocks'; + +import { getHistoricalResultStub } from '../../../../stub/get_historical_result_stub'; +import { useStoredPatternResults } from '.'; + +describe('useStoredPatternResults', () => { + const httpFetch = jest.fn(); + const mockToasts = notificationServiceMock.createStartContract().toasts; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe('when patterns are empty', () => { + it('should return an empty array and not call getStorageResults', () => { + const { result } = renderHook(() => useStoredPatternResults([], mockToasts, httpFetch)); + + expect(result.current).toEqual([]); + expect(httpFetch).not.toHaveBeenCalled(); + }); + }); + + describe('when patterns are provided', () => { + it('should fetch and return stored pattern results correctly', async () => { + const patterns = ['pattern1-*', 'pattern2-*']; + + httpFetch.mockImplementation((path: string) => { + if (path === '/internal/ecs_data_quality_dashboard/results_latest/pattern1-*') { + return Promise.resolve([getHistoricalResultStub('pattern1-index1')]); + } + + if (path === '/internal/ecs_data_quality_dashboard/results_latest/pattern2-*') { + return Promise.resolve([getHistoricalResultStub('pattern2-index1')]); + } + + return Promise.reject(new Error('Invalid path')); + }); + + const { result, waitFor } = renderHook(() => + useStoredPatternResults(patterns, mockToasts, httpFetch) + ); + + await waitFor(() => result.current.length > 0); + + expect(httpFetch).toHaveBeenCalledTimes(2); + + expect(httpFetch).toHaveBeenCalledWith( + '/internal/ecs_data_quality_dashboard/results_latest/pattern1-*', + { + method: 'GET', + signal: expect.any(AbortSignal), + version: '1', + } + ); + expect(httpFetch).toHaveBeenCalledWith( + '/internal/ecs_data_quality_dashboard/results_latest/pattern2-*', + { + method: 'GET', + signal: expect.any(AbortSignal), + version: '1', + } + ); + + expect(result.current).toEqual([ + { + pattern: 'pattern1-*', + results: { + 'pattern1-index1': { + docsCount: expect.any(Number), + error: null, + ilmPhase: expect.any(String), + incompatible: expect.any(Number), + indexName: 'pattern1-index1', + pattern: 'pattern1-*', + markdownComments: expect.any(Array), + sameFamily: expect.any(Number), + checkedAt: expect.any(Number), + }, + }, + }, + { + pattern: 'pattern2-*', + results: { + 'pattern2-index1': { + docsCount: expect.any(Number), + error: null, + ilmPhase: expect.any(String), + incompatible: expect.any(Number), + indexName: 'pattern2-index1', + pattern: 'pattern2-*', + markdownComments: expect.any(Array), + sameFamily: expect.any(Number), + checkedAt: expect.any(Number), + }, + }, + }, + ]); + }); + }); +}); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/hooks/use_stored_pattern_results/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/hooks/use_stored_pattern_results/index.tsx new file mode 100644 index 0000000000000..17334c4b4a586 --- /dev/null +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/hooks/use_stored_pattern_results/index.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { useEffect, useState } from 'react'; +import { IToasts } from '@kbn/core-notifications-browser'; +import { HttpHandler } from '@kbn/core-http-browser'; +import { isEmpty } from 'lodash/fp'; + +import { DataQualityCheckResult } from '../../../../types'; +import { formatResultFromStorage, getStorageResults } from '../../utils/storage'; + +export const useStoredPatternResults = ( + patterns: string[], + toasts: IToasts, + httpFetch: HttpHandler +) => { + const [storedPatternResults, setStoredPatternResults] = useState< + Array<{ pattern: string; results: Record }> + >([]); + + useEffect(() => { + if (isEmpty(patterns)) { + return; + } + + const abortController = new AbortController(); + 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) { + setStoredPatternResults(patternResults); + } + }; + + fetchStoredPatternResults(); + }, [httpFetch, patterns, toasts]); + + return storedPatternResults; +}; diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/index.test.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/index.test.tsx new file mode 100644 index 0000000000000..bff3c3dd54f12 --- /dev/null +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/index.test.tsx @@ -0,0 +1,685 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// fixing timezone for Date +// so when tests are run in different timezones, the results are consistent +process.env.TZ = 'UTC'; + +import { renderHook, act } from '@testing-library/react-hooks'; +import { notificationServiceMock } from '@kbn/core-notifications-browser-mocks'; + +import type { TelemetryEvents } from '../../types'; +import { useStoredPatternResults } from './hooks/use_stored_pattern_results'; +import { mockPartitionedFieldMetadata } from '../../mock/partitioned_field_metadata/mock_partitioned_field_metadata'; +import { useResultsRollup } from '.'; +import { getPatternRollupStub } from '../../stub/get_pattern_rollup_stub'; +import { formatBytes, formatNumber } from '../../mock/test_providers/utils/format'; + +jest.mock('./hooks/use_stored_pattern_results', () => ({ + ...jest.requireActual('./hooks/use_stored_pattern_results'), + useStoredPatternResults: jest.fn().mockReturnValue([]), +})); + +describe('useResultsRollup', () => { + const httpFetch = jest.fn(); + const toasts = notificationServiceMock.createStartContract().toasts; + + const mockTelemetryEvents: TelemetryEvents = { + reportDataQualityIndexChecked: jest.fn(), + reportDataQualityCheckAllCompleted: jest.fn(), + }; + + const patterns = ['auditbeat-*', 'packetbeat-*']; + const isILMAvailable = true; + + const useStoredPatternResultsMock = useStoredPatternResults as jest.Mock; + + beforeEach(() => { + jest.clearAllMocks(); + useStoredPatternResultsMock.mockReturnValue([]); + }); + + describe('initialization', () => { + it('should initialize with default values', () => { + const { result } = renderHook(() => + useResultsRollup({ + httpFetch, + toasts, + patterns, + isILMAvailable, + telemetryEvents: mockTelemetryEvents, + }) + ); + + expect(result.current.patternIndexNames).toEqual({}); + expect(result.current.patternRollups).toEqual({}); + expect(result.current.totalDocsCount).toBe(0); + expect(result.current.totalIncompatible).toBeUndefined(); + expect(result.current.totalIndices).toBe(0); + expect(result.current.totalIndicesChecked).toBe(0); + expect(result.current.totalSameFamily).toBeUndefined(); + expect(result.current.totalSizeInBytes).toBe(0); + }); + + it('should fetch stored pattern results and update patternRollups from it', () => { + const mockStoredResults = [ + { + pattern: 'auditbeat-*', + results: { + 'auditbeat-7.11.0-2021.01.01': { + indexName: 'auditbeat-7.11.0-2021.01.01', + pattern: 'auditbeat-*', + docsCount: 500, + incompatible: 0, + error: null, + ilmPhase: 'hot', + sameFamily: 0, + markdownComments: [], + checkedAt: Date.now(), + }, + }, + }, + ]; + + useStoredPatternResultsMock.mockReturnValue(mockStoredResults); + + const { result } = renderHook(() => + useResultsRollup({ + httpFetch, + toasts, + patterns: ['auditbeat-*'], + isILMAvailable, + telemetryEvents: mockTelemetryEvents, + }) + ); + + expect(useStoredPatternResultsMock).toHaveBeenCalledWith(['auditbeat-*'], toasts, httpFetch); + + expect(result.current.patternRollups).toEqual({ + 'auditbeat-*': { + pattern: 'auditbeat-*', + results: { + 'auditbeat-7.11.0-2021.01.01': expect.any(Object), + }, + }, + }); + }); + }); + + describe('updatePatternIndexNames', () => { + it('should update pattern index names', () => { + const { result } = renderHook(() => + useResultsRollup({ + httpFetch, + toasts, + patterns, + isILMAvailable, + telemetryEvents: mockTelemetryEvents, + }) + ); + + act(() => { + result.current.updatePatternIndexNames({ + pattern: 'packetbeat-*', + indexNames: ['packetbeat-7.10.0-2021.01.01'], + }); + }); + + expect(result.current.patternIndexNames).toEqual({ + 'packetbeat-*': ['packetbeat-7.10.0-2021.01.01'], + }); + }); + }); + + describe('updatePatternRollup', () => { + it('should update pattern rollup when called', () => { + const { result } = renderHook(() => + useResultsRollup({ + httpFetch, + toasts, + patterns, + isILMAvailable, + telemetryEvents: mockTelemetryEvents, + }) + ); + + const patternRollup = getPatternRollupStub('packetbeat-*', 1); + + expect(result.current.patternRollups).toEqual({}); + + act(() => { + result.current.updatePatternRollup(patternRollup); + }); + + expect(result.current.patternRollups).toEqual({ + 'packetbeat-*': patternRollup, + }); + }); + }); + + describe('onCheckCompleted', () => { + describe('when invoked with successful check data', () => { + beforeEach(() => { + jest.useFakeTimers(); + jest.setSystemTime(new Date('2021-10-07T00:00:00Z').getTime()); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('should update patternRollup with said data, report to telemetry and persist it in storage', () => { + const { result } = renderHook(() => + useResultsRollup({ + httpFetch, + toasts, + patterns, + isILMAvailable, + telemetryEvents: mockTelemetryEvents, + }) + ); + + const patternRollup = getPatternRollupStub('packetbeat-*', 1); + + act(() => { + result.current.updatePatternRollup(patternRollup); + }); + + expect(result.current.patternRollups['packetbeat-*'].results?.['.ds-packetbeat-1']).toEqual( + { + checkedAt: new Date('2021-10-07T00:00:00Z').getTime(), + docsCount: 1000000, + error: null, + ilmPhase: 'hot', + incompatible: 0, + indexName: '.ds-packetbeat-1', + markdownComments: ['foo', 'bar', 'baz'], + pattern: 'packetbeat-*', + sameFamily: 0, + } + ); + + jest.advanceTimersByTime(1000); + + const mockOnCheckCompletedOpts = { + batchId: 'test-batch', + checkAllStartTime: Date.now(), + error: null, + formatBytes, + formatNumber, + indexName: '.ds-packetbeat-1', + partitionedFieldMetadata: mockPartitionedFieldMetadata, + pattern: 'packetbeat-*', + requestTime: 1500, + isLastCheck: true, + isCheckAll: true, + }; + + jest.advanceTimersByTime(1000); + + act(() => { + result.current.onCheckCompleted(mockOnCheckCompletedOpts); + }); + + expect(result.current.patternRollups['packetbeat-*'].results?.['.ds-packetbeat-1']).toEqual( + { + checkedAt: new Date('2021-10-07T00:00:02Z').getTime(), + docsCount: 1000000, + error: null, + ilmPhase: 'hot', + incompatible: 3, + indexName: '.ds-packetbeat-1', + markdownComments: expect.any(Array), + pattern: 'packetbeat-*', + sameFamily: 0, + } + ); + + expect(mockTelemetryEvents.reportDataQualityIndexChecked).toHaveBeenCalledWith({ + batchId: 'test-batch', + ecsVersion: '8.11.0', + errorCount: 0, + ilmPhase: 'hot', + indexId: 'uuid-1', + indexName: '.ds-packetbeat-1', + isCheckAll: true, + numberOfCustomFields: 4, + numberOfDocuments: 1000000, + numberOfEcsFields: 2, + numberOfFields: 9, + numberOfIncompatibleFields: 3, + numberOfIndices: 1, + numberOfIndicesChecked: 1, + numberOfSameFamily: 0, + sameFamilyFields: [], + sizeInBytes: 500000000, + timeConsumedMs: 1500, + unallowedMappingFields: ['host.name', 'source.ip'], + unallowedValueFields: ['event.category'], + }); + expect(mockTelemetryEvents.reportDataQualityCheckAllCompleted).toHaveBeenCalledWith({ + batchId: 'test-batch', + ecsVersion: '8.11.0', + isCheckAll: true, + numberOfDocuments: 1000000, + numberOfIncompatibleFields: 3, + numberOfIndices: 1, + numberOfIndicesChecked: 1, + numberOfSameFamily: 0, + sizeInBytes: 500000000, + timeConsumedMs: 1000, + }); + + expect(httpFetch).toHaveBeenCalledWith('/internal/ecs_data_quality_dashboard/results', { + method: 'POST', + version: '1', + signal: expect.any(AbortSignal), + body: expect.any(String), + }); + + const body = JSON.parse(httpFetch.mock.calls[0][1].body); + + expect(body).toEqual({ + batchId: 'test-batch', + indexName: '.ds-packetbeat-1', + indexPattern: 'packetbeat-*', + isCheckAll: true, + checkedAt: new Date('2021-10-07T00:00:02Z').getTime(), + docsCount: 1000000, + totalFieldCount: 9, + ecsFieldCount: 2, + customFieldCount: 4, + incompatibleFieldCount: 3, + incompatibleFieldMappingItems: [ + { + fieldName: 'host.name', + expectedValue: 'keyword', + actualValue: 'text', + description: + 'Name of the host.\nIt can contain what `hostname` returns on Unix systems, the fully qualified domain name, or a name specified by the user. The sender decides which value to use.', + }, + { + fieldName: 'source.ip', + expectedValue: 'ip', + actualValue: 'text', + description: 'IP address of the source (IPv4 or IPv6).', + }, + ], + incompatibleFieldValueItems: [ + { + fieldName: 'event.category', + expectedValues: [ + 'authentication', + 'configuration', + 'database', + 'driver', + 'email', + 'file', + 'host', + 'iam', + 'intrusion_detection', + 'malware', + 'network', + 'package', + 'process', + 'registry', + 'session', + 'threat', + 'vulnerability', + 'web', + ], + actualValues: [ + { name: 'an_invalid_category', count: 2 }, + { name: 'theory', count: 1 }, + ], + description: + 'This is one of four ECS Categorization Fields, and indicates the second level in the ECS category hierarchy.\n`event.category` represents the "big buckets" of ECS categories. For example, filtering on `event.category:process` yields all events relating to process activity. This field is closely related to `event.type`, which is used as a subcategory.\nThis field is an array. This will allow proper categorization of some events that fall in multiple categories.', + }, + ], + sameFamilyFieldCount: 0, + sameFamilyFields: [], + sameFamilyFieldItems: [], + unallowedMappingFields: ['host.name', 'source.ip'], + unallowedValueFields: ['event.category'], + sizeInBytes: 500000000, + ilmPhase: 'hot', + markdownComments: [ + '### .ds-packetbeat-1\n', + '| Result | Index | Docs | Incompatible fields | ILM Phase | Size |\n|--------|-------|------|---------------------|-----------|------|\n| ❌ | .ds-packetbeat-1 | 1,000,000 (100.0%) | 3 | `hot` | 476.8MB |\n\n', + '### **Incompatible fields** `3` **Same family** `0` **Custom fields** `4` **ECS compliant fields** `2` **All fields** `9`\n', + "#### 3 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.11.0.\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#### Incompatible field mappings - .ds-packetbeat-1\n\n\n| Field | ECS mapping type (expected) | Index mapping type (actual) | \n|-------|-----------------------------|-----------------------------|\n| host.name | `keyword` | `text` |\n| source.ip | `ip` | `text` |\n\n#### Incompatible field values - .ds-packetbeat-1\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` | `an_invalid_category` (2), `theory` (1) |\n\n', + ], + ecsVersion: '8.11.0', + indexId: 'uuid-1', + error: null, + }); + }); + + describe('when isILMAvailable is false', () => { + it('should omit ilmPhase and nullify sizeInBytes when storing payload', () => { + const { result } = renderHook(() => + useResultsRollup({ + httpFetch, + toasts, + patterns, + isILMAvailable: false, + telemetryEvents: mockTelemetryEvents, + }) + ); + + const patternRollup = getPatternRollupStub('packetbeat-*', 1, false); + + act(() => { + result.current.updatePatternRollup(patternRollup); + }); + + jest.advanceTimersByTime(1000); + + const mockOnCheckCompletedOpts = { + batchId: 'test-batch', + checkAllStartTime: Date.now(), + error: null, + formatBytes, + formatNumber, + indexName: '.ds-packetbeat-1', + partitionedFieldMetadata: mockPartitionedFieldMetadata, + pattern: 'packetbeat-*', + requestTime: 1500, + isLastCheck: true, + isCheckAll: true, + }; + + jest.advanceTimersByTime(1000); + + act(() => { + result.current.onCheckCompleted(mockOnCheckCompletedOpts); + }); + + expect(mockTelemetryEvents.reportDataQualityIndexChecked).toHaveBeenCalledWith({ + batchId: 'test-batch', + ecsVersion: '8.11.0', + errorCount: 0, + ilmPhase: undefined, + indexId: 'uuid-1', + indexName: '.ds-packetbeat-1', + isCheckAll: true, + numberOfCustomFields: 4, + numberOfDocuments: 1000000, + numberOfEcsFields: 2, + numberOfFields: 9, + numberOfIncompatibleFields: 3, + numberOfIndices: 1, + numberOfIndicesChecked: 1, + numberOfSameFamily: 0, + sameFamilyFields: [], + sizeInBytes: undefined, + timeConsumedMs: 1500, + unallowedMappingFields: ['host.name', 'source.ip'], + unallowedValueFields: ['event.category'], + }); + expect(mockTelemetryEvents.reportDataQualityCheckAllCompleted).toHaveBeenCalledWith({ + batchId: 'test-batch', + ecsVersion: '8.11.0', + isCheckAll: true, + numberOfDocuments: 1000000, + numberOfIncompatibleFields: 3, + numberOfIndices: 1, + numberOfIndicesChecked: 1, + numberOfSameFamily: 0, + sizeInBytes: undefined, + timeConsumedMs: 1000, + }); + + expect(httpFetch).toHaveBeenCalledWith('/internal/ecs_data_quality_dashboard/results', { + method: 'POST', + version: '1', + signal: expect.any(AbortSignal), + body: expect.any(String), + }); + + const body = JSON.parse(httpFetch.mock.calls[0][1].body); + + expect(body).toEqual({ + batchId: 'test-batch', + indexName: '.ds-packetbeat-1', + indexPattern: 'packetbeat-*', + isCheckAll: true, + checkedAt: new Date('2021-10-07T00:00:02Z').getTime(), + docsCount: 1000000, + totalFieldCount: 9, + ecsFieldCount: 2, + customFieldCount: 4, + incompatibleFieldCount: 3, + incompatibleFieldMappingItems: [ + { + fieldName: 'host.name', + expectedValue: 'keyword', + actualValue: 'text', + description: + 'Name of the host.\nIt can contain what `hostname` returns on Unix systems, the fully qualified domain name, or a name specified by the user. The sender decides which value to use.', + }, + { + fieldName: 'source.ip', + expectedValue: 'ip', + actualValue: 'text', + description: 'IP address of the source (IPv4 or IPv6).', + }, + ], + incompatibleFieldValueItems: [ + { + fieldName: 'event.category', + expectedValues: [ + 'authentication', + 'configuration', + 'database', + 'driver', + 'email', + 'file', + 'host', + 'iam', + 'intrusion_detection', + 'malware', + 'network', + 'package', + 'process', + 'registry', + 'session', + 'threat', + 'vulnerability', + 'web', + ], + actualValues: [ + { name: 'an_invalid_category', count: 2 }, + { name: 'theory', count: 1 }, + ], + description: + 'This is one of four ECS Categorization Fields, and indicates the second level in the ECS category hierarchy.\n`event.category` represents the "big buckets" of ECS categories. For example, filtering on `event.category:process` yields all events relating to process activity. This field is closely related to `event.type`, which is used as a subcategory.\nThis field is an array. This will allow proper categorization of some events that fall in multiple categories.', + }, + ], + sameFamilyFieldCount: 0, + sameFamilyFields: [], + sameFamilyFieldItems: [], + unallowedMappingFields: ['host.name', 'source.ip'], + unallowedValueFields: ['event.category'], + ilmPhase: undefined, + sizeInBytes: 0, + markdownComments: [ + '### .ds-packetbeat-1\n', + '| Result | Index | Docs | Incompatible fields |\n|--------|-------|------|---------------------|\n| ❌ | .ds-packetbeat-1 | 1,000,000 (100.0%) | 3 |\n\n', + '### **Incompatible fields** `3` **Same family** `0` **Custom fields** `4` **ECS compliant fields** `2` **All fields** `9`\n', + "#### 3 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.11.0.\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#### Incompatible field mappings - .ds-packetbeat-1\n\n\n| Field | ECS mapping type (expected) | Index mapping type (actual) | \n|-------|-----------------------------|-----------------------------|\n| host.name | `keyword` | `text` |\n| source.ip | `ip` | `text` |\n\n#### Incompatible field values - .ds-packetbeat-1\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` | `an_invalid_category` (2), `theory` (1) |\n\n', + ], + ecsVersion: '8.11.0', + indexId: 'uuid-1', + error: null, + }); + }); + }); + }); + + describe('when check fails with error message and no partitionedFieldMetadata', () => { + it('should update patternRollup with error message, reset state without persisting in storage', () => { + const { result } = renderHook(() => + useResultsRollup({ + httpFetch, + toasts, + patterns, + isILMAvailable, + telemetryEvents: mockTelemetryEvents, + }) + ); + + const patternRollup = getPatternRollupStub('packetbeat-*', 1); + + act(() => { + result.current.updatePatternRollup(patternRollup); + }); + + const mockOnCheckCompletedOpts = { + batchId: 'test-batch', + checkAllStartTime: Date.now(), + error: 'Something went wrong', + formatBytes, + formatNumber, + indexName: '.ds-packetbeat-1', + partitionedFieldMetadata: null, + pattern: 'packetbeat-*', + requestTime: 1500, + isLastCheck: true, + isCheckAll: true, + }; + + act(() => { + result.current.onCheckCompleted(mockOnCheckCompletedOpts); + }); + + expect(result.current.patternRollups['packetbeat-*'].results?.['.ds-packetbeat-1']).toEqual( + { + checkedAt: undefined, + docsCount: 1000000, + error: 'Something went wrong', + ilmPhase: 'hot', + incompatible: undefined, + indexName: '.ds-packetbeat-1', + markdownComments: expect.any(Array), + pattern: 'packetbeat-*', + sameFamily: undefined, + } + ); + + expect(mockTelemetryEvents.reportDataQualityIndexChecked).not.toHaveBeenCalled(); + + expect(httpFetch).not.toHaveBeenCalledWith( + '/internal/ecs_data_quality_dashboard/results', + expect.any(Object) + ); + }); + }); + + describe('edge cases', () => { + describe('given no error nor partitionedFieldMetadata', () => { + it('should reset result state accordingly and not invoke telemetry report nor persist in storage', () => { + const { result } = renderHook(() => + useResultsRollup({ + httpFetch, + toasts, + patterns, + isILMAvailable, + telemetryEvents: mockTelemetryEvents, + }) + ); + + const patternRollup = getPatternRollupStub('packetbeat-*', 1); + + act(() => { + result.current.updatePatternRollup(patternRollup); + }); + + const mockOnCheckCompletedOpts = { + batchId: 'test-batch', + checkAllStartTime: Date.now(), + error: null, + formatBytes, + formatNumber, + indexName: '.ds-packetbeat-1', + partitionedFieldMetadata: null, + pattern: 'packetbeat-*', + requestTime: 1500, + isLastCheck: true, + isCheckAll: true, + }; + + act(() => { + result.current.onCheckCompleted(mockOnCheckCompletedOpts); + }); + + expect( + result.current.patternRollups['packetbeat-*'].results?.['.ds-packetbeat-1'] + ).toEqual({ + checkedAt: undefined, + docsCount: 1000000, + error: null, + ilmPhase: 'hot', + incompatible: undefined, + indexName: '.ds-packetbeat-1', + markdownComments: expect.any(Array), + pattern: 'packetbeat-*', + sameFamily: undefined, + }); + + expect(mockTelemetryEvents.reportDataQualityIndexChecked).not.toHaveBeenCalled(); + + expect(httpFetch).not.toHaveBeenCalledWith( + '/internal/ecs_data_quality_dashboard/results', + expect.any(Object) + ); + }); + }); + }); + }); + + describe('calculating totals', () => { + describe('when patternRollups change', () => { + it('should update totals', () => { + const { result } = renderHook(() => + useResultsRollup({ + httpFetch, + toasts, + patterns: ['packetbeat-*', 'auditbeat-*'], + isILMAvailable, + telemetryEvents: mockTelemetryEvents, + }) + ); + + const patternRollup1 = getPatternRollupStub('packetbeat-*', 1); + const patternRollup2 = getPatternRollupStub('auditbeat-*', 1); + + expect(result.current.totalIndices).toBe(0); + expect(result.current.totalDocsCount).toBe(0); + expect(result.current.totalSizeInBytes).toBe(0); + + act(() => { + result.current.updatePatternRollup(patternRollup1); + }); + + expect(result.current.totalIndices).toEqual(1); + expect(result.current.totalDocsCount).toEqual(1000000); + expect(result.current.totalSizeInBytes).toEqual(500000000); + + act(() => { + result.current.updatePatternRollup(patternRollup2); + }); + + expect(result.current.totalIndices).toEqual(2); + expect(result.current.totalDocsCount).toEqual(2000000); + expect(result.current.totalSizeInBytes).toEqual(1000000000); + }); + }); + }); +}); diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/index.tsx index 28b36765a245b..d95f1d1b7f20f 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/hooks/use_results_rollup/index.tsx @@ -21,83 +21,29 @@ import { getTotalPatternSameFamily, getIndexId, } from './utils/stats'; -import { - getStorageResults, - postStorageResult, - formatStorageResult, - formatResultFromStorage, -} from './utils/storage'; +import { postStorageResult, formatStorageResult } from './utils/storage'; import { getPatternRollupsWithLatestCheckResult } from './utils/get_pattern_rollups_with_latest_check_result'; -import type { - DataQualityCheckResult, - OnCheckCompleted, - PatternRollup, - TelemetryEvents, -} from '../../types'; +import type { OnCheckCompleted, PatternRollup, TelemetryEvents } from '../../types'; import { getEscapedIncompatibleMappingsFields, getEscapedIncompatibleValuesFields, getEscapedSameFamilyFields, } from './utils/metadata'; import { UseResultsRollupReturnValue } from './types'; -import { useIsMountedRef } from '../use_is_mounted_ref'; import { getDocsCount, getIndexIncompatible, getSizeInBytes } from '../../utils/stats'; import { getIlmPhase } from '../../utils/get_ilm_phase'; +import { useStoredPatternResults } from './hooks/use_stored_pattern_results'; interface Props { - ilmPhases: string[]; patterns: string[]; toasts: IToasts; httpFetch: HttpHandler; telemetryEvents: TelemetryEvents; isILMAvailable: boolean; } -const useStoredPatternResults = (patterns: string[], toasts: IToasts, httpFetch: HttpHandler) => { - const { isMountedRef } = useIsMountedRef(); - const [storedPatternResults, setStoredPatternResults] = useState< - Array<{ pattern: string; results: Record }> - >([]); - - useEffect(() => { - if (isEmpty(patterns)) { - return; - } - - let ignore = false; - const abortController = new AbortController(); - 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) { - if (isMountedRef.current) { - setStoredPatternResults(patternResults); - } - } - }; - - fetchStoredPatternResults(); - return () => { - ignore = true; - }; - }, [httpFetch, isMountedRef, patterns, toasts]); - - return storedPatternResults; -}; - export const useResultsRollup = ({ httpFetch, toasts, - ilmPhases, patterns, isILMAvailable, telemetryEvents, @@ -247,12 +193,6 @@ export const useResultsRollup = ({ [httpFetch, isILMAvailable, telemetryEvents, toasts] ); - useEffect(() => { - // reset all state - setPatternRollups({}); - setPatternIndexNames({}); - }, [ilmPhases, patterns]); - const useResultsRollupReturnValue = useMemo( () => ({ onCheckCompleted, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/index.tsx b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/index.tsx index 7d1a106d83570..b6d2736d7e175 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/index.tsx +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/index.tsx @@ -104,7 +104,6 @@ const DataQualityPanelComponent: React.FC = ({ ); const resultsRollupHookReturnValue = useResultsRollup({ - ilmPhases, patterns, httpFetch, toasts, diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/mock/test_providers/utils/format.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/mock/test_providers/utils/format.ts new file mode 100644 index 0000000000000..844b573b61cad --- /dev/null +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/mock/test_providers/utils/format.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import numeral from '@elastic/numeral'; + +import { EMPTY_STAT } from '../../../constants'; + +const defaultBytesFormat = '0,0.[0]b'; +export const formatBytes = (value: number | undefined) => + value != null ? numeral(value).format(defaultBytesFormat) : EMPTY_STAT; + +const defaultNumberFormat = '0,0.[000]'; +export const formatNumber = (value: number | undefined) => + value != null ? numeral(value).format(defaultNumberFormat) : EMPTY_STAT; diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/mock/test_providers/utils/get_merged_data_quality_context_props.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/mock/test_providers/utils/get_merged_data_quality_context_props.ts index 264198e510b5e..a8df6818605a1 100644 --- a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/mock/test_providers/utils/get_merged_data_quality_context_props.ts +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/mock/test_providers/utils/get_merged_data_quality_context_props.ts @@ -5,10 +5,9 @@ * 2.0. */ -import numeral from '@elastic/numeral'; - import { DataQualityProviderProps } from '../../../data_quality_context'; -import { EMPTY_STAT } from '../../../constants'; + +import { formatBytes as formatBytesMock, formatNumber as formatNumberMock } from './format'; export const getMergedDataQualityContextProps = ( dataQualityContextProps?: Partial @@ -36,10 +35,8 @@ export const getMergedDataQualityContextProps = ( addSuccessToast: jest.fn(), canUserCreateAndReadCases: jest.fn(() => true), endDate: null, - formatBytes: (value: number | undefined) => - value != null ? numeral(value).format('0,0.[0]b') : EMPTY_STAT, - formatNumber: (value: number | undefined) => - value != null ? numeral(value).format('0,0.[000]') : EMPTY_STAT, + formatBytes: formatBytesMock, + formatNumber: formatNumberMock, isAssistantEnabled: true, lastChecked: '2023-03-28T22:27:28.159Z', openCreateCaseFlyout: jest.fn(), diff --git a/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/stub/get_pattern_rollup_stub/index.ts b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/stub/get_pattern_rollup_stub/index.ts new file mode 100644 index 0000000000000..38aa129a6ec9a --- /dev/null +++ b/x-pack/packages/security-solution/ecs_data_quality_dashboard/impl/data_quality_panel/stub/get_pattern_rollup_stub/index.ts @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { PatternRollup } from '../../types'; + +const phases = ['hot', 'warm', 'cold', 'frozen'] as const; + +/** + * + * This function derives ilmExplain, results, stats and ilmExplainPhaseCounts + * from the provided pattern and indicesCount for the purpose of simplifying + * stubbing of resultsRollup in tests. + * + * @param pattern - The index pattern to simulate. Defaults to `'packetbeat-*'`. + * @param indicesCount - The number of indices to generate. Defaults to `2`. + * @param isILMAvailable - Whether ILM is available. Defaults to `true`. + * @returns An object containing stubbed pattern rollup data + */ +export const getPatternRollupStub = ( + pattern = 'packetbeat-*', + indicesCount = 2, + isILMAvailable = true +): PatternRollup => { + // Derive ilmExplain from isILMAvailable, pattern and indicesCount + const ilmExplain = isILMAvailable + ? Object.fromEntries( + Array.from({ length: indicesCount }).map((_, i) => { + const indexName = pattern.replace('*', `${i + 1}`); + const dsIndexName = `.ds-${indexName}`; + // Cycle through phases + const phase = phases[i % phases.length]; + return [ + dsIndexName, + { + index: dsIndexName, + managed: true, + policy: pattern, + phase, + }, + ]; + }) + ) + : null; + + // Derive ilmExplainPhaseCounts from ilmExplain + const ilmExplainPhaseCounts = ilmExplain + ? phases.reduce( + (counts, phase) => ({ + ...counts, + [phase]: Object.values(ilmExplain).filter((explain) => explain.phase === phase).length, + }), + { hot: 0, warm: 0, cold: 0, frozen: 0, unmanaged: 0 } + ) + : undefined; + + // Derive results from pattern and indicesCount + const results = Object.fromEntries( + Array.from({ length: indicesCount }, (_, i) => { + const indexName = pattern.replace('*', `${i + 1}`); + const dsIndexName = `.ds-${indexName}`; + return [ + dsIndexName, + { + docsCount: 1000000 + i * 100000, // Example doc count + error: null, + ilmPhase: ilmExplain?.[dsIndexName].phase, + incompatible: i, + indexName: dsIndexName, + markdownComments: ['foo', 'bar', 'baz'], + pattern, + sameFamily: i, + checkedAt: Date.now(), + }, + ]; + }) + ); + + // Derive stats from isILMAvailable, pattern and indicesCount + const stats = Object.fromEntries( + Array.from({ length: indicesCount }, (_, i) => { + const indexName = pattern.replace('*', `${i + 1}`); + const dsIndexName = `.ds-${indexName}`; + return [ + dsIndexName, + { + uuid: `uuid-${i + 1}`, + size_in_bytes: isILMAvailable ? 500000000 + i * 10000000 : null, + name: dsIndexName, + num_docs: results[dsIndexName].docsCount, + }, + ]; + }) + ); + + // Derive total docsCount and sizeInBytes from stats + const totalDocsCount = Object.values(stats).reduce((sum, stat) => sum + stat.num_docs, 0); + const totalSizeInBytes = isILMAvailable + ? Object.values(stats).reduce((sum, stat) => sum + (stat.size_in_bytes ?? 0), 0) + : undefined; + + return { + docsCount: totalDocsCount, + error: null, + pattern, + ilmExplain, + ilmExplainPhaseCounts, + indices: indicesCount, + results, + sizeInBytes: totalSizeInBytes, + stats, + }; +}; diff --git a/x-pack/plugins/actions/server/actions_client/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client/actions_client.test.ts index 3421e381d07b6..99bcbf15ecfb9 100644 --- a/x-pack/plugins/actions/server/actions_client/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client/actions_client.test.ts @@ -575,8 +575,6 @@ describe('create()', () => { allowedHosts: ['*'], preconfiguredAlertHistoryEsIndex: false, preconfigured: {}, - proxyRejectUnauthorizedCertificates: true, // legacy - rejectUnauthorized: true, // legacy proxyBypassHosts: undefined, proxyOnlyHosts: undefined, maxResponseContentLength: new ByteSizeValue(1000000), diff --git a/x-pack/plugins/actions/server/actions_config.test.ts b/x-pack/plugins/actions/server/actions_config.test.ts index 2b5c4efc283b6..ce16aca508af6 100644 --- a/x-pack/plugins/actions/server/actions_config.test.ts +++ b/x-pack/plugins/actions/server/actions_config.test.ts @@ -30,8 +30,6 @@ const defaultActionsConfig: ActionsConfig = { enabledActionTypes: [], preconfiguredAlertHistoryEsIndex: false, preconfigured: {}, - proxyRejectUnauthorizedCertificates: true, // legacy - rejectUnauthorized: true, // legacy maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration(60000), ssl: { @@ -318,25 +316,6 @@ describe('getProxySettings', () => { expect(proxySettings?.proxyUrl).toBe(config.proxyUrl); }); - test('returns proper verificationMode values, beased on the legacy config option proxyRejectUnauthorizedCertificates', () => { - const configTrue: ActionsConfig = { - ...defaultActionsConfig, - proxyUrl: 'https://proxy.elastic.co', - proxyRejectUnauthorizedCertificates: true, - }; - let proxySettings = getActionsConfigurationUtilities(configTrue).getProxySettings(); - expect(proxySettings?.proxySSLSettings.verificationMode).toBe('full'); - - const configFalse: ActionsConfig = { - ...defaultActionsConfig, - proxyUrl: 'https://proxy.elastic.co', - proxyRejectUnauthorizedCertificates: false, - ssl: {}, - }; - proxySettings = getActionsConfigurationUtilities(configFalse).getProxySettings(); - expect(proxySettings?.proxySSLSettings.verificationMode).toBe('none'); - }); - test('returns proper verificationMode value, based on the SSL proxy configuration', () => { const configTrue: ActionsConfig = { ...defaultActionsConfig, diff --git a/x-pack/plugins/actions/server/actions_config.ts b/x-pack/plugins/actions/server/actions_config.ts index e77c0528d16a1..30c96b4b6a998 100644 --- a/x-pack/plugins/actions/server/actions_config.ts +++ b/x-pack/plugins/actions/server/actions_config.ts @@ -122,10 +122,7 @@ function getProxySettingsFromConfig(config: ActionsConfig): undefined | ProxySet proxyBypassHosts: arrayAsSet(config.proxyBypassHosts), proxyOnlyHosts: arrayAsSet(config.proxyOnlyHosts), proxyHeaders: config.proxyHeaders, - proxySSLSettings: getSSLSettingsFromConfig( - config.ssl?.proxyVerificationMode, - config.proxyRejectUnauthorizedCertificates - ), + proxySSLSettings: getSSLSettingsFromConfig(config.ssl?.proxyVerificationMode), }; } @@ -200,8 +197,7 @@ export function getActionsConfigurationUtilities( isActionTypeEnabled, getProxySettings: () => getProxySettingsFromConfig(config), getResponseSettings: () => getResponseSettingsFromConfig(config), - getSSLSettings: () => - getSSLSettingsFromConfig(config.ssl?.verificationMode, config.rejectUnauthorized), + getSSLSettings: () => getSSLSettingsFromConfig(config.ssl?.verificationMode), ensureUriAllowed(uri: string) { if (!isUriAllowed(uri)) { throw new Error(allowListErrorMessage(AllowListingField.URL, uri)); diff --git a/x-pack/plugins/actions/server/config.test.ts b/x-pack/plugins/actions/server/config.test.ts index 4034fc5cb50b5..01bcd867fda53 100644 --- a/x-pack/plugins/actions/server/config.test.ts +++ b/x-pack/plugins/actions/server/config.test.ts @@ -35,8 +35,6 @@ describe('config validation', () => { "microsoftGraphApiUrl": "https://graph.microsoft.com/v1.0", "preconfigured": Object {}, "preconfiguredAlertHistoryEsIndex": false, - "proxyRejectUnauthorizedCertificates": true, - "rejectUnauthorized": true, "responseTimeout": "PT1M", "usage": Object { "url": "https://usage-api.usage-api/api/v1/usage", @@ -56,8 +54,6 @@ describe('config validation', () => { }, }, }, - proxyRejectUnauthorizedCertificates: false, - rejectUnauthorized: false, }; expect(configSchema.validate(config)).toMatchInlineSnapshot(` Object { @@ -85,8 +81,6 @@ describe('config validation', () => { }, }, "preconfiguredAlertHistoryEsIndex": false, - "proxyRejectUnauthorizedCertificates": false, - "rejectUnauthorized": false, "responseTimeout": "PT1M", "usage": Object { "url": "https://usage-api.usage-api/api/v1/usage", @@ -224,8 +218,6 @@ describe('config validation', () => { "microsoftGraphApiUrl": "https://graph.microsoft.com/v1.0", "preconfigured": Object {}, "preconfiguredAlertHistoryEsIndex": false, - "proxyRejectUnauthorizedCertificates": true, - "rejectUnauthorized": true, "responseTimeout": "PT1M", "ssl": Object { "proxyVerificationMode": "none", diff --git a/x-pack/plugins/actions/server/config.ts b/x-pack/plugins/actions/server/config.ts index f475c05424df4..f16a9830678cd 100644 --- a/x-pack/plugins/actions/server/config.ts +++ b/x-pack/plugins/actions/server/config.ts @@ -44,10 +44,6 @@ const customHostSettingsSchema = schema.object({ ), ssl: schema.maybe( schema.object({ - /** - * @deprecated in favor of `verificationMode` - **/ - rejectUnauthorized: schema.maybe(schema.boolean()), verificationMode: schema.maybe( schema.oneOf( [schema.literal('none'), schema.literal('certificate'), schema.literal('full')], @@ -98,16 +94,8 @@ export const configSchema = schema.object({ }), proxyUrl: schema.maybe(schema.string()), proxyHeaders: schema.maybe(schema.recordOf(schema.string(), schema.string())), - /** - * @deprecated in favor of `ssl.proxyVerificationMode` - **/ - proxyRejectUnauthorizedCertificates: schema.boolean({ defaultValue: true }), proxyBypassHosts: schema.maybe(schema.arrayOf(schema.string({ hostname: true }))), proxyOnlyHosts: schema.maybe(schema.arrayOf(schema.string({ hostname: true }))), - /** - * @deprecated in favor of `ssl.verificationMode` - **/ - rejectUnauthorized: schema.boolean({ defaultValue: true }), ssl: schema.maybe( schema.object({ verificationMode: schema.maybe( diff --git a/x-pack/plugins/actions/server/index.test.ts b/x-pack/plugins/actions/server/index.test.ts deleted file mode 100644 index 43f69da15de2f..0000000000000 --- a/x-pack/plugins/actions/server/index.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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { config } from '.'; -import { applyDeprecations, configDeprecationFactory } from '@kbn/config'; -import { configDeprecationsMock } from '@kbn/core/server/mocks'; - -const CONFIG_PATH = 'xpack.actions'; -const applyStackAlertDeprecations = (settings: Record = {}) => { - const deprecations = config.deprecations!(configDeprecationFactory); - const deprecationMessages: string[] = []; - const _config = { - [CONFIG_PATH]: settings, - }; - const { config: migrated, changedPaths } = applyDeprecations( - _config, - deprecations.map((deprecation) => ({ - deprecation, - path: CONFIG_PATH, - context: configDeprecationsMock.createContext(), - })), - () => - ({ message }) => - deprecationMessages.push(message) - ); - return { - messages: deprecationMessages, - migrated, - changedPaths, - }; -}; - -describe('index', () => { - describe('deprecations', () => { - it('should properly unset deprecated configs', () => { - const { messages, changedPaths } = applyStackAlertDeprecations({ - customHostSettings: [{ ssl: { rejectUnauthorized: false } }], - rejectUnauthorized: false, - proxyRejectUnauthorizedCertificates: false, - }); - expect(changedPaths.unset).toStrictEqual([ - 'xpack.actions.customHostSettings.ssl.rejectUnauthorized', - 'xpack.actions.rejectUnauthorized', - 'xpack.actions.proxyRejectUnauthorizedCertificates', - ]); - expect(messages.length).toBe(3); - expect(messages[0]).toBe( - '"xpack.actions.customHostSettings[].ssl.rejectUnauthorized" is deprecated.Use "xpack.actions.customHostSettings[].ssl.verificationMode" instead, with the setting "verificationMode:full" eql to "rejectUnauthorized:true", and "verificationMode:none" eql to "rejectUnauthorized:false".' - ); - expect(messages[1]).toBe( - '"xpack.actions.rejectUnauthorized" is deprecated. Use "xpack.actions.ssl.verificationMode" instead, with the setting "verificationMode:full" eql to "rejectUnauthorized:true", and "verificationMode:none" eql to "rejectUnauthorized:false".' - ); - expect(messages[2]).toBe( - '"xpack.actions.proxyRejectUnauthorizedCertificates" is deprecated. Use "xpack.actions.ssl.proxyVerificationMode" instead, with the setting "proxyVerificationMode:full" eql to "rejectUnauthorized:true",and "proxyVerificationMode:none" eql to "rejectUnauthorized:false".' - ); - }); - }); -}); diff --git a/x-pack/plugins/actions/server/index.ts b/x-pack/plugins/actions/server/index.ts index 1d5aa22ba07cf..d391911ff0fc3 100644 --- a/x-pack/plugins/actions/server/index.ts +++ b/x-pack/plugins/actions/server/index.ts @@ -4,10 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { get } from 'lodash'; import type { PublicMethodsOf } from '@kbn/utility-types'; import { PluginInitializerContext, PluginConfigDescriptor } from '@kbn/core/server'; -import { configSchema, ActionsConfig, CustomHostSettings } from './config'; +import { configSchema, ActionsConfig } from './config'; import { ActionsClient as ActionsClientClass } from './actions_client'; import { ActionsAuthorization as ActionsAuthorizationClass } from './authorization/actions_authorization'; @@ -51,103 +50,6 @@ export const config: PluginConfigDescriptor = { exposeToBrowser: { email: { domain_allowlist: true }, }, - deprecations: ({ renameFromRoot, unused }) => [ - renameFromRoot('xpack.actions.whitelistedHosts', 'xpack.actions.allowedHosts', { - level: 'warning', - }), - (settings, fromPath, addDeprecation) => { - const actions = get(settings, fromPath); - const customHostSettings = actions?.customHostSettings ?? []; - if ( - customHostSettings.find( - (customHostSchema: CustomHostSettings) => - Object.hasOwn(customHostSchema, 'ssl') && - Object.hasOwn(customHostSchema.ssl ?? {}, 'rejectUnauthorized') - ) - ) { - addDeprecation({ - level: 'warning', - configPath: 'xpack.actions.customHostSettings.ssl.rejectUnauthorized', - message: - `"xpack.actions.customHostSettings[].ssl.rejectUnauthorized" is deprecated.` + - `Use "xpack.actions.customHostSettings[].ssl.verificationMode" instead, ` + - `with the setting "verificationMode:full" eql to "rejectUnauthorized:true", ` + - `and "verificationMode:none" eql to "rejectUnauthorized:false".`, - correctiveActions: { - manualSteps: [ - `Remove "xpack.actions.customHostSettings[].ssl.rejectUnauthorized" from your kibana configs.`, - `Use "xpack.actions.customHostSettings[].ssl.verificationMode" ` + - `with the setting "verificationMode:full" eql to "rejectUnauthorized:true", ` + - `and "verificationMode:none" eql to "rejectUnauthorized:false".`, - ], - }, - }); - return { - unset: [ - { - path: `xpack.actions.customHostSettings.ssl.rejectUnauthorized`, - }, - ], - }; - } - }, - (settings, fromPath, addDeprecation) => { - const actions = get(settings, fromPath); - if (Object.hasOwn(actions ?? {}, 'rejectUnauthorized')) { - addDeprecation({ - level: 'warning', - configPath: `${fromPath}.rejectUnauthorized`, - message: - `"xpack.actions.rejectUnauthorized" is deprecated. Use "xpack.actions.ssl.verificationMode" instead, ` + - `with the setting "verificationMode:full" eql to "rejectUnauthorized:true", ` + - `and "verificationMode:none" eql to "rejectUnauthorized:false".`, - correctiveActions: { - manualSteps: [ - `Remove "xpack.actions.rejectUnauthorized" from your kibana configs.`, - `Use "xpack.actions.ssl.verificationMode" ` + - `with the setting "verificationMode:full" eql to "rejectUnauthorized:true", ` + - `and "verificationMode:none" eql to "rejectUnauthorized:false".`, - ], - }, - }); - return { - unset: [ - { - path: `xpack.actions.rejectUnauthorized`, - }, - ], - }; - } - }, - (settings, fromPath, addDeprecation) => { - const actions = get(settings, fromPath); - if (Object.hasOwn(actions ?? {}, 'proxyRejectUnauthorizedCertificates')) { - addDeprecation({ - level: 'warning', - configPath: `${fromPath}.proxyRejectUnauthorizedCertificates`, - message: - `"xpack.actions.proxyRejectUnauthorizedCertificates" is deprecated. Use "xpack.actions.ssl.proxyVerificationMode" instead, ` + - `with the setting "proxyVerificationMode:full" eql to "rejectUnauthorized:true",` + - `and "proxyVerificationMode:none" eql to "rejectUnauthorized:false".`, - correctiveActions: { - manualSteps: [ - `Remove "xpack.actions.proxyRejectUnauthorizedCertificates" from your kibana configs.`, - `Use "xpack.actions.ssl.proxyVerificationMode" ` + - `with the setting "proxyVerificationMode:full" eql to "rejectUnauthorized:true",` + - `and "proxyVerificationMode:none" eql to "rejectUnauthorized:false".`, - ], - }, - }); - return { - unset: [ - { - path: `xpack.actions.proxyRejectUnauthorizedCertificates`, - }, - ], - }; - } - }, - ], }; export { urlAllowListValidator } from './sub_action_framework/helpers'; diff --git a/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts b/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts index 3a4101bb9f152..a0454cb2bbc18 100644 --- a/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts +++ b/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts @@ -461,7 +461,6 @@ async function rejectUnauthorizedTargetProxyTest(opts: RunTestOptions) { await runWithSetup(opts, async (target, proxyInstance, axiosDefaults) => { const acu = getACUfromConfig({ proxyUrl: proxyInstance.url, - rejectUnauthorized: false, customHostSettings: [{ url: target.url, ssl: { verificationMode: 'none' } }], }); @@ -676,14 +675,12 @@ const BaseActionsConfig: ActionsConfig = { preconfigured: {}, proxyUrl: undefined, proxyHeaders: undefined, - proxyRejectUnauthorizedCertificates: true, ssl: { proxyVerificationMode: 'full', verificationMode: 'full', }, proxyBypassHosts: undefined, proxyOnlyHosts: undefined, - rejectUnauthorized: true, maxResponseContentLength: ByteSizeValue.parse('1mb'), responseTimeout: momentDuration(1000 * 30), customHostSettings: undefined, diff --git a/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts b/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts index 1c1d411111253..97a917d6b6893 100644 --- a/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts +++ b/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts @@ -366,7 +366,6 @@ async function rejectUnauthorizedTargetProxyTest(opts: RunTestOptions) { await runWithSetup(opts, async (target, proxyInstance, axiosDefaults) => { const acu = getACUfromConfig({ proxyUrl: proxyInstance.url, - rejectUnauthorized: false, customHostSettings: [{ url: target.url, ssl: { verificationMode: 'none' } }], }); @@ -582,14 +581,12 @@ const BaseActionsConfig: ActionsConfig = { preconfigured: {}, proxyUrl: undefined, proxyHeaders: undefined, - proxyRejectUnauthorizedCertificates: true, ssl: { proxyVerificationMode: 'full', verificationMode: 'full', }, proxyBypassHosts: undefined, proxyOnlyHosts: undefined, - rejectUnauthorized: true, maxResponseContentLength: ByteSizeValue.parse('1mb'), responseTimeout: momentDuration(1000 * 30), customHostSettings: undefined, diff --git a/x-pack/plugins/actions/server/lib/custom_host_settings.test.ts b/x-pack/plugins/actions/server/lib/custom_host_settings.test.ts index 0a9d9c6df31e7..f9173f5e007d0 100644 --- a/x-pack/plugins/actions/server/lib/custom_host_settings.test.ts +++ b/x-pack/plugins/actions/server/lib/custom_host_settings.test.ts @@ -74,8 +74,6 @@ describe('custom_host_settings', () => { enabledActionTypes: [], preconfiguredAlertHistoryEsIndex: false, preconfigured: {}, - proxyRejectUnauthorizedCertificates: true, - rejectUnauthorized: true, maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration(60000), enableFooterInEmail: true, @@ -119,14 +117,12 @@ describe('custom_host_settings', () => { url: 'https://elastic.co:443', ssl: { certificateAuthoritiesData: 'xyz', - rejectUnauthorized: false, }, }, { url: 'smtp://mail.elastic.com:25', ssl: { certificateAuthoritiesData: 'abc', - rejectUnauthorized: true, }, smtp: { ignoreTLS: true, @@ -473,15 +469,9 @@ describe('custom_host_settings', () => { customHostSettings: [ { url: 'https://almost.purrfect.com/', - ssl: { - rejectUnauthorized: true, - }, }, { url: 'https://almost.purrfect.com:443', - ssl: { - rejectUnauthorized: false, - }, }, ], }; @@ -491,9 +481,6 @@ describe('custom_host_settings', () => { customHostSettings: [ { url: 'https://almost.purrfect.com:443', - ssl: { - rejectUnauthorized: true, - }, }, ], }; diff --git a/x-pack/plugins/actions/server/lib/get_custom_agents.ts b/x-pack/plugins/actions/server/lib/get_custom_agents.ts index 26b1495902eb1..c433bec18a54b 100644 --- a/x-pack/plugins/actions/server/lib/get_custom_agents.ts +++ b/x-pack/plugins/actions/server/lib/get_custom_agents.ts @@ -59,10 +59,7 @@ export function getCustomAgents( agentOptions.ca = sslSettings.certificateAuthoritiesData; } - const sslSettingsFromConfig = getSSLSettingsFromConfig( - sslSettings.verificationMode, - sslSettings.rejectUnauthorized - ); + const sslSettingsFromConfig = getSSLSettingsFromConfig(sslSettings.verificationMode); // see: src/core/server/elasticsearch/legacy/elasticsearch_client_config.ts // This is where the global rejectUnauthorized is overridden by a custom host const customHostNodeSSLOptions = getNodeSSLOptions( diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index 4ff87aa0459ef..f5de52810b162 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -50,10 +50,8 @@ function getConfig(overrides = {}) { secrets: {}, }, }, - proxyRejectUnauthorizedCertificates: true, proxyBypassHosts: undefined, proxyOnlyHosts: undefined, - rejectUnauthorized: true, maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration('60s'), enableFooterInEmail: true, @@ -80,8 +78,6 @@ describe('Actions Plugin', () => { allowedHosts: ['*'], preconfiguredAlertHistoryEsIndex: false, preconfigured: {}, - proxyRejectUnauthorizedCertificates: true, - rejectUnauthorized: true, maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration(60000), enableFooterInEmail: true, @@ -587,8 +583,6 @@ describe('Actions Plugin', () => { secrets: {}, }, }, - proxyRejectUnauthorizedCertificates: true, - rejectUnauthorized: true, maxResponseContentLength: new ByteSizeValue(1000000), responseTimeout: moment.duration(60000), enableFooterInEmail: true, diff --git a/x-pack/plugins/actions/tsconfig.json b/x-pack/plugins/actions/tsconfig.json index 384aba6a6b014..8a3c56a472064 100644 --- a/x-pack/plugins/actions/tsconfig.json +++ b/x-pack/plugins/actions/tsconfig.json @@ -24,7 +24,6 @@ "@kbn/i18n", "@kbn/utility-types", "@kbn/config-schema", - "@kbn/config", "@kbn/core-saved-objects-server", "@kbn/es-query", "@kbn/apm-utils", diff --git a/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx b/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx index 38b5620465a0d..b1c0e3d89f35a 100644 --- a/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx +++ b/x-pack/plugins/aiops/public/components/change_point_detection/fields_config.tsx @@ -261,7 +261,7 @@ const FieldPanel: FC = ({ disabled: removeDisabled, }, ], - 'data=test-subj': 'aiopsChangePointDetectionContextMenuPanel', + 'data-test-subj': 'aiopsChangePointDetectionContextMenuPanel', }, { id: 'attachMainPanel', diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx index b97019c4b4d29..ad8e7740b505d 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis/log_rate_analysis_results.tsx @@ -183,6 +183,7 @@ export const LogRateAnalysisResults: FC = ({ // to be able to track it across rerenders. const analysisStartTime = useRef(window.performance.now()); const abortCtrl = useRef(new AbortController()); + const previousSearchQuery = useRef(searchQuery); const [groupResults, setGroupResults] = useState(false); const [overrides, setOverrides] = useState( @@ -386,6 +387,19 @@ export const LogRateAnalysisResults: FC = ({ [data.significantItemsGroups] ); + const searchQueryUpdated = useMemo(() => { + let searchQueryChanged = false; + if ( + !isRunning && + previousSearchQuery.current !== undefined && + !isEqual(previousSearchQuery.current, searchQuery) + ) { + searchQueryChanged = true; + } + previousSearchQuery.current = searchQuery; + return searchQueryChanged; + }, [searchQuery, isRunning]); + const shouldRerunAnalysis = useMemo( () => currentAnalysisWindowParameters !== undefined && @@ -426,7 +440,7 @@ export const LogRateAnalysisResults: FC = ({ onRefresh={() => startHandler(false)} onCancel={cancelHandler} onReset={onReset} - shouldRerunAnalysis={shouldRerunAnalysis} + shouldRerunAnalysis={shouldRerunAnalysis || searchQueryUpdated} analysisInfo={} > diff --git a/x-pack/plugins/aiops/public/components/page_header/page_header.tsx b/x-pack/plugins/aiops/public/components/page_header/page_header.tsx index 9895fe082fcc1..a01e715e86272 100644 --- a/x-pack/plugins/aiops/public/components/page_header/page_header.tsx +++ b/x-pack/plugins/aiops/public/components/page_header/page_header.tsx @@ -9,7 +9,7 @@ import { css } from '@emotion/react'; import type { FC } from 'react'; import React, { useCallback, useMemo } from 'react'; -import { EuiFlexGroup, EuiFlexItem, EuiPageHeader } from '@elastic/eui'; +import { EuiPageHeader } from '@elastic/eui'; import { useUrlState } from '@kbn/ml-url-state'; import { useStorage } from '@kbn/ml-local-storage'; @@ -71,29 +71,29 @@ export const PageHeader: FC = () => { return ( {dataView.getName()}} + rightSideGroupProps={{ + gutterSize: 's', + 'data-test-subj': 'aiopsTimeRangeSelectorSection', + }} rightSideItems={[ - - {hasValidTimeField ? ( - - - - ) : null} - , + hasValidTimeField && ( + - , - ]} + ), + ].filter(Boolean)} /> ); }; diff --git a/x-pack/plugins/aiops/server/routes/categorization_field_validation/define_route.ts b/x-pack/plugins/aiops/server/routes/categorization_field_validation/define_route.ts index ecc4d9c94bde1..5d166d1493b33 100644 --- a/x-pack/plugins/aiops/server/routes/categorization_field_validation/define_route.ts +++ b/x-pack/plugins/aiops/server/routes/categorization_field_validation/define_route.ts @@ -27,6 +27,13 @@ export const defineRoute = ( .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: categorizationFieldValidationSchema, diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/define_route.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/define_route.ts index 5c092c1a3be58..b69a66e4e69c5 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/define_route.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/define_route.ts @@ -38,6 +38,13 @@ export const defineRoute = ( .addVersion( { version: '2', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: aiopsLogRateAnalysisSchemaV2, @@ -49,6 +56,13 @@ export const defineRoute = ( .addVersion( { version: '3', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: aiopsLogRateAnalysisSchemaV3, diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis_field_candidates/define_route.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis_field_candidates/define_route.ts index 132ecfee7b212..fc7ed7c808975 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis_field_candidates/define_route.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis_field_candidates/define_route.ts @@ -35,6 +35,13 @@ export const defineRoute = ( .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: aiopsLogRateAnalysisSchemaV3, diff --git a/x-pack/plugins/alerting/server/index.ts b/x-pack/plugins/alerting/server/index.ts index 2f5cd3994e436..2cb2c212a91ba 100644 --- a/x-pack/plugins/alerting/server/index.ts +++ b/x-pack/plugins/alerting/server/index.ts @@ -84,20 +84,6 @@ export const config: PluginConfigDescriptor = { rules: { run: { alerts: { max: true } } }, }, deprecations: ({ renameFromRoot, deprecate }) => [ - renameFromRoot('xpack.alerts.healthCheck', 'xpack.alerting.healthCheck', { level: 'warning' }), - renameFromRoot( - 'xpack.alerts.invalidateApiKeysTask.interval', - 'xpack.alerting.invalidateApiKeysTask.interval', - { level: 'warning' } - ), - renameFromRoot( - 'xpack.alerts.invalidateApiKeysTask.removalDelay', - 'xpack.alerting.invalidateApiKeysTask.removalDelay', - { level: 'warning' } - ), - renameFromRoot('xpack.alerting.defaultRuleTaskTimeout', 'xpack.alerting.rules.run.timeout', { - level: 'warning', - }), deprecate('maxEphemeralActionsPerAlert', 'a future version', { level: 'warning', message: `Configuring "xpack.alerting.maxEphemeralActionsPerAlert" is deprecated and will be removed in a future version. Remove this setting to increase action execution resiliency.`, diff --git a/x-pack/plugins/cases/public/components/case_view/components/user_list.test.tsx b/x-pack/plugins/cases/public/components/case_view/components/user_list.test.tsx index 7254f7f500f63..b1601e471915f 100644 --- a/x-pack/plugins/cases/public/components/case_view/components/user_list.test.tsx +++ b/x-pack/plugins/cases/public/components/case_view/components/user_list.test.tsx @@ -20,7 +20,8 @@ jest.mock('../../../common/navigation/hooks'); const useCaseViewNavigationMock = useCaseViewNavigation as jest.Mock; -describe('UserList ', () => { +// FLAKY: https://github.com/elastic/kibana/issues/192640 +describe.skip('UserList ', () => { const title = basicCase.title; const caseLink = 'https://example.com/cases/test'; const user = { diff --git a/x-pack/plugins/cloud_security_posture/public/common/constants.ts b/x-pack/plugins/cloud_security_posture/public/common/constants.ts index fab73eb153e69..ea3866cbe1256 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/constants.ts @@ -263,9 +263,7 @@ The runtime mappings are used to prevent filtering out the data when any of thes TODO: Remove the fields below once they are mapped as Keyword in the Third Party integrations, or remove the fields from the runtime mappings if they are removed from the Data Table. */ -export const CDR_VULNERABILITY_DATA_TABLE_RUNTIME_MAPPING_FIELDS: string[] = [ - VULNERABILITY_FIELDS.VENDOR, -]; +export const CDR_VULNERABILITY_DATA_TABLE_RUNTIME_MAPPING_FIELDS: string[] = []; export const CDR_MISCONFIGURATION_DATA_TABLE_RUNTIME_MAPPING_FIELDS: string[] = [ 'rule.benchmark.rule_number', 'rule.section', @@ -279,9 +277,7 @@ to prevent filtering out the data when grouping by the key field. TODO: Remove the fields below once they are mapped as Keyword in the Third Party integrations, or remove the fields from the runtime mappings if they are removed from the Data Table. */ -export const CDR_VULNERABILITY_GROUPING_RUNTIME_MAPPING_FIELDS: Record = { - [VULNERABILITY_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME]: [VULNERABILITY_FIELDS.CLOUD_PROVIDER], -}; +export const CDR_VULNERABILITY_GROUPING_RUNTIME_MAPPING_FIELDS: Record = {}; export const CDR_MISCONFIGURATION_GROUPING_RUNTIME_MAPPING_FIELDS: Record = { [FINDINGS_GROUPING_OPTIONS.ORCHESTRATOR_CLUSTER_NAME]: ['orchestrator.cluster.name'], [FINDINGS_GROUPING_OPTIONS.CLOUD_ACCOUNT_NAME]: ['cloud.account.name'], diff --git a/x-pack/plugins/data_visualizer/public/application/data_drift/data_drift_page.tsx b/x-pack/plugins/data_visualizer/public/application/data_drift/data_drift_page.tsx index 86bb350849a33..4623e886852d8 100644 --- a/x-pack/plugins/data_visualizer/public/application/data_drift/data_drift_page.tsx +++ b/x-pack/plugins/data_visualizer/public/application/data_drift/data_drift_page.tsx @@ -106,31 +106,31 @@ export const PageHeader: FC = ({ onRefresh, needsUpdate }) => { {dataView.getName()} } + rightSideGroupProps={{ + gutterSize: 's', + 'data-test-subj': 'dataComparisonTimeRangeSelectorSection', + }} rightSideItems={[ - - {hasValidTimeField ? ( - - - - ) : null} - , + hasValidTimeField && ( + - , - ]} + ), + ].filter(Boolean)} /> ); }; diff --git a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.test.ts b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.test.tsx similarity index 80% rename from x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.test.ts rename to x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.test.tsx index f4631ea96b937..8eefae138b6c3 100644 --- a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.test.ts +++ b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.test.tsx @@ -7,19 +7,20 @@ import { BehaviorSubject } from 'rxjs'; import { IExternalUrl } from '@kbn/core/public'; -import { UrlDrilldown, Config } from './url_drilldown'; +import { render, waitFor } from '@testing-library/react'; +import { Config, UrlDrilldown } from './url_drilldown'; import { - ValueClickContext, - VALUE_CLICK_TRIGGER, - SELECT_RANGE_TRIGGER, CONTEXT_MENU_TRIGGER, + SELECT_RANGE_TRIGGER, + VALUE_CLICK_TRIGGER, + ValueClickContext, } from '@kbn/embeddable-plugin/public'; import { DatatableColumnType } from '@kbn/expressions-plugin/common'; -import { of } from '@kbn/kibana-utils-plugin/common'; import { createPoint, rowClickData } from './test/data'; import { ROW_CLICK_TRIGGER } from '@kbn/ui-actions-plugin/public'; import { settingsServiceMock } from '@kbn/core-ui-settings-browser-mocks'; import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; +import React from 'react'; const mockDataPoints = [ { @@ -61,6 +62,7 @@ const mockEmbeddableApi = { filters$: new BehaviorSubject([]), query$: new BehaviorSubject({ query: 'test', language: 'kuery' }), timeRange$: new BehaviorSubject({ from: 'now-15m', to: 'now' }), + viewMode: new BehaviorSubject('edit'), }, }; @@ -93,6 +95,20 @@ const createDrilldown = (isExternalUrlValid: boolean = true) => { return drilldown; }; +const renderActionMenuItem = async ( + drilldown: UrlDrilldown, + config: Config, + context: ValueClickContext +) => { + const { getByTestId } = render( + + ); + await waitFor(() => null); // wait for effects to complete + return { + getError: () => getByTestId('urlDrilldown-error'), + }; +}; + describe('UrlDrilldown', () => { const urlDrilldown = createDrilldown(); @@ -119,7 +135,73 @@ describe('UrlDrilldown', () => { await expect(urlDrilldown.isCompatible(config, context)).rejects.toThrowError(); }); - test('compatible if url is valid', async () => { + test('compatible in edit mode if url is valid', async () => { + const config: Config = { + url: { + template: `https://elasti.co/?{{event.value}}&{{rison context.panel.query}}`, + }, + openInNewTab: false, + encodeUrl: true, + }; + + const context: ValueClickContext = { + data: { + data: mockDataPoints, + }, + embeddable: mockEmbeddableApi, + }; + + const result = urlDrilldown.isCompatible(config, context); + await expect(result).resolves.toBe(true); + }); + + test('compatible in edit mode if url is invalid', async () => { + const config: Config = { + url: { + template: `https://elasti.co/?{{event.value}}&{{rison context.panel.somethingFake}}`, + }, + openInNewTab: false, + encodeUrl: true, + }; + + const context: ValueClickContext = { + data: { + data: mockDataPoints, + }, + embeddable: mockEmbeddableApi, + }; + + await expect(urlDrilldown.isCompatible(config, context)).resolves.toBe(true); + }); + + test('compatible in edit mode if external URL is denied', async () => { + const drilldown1 = createDrilldown(true); + const drilldown2 = createDrilldown(false); + const config: Config = { + url: { + template: `https://elasti.co/?{{event.value}}&{{rison context.panel.query}}`, + }, + openInNewTab: false, + encodeUrl: true, + }; + + const context: ValueClickContext = { + data: { + data: mockDataPoints, + }, + embeddable: mockEmbeddableApi, + }; + + const result1 = await drilldown1.isCompatible(config, context); + const result2 = await drilldown2.isCompatible(config, context); + + expect(result1).toBe(true); + expect(result2).toBe(true); + }); + + test('compatible in view mode if url is valid', async () => { + mockEmbeddableApi.parentApi.viewMode.next('view'); + const config: Config = { url: { template: `https://elasti.co/?{{event.value}}&{{rison context.panel.query}}`, @@ -139,7 +221,8 @@ describe('UrlDrilldown', () => { await expect(result).resolves.toBe(true); }); - test('not compatible if url is invalid', async () => { + test('not compatible in view mode if url is invalid', async () => { + mockEmbeddableApi.parentApi.viewMode.next('view'); const config: Config = { url: { template: `https://elasti.co/?{{event.value}}&{{rison context.panel.somethingFake}}`, @@ -158,7 +241,8 @@ describe('UrlDrilldown', () => { await expect(urlDrilldown.isCompatible(config, context)).resolves.toBe(false); }); - test('not compatible if external URL is denied', async () => { + test('not compatible in view mode if external URL is denied', async () => { + mockEmbeddableApi.parentApi.viewMode.next('view'); const drilldown1 = createDrilldown(true); const drilldown2 = createDrilldown(false); const config: Config = { @@ -184,7 +268,7 @@ describe('UrlDrilldown', () => { }); }); - describe('getHref & execute', () => { + describe('getHref & execute & title', () => { beforeEach(() => { mockNavigateToUrl.mockReset(); }); @@ -210,6 +294,9 @@ describe('UrlDrilldown', () => { await urlDrilldown.execute(config, context); expect(mockNavigateToUrl).toBeCalledWith(url); + + const { getError } = await renderActionMenuItem(urlDrilldown, config, context); + expect(() => getError()).toThrow(); }); test('invalid url', async () => { @@ -228,12 +315,17 @@ describe('UrlDrilldown', () => { embeddable: mockEmbeddableApi, }; - await expect(urlDrilldown.getHref(config, context)).rejects.toThrowError(); - await expect(urlDrilldown.execute(config, context)).rejects.toThrowError(); + await expect(urlDrilldown.getHref(config, context)).resolves.toBeUndefined(); + await expect(urlDrilldown.execute(config, context)).resolves.toBeUndefined(); expect(mockNavigateToUrl).not.toBeCalled(); + + const { getError } = await renderActionMenuItem(urlDrilldown, config, context); + expect(getError()).toHaveTextContent( + `Error building URL: The URL template is not valid in the given context.` + ); }); - test('should throw on denied external URL', async () => { + test('should not throw on denied external URL', async () => { const drilldown1 = createDrilldown(true); const drilldown2 = createDrilldown(false); const config: Config = { @@ -257,17 +349,11 @@ describe('UrlDrilldown', () => { expect(url).toMatchInlineSnapshot(`"https://elasti.co/?test&(language:kuery,query:test)"`); expect(mockNavigateToUrl).toBeCalledWith(url); - const [, error1] = await of(drilldown2.getHref(config, context)); - const [, error2] = await of(drilldown2.execute(config, context)); + await expect(drilldown2.getHref(config, context)).resolves.toBeUndefined(); + await expect(drilldown2.execute(config, context)).resolves.toBeUndefined(); - expect(error1).toBeInstanceOf(Error); - expect(error1.message).toMatchInlineSnapshot( - `"External URL [https://elasti.co/?test&(language:kuery,query:test)] was denied by ExternalUrl service. You can configure external URL policies using \\"externalUrl.policy\\" setting in kibana.yml."` - ); - expect(error2).toBeInstanceOf(Error); - expect(error2.message).toMatchInlineSnapshot( - `"External URL [https://elasti.co/?test&(language:kuery,query:test)] was denied by ExternalUrl service. You can configure external URL policies using \\"externalUrl.policy\\" setting in kibana.yml."` - ); + const { getError } = await renderActionMenuItem(drilldown2, config, context); + expect(getError()).toHaveTextContent(`Error building URL: external URL was denied.`); }); }); diff --git a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx index 1dd9c94ef329f..fed0542883611 100644 --- a/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx +++ b/x-pack/plugins/drilldowns/url_drilldown/public/lib/url_drilldown.tsx @@ -7,7 +7,11 @@ import React from 'react'; import { IExternalUrl, ThemeServiceStart } from '@kbn/core/public'; -import type { EmbeddableApiContext } from '@kbn/presentation-publishing'; +import { + type EmbeddableApiContext, + getInheritedViewMode, + apiCanAccessViewMode, +} from '@kbn/presentation-publishing'; import { ChartActionContext, CONTEXT_MENU_TRIGGER, @@ -17,21 +21,23 @@ import { import { IMAGE_CLICK_TRIGGER } from '@kbn/image-embeddable-plugin/public'; import { ActionExecutionContext, ROW_CLICK_TRIGGER } from '@kbn/ui-actions-plugin/public'; import type { CollectConfigProps as CollectConfigPropsBase } from '@kbn/kibana-utils-plugin/public'; -import { UrlTemplateEditorVariable, KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; +import { KibanaContextProvider, UrlTemplateEditorVariable } from '@kbn/kibana-react-plugin/public'; import { + UiActionsEnhancedBaseActionFactoryContext as BaseActionFactoryContext, UiActionsEnhancedDrilldownDefinition as Drilldown, - UrlDrilldownGlobalScope, - UrlDrilldownConfig, UrlDrilldownCollectConfig, - urlDrilldownValidateUrlTemplate, urlDrilldownCompileUrl, - UiActionsEnhancedBaseActionFactoryContext as BaseActionFactoryContext, + UrlDrilldownConfig, + UrlDrilldownGlobalScope, + urlDrilldownValidateUrlTemplate, } from '@kbn/ui-actions-enhanced-plugin/public'; import type { SerializedAction } from '@kbn/ui-actions-enhanced-plugin/common/types'; import type { SettingsStart } from '@kbn/core-ui-settings-browser'; +import { EuiText, EuiTextBlockTruncate } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { txtUrlDrilldownDisplayName } from './i18n'; -import { getEventVariableList, getEventScopeValues } from './variables/event_variables'; -import { getContextVariableList, getContextScopeValues } from './variables/context_variables'; +import { getEventScopeValues, getEventVariableList } from './variables/event_variables'; +import { getContextScopeValues, getContextVariableList } from './variables/context_variables'; import { getGlobalVariableList } from './variables/global_variables'; interface UrlDrilldownDeps { @@ -58,6 +64,13 @@ export type CollectConfigProps = CollectConfigPropsBase { + if (apiCanAccessViewMode(context.embeddable)) { + return getInheritedViewMode(context.embeddable); + } + throw new Error('Cannot access view mode'); +}; + export class UrlDrilldown implements Drilldown { public readonly id = URL_DRILLDOWN; @@ -75,20 +88,39 @@ export class UrlDrilldown implements Drilldown; }> = ({ config, context }) => { const [title, setTitle] = React.useState(config.name); + const [error, setError] = React.useState(); React.useEffect(() => { - let unmounted = false; const variables = this.getRuntimeVariables(context); urlDrilldownCompileUrl(title, variables, false) .then((result) => { - if (unmounted) return; if (title !== result) setTitle(result); }) .catch(() => {}); - return () => { - unmounted = true; - }; - }); - return <>{title}; + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + React.useEffect(() => { + this.buildUrl(config.config, context).catch((e) => { + setError(e.message); + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + return ( + /* title is used as a tooltip, EuiToolTip doesn't work in this context menu due to hacky zIndex */ + + {title} + {/* note: ideally we'd use EuiIconTip for the error, but it doesn't play well with this context menu*/} + {error ? ( + + + {error} + + + ) : null} + + ); }; public readonly euiIcon = 'link'; @@ -140,53 +172,81 @@ export class UrlDrilldown implements Drilldown { - const scope = this.getRuntimeVariables(context); - const { isValid, error } = await urlDrilldownValidateUrlTemplate(config.url, scope); + const viewMode = getViewMode(context); - if (!isValid) { - // eslint-disable-next-line no-console - console.warn( - `UrlDrilldown [${config.url.template}] is not valid. Error [${error}]. Skipping execution.` - ); - return false; + if (viewMode === 'edit') { + // check if context is compatible by building the scope + const scope = this.getRuntimeVariables(context); + return !!scope; } - const url = await this.buildUrl(config, context); - const validUrl = this.deps.externalUrl.validateUrl(url); - if (!validUrl) { + try { + await this.buildUrl(config, context); + return true; + } catch (e) { + // eslint-disable-next-line no-console + console.warn(e); return false; } - - return true; }; private async buildUrl(config: Config, context: ChartActionContext): Promise { + const scope = this.getRuntimeVariables(context); + const { isValid, error, invalidUrl } = await urlDrilldownValidateUrlTemplate(config.url, scope); + + if (!isValid) { + const errorMessage = i18n.translate('xpack.urlDrilldown.invalidUrlErrorMessage', { + defaultMessage: + 'Error building URL: {error} Use drilldown editor to check your URL template. Invalid URL: {invalidUrl}', + values: { + error, + invalidUrl, + }, + }); + throw new Error(errorMessage); + } + const doEncode = config.encodeUrl ?? true; + const url = await urlDrilldownCompileUrl( config.url.template, this.getRuntimeVariables(context), doEncode ); + + const validUrl = this.deps.externalUrl.validateUrl(url); + if (!validUrl) { + const errorMessage = i18n.translate('xpack.urlDrilldown.invalidUrlErrorMessage', { + defaultMessage: + 'Error building URL: external URL was denied. Administrator can configure external URL policies using "externalUrl.policy" setting in kibana.yml. Invalid URL: {invalidUrl}', + values: { + invalidUrl: url, + }, + }); + throw new Error(errorMessage); + } + return url; } public readonly getHref = async ( config: Config, context: ChartActionContext - ): Promise => { - const url = await this.buildUrl(config, context); - const validUrl = this.deps.externalUrl.validateUrl(url); - if (!validUrl) { - throw new Error( - `External URL [${url}] was denied by ExternalUrl service. ` + - `You can configure external URL policies using "externalUrl.policy" setting in kibana.yml.` - ); + ): Promise => { + try { + const url = await this.buildUrl(config, context); + return url; + } catch (e) { + // eslint-disable-next-line no-console + console.warn(e); + return undefined; } - return url; }; public readonly execute = async (config: Config, context: ChartActionContext) => { const url = await this.getHref(config, context); + if (!url) return; + if (config.openInNewTab) { window.open(url, '_blank', 'noopener'); } else { diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/components/generated_config_fields.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/components/generated_config_fields.tsx index 133c15f97f61c..53cbf579a940f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/components/generated_config_fields.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/connector_detail/components/generated_config_fields.tsx @@ -156,6 +156,10 @@ export const GeneratedConfigFields: React.FC = ({ data-test-subj="enterpriseSearchConnectorDeploymentButton" iconType="copyClipboard" onClick={copy} + aria-label={i18n.translate( + 'xpack.enterpriseSearch.connectorDeployment.copyConnectorId', + { defaultMessage: 'Copy connector ID' } + )} /> )} @@ -237,6 +241,10 @@ export const GeneratedConfigFields: React.FC = ({ isLoading={isGenerateLoading} onClick={refreshButtonClick} disabled={!connector.index_name} + aria-label={i18n.translate( + 'xpack.enterpriseSearch.connectorDeployment.refreshAPIKey', + { defaultMessage: 'Refresh an Elasticsearch API key' } + )} /> )} @@ -246,6 +254,10 @@ export const GeneratedConfigFields: React.FC = ({ data-test-subj="enterpriseSearchConnectorDeploymentButton" iconType="copyClipboard" onClick={copy} + aria-label={i18n.translate( + 'xpack.enterpriseSearch.connectorDeployment.copyIndexName', + { defaultMessage: 'Copy index name' } + )} />
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.tsx index 18514ef93d9d9..d19568bea9e3c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/components/generate_api_key_modal/modal.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React from 'react'; +import React, { useRef, useEffect } from 'react'; import { useValues, useActions } from 'kea'; @@ -26,11 +26,12 @@ import { EuiText, EuiSpacer, EuiLink, - EuiFormLabel, EuiCodeBlock, + EuiCallOut, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; import { docLinks } from '../../../../../shared/doc_links'; @@ -49,6 +50,13 @@ export const GenerateApiKeyModal: React.FC = ({ indexN const { ingestionMethod } = useValues(IndexViewLogic); const { setKeyName } = useActions(GenerateApiKeyModalLogic); const { makeRequest } = useActions(GenerateApiKeyLogic); + const copyApiKeyRef = useRef(null); + + useEffect(() => { + if (isSuccess) { + copyApiKeyRef.current?.focus(); + } + }, [isSuccess]); return ( @@ -68,7 +76,11 @@ export const GenerateApiKeyModal: React.FC = ({ indexN "Before you can start posting documents to your Elasticsearch index you'll need to create at least one API key.", })}   - + {i18n.translate( 'xpack.enterpriseSearch.content.overview.generateApiKeyModal.learnMore', { defaultMessage: 'Learn more about API keys' } @@ -77,15 +89,25 @@ export const GenerateApiKeyModal: React.FC = ({ indexN

- + + {!isSuccess ? ( <> - + + } + fullWidth + > = ({ indexN ) : ( - {keyName} - + {keyName}, + }} + /> + } + color="success" + iconType="check" + role="alert" + /> = ({ indexN = ({ indexN diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/api_key/api_key_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/api_key/api_key_panel.tsx index 34c7ac66343c9..b9d5cf8c414d6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/api_key/api_key_panel.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/api_key/api_key_panel.tsx @@ -76,6 +76,7 @@ export const ApiKeyPanel: React.FC = () => { {(copy) => ( { {(copy) => ( { - - - - 0 ? 'success' : 'warning'} - data-test-subj="api-keys-count-badge" - > - {apiKeys.length} - - ), - }} - /> - - - + 0 ? 'success' : 'warning'} + data-test-subj="api-keys-count-badge" + > + + diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/api_key_panel_content.tsx b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/api_key_panel_content.tsx index ff271a3a3d79e..a220e077f0824 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/api_key_panel_content.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/shared/getting_started/panels/api_key_panel_content.tsx @@ -102,26 +102,18 @@ export const ApiKeyPanelContent: React.FC = ({ apiKeys, open - - - - 0 ? 'success' : 'warning'} - data-test-subj="api-keys-count-badge" - > - {apiKeys?.length || 0} - - ), - }} - /> - - - + 0 ? 'success' : 'warning'} + data-test-subj="api-keys-count-badge" + > + + diff --git a/x-pack/plugins/entity_manager/public/lib/entity_client.test.ts b/x-pack/plugins/entity_manager/public/lib/entity_client.test.ts new file mode 100644 index 0000000000000..dbaf1205cdf98 --- /dev/null +++ b/x-pack/plugins/entity_manager/public/lib/entity_client.test.ts @@ -0,0 +1,139 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EntityClient, EnitityInstance } from './entity_client'; +import { coreMock } from '@kbn/core/public/mocks'; + +const commonEntityFields: EnitityInstance = { + entity: { + last_seen_timestamp: '2023-10-09T00:00:00Z', + id: '1', + display_name: 'entity_name', + definition_id: 'entity_definition_id', + } as EnitityInstance['entity'], +}; + +describe('EntityClient', () => { + let entityClient: EntityClient; + + beforeEach(() => { + entityClient = new EntityClient(coreMock.createStart()); + }); + + describe('asKqlFilter', () => { + it('should return the kql filter', () => { + const entityLatest: EnitityInstance = { + entity: { + ...commonEntityFields.entity, + identity_fields: ['service.name', 'service.environment'], + type: 'service', + }, + service: { + name: 'my-service', + }, + }; + + const result = entityClient.asKqlFilter(entityLatest); + expect(result).toEqual('service.name: my-service'); + }); + + it('should return the kql filter when indentity_fields is composed by multiple fields', () => { + const entityLatest: EnitityInstance = { + entity: { + ...commonEntityFields.entity, + identity_fields: ['service.name', 'service.environment'], + type: 'service', + }, + service: { + name: 'my-service', + environment: 'staging', + }, + }; + + const result = entityClient.asKqlFilter(entityLatest); + expect(result).toEqual('(service.name: my-service AND service.environment: staging)'); + }); + + it('should ignore fields that are not present in the entity', () => { + const entityLatest: EnitityInstance = { + entity: { + ...commonEntityFields.entity, + identity_fields: ['host.name', 'foo.bar'], + }, + host: { + name: 'my-host', + }, + }; + + const result = entityClient.asKqlFilter(entityLatest); + expect(result).toEqual('host.name: my-host'); + }); + }); + + describe('getIdentityFieldsValue', () => { + it('should return identity fields values', () => { + const entityLatest: EnitityInstance = { + entity: { + ...commonEntityFields.entity, + identity_fields: ['service.name', 'service.environment'], + type: 'service', + }, + service: { + name: 'my-service', + }, + }; + + expect(entityClient.getIdentityFieldsValue(entityLatest)).toEqual({ + 'service.name': 'my-service', + }); + }); + + it('should return identity fields values when indentity_fields is composed by multiple fields', () => { + const entityLatest: EnitityInstance = { + entity: { + ...commonEntityFields.entity, + identity_fields: ['service.name', 'service.environment'], + type: 'service', + }, + service: { + name: 'my-service', + environment: 'staging', + }, + }; + + expect(entityClient.getIdentityFieldsValue(entityLatest)).toEqual({ + 'service.name': 'my-service', + 'service.environment': 'staging', + }); + }); + + it('should return identity fields when field is in the root', () => { + const entityLatest: EnitityInstance = { + entity: { + ...commonEntityFields.entity, + identity_fields: ['name'], + type: 'service', + }, + name: 'foo', + }; + + expect(entityClient.getIdentityFieldsValue(entityLatest)).toEqual({ + name: 'foo', + }); + }); + + it('should throw an error when identity fields are missing', () => { + const entityLatest: EnitityInstance = { + ...commonEntityFields, + }; + + expect(() => entityClient.getIdentityFieldsValue(entityLatest)).toThrow( + 'Identity fields are missing' + ); + }); + }); +}); diff --git a/x-pack/plugins/entity_manager/public/lib/entity_client.ts b/x-pack/plugins/entity_manager/public/lib/entity_client.ts index dc22a0b991b0d..08794873ba930 100644 --- a/x-pack/plugins/entity_manager/public/lib/entity_client.ts +++ b/x-pack/plugins/entity_manager/public/lib/entity_client.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { z } from '@kbn/zod'; import { CoreSetup, CoreStart } from '@kbn/core/public'; import { ClientRequestParamsOf, @@ -12,6 +13,9 @@ import { createRepositoryClient, isHttpFetchError, } from '@kbn/server-route-repository-client'; +import { type KueryNode, nodeTypes, toKqlExpression } from '@kbn/es-query'; +import { entityLatestSchema } from '@kbn/entities-schema'; +import { castArray } from 'lodash'; import { DisableManagedEntityResponse, EnableManagedEntityResponse, @@ -35,6 +39,8 @@ type CreateEntityDefinitionQuery = QueryParamOf< ClientRequestParamsOf >; +export type EnitityInstance = z.infer; + export class EntityClient { public readonly repositoryClient: EntityManagerRepositoryClient['fetch']; @@ -83,4 +89,38 @@ export class EntityClient { throw err; } } + + asKqlFilter(entityLatest: EnitityInstance) { + const identityFieldsValue = this.getIdentityFieldsValue(entityLatest); + + const nodes: KueryNode[] = Object.entries(identityFieldsValue).map(([identityField, value]) => { + return nodeTypes.function.buildNode('is', identityField, value); + }); + + if (nodes.length === 0) return ''; + + const kqlExpression = nodes.length > 1 ? nodeTypes.function.buildNode('and', nodes) : nodes[0]; + + return toKqlExpression(kqlExpression); + } + + getIdentityFieldsValue(entityLatest: EnitityInstance) { + const { identity_fields: identityFields } = entityLatest.entity; + + if (!identityFields) { + throw new Error('Identity fields are missing'); + } + + return castArray(identityFields).reduce((acc, field) => { + const value = field.split('.').reduce((obj: any, part: string) => { + return obj && typeof obj === 'object' ? (obj as Record)[part] : undefined; + }, entityLatest); + + if (value) { + acc[field] = value; + } + + return acc; + }, {} as Record); + } } diff --git a/x-pack/plugins/file_upload/server/routes.ts b/x-pack/plugins/file_upload/server/routes.ts index 4336049b7fe58..8818e0a2e2dff 100644 --- a/x-pack/plugins/file_upload/server/routes.ts +++ b/x-pack/plugins/file_upload/server/routes.ts @@ -58,6 +58,13 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { query: schema.object({ @@ -155,6 +162,13 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { query: importFileQuerySchema, @@ -206,6 +220,13 @@ export function fileUploadRoutes(coreSetup: CoreSetup, logge .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: schema.object({ index: schema.string() }), diff --git a/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts b/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts index 04ba66acbebfb..34f05fcc82025 100644 --- a/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts +++ b/x-pack/plugins/integration_assistant/server/routes/analyze_logs_routes.ts @@ -36,6 +36,13 @@ export function registerAnalyzeLogsRoutes( .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because the privileges are not defined yet.', + }, + }, validate: { request: { body: buildRouteValidationWithZod(AnalyzeLogsRequestBody), diff --git a/x-pack/plugins/integration_assistant/server/routes/build_integration_routes.ts b/x-pack/plugins/integration_assistant/server/routes/build_integration_routes.ts index 6d7e5155a3d23..f62d6d55f933d 100644 --- a/x-pack/plugins/integration_assistant/server/routes/build_integration_routes.ts +++ b/x-pack/plugins/integration_assistant/server/routes/build_integration_routes.ts @@ -25,6 +25,13 @@ export function registerIntegrationBuilderRoutes( .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because the privileges are not defined yet.', + }, + }, validate: { request: { body: buildRouteValidationWithZod(BuildIntegrationRequestBody), diff --git a/x-pack/plugins/integration_assistant/server/routes/categorization_routes.ts b/x-pack/plugins/integration_assistant/server/routes/categorization_routes.ts index 10d72b92563fe..5f63ed9c7bf3c 100644 --- a/x-pack/plugins/integration_assistant/server/routes/categorization_routes.ts +++ b/x-pack/plugins/integration_assistant/server/routes/categorization_routes.ts @@ -40,6 +40,13 @@ export function registerCategorizationRoutes( .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because the privileges are not defined yet.', + }, + }, validate: { request: { body: buildRouteValidationWithZod(CategorizationRequestBody), diff --git a/x-pack/plugins/integration_assistant/server/routes/cel_routes.ts b/x-pack/plugins/integration_assistant/server/routes/cel_routes.ts index 5f417bbc0aec9..9ce16c3909119 100644 --- a/x-pack/plugins/integration_assistant/server/routes/cel_routes.ts +++ b/x-pack/plugins/integration_assistant/server/routes/cel_routes.ts @@ -32,6 +32,13 @@ export function registerCelInputRoutes(router: IRouter { + if (e.key === keys.ESCAPE) { + closeFlyout?.(); + setIsInlineFlyoutVisible(false); + } + }; + if (isLoading) return null; // Example is the Discover editing where we dont want to render the text based editor on the panel, neither the suggestions (for now) if (!canEditTextBasedQuery && hidesSuggestions) { return ( - - - + <> + {isInlineFlyoutVisible && } + + + + ); } return ( <> + {isInlineFlyoutVisible && } { expect((suggestions[0].state.layers[0] as XYDataLayerConfig).seriesType).toEqual('line'); }); - test('suggests line if changeType is initial and date column is involved', () => { + test('suggests bar if changeType is initial and date column is involved', () => { const currentState: XYState = { legend: { isVisible: true, position: 'bottom' }, valueLabels: 'hide', @@ -885,8 +885,8 @@ describe('xy_suggestions', () => { expect(suggestions).toHaveLength(1); expect(suggestions[0].hide).toEqual(false); - expect(suggestions[0].state.preferredSeriesType).toEqual('line'); - expect((suggestions[0].state.layers[0] as XYDataLayerConfig).seriesType).toEqual('line'); + expect(suggestions[0].state.preferredSeriesType).toEqual('bar_stacked'); + expect((suggestions[0].state.layers[0] as XYDataLayerConfig).seriesType).toEqual('bar_stacked'); }); test('makes a visible seriesType suggestion for unchanged table without split', () => { diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.ts b/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.ts index 5efaf4d8c949e..f13bcc57e3c84 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.ts +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_suggestions.ts @@ -233,9 +233,6 @@ function getSuggestionsForLayer({ allowMixed, }; - if (changeType === 'initial' && xValue?.operation.dataType === 'date') { - return buildSuggestion({ ...options, seriesType: 'line' }); - } // handles the simplest cases, acting as a chart switcher if (!currentState && changeType === 'unchanged') { // Chart switcher needs to include every chart type diff --git a/x-pack/plugins/ml/server/routes/system.ts b/x-pack/plugins/ml/server/routes/system.ts index bf4fa3161f5b9..b6765c4b5f16c 100644 --- a/x-pack/plugins/ml/server/routes/system.ts +++ b/x-pack/plugins/ml/server/routes/system.ts @@ -97,6 +97,13 @@ export function systemRoutes( .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: false, }, routeGuard.basicLicenseAPIGuard(async ({ mlClient, request, response }) => { diff --git a/x-pack/plugins/observability_solution/apm/common/entities/types.ts b/x-pack/plugins/observability_solution/apm/common/entities/types.ts deleted file mode 100644 index 9775b1e32eae6..0000000000000 --- a/x-pack/plugins/observability_solution/apm/common/entities/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export enum EntityDataStreamType { - METRICS = 'metrics', - TRACES = 'traces', - LOGS = 'logs', -} diff --git a/x-pack/plugins/observability_solution/apm/common/es_fields/entities.ts b/x-pack/plugins/observability_solution/apm/common/es_fields/entities.ts deleted file mode 100644 index 28e4a3ec79165..0000000000000 --- a/x-pack/plugins/observability_solution/apm/common/es_fields/entities.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const ENTITY_METRICS_LATENCY = 'entity.metrics.latency'; -export const ENTITY_METRICS_LOG_ERROR_RATE = 'entity.metrics.logErrorRate'; -export const ENTITY_METRICS_LOG_RATE = 'entity.metrics.logRate'; -export const ENTITY_METRICS_THROUGHPUT = 'entity.metrics.throughput'; -export const ENTITY_METRICS_FAILED_TRANSACTION_RATE = 'entity.metrics.failedTransactionRate'; diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/metrics/static_dashboard/dashboards/dashboard_catalog.ts b/x-pack/plugins/observability_solution/apm/public/components/app/metrics/static_dashboard/dashboards/dashboard_catalog.ts index 2d3ea5fded80b..6f81ef6db535b 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/app/metrics/static_dashboard/dashboards/dashboard_catalog.ts +++ b/x-pack/plugins/observability_solution/apm/public/components/app/metrics/static_dashboard/dashboards/dashboard_catalog.ts @@ -12,6 +12,9 @@ export const AGENT_NAME_DASHBOARD_FILE_MAPPING: Record = { 'opentelemetry/java': 'opentelemetry_java', 'opentelemetry/java/opentelemetry-java-instrumentation': 'opentelemetry_java', 'opentelemetry/java/elastic': 'opentelemetry_java', + 'opentelemetry/dotnet': 'opentelemetry_dotnet', + 'opentelemetry/dotnet/opentelemetry-dotnet-instrumentation': 'opentelemetry_dotnet', + 'opentelemetry/dotnet/elastic': 'opentelemetry_dotnet', }; /** @@ -44,6 +47,12 @@ export async function loadDashboardFile(filename: string): Promise { './opentelemetry_java.json' ); } + case 'opentelemetry_dotnet': { + return import( + /* webpackChunkName: "lazyOtelDotnetDashboard" */ + './opentelemetry_dotnet.json' + ); + } default: { break; } diff --git a/x-pack/plugins/observability_solution/apm/public/components/app/metrics/static_dashboard/dashboards/opentelemetry_dotnet.json b/x-pack/plugins/observability_solution/apm/public/components/app/metrics/static_dashboard/dashboards/opentelemetry_dotnet.json new file mode 100644 index 0000000000000..2862bf0a586d7 --- /dev/null +++ b/x-pack/plugins/observability_solution/apm/public/components/app/metrics/static_dashboard/dashboards/opentelemetry_dotnet.json @@ -0,0 +1 @@ +{"attributes":{"controlGroupInput":{"chainingSystem":"HIERARCHICAL","controlStyle":"oneLine","ignoreParentSettingsJSON":"{\"ignoreFilters\":false,\"ignoreQuery\":false,\"ignoreTimerange\":false,\"ignoreValidations\":false}","panelsJSON":"{\"2be66584-9de4-4a36-ba54-bfdd1b4ccfb4\":{\"type\":\"optionsListControl\",\"order\":0,\"grow\":true,\"width\":\"medium\",\"explicitInput\":{\"id\":\"2be66584-9de4-4a36-ba54-bfdd1b4ccfb4\",\"fieldName\":\"service.node.name\",\"title\":\"Instance\",\"grow\":true,\"width\":\"medium\",\"searchTechnique\":\"prefix\",\"selectedOptions\":[],\"existsSelected\":true,\"enhancements\":{}}}}"},"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"optionsJSON":"{\"useMargins\":true,\"syncColors\":false,\"syncCursor\":true,\"syncTooltips\":false,\"hidePanelTitles\":false}","panelsJSON":"[{\"type\":\"lens\",\"gridData\":{\"x\":0,\"y\":0,\"w\":48,\"h\":8,\"i\":\"ea9f86f0-ff73-4c92-9b93-41baebdcffab\"},\"panelIndex\":\"ea9f86f0-ff73-4c92-9b93-41baebdcffab\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"visualizationType\":\"lnsDatatable\",\"type\":\"lens\",\"references\":[{\"type\":\"index-pattern\",\"id\":\"APM_STATIC_DATA_VIEW_ID\",\"name\":\"indexpattern-datasource-layer-1ba88117-6e95-46e2-8667-e0bc15145182\"}],\"state\":{\"visualization\":{\"columns\":[{\"columnId\":\"d5553b2b-25e9-4b94-9697-f04885f4a067\",\"isTransposed\":false,\"isMetric\":false,\"alignment\":\"left\",\"summaryRow\":\"none\",\"width\":547.5714285714286},{\"columnId\":\"b3da070f-3463-4990-b257-40ac399bec87\",\"isTransposed\":false,\"isMetric\":true,\"colorMode\":\"none\",\"hidden\":false,\"alignment\":\"left\",\"summaryRow\":\"avg\",\"width\":135.73809523809527},{\"columnId\":\"a7f6a205-1e8f-4b64-b745-efe20c2c6545\",\"isTransposed\":false,\"isMetric\":true,\"alignment\":\"left\",\"summaryRow\":\"sum\",\"width\":143.93809523809523},{\"columnId\":\"2bbcd9e9-15ff-42c1-98a8-65a5b9b4e4c5\",\"isTransposed\":false,\"isMetric\":true,\"alignment\":\"left\",\"summaryRow\":\"sum\",\"width\":142.68809523809523},{\"columnId\":\"9f3d67e3-0513-468e-b9b2-6d8780dac3e0\",\"isTransposed\":false,\"isMetric\":true,\"alignment\":\"left\",\"summaryRow\":\"sum\",\"width\":163.18809523809523},{\"columnId\":\"21bdcb2d-cee4-4dd9-84cb-5031f073bf85\",\"isTransposed\":false,\"isMetric\":true,\"alignment\":\"left\",\"width\":183.68809523809523}],\"layerId\":\"1ba88117-6e95-46e2-8667-e0bc15145182\",\"layerType\":\"data\",\"paging\":{\"size\":10,\"enabled\":true}},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[],\"datasourceStates\":{\"formBased\":{\"layers\":{\"1ba88117-6e95-46e2-8667-e0bc15145182\":{\"columns\":{\"d5553b2b-25e9-4b94-9697-f04885f4a067\":{\"label\":\"Host + Service instance\",\"dataType\":\"string\",\"operationType\":\"terms\",\"scale\":\"ordinal\",\"sourceField\":\"host.name\",\"isBucketed\":true,\"params\":{\"size\":25,\"orderBy\":{\"type\":\"alphabetical\",\"fallback\":false},\"orderDirection\":\"asc\",\"otherBucket\":true,\"missingBucket\":false,\"parentFormat\":{\"id\":\"multi_terms\"},\"include\":[],\"exclude\":[],\"includeIsRegex\":false,\"excludeIsRegex\":false,\"secondaryFields\":[\"service.node.name\"]},\"customLabel\":true},\"b3da070f-3463-4990-b257-40ac399bec87\":{\"label\":\"Memory usage\",\"dataType\":\"number\",\"operationType\":\"last_value\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"process.memory.usage\",\"filter\":{\"query\":\"\\\"process.memory.usage\\\": *\",\"language\":\"kuery\"},\"params\":{\"sortField\":\"@timestamp\",\"format\":{\"id\":\"bytes\",\"params\":{\"decimals\":0}}},\"customLabel\":true},\"a7f6a205-1e8f-4b64-b745-efe20c2c6545\":{\"label\":\"Gen 0 collections\",\"dataType\":\"number\",\"operationType\":\"last_value\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"process.runtime.dotnet.gc.collections.count\",\"filter\":{\"query\":\"\\\"process.runtime.dotnet.gc.collections.count\\\": * AND labels.generation : \\\"gen0\\\" \",\"language\":\"kuery\"},\"params\":{\"sortField\":\"@timestamp\"},\"customLabel\":true},\"2bbcd9e9-15ff-42c1-98a8-65a5b9b4e4c5\":{\"label\":\"Gen 1 collections\",\"dataType\":\"number\",\"operationType\":\"last_value\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"process.runtime.dotnet.gc.collections.count\",\"filter\":{\"query\":\"\\\"process.runtime.dotnet.gc.collections.count\\\": * AND labels.generation : \\\"gen1\\\" \",\"language\":\"kuery\"},\"params\":{\"sortField\":\"@timestamp\"},\"customLabel\":true},\"9f3d67e3-0513-468e-b9b2-6d8780dac3e0\":{\"label\":\"Gen 2 collections\",\"dataType\":\"number\",\"operationType\":\"last_value\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"process.runtime.dotnet.gc.collections.count\",\"filter\":{\"query\":\"\\\"process.runtime.dotnet.gc.collections.count\\\": * AND labels.generation : \\\"gen2\\\" \",\"language\":\"kuery\"},\"params\":{\"sortField\":\"@timestamp\"},\"customLabel\":true},\"21bdcb2d-cee4-4dd9-84cb-5031f073bf85\":{\"label\":\"Managed threads\",\"dataType\":\"number\",\"operationType\":\"last_value\",\"isBucketed\":false,\"scale\":\"ratio\",\"sourceField\":\"process.runtime.dotnet.thread_pool.threads.count\",\"filter\":{\"query\":\"\\\"process.runtime.dotnet.thread_pool.threads.count\\\": *\",\"language\":\"kuery\"},\"params\":{\"sortField\":\"@timestamp\"},\"customLabel\":true}},\"columnOrder\":[\"d5553b2b-25e9-4b94-9697-f04885f4a067\",\"21bdcb2d-cee4-4dd9-84cb-5031f073bf85\",\"b3da070f-3463-4990-b257-40ac399bec87\",\"a7f6a205-1e8f-4b64-b745-efe20c2c6545\",\"2bbcd9e9-15ff-42c1-98a8-65a5b9b4e4c5\",\"9f3d67e3-0513-468e-b9b2-6d8780dac3e0\"],\"sampling\":1,\"ignoreGlobalFilters\":false,\"incompleteColumns\":{},\"indexPatternId\":\"apm_static_data_view_id_default\"}},\"currentIndexPatternId\":\"apm_static_data_view_id_default\"},\"indexpattern\":{\"layers\":{}},\"textBased\":{\"layers\":{}}},\"internalReferences\":[],\"adHocDataViews\":{}}},\"hidePanelTitles\":true,\"enhancements\":{}},\"title\":\"\"},{\"type\":\"lens\",\"gridData\":{\"x\":0,\"y\":8,\"w\":25,\"h\":16,\"i\":\"d0991248-2fad-4f28-bedc-b8723bc45a81\"},\"panelIndex\":\"d0991248-2fad-4f28-bedc-b8723bc45a81\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"description\":\"The amount of physical memory allocated for this process.\",\"visualizationType\":\"lnsXY\",\"type\":\"lens\",\"references\":[{\"type\":\"index-pattern\",\"id\":\"APM_STATIC_DATA_VIEW_ID\",\"name\":\"indexpattern-datasource-layer-961b1efd-6f0d-41e4-a72b-5d66237d212b\"}],\"state\":{\"visualization\":{\"legend\":{\"isVisible\":true,\"position\":\"bottom\",\"showSingleSeries\":true},\"valueLabels\":\"hide\",\"fittingFunction\":\"None\",\"yTitle\":\"Allocated physical memory\",\"axisTitlesVisibilitySettings\":{\"x\":false,\"yLeft\":false,\"yRight\":true},\"tickLabelsVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"labelsOrientation\":{\"x\":0,\"yLeft\":0,\"yRight\":0},\"gridlinesVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"preferredSeriesType\":\"bar_stacked\",\"layers\":[{\"layerId\":\"961b1efd-6f0d-41e4-a72b-5d66237d212b\",\"accessors\":[\"81968f1a-1c2f-46cb-8276-3dca900342e9\",\"54c0cda3-76f3-4b75-9fe1-2265fa68993c\"],\"position\":\"top\",\"seriesType\":\"line\",\"showGridlines\":false,\"layerType\":\"data\",\"colorMapping\":{\"assignments\":[],\"specialAssignments\":[{\"rule\":{\"type\":\"other\"},\"color\":{\"type\":\"loop\"},\"touched\":false}],\"paletteId\":\"eui_amsterdam_color_blind\",\"colorMode\":{\"type\":\"categorical\"}},\"xAccessor\":\"2405efa8-e18d-426f-822f-3a4551bf97d2\",\"yConfig\":[]}]},\"query\":{\"query\":\"agent.name: \\\"opentelemetry/dotnet\\\" \",\"language\":\"kuery\"},\"filters\":[],\"datasourceStates\":{\"formBased\":{\"layers\":{\"961b1efd-6f0d-41e4-a72b-5d66237d212b\":{\"columns\":{\"2405efa8-e18d-426f-822f-3a4551bf97d2\":{\"label\":\"@timestamp\",\"dataType\":\"date\",\"operationType\":\"date_histogram\",\"sourceField\":\"@timestamp\",\"isBucketed\":true,\"scale\":\"interval\",\"params\":{\"interval\":\"auto\",\"includeEmptyRows\":true,\"dropPartials\":false}},\"81968f1a-1c2f-46cb-8276-3dca900342e9\":{\"label\":\"Average\",\"dataType\":\"number\",\"operationType\":\"average\",\"sourceField\":\"process.memory.usage\",\"isBucketed\":false,\"scale\":\"ratio\",\"params\":{\"format\":{\"id\":\"bytes\",\"params\":{\"decimals\":0}},\"emptyAsNull\":true},\"customLabel\":true},\"54c0cda3-76f3-4b75-9fe1-2265fa68993c\":{\"label\":\"Max\",\"dataType\":\"number\",\"operationType\":\"max\",\"sourceField\":\"process.memory.usage\",\"isBucketed\":false,\"scale\":\"ratio\",\"params\":{\"emptyAsNull\":true,\"format\":{\"id\":\"bytes\",\"params\":{\"decimals\":0}}},\"customLabel\":true}},\"columnOrder\":[\"2405efa8-e18d-426f-822f-3a4551bf97d2\",\"81968f1a-1c2f-46cb-8276-3dca900342e9\",\"54c0cda3-76f3-4b75-9fe1-2265fa68993c\"],\"incompleteColumns\":{},\"sampling\":1,\"indexPatternId\":\"apm_static_data_view_id_default\"}},\"currentIndexPatternId\":\"apm_static_data_view_id_default\"},\"indexpattern\":{\"layers\":{}},\"textBased\":{\"layers\":{}}},\"internalReferences\":[],\"adHocDataViews\":{}}},\"description\":\"The amount of physical memory allocated to the .NET process.\",\"enhancements\":{}},\"title\":\"Allocated physical memory\"},{\"type\":\"lens\",\"gridData\":{\"x\":25,\"y\":8,\"w\":23,\"h\":16,\"i\":\"0bf63f9e-8797-4249-85f7-9407c165f732\"},\"panelIndex\":\"0bf63f9e-8797-4249-85f7-9407c165f732\",\"embeddableConfig\":{\"attributes\":{\"title\":\"\",\"visualizationType\":\"lnsXY\",\"type\":\"lens\",\"references\":[{\"type\":\"index-pattern\",\"id\":\"APM_STATIC_DATA_VIEW_ID\",\"name\":\"indexpattern-datasource-layer-eb4e02de-8962-40fa-9e75-ff25862ca5f3\"}],\"state\":{\"visualization\":{\"legend\":{\"isVisible\":true,\"position\":\"right\",\"maxLines\":1},\"valueLabels\":\"hide\",\"fittingFunction\":\"None\",\"axisTitlesVisibilitySettings\":{\"x\":false,\"yLeft\":false,\"yRight\":true},\"tickLabelsVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"labelsOrientation\":{\"x\":0,\"yLeft\":0,\"yRight\":0},\"gridlinesVisibilitySettings\":{\"x\":true,\"yLeft\":true,\"yRight\":true},\"preferredSeriesType\":\"line\",\"layers\":[{\"layerId\":\"eb4e02de-8962-40fa-9e75-ff25862ca5f3\",\"accessors\":[\"cced3ff5-cfa3-4804-93be-c8d893114e93\",\"211c2cbb-033a-454b-b379-186b8d7b247e\",\"5ac14ba1-f6d4-4015-96d1-aeaa3ed63aec\",\"938252b1-14ec-4a64-b3e5-108e096f116b\",\"1e106c40-c845-4368-baaa-4057e1d29d92\"],\"position\":\"top\",\"seriesType\":\"line\",\"showGridlines\":false,\"layerType\":\"data\",\"colorMapping\":{\"assignments\":[],\"specialAssignments\":[{\"rule\":{\"type\":\"other\"},\"color\":{\"type\":\"loop\"},\"touched\":false}],\"paletteId\":\"eui_amsterdam_color_blind\",\"colorMode\":{\"type\":\"categorical\"}},\"xAccessor\":\"cb7bae9c-fdc5-44a8-8ee8-c0762595511c\"}]},\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filters\":[],\"datasourceStates\":{\"formBased\":{\"layers\":{\"eb4e02de-8962-40fa-9e75-ff25862ca5f3\":{\"columns\":{\"cb7bae9c-fdc5-44a8-8ee8-c0762595511c\":{\"label\":\"@timestamp\",\"dataType\":\"date\",\"operationType\":\"date_histogram\",\"sourceField\":\"@timestamp\",\"isBucketed\":true,\"scale\":\"interval\",\"params\":{\"interval\":\"auto\",\"includeEmptyRows\":true,\"dropPartials\":false}},\"cced3ff5-cfa3-4804-93be-c8d893114e93\":{\"label\":\"Gen 0\",\"dataType\":\"number\",\"operationType\":\"average\",\"sourceField\":\"process.runtime.dotnet.gc.heap.size\",\"isBucketed\":false,\"scale\":\"ratio\",\"filter\":{\"query\":\"labels.generation : \\\"gen0\\\" \",\"language\":\"kuery\"},\"params\":{\"format\":{\"id\":\"bytes\",\"params\":{\"decimals\":2}},\"emptyAsNull\":true},\"customLabel\":true},\"211c2cbb-033a-454b-b379-186b8d7b247e\":{\"label\":\"Gen 1\",\"dataType\":\"number\",\"operationType\":\"average\",\"sourceField\":\"process.runtime.dotnet.gc.heap.size\",\"isBucketed\":false,\"scale\":\"ratio\",\"filter\":{\"query\":\"labels.generation : \\\"gen1\\\" \",\"language\":\"kuery\"},\"params\":{\"emptyAsNull\":true,\"format\":{\"id\":\"bytes\",\"params\":{\"decimals\":2}}},\"customLabel\":true},\"5ac14ba1-f6d4-4015-96d1-aeaa3ed63aec\":{\"label\":\"Gen 2\",\"dataType\":\"number\",\"operationType\":\"average\",\"sourceField\":\"process.runtime.dotnet.gc.heap.size\",\"isBucketed\":false,\"scale\":\"ratio\",\"filter\":{\"query\":\"labels.generation : \\\"gen2\\\" \",\"language\":\"kuery\"},\"params\":{\"emptyAsNull\":true,\"format\":{\"id\":\"bytes\",\"params\":{\"decimals\":2}}},\"customLabel\":true},\"938252b1-14ec-4a64-b3e5-108e096f116b\":{\"label\":\"LOH\",\"dataType\":\"number\",\"operationType\":\"average\",\"sourceField\":\"process.runtime.dotnet.gc.heap.size\",\"isBucketed\":false,\"scale\":\"ratio\",\"filter\":{\"query\":\"labels.generation:\\\"loh\\\" \",\"language\":\"kuery\"},\"params\":{\"emptyAsNull\":true,\"format\":{\"id\":\"bytes\",\"params\":{\"decimals\":2}}},\"customLabel\":true},\"1e106c40-c845-4368-baaa-4057e1d29d92\":{\"label\":\"POH\",\"dataType\":\"number\",\"operationType\":\"median\",\"sourceField\":\"process.runtime.dotnet.gc.heap.size\",\"isBucketed\":false,\"scale\":\"ratio\",\"filter\":{\"query\":\"labels.generation : \\\"poh\\\" \",\"language\":\"kuery\"},\"params\":{\"emptyAsNull\":true,\"format\":{\"id\":\"bytes\",\"params\":{\"decimals\":2}}},\"customLabel\":true}},\"columnOrder\":[\"cb7bae9c-fdc5-44a8-8ee8-c0762595511c\",\"cced3ff5-cfa3-4804-93be-c8d893114e93\",\"211c2cbb-033a-454b-b379-186b8d7b247e\",\"5ac14ba1-f6d4-4015-96d1-aeaa3ed63aec\",\"938252b1-14ec-4a64-b3e5-108e096f116b\",\"1e106c40-c845-4368-baaa-4057e1d29d92\"],\"incompleteColumns\":{},\"sampling\":1,\"indexPatternId\":\"apm_static_data_view_id_default\"}},\"currentIndexPatternId\":\"apm_static_data_view_id_default\"},\"indexpattern\":{\"layers\":{}},\"textBased\":{\"layers\":{}}},\"internalReferences\":[],\"adHocDataViews\":{}}},\"enhancements\":{}},\"title\":\"Average GC heap size by generation\"}]","timeRestore":false,"title":".NET OpenTelemetry Runtime Metrics","version":1},"coreMigrationVersion":"8.8.0","created_at":"2024-05-17T13:46:01.942Z","id":"c65be603-2c73-4417-972c-033586a56102","managed":false,"references":[{"id":"apm_static_data_view_id_default","name":"ea9f86f0-ff73-4c92-9b93-41baebdcffab:indexpattern-datasource-layer-1ba88117-6e95-46e2-8667-e0bc15145182","type":"index-pattern"},{"id":"APM_STATIC_DATA_VIEW_ID","name":"d0991248-2fad-4f28-bedc-b8723bc45a81:indexpattern-datasource-layer-961b1efd-6f0d-41e4-a72b-5d66237d212b","type":"index-pattern"},{"id":"APM_STATIC_DATA_VIEW_ID","name":"0bf63f9e-8797-4249-85f7-9407c165f732:indexpattern-datasource-layer-eb4e02de-8962-40fa-9e75-ff25862ca5f3","type":"index-pattern"},{"id":"APM_STATIC_DATA_VIEW_ID","name":"controlGroup_2be66584-9de4-4a36-ba54-bfdd1b4ccfb4:optionsListDataView","type":"index-pattern"}],"type":"dashboard","typeMigrationVersion":"8.9.0","updated_at":"2024-05-17T13:46:01.942Z","version":"WzM0NTMsN10="} \ No newline at end of file diff --git a/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_service_template/index.tsx b/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_service_template/index.tsx index 0e095694cd538..6c2fdaea96687 100644 --- a/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_service_template/index.tsx +++ b/x-pack/plugins/observability_solution/apm/public/components/routing/templates/apm_service_template/index.tsx @@ -8,7 +8,6 @@ import { EuiFlexGroup, EuiFlexItem, EuiLoadingLogo, EuiSpacer, EuiTitle } from '@elastic/eui'; import React from 'react'; import { useHistory, useLocation } from 'react-router-dom'; -import { isLogsOnlySignal } from '../../../../utils/get_signal_type'; import { isMobileAgentName } from '../../../../../common/agent_name'; import { ApmServiceContextProvider } from '../../../../context/apm_service/apm_service_context'; import { useApmServiceContext } from '../../../../context/apm_service/use_apm_service_context'; @@ -55,7 +54,7 @@ function TemplateWithContext({ title, children, selectedTab, searchBarOptions }: const tabs = useTabs({ selectedTab }); - const { agentName, serviceAgentStatus, serviceEntitySummary } = useApmServiceContext(); + const { agentName, serviceAgentStatus } = useApmServiceContext(); const isPendingServiceAgent = !agentName && isPending(serviceAgentStatus); @@ -76,9 +75,6 @@ function TemplateWithContext({ title, children, selectedTab, searchBarOptions }: }); } - const hasLogsOnlySignal = - serviceEntitySummary?.dataStreamTypes && isLogsOnlySignal(serviceEntitySummary.dataStreamTypes); - return ( ) : ( <> - {!hasLogsOnlySignal && } + {children} diff --git a/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx b/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx index 9d5583b0ecf4c..51749d8095481 100644 --- a/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx +++ b/x-pack/plugins/observability_solution/infra/public/apps/logs_app.tsx @@ -6,19 +6,13 @@ */ import { History } from 'history'; -import { AppStatus, CoreStart } from '@kbn/core/public'; -import React, { useMemo } from 'react'; +import { CoreStart } from '@kbn/core/public'; +import React from 'react'; import ReactDOM from 'react-dom'; import { Router, Routes, Route } from '@kbn/shared-ux-router'; import { AppMountParameters } from '@kbn/core/public'; import { Storage } from '@kbn/kibana-utils-plugin/public'; -import { - AllDatasetsLocatorParams, - ALL_DATASETS_LOCATOR_ID, - OBSERVABILITY_LOGS_EXPLORER_APP_ID, -} from '@kbn/deeplinks-observability'; -import useObservable from 'react-use/lib/useObservable'; -import { map } from 'rxjs'; +import { AllDatasetsLocatorParams, ALL_DATASETS_LOCATOR_ID } from '@kbn/deeplinks-observability'; import { LinkToLogsPage } from '../pages/link_to/link_to_logs'; import { LogsPage } from '../pages/logs'; import { InfraClientStartDeps, InfraClientStartExports } from '../types'; @@ -30,6 +24,7 @@ export const renderApp = ( core: CoreStart, plugins: InfraClientStartDeps, pluginStart: InfraClientStartExports, + isLogsExplorerAccessible: boolean, { element, history, setHeaderActionMenu, theme$ }: AppMountParameters ) => { const storage = new Storage(window.localStorage); @@ -45,6 +40,7 @@ export const renderApp = ( pluginStart={pluginStart} setHeaderActionMenu={setHeaderActionMenu} theme$={theme$} + isLogsExplorerAccessible={isLogsExplorerAccessible} />, element ); @@ -62,24 +58,19 @@ const LogsApp: React.FC<{ setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; storage: Storage; theme$: AppMountParameters['theme$']; -}> = ({ core, history, pluginStart, plugins, setHeaderActionMenu, storage, theme$ }) => { + isLogsExplorerAccessible: boolean; +}> = ({ + core, + history, + pluginStart, + plugins, + setHeaderActionMenu, + storage, + theme$, + isLogsExplorerAccessible, +}) => { const { logs } = core.application.capabilities; - const isLogsExplorerAppAccessible = useObservable( - useMemo( - () => - core.application.applications$.pipe( - map( - (apps) => - (apps.get(OBSERVABILITY_LOGS_EXPLORER_APP_ID)?.status ?? AppStatus.inaccessible) === - AppStatus.accessible - ) - ), - [core.application.applications$] - ), - false - ); - return ( - {isLogsExplorerAppAccessible && ( + {isLogsExplorerAccessible && ( { const { request$ } = useRequestObservable(); const { isActiveTab } = useTabSwitcherContext(); const { dataStreams, status: dataStreamsStatus } = useEntitySummary({ - entityType: EntityType.HOST, + entityType: ENTITY_TYPES.HOST, entityId: asset.name, }); const addMetricsCalloutId: AddMetricsCalloutKey = 'hostProcesses'; diff --git a/x-pack/plugins/observability_solution/infra/public/plugin.ts b/x-pack/plugins/observability_solution/infra/public/plugin.ts index 0e88b514c51ec..c8217794acf70 100644 --- a/x-pack/plugins/observability_solution/infra/public/plugin.ts +++ b/x-pack/plugins/observability_solution/infra/public/plugin.ts @@ -29,6 +29,7 @@ import { of, switchMap, map, + firstValueFrom, } from 'rxjs'; import type { EmbeddableApiContext } from '@kbn/presentation-publishing'; import { apiCanAddNewPanel } from '@kbn/presentation-containers'; @@ -231,8 +232,12 @@ export class Plugin implements InfraClientPluginClass { // mount callback should not use setup dependencies, get start dependencies instead const [coreStart, plugins, pluginStart] = await core.getStartServices(); + const isLogsExplorerAccessible = await firstValueFrom( + getLogsExplorerAccessible$(coreStart.application) + ); + const { renderApp } = await import('./apps/logs_app'); - return renderApp(coreStart, plugins, pluginStart, params); + return renderApp(coreStart, plugins, pluginStart, isLogsExplorerAccessible, params); }, }); } diff --git a/x-pack/plugins/observability_solution/infra/server/routes/entities/index.ts b/x-pack/plugins/observability_solution/infra/server/routes/entities/index.ts index cb169f83f171d..1a8707678e8f7 100644 --- a/x-pack/plugins/observability_solution/infra/server/routes/entities/index.ts +++ b/x-pack/plugins/observability_solution/infra/server/routes/entities/index.ts @@ -9,6 +9,7 @@ import { schema } from '@kbn/config-schema'; import { METRICS_APP_ID } from '@kbn/deeplinks-observability/constants'; import { entityCentricExperience } from '@kbn/observability-plugin/common'; import { createObservabilityEsClient } from '@kbn/observability-utils/es/client/create_observability_es_client'; +import { ENTITY_TYPES } from '@kbn/observability-shared-plugin/common'; import { getInfraMetricsClient } from '../../lib/helpers/get_infra_metrics_client'; import { InfraBackendLibs } from '../../lib/infra_types'; import { getDataStreamTypes } from './get_data_stream_types'; @@ -22,7 +23,10 @@ export const initEntitiesConfigurationRoutes = (libs: InfraBackendLibs) => { path: '/api/infra/entities/{entityType}/{entityId}/summary', validate: { params: schema.object({ - entityType: schema.oneOf([schema.literal('host'), schema.literal('container')]), + entityType: schema.oneOf([ + schema.literal(ENTITY_TYPES.HOST), + schema.literal(ENTITY_TYPES.CONTAINER), + ]), entityId: schema.string(), }), }, diff --git a/x-pack/plugins/observability_solution/inventory/common/entities.ts b/x-pack/plugins/observability_solution/inventory/common/entities.ts index e5bd12d252767..f686490b90bfc 100644 --- a/x-pack/plugins/observability_solution/inventory/common/entities.ts +++ b/x-pack/plugins/observability_solution/inventory/common/entities.ts @@ -4,7 +4,8 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { ENTITY_LATEST, entitiesAliasPattern } from '@kbn/entities-schema'; +import { z } from '@kbn/zod'; +import { ENTITY_LATEST, entitiesAliasPattern, entityLatestSchema } from '@kbn/entities-schema'; import { ENTITY_DEFINITION_ID, ENTITY_DISPLAY_NAME, @@ -117,3 +118,7 @@ export type EntityGroup = { } & { [key: string]: any; }; + +export type InventoryEntityLatest = z.infer & { + alertsCount?: number; +}; diff --git a/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts b/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts deleted file mode 100644 index 8703e995b4446..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.test.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { - ENTITY_DEFINITION_ID, - ENTITY_DISPLAY_NAME, - ENTITY_ID, - ENTITY_IDENTITY_FIELDS, - ENTITY_LAST_SEEN, -} from '@kbn/observability-shared-plugin/common'; -import type { Entity } from '../entities'; -import { parseIdentityFieldValuesToKql } from './parse_identity_field_values_to_kql'; - -const commonEntityFields = { - [ENTITY_LAST_SEEN]: '2023-10-09T00:00:00Z', - [ENTITY_ID]: '1', - [ENTITY_DISPLAY_NAME]: 'entity_name', - [ENTITY_DEFINITION_ID]: 'entity_definition_id', - alertCount: 3, -}; - -describe('parseIdentityFieldValuesToKql', () => { - it('should return the value when identityFields is a single string', () => { - const entity: Entity = { - 'agent.name': 'node', - [ENTITY_IDENTITY_FIELDS]: 'service.name', - 'service.name': 'my-service', - 'entity.type': 'service', - ...commonEntityFields, - }; - - const result = parseIdentityFieldValuesToKql({ entity }); - expect(result).toEqual('service.name: "my-service"'); - }); - - it('should return values when identityFields is an array of strings', () => { - const entity: Entity = { - 'agent.name': 'node', - [ENTITY_IDENTITY_FIELDS]: ['service.name', 'service.environment'], - 'service.name': 'my-service', - 'entity.type': 'service', - 'service.environment': 'staging', - ...commonEntityFields, - }; - - const result = parseIdentityFieldValuesToKql({ entity }); - expect(result).toEqual('service.name: "my-service" AND service.environment: "staging"'); - }); - - it('should return an empty string if identityFields is empty string', () => { - const entity: Entity = { - 'agent.name': 'node', - [ENTITY_IDENTITY_FIELDS]: '', - 'service.name': 'my-service', - 'entity.type': 'service', - ...commonEntityFields, - }; - - const result = parseIdentityFieldValuesToKql({ entity }); - expect(result).toEqual(''); - }); - it('should return an empty array if identityFields is empty array', () => { - const entity: Entity = { - 'agent.name': 'node', - [ENTITY_IDENTITY_FIELDS]: [], - 'service.name': 'my-service', - 'entity.type': 'service', - ...commonEntityFields, - }; - - const result = parseIdentityFieldValuesToKql({ entity }); - expect(result).toEqual(''); - }); - - it('should ignore fields that are not present in the entity', () => { - const entity: Entity = { - [ENTITY_IDENTITY_FIELDS]: ['host.name', 'foo.bar'], - 'host.name': 'my-host', - 'entity.type': 'host', - 'cloud.provider': null, - ...commonEntityFields, - }; - - const result = parseIdentityFieldValuesToKql({ entity }); - expect(result).toEqual('host.name: "my-host"'); - }); -}); diff --git a/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.ts b/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.ts deleted file mode 100644 index 2e3f3dadd4109..0000000000000 --- a/x-pack/plugins/observability_solution/inventory/common/utils/parse_identity_field_values_to_kql.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { ENTITY_IDENTITY_FIELDS } from '@kbn/observability-shared-plugin/common'; -import { Entity } from '../entities'; - -type Operator = 'AND'; -export function parseIdentityFieldValuesToKql({ - entity, - operator = 'AND', -}: { - entity: Entity; - operator?: Operator; -}) { - const mapping: string[] = []; - - const identityFields = entity[ENTITY_IDENTITY_FIELDS]; - - if (identityFields) { - const fields = [identityFields].flat(); - - fields.forEach((field) => { - if (field in entity) { - mapping.push(`${[field]}: "${entity[field as keyof Entity]}"`); - } - }); - } - - return mapping.join(` ${operator} `); -} diff --git a/x-pack/plugins/observability_solution/inventory/common/utils/unflatten_entity.ts b/x-pack/plugins/observability_solution/inventory/common/utils/unflatten_entity.ts new file mode 100644 index 0000000000000..758d185a5753b --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/common/utils/unflatten_entity.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { unflattenObject } from '@kbn/observability-utils/object/unflatten_object'; +import type { Entity, InventoryEntityLatest } from '../entities'; + +export function unflattenEntity(entity: Entity) { + return unflattenObject(entity) as InventoryEntityLatest; +} diff --git a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx index 60124e7813bc4..b5244cb29f7fc 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.test.tsx @@ -5,22 +5,35 @@ * 2.0. */ import React from 'react'; -import { type KibanaReactContextValue } from '@kbn/kibana-react-plugin/public'; import { render, screen } from '@testing-library/react'; import { AlertsBadge } from './alerts_badge'; -import * as useKibana from '../../hooks/use_kibana'; +import { useKibana } from '../../hooks/use_kibana'; import type { Entity } from '../../../common/entities'; +jest.mock('../../hooks/use_kibana'); +const useKibanaMock = useKibana as jest.Mock; + describe('AlertsBadge', () => { - jest.spyOn(useKibana, 'useKibana').mockReturnValue({ - services: { - http: { - basePath: { - prepend: (path: string) => path, + const mockAsKqlFilter = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + + useKibanaMock.mockReturnValue({ + services: { + http: { + basePath: { + prepend: (path: string) => path, + }, + }, + entityManager: { + entityClient: { + asKqlFilter: mockAsKqlFilter, + }, }, }, - }, - } as unknown as KibanaReactContextValue); + }); + }); afterAll(() => { jest.clearAllMocks(); @@ -38,9 +51,11 @@ describe('AlertsBadge', () => { 'cloud.provider': null, alertsCount: 1, }; + mockAsKqlFilter.mockReturnValue('host.name: foo'); + render(); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.getAttribute('href')).toEqual( - '/app/observability/alerts?_a=(kuery:\'host.name: "foo"\',status:active)' + "/app/observability/alerts?_a=(kuery:'host.name: foo',status:active)" ); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.textContent).toEqual('1'); }); @@ -57,9 +72,11 @@ describe('AlertsBadge', () => { 'cloud.provider': null, alertsCount: 5, }; + mockAsKqlFilter.mockReturnValue('service.name: bar'); + render(); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.getAttribute('href')).toEqual( - '/app/observability/alerts?_a=(kuery:\'service.name: "bar"\',status:active)' + "/app/observability/alerts?_a=(kuery:'service.name: bar',status:active)" ); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.textContent).toEqual('5'); }); @@ -77,9 +94,12 @@ describe('AlertsBadge', () => { 'cloud.provider': null, alertsCount: 2, }; + + mockAsKqlFilter.mockReturnValue('service.name: bar AND service.environment: prod'); + render(); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.getAttribute('href')).toEqual( - '/app/observability/alerts?_a=(kuery:\'service.name: "bar" AND service.environment: "prod"\',status:active)' + "/app/observability/alerts?_a=(kuery:'service.name: bar AND service.environment: prod',status:active)" ); expect(screen.queryByTestId('inventoryAlertsBadgeLink')?.textContent).toEqual('2'); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx index ba1b992ff62c1..a5845a7b42dcf 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/alerts_badge/alerts_badge.tsx @@ -8,20 +8,21 @@ import React from 'react'; import rison from '@kbn/rison'; import { EuiBadge, EuiToolTip } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { Entity } from '../../../common/entities'; +import type { Entity } from '../../../common/entities'; +import { unflattenEntity } from '../../../common/utils/unflatten_entity'; import { useKibana } from '../../hooks/use_kibana'; -import { parseIdentityFieldValuesToKql } from '../../../common/utils/parse_identity_field_values_to_kql'; export function AlertsBadge({ entity }: { entity: Entity }) { const { services: { http: { basePath }, + entityManager, }, } = useKibana(); const activeAlertsHref = basePath.prepend( `/app/observability/alerts?_a=${rison.encode({ - kuery: parseIdentityFieldValuesToKql({ entity }), + kuery: entityManager.entityClient.asKqlFilter(unflattenEntity(entity)), status: 'active', })}` ); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx index 2e4f0c319edfc..d5d08ed415a40 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/entity_name.test.tsx @@ -5,148 +5,65 @@ * 2.0. */ -import { type KibanaReactContextValue } from '@kbn/kibana-react-plugin/public'; -import * as useKibana from '../../../hooks/use_kibana'; -import { EntityName } from '.'; -import type { Entity } from '../../../../common/entities'; -import { render, screen } from '@testing-library/react'; import React from 'react'; -import { ASSET_DETAILS_LOCATOR_ID } from '@kbn/observability-shared-plugin/common/locators/infra/asset_details_locator'; +import { render, screen } from '@testing-library/react'; +import { EntityName } from '.'; +import { useDetailViewRedirect } from '../../../hooks/use_detail_view_redirect'; +import { Entity } from '../../../../common/entities'; +import { + ENTITY_DEFINITION_ID, + ENTITY_DISPLAY_NAME, + ENTITY_ID, + ENTITY_IDENTITY_FIELDS, + ENTITY_LAST_SEEN, + ENTITY_TYPE, +} from '@kbn/observability-shared-plugin/common'; + +jest.mock('../../../hooks/use_detail_view_redirect'); + +const useDetailViewRedirectMock = useDetailViewRedirect as jest.Mock; describe('EntityName', () => { - jest.spyOn(useKibana, 'useKibana').mockReturnValue({ - services: { - share: { - url: { - locators: { - get: (locatorId: string) => { - return { - getRedirectUrl: (params: { [key: string]: any }) => { - if (locatorId === ASSET_DETAILS_LOCATOR_ID) { - return `assets_url/${params.assetType}/${params.assetId}`; - } - return `services_url/${params.serviceName}?environment=${params.environment}`; - }, - }; - }, - }, - }, - }, - }, - } as unknown as KibanaReactContextValue); + const mockEntity: Entity = { + [ENTITY_LAST_SEEN]: '2023-10-09T00:00:00Z', + [ENTITY_ID]: '1', + [ENTITY_DISPLAY_NAME]: 'entity_name', + [ENTITY_DEFINITION_ID]: 'entity_definition_id', + [ENTITY_IDENTITY_FIELDS]: ['service.name', 'service.environment'], + [ENTITY_TYPE]: 'service', + }; - afterAll(() => { + beforeEach(() => { jest.clearAllMocks(); }); - it('returns host link', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'host', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'host.name', - 'host.name': 'foo', - 'entity.definition_id': 'host', - 'cloud.provider': null, - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'assets_url/host/foo' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); - }); + it('should render the entity name correctly', () => { + useDetailViewRedirectMock.mockReturnValue({ + getEntityRedirectUrl: jest.fn().mockReturnValue(null), + }); - it('returns container link', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'container', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'container.id', - 'container.id': 'foo', - 'entity.definition_id': 'container', - 'cloud.provider': null, - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'assets_url/container/foo' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); - }); + render(); - it('returns service link without environment', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'service', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'service.name', - 'service.name': 'foo', - 'entity.definition_id': 'service', - 'agent.name': 'bar', - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'services_url/foo?environment=undefined' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); + expect(screen.getByText('entity_name')).toBeInTheDocument(); }); - it('returns service link with environment', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'service', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'service.name', - 'service.name': 'foo', - 'entity.definition_id': 'service', - 'agent.name': 'bar', - 'service.environment': 'baz', - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'services_url/foo?environment=baz' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); - }); + it('should a link when getEntityRedirectUrl returns a URL', () => { + useDetailViewRedirectMock.mockReturnValue({ + getEntityRedirectUrl: jest.fn().mockReturnValue('http://foo.bar'), + }); - it('returns service link with first environment when it is an array', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'service', - 'entity.display_name': 'foo', - 'entity.identity_fields': 'service.name', - 'service.name': 'foo', - 'entity.definition_id': 'service', - 'agent.name': 'bar', - 'service.environment': ['baz', 'bar', 'foo'], - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'services_url/foo?environment=baz' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); + render(); + + expect(screen.getByRole('link')).toHaveAttribute('href', 'http://foo.bar'); }); - it('returns service link identity fields is an array', () => { - const entity: Entity = { - 'entity.last_seen_timestamp': 'foo', - 'entity.id': '1', - 'entity.type': 'service', - 'entity.display_name': 'foo', - 'entity.identity_fields': ['service.name', 'service.environment'], - 'service.name': 'foo', - 'entity.definition_id': 'service', - 'agent.name': 'bar', - 'service.environment': 'baz', - }; - render(); - expect(screen.queryByTestId('entityNameLink')?.getAttribute('href')).toEqual( - 'services_url/foo?environment=baz' - ); - expect(screen.queryByTestId('entityNameDisplayName')?.textContent).toEqual('foo'); + it('should not render a link when getEntityRedirectUrl returns null', () => { + useDetailViewRedirectMock.mockReturnValue({ + getEntityRedirectUrl: jest.fn().mockReturnValue(null), + }); + + render(); + + expect(screen.queryByRole('link')).not.toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/index.tsx index 982a616da8fda..e8db7013f8cb3 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entities_grid/entity_name/index.tsx @@ -6,19 +6,12 @@ */ import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui'; -import { - ASSET_DETAILS_LOCATOR_ID, - AssetDetailsLocatorParams, - ENTITY_DISPLAY_NAME, - ENTITY_IDENTITY_FIELDS, - ENTITY_TYPE, - SERVICE_ENVIRONMENT, - ServiceOverviewParams, -} from '@kbn/observability-shared-plugin/common'; import React, { useCallback } from 'react'; -import { Entity } from '../../../../common/entities'; +import { ENTITY_DISPLAY_NAME } from '@kbn/observability-shared-plugin/common'; import { useKibana } from '../../../hooks/use_kibana'; +import type { Entity } from '../../../../common/entities'; import { EntityIcon } from '../../entity_icon'; +import { useDetailViewRedirect } from '../../../hooks/use_detail_view_redirect'; interface EntityNameProps { entity: Entity; @@ -26,14 +19,12 @@ interface EntityNameProps { export function EntityName({ entity }: EntityNameProps) { const { - services: { telemetry, share }, + services: { telemetry }, } = useKibana(); - const assetDetailsLocator = - share?.url.locators.get(ASSET_DETAILS_LOCATOR_ID); + const { getEntityRedirectUrl } = useDetailViewRedirect(); - const serviceOverviewLocator = - share?.url.locators.get('serviceOverviewLocator'); + const href = getEntityRedirectUrl(entity); const handleLinkClick = useCallback(() => { telemetry.reportEntityViewClicked({ @@ -42,47 +33,25 @@ export function EntityName({ entity }: EntityNameProps) { }); }, [entity, telemetry]); - const getEntityRedirectUrl = useCallback(() => { - const type = entity[ENTITY_TYPE]; - // For service, host and container type there is only one identity field - const identityField = Array.isArray(entity[ENTITY_IDENTITY_FIELDS]) - ? entity[ENTITY_IDENTITY_FIELDS][0] - : entity[ENTITY_IDENTITY_FIELDS]; - const identityValue = entity[identityField]; - - switch (type) { - case 'host': - case 'container': - return assetDetailsLocator?.getRedirectUrl({ - assetId: identityValue, - assetType: type, - }); - - case 'service': - return serviceOverviewLocator?.getRedirectUrl({ - serviceName: identityValue, - environment: [entity[SERVICE_ENVIRONMENT] || undefined].flat()[0], - }); - } - }, [entity, assetDetailsLocator, serviceOverviewLocator]); + const entityName = ( + + + + + + + {entity[ENTITY_DISPLAY_NAME]} + + + + ); - return ( + return href ? ( // eslint-disable-next-line @elastic/eui/href-or-on-click - - - - - - - - {entity[ENTITY_DISPLAY_NAME]} - - - + + {entityName} + ) : ( + entityName ); } diff --git a/x-pack/plugins/observability_solution/inventory/public/components/entity_icon/index.tsx b/x-pack/plugins/observability_solution/inventory/public/components/entity_icon/index.tsx index a62f0026ddfa0..48b21779d2e38 100644 --- a/x-pack/plugins/observability_solution/inventory/public/components/entity_icon/index.tsx +++ b/x-pack/plugins/observability_solution/inventory/public/components/entity_icon/index.tsx @@ -6,7 +6,12 @@ */ import React from 'react'; -import { AGENT_NAME, CLOUD_PROVIDER, ENTITY_TYPE } from '@kbn/observability-shared-plugin/common'; +import { + AGENT_NAME, + CLOUD_PROVIDER, + ENTITY_TYPE, + ENTITY_TYPES, +} from '@kbn/observability-shared-plugin/common'; import { type CloudProvider, CloudProviderIcon, AgentIcon } from '@kbn/custom-icons'; import { EuiFlexGroup, EuiFlexItem, EuiIcon } from '@elastic/eui'; import type { AgentName } from '@kbn/elastic-agent-utils'; @@ -27,7 +32,7 @@ export function EntityIcon({ entity }: EntityIconProps) { const entityType = entity[ENTITY_TYPE]; const defaultIconSize = euiThemeVars.euiSizeL; - if (entityType === 'host' || entityType === 'container') { + if (entityType === ENTITY_TYPES.HOST || entityType === ENTITY_TYPES.CONTAINER) { const cloudProvider = getSingleValue( entity[CLOUD_PROVIDER] as NotNullableCloudProvider | NotNullableCloudProvider[] ); @@ -49,7 +54,7 @@ export function EntityIcon({ entity }: EntityIconProps) { ); } - if (entityType === 'service') { + if (entityType === ENTITY_TYPES.SERVICE) { const agentName = getSingleValue(entity[AGENT_NAME] as AgentName | AgentName[]); return ; } diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts new file mode 100644 index 0000000000000..cf4993f871880 --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.test.ts @@ -0,0 +1,170 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import { useDetailViewRedirect } from './use_detail_view_redirect'; +import { useKibana } from './use_kibana'; +import { + AGENT_NAME, + CLOUD_PROVIDER, + CONTAINER_ID, + ENTITY_DEFINITION_ID, + ENTITY_DISPLAY_NAME, + ENTITY_ID, + ENTITY_IDENTITY_FIELDS, + ENTITY_LAST_SEEN, + ENTITY_TYPE, + HOST_NAME, + ENTITY_TYPES, + SERVICE_ENVIRONMENT, + SERVICE_NAME, +} from '@kbn/observability-shared-plugin/common'; +import { unflattenEntity } from '../../common/utils/unflatten_entity'; +import type { Entity } from '../../common/entities'; + +jest.mock('./use_kibana'); +jest.mock('../../common/utils/unflatten_entity'); + +const useKibanaMock = useKibana as jest.Mock; +const unflattenEntityMock = unflattenEntity as jest.Mock; + +const commonEntityFields: Partial = { + [ENTITY_LAST_SEEN]: '2023-10-09T00:00:00Z', + [ENTITY_ID]: '1', + [ENTITY_DISPLAY_NAME]: 'entity_name', + [ENTITY_DEFINITION_ID]: 'entity_definition_id', +}; + +describe('useDetailViewRedirect', () => { + const mockGetIdentityFieldsValue = jest.fn(); + const mockAsKqlFilter = jest.fn(); + const mockGetRedirectUrl = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + + useKibanaMock.mockReturnValue({ + services: { + share: { + url: { + locators: { + get: jest.fn().mockReturnValue({ + getRedirectUrl: mockGetRedirectUrl, + }), + }, + }, + }, + entityManager: { + entityClient: { + getIdentityFieldsValue: mockGetIdentityFieldsValue, + asKqlFilter: mockAsKqlFilter, + }, + }, + }, + }); + + unflattenEntityMock.mockImplementation((entity) => entity); + }); + + it('getEntityRedirectUrl should return the correct URL for host entity', () => { + const entity: Entity = { + ...(commonEntityFields as Entity), + [ENTITY_IDENTITY_FIELDS]: [HOST_NAME], + [ENTITY_TYPE]: 'host', + [HOST_NAME]: 'host-1', + [CLOUD_PROVIDER]: null, + }; + + mockGetIdentityFieldsValue.mockReturnValue({ [HOST_NAME]: 'host-1' }); + mockGetRedirectUrl.mockReturnValue('asset-details-url'); + + const { result } = renderHook(() => useDetailViewRedirect()); + const url = result.current.getEntityRedirectUrl(entity); + + expect(url).toBe('asset-details-url'); + expect(mockGetRedirectUrl).toHaveBeenCalledWith({ assetId: 'host-1', assetType: 'host' }); + }); + + it('getEntityRedirectUrl should return the correct URL for container entity', () => { + const entity: Entity = { + ...(commonEntityFields as Entity), + [ENTITY_IDENTITY_FIELDS]: [CONTAINER_ID], + [ENTITY_TYPE]: 'container', + [CONTAINER_ID]: 'container-1', + [CLOUD_PROVIDER]: null, + }; + + mockGetIdentityFieldsValue.mockReturnValue({ [CONTAINER_ID]: 'container-1' }); + mockGetRedirectUrl.mockReturnValue('asset-details-url'); + + const { result } = renderHook(() => useDetailViewRedirect()); + const url = result.current.getEntityRedirectUrl(entity); + + expect(url).toBe('asset-details-url'); + expect(mockGetRedirectUrl).toHaveBeenCalledWith({ + assetId: 'container-1', + assetType: 'container', + }); + }); + + it('getEntityRedirectUrl should return the correct URL for service entity', () => { + const entity: Entity = { + ...(commonEntityFields as Entity), + [ENTITY_IDENTITY_FIELDS]: [SERVICE_NAME], + [ENTITY_TYPE]: 'service', + [SERVICE_NAME]: 'service-1', + [SERVICE_ENVIRONMENT]: 'prod', + [AGENT_NAME]: 'node', + }; + mockGetIdentityFieldsValue.mockReturnValue({ [SERVICE_NAME]: 'service-1' }); + mockGetRedirectUrl.mockReturnValue('service-overview-url'); + + const { result } = renderHook(() => useDetailViewRedirect()); + const url = result.current.getEntityRedirectUrl(entity); + + expect(url).toBe('service-overview-url'); + expect(mockGetRedirectUrl).toHaveBeenCalledWith({ + serviceName: 'service-1', + environment: 'prod', + }); + }); + + [ + [ENTITY_TYPES.KUBERNETES.CLUSTER.ecs, 'kubernetes-f4dc26db-1b53-4ea2-a78b-1bfab8ea267c'], + [ENTITY_TYPES.KUBERNETES.CLUSTER.semconv, 'kubernetes_otel-cluster-overview'], + [ENTITY_TYPES.KUBERNETES.CRONJOB.ecs, 'kubernetes-0a672d50-bcb1-11ec-b64f-7dd6e8e82013'], + [ENTITY_TYPES.KUBERNETES.DAEMONSET.ecs, 'kubernetes-85879010-bcb1-11ec-b64f-7dd6e8e82013'], + [ENTITY_TYPES.KUBERNETES.DEPLOYMENT.ecs, 'kubernetes-5be46210-bcb1-11ec-b64f-7dd6e8e82013'], + [ENTITY_TYPES.KUBERNETES.JOB.ecs, 'kubernetes-9bf990a0-bcb1-11ec-b64f-7dd6e8e82013'], + [ENTITY_TYPES.KUBERNETES.NODE.ecs, 'kubernetes-b945b7b0-bcb1-11ec-b64f-7dd6e8e82013'], + [ENTITY_TYPES.KUBERNETES.POD.ecs, 'kubernetes-3d4d9290-bcb1-11ec-b64f-7dd6e8e82013'], + [ENTITY_TYPES.KUBERNETES.STATEFULSET.ecs, 'kubernetes-21694370-bcb2-11ec-b64f-7dd6e8e82013'], + ].forEach(([entityType, dashboardId]) => { + it(`getEntityRedirectUrl should return the correct URL for ${entityType} entity`, () => { + const entity: Entity = { + ...(commonEntityFields as Entity), + [ENTITY_IDENTITY_FIELDS]: ['some.field'], + [ENTITY_TYPE]: entityType, + }; + + mockAsKqlFilter.mockReturnValue('kql-query'); + mockGetRedirectUrl.mockReturnValue('dashboard-url'); + + const { result } = renderHook(() => useDetailViewRedirect()); + const url = result.current.getEntityRedirectUrl(entity); + + expect(url).toBe('dashboard-url'); + expect(mockGetRedirectUrl).toHaveBeenCalledWith({ + dashboardId, + query: { + language: 'kuery', + query: 'kql-query', + }, + }); + }); + }); +}); diff --git a/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts new file mode 100644 index 0000000000000..23380dc3704de --- /dev/null +++ b/x-pack/plugins/observability_solution/inventory/public/hooks/use_detail_view_redirect.ts @@ -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 { + ASSET_DETAILS_LOCATOR_ID, + AssetDetailsLocatorParams, + ENTITY_IDENTITY_FIELDS, + ENTITY_TYPE, + ENTITY_TYPES, + SERVICE_ENVIRONMENT, + SERVICE_OVERVIEW_LOCATOR_ID, + ServiceOverviewParams, +} from '@kbn/observability-shared-plugin/common'; +import { useCallback } from 'react'; +import { DashboardLocatorParams } from '@kbn/dashboard-plugin/public'; +import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics'; +import { castArray } from 'lodash'; +import type { Entity } from '../../common/entities'; +import { unflattenEntity } from '../../common/utils/unflatten_entity'; +import { useKibana } from './use_kibana'; + +const KUBERNETES_DASHBOARDS_IDS: Record = { + [ENTITY_TYPES.KUBERNETES.CLUSTER.ecs]: 'kubernetes-f4dc26db-1b53-4ea2-a78b-1bfab8ea267c', + [ENTITY_TYPES.KUBERNETES.CLUSTER.semconv]: 'kubernetes_otel-cluster-overview', + [ENTITY_TYPES.KUBERNETES.CRONJOB.ecs]: 'kubernetes-0a672d50-bcb1-11ec-b64f-7dd6e8e82013', + [ENTITY_TYPES.KUBERNETES.DAEMONSET.ecs]: 'kubernetes-85879010-bcb1-11ec-b64f-7dd6e8e82013', + [ENTITY_TYPES.KUBERNETES.DEPLOYMENT.ecs]: 'kubernetes-5be46210-bcb1-11ec-b64f-7dd6e8e82013', + [ENTITY_TYPES.KUBERNETES.JOB.ecs]: 'kubernetes-9bf990a0-bcb1-11ec-b64f-7dd6e8e82013', + [ENTITY_TYPES.KUBERNETES.NODE.ecs]: 'kubernetes-b945b7b0-bcb1-11ec-b64f-7dd6e8e82013', + [ENTITY_TYPES.KUBERNETES.POD.ecs]: 'kubernetes-3d4d9290-bcb1-11ec-b64f-7dd6e8e82013', + [ENTITY_TYPES.KUBERNETES.STATEFULSET.ecs]: 'kubernetes-21694370-bcb2-11ec-b64f-7dd6e8e82013', +}; + +export const useDetailViewRedirect = () => { + const { + services: { share, entityManager }, + } = useKibana(); + + const locators = share.url.locators; + const assetDetailsLocator = locators.get(ASSET_DETAILS_LOCATOR_ID); + const dashboardLocator = locators.get(DASHBOARD_APP_LOCATOR); + const serviceOverviewLocator = locators.get(SERVICE_OVERVIEW_LOCATOR_ID); + + const getSingleIdentityFieldValue = useCallback( + (entity: Entity) => { + const identityFields = castArray(entity[ENTITY_IDENTITY_FIELDS]); + if (identityFields.length > 1) { + throw new Error(`Multiple identity fields are not supported for ${entity[ENTITY_TYPE]}`); + } + + const identityField = identityFields[0]; + return entityManager.entityClient.getIdentityFieldsValue(unflattenEntity(entity))[ + identityField + ]; + }, + [entityManager.entityClient] + ); + + const getDetailViewRedirectUrl = useCallback( + (entity: Entity) => { + const type = entity[ENTITY_TYPE]; + const identityValue = getSingleIdentityFieldValue(entity); + + switch (type) { + case ENTITY_TYPES.HOST: + case ENTITY_TYPES.CONTAINER: + return assetDetailsLocator?.getRedirectUrl({ + assetId: identityValue, + assetType: type, + }); + + case 'service': + return serviceOverviewLocator?.getRedirectUrl({ + serviceName: identityValue, + // service.environemnt is not part of entity.identityFields + // we need to manually get its value + environment: [entity[SERVICE_ENVIRONMENT] || undefined].flat()[0], + }); + + default: + return undefined; + } + }, + [assetDetailsLocator, getSingleIdentityFieldValue, serviceOverviewLocator] + ); + + const getDashboardRedirectUrl = useCallback( + (entity: Entity) => { + const type = entity[ENTITY_TYPE]; + const dashboardId = KUBERNETES_DASHBOARDS_IDS[type]; + + return dashboardId + ? dashboardLocator?.getRedirectUrl({ + dashboardId, + query: { + language: 'kuery', + query: entityManager.entityClient.asKqlFilter(unflattenEntity(entity)), + }, + }) + : undefined; + }, + [dashboardLocator, entityManager.entityClient] + ); + + const getEntityRedirectUrl = useCallback( + (entity: Entity) => getDetailViewRedirectUrl(entity) ?? getDashboardRedirectUrl(entity), + [getDashboardRedirectUrl, getDetailViewRedirectUrl] + ); + + return { getEntityRedirectUrl }; +}; diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts index ffd5ba9c6f855..62d77c08fd27a 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/entities/get_identify_fields.test.ts @@ -30,7 +30,7 @@ describe('getIdentityFields', () => { it('should return a Map with unique entity types and their respective identity fields', () => { const serviceEntity: Entity = { 'agent.name': 'node', - 'entity.identity_fields': ['service.name', 'service.environment'], + [ENTITY_IDENTITY_FIELDS]: ['service.name', 'service.environment'], 'service.name': 'my-service', 'entity.type': 'service', ...commonEntityFields, diff --git a/x-pack/plugins/observability_solution/inventory/server/routes/has_data/get_has_data.ts b/x-pack/plugins/observability_solution/inventory/server/routes/has_data/get_has_data.ts index 27ba8c0fe46c3..c1e4a82c343b0 100644 --- a/x-pack/plugins/observability_solution/inventory/server/routes/has_data/get_has_data.ts +++ b/x-pack/plugins/observability_solution/inventory/server/routes/has_data/get_has_data.ts @@ -26,7 +26,6 @@ export async function getHasData({ }); const totalCount = esqlResultToPlainObjects(esqlResults)?.[0]._count ?? 0; - return { hasData: totalCount > 0 }; } catch (e) { logger.error(e); diff --git a/x-pack/plugins/observability_solution/inventory/tsconfig.json b/x-pack/plugins/observability_solution/inventory/tsconfig.json index d27d170b0990e..bd77df478cad1 100644 --- a/x-pack/plugins/observability_solution/inventory/tsconfig.json +++ b/x-pack/plugins/observability_solution/inventory/tsconfig.json @@ -53,5 +53,8 @@ "@kbn/spaces-plugin", "@kbn/cloud-plugin", "@kbn/storybook", + "@kbn/zod", + "@kbn/dashboard-plugin", + "@kbn/deeplinks-analytics" ] } diff --git a/x-pack/plugins/observability_solution/observability_shared/common/entity/entity_types.ts b/x-pack/plugins/observability_solution/observability_shared/common/entity/entity_types.ts index b905f542d3473..4d8be9efc59c6 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/entity/entity_types.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/entity/entity_types.ts @@ -5,7 +5,25 @@ * 2.0. */ -export enum EntityType { - HOST = 'host', - CONTAINER = 'container', -} +const createKubernetesEntity = (base: T) => ({ + ecs: `kubernetes_${base}_ecs` as const, + semconv: `kubernetes_${base}_semconv` as const, +}); + +export const ENTITY_TYPES = { + HOST: 'host', + CONTAINER: 'container', + SERVICE: 'service', + KUBERNETES: { + CLUSTER: createKubernetesEntity('cluster'), + CONTAINER: createKubernetesEntity('container'), + CRONJOB: createKubernetesEntity('cron_job'), + DAEMONSET: createKubernetesEntity('daemon_set'), + DEPLOYMENT: createKubernetesEntity('deployment'), + JOB: createKubernetesEntity('job'), + NAMESPACE: createKubernetesEntity('namespace'), + NODE: createKubernetesEntity('node'), + POD: createKubernetesEntity('pod'), + STATEFULSET: createKubernetesEntity('stateful_set'), + }, +} as const; diff --git a/x-pack/plugins/observability_solution/observability_shared/common/entity/index.ts b/x-pack/plugins/observability_solution/observability_shared/common/entity/index.ts index 27bef43d5ff7a..adc07a2931b60 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/entity/index.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/entity/index.ts @@ -5,5 +5,5 @@ * 2.0. */ -export { EntityType } from './entity_types'; +export { ENTITY_TYPES } from './entity_types'; export { EntityDataStreamType } from './entity_data_stream_types'; diff --git a/x-pack/plugins/observability_solution/observability_shared/common/index.ts b/x-pack/plugins/observability_solution/observability_shared/common/index.ts index e9be61e8fde34..b4b7731d166b7 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/index.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/index.ts @@ -193,6 +193,7 @@ export type { export { ServiceOverviewLocatorDefinition, + SERVICE_OVERVIEW_LOCATOR_ID, TransactionDetailsByNameLocatorDefinition, ASSET_DETAILS_FLYOUT_LOCATOR_ID, AssetDetailsFlyoutLocatorDefinition, @@ -218,4 +219,4 @@ export { export { COMMON_OBSERVABILITY_GROUPING } from './embeddable_grouping'; -export { EntityType, EntityDataStreamType } from './entity'; +export { ENTITY_TYPES, EntityDataStreamType } from './entity'; diff --git a/x-pack/plugins/observability_solution/observability_shared/common/locators/apm/service_overview_locator.ts b/x-pack/plugins/observability_solution/observability_shared/common/locators/apm/service_overview_locator.ts index 2a4e8aac330ec..e216640f31b4f 100644 --- a/x-pack/plugins/observability_solution/observability_shared/common/locators/apm/service_overview_locator.ts +++ b/x-pack/plugins/observability_solution/observability_shared/common/locators/apm/service_overview_locator.ts @@ -16,9 +16,10 @@ export interface ServiceOverviewParams extends SerializableRecord { } export type ServiceOverviewLocator = LocatorPublic; +export const SERVICE_OVERVIEW_LOCATOR_ID = 'serviceOverviewLocator'; export class ServiceOverviewLocatorDefinition implements LocatorDefinition { - public readonly id = 'serviceOverviewLocator'; + public readonly id = SERVICE_OVERVIEW_LOCATOR_ID; public readonly getLocation = async ({ rangeFrom, diff --git a/x-pack/plugins/osquery/cypress/e2e/all/alerts_automated_action_results.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/alerts_automated_action_results.cy.ts index cd36950ba3b60..a815497e40c96 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/alerts_automated_action_results.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/alerts_automated_action_results.cy.ts @@ -13,6 +13,8 @@ const UUID_REGEX = '[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}- // FLAKY: https://github.com/elastic/kibana/issues/178404 // FLAKY: https://github.com/elastic/kibana/issues/197335 +// Failing: See https://github.com/elastic/kibana/issues/197335 +// Failing: See https://github.com/elastic/kibana/issues/178404 describe.skip('Alert Flyout Automated Action Results', () => { let ruleId: string; diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/misconfiguration/misconfiguration_preview.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/misconfiguration/misconfiguration_preview.tsx index 091179b40393c..b133e9db22050 100644 --- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/misconfiguration/misconfiguration_preview.tsx +++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/misconfiguration/misconfiguration_preview.tsx @@ -13,7 +13,6 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { DistributionBar } from '@kbn/security-solution-distribution-bar'; import { useMisconfigurationPreview } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_preview'; import { i18n } from '@kbn/i18n'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { useVulnerabilitiesPreview } from '@kbn/cloud-security-posture/src/hooks/use_vulnerabilities_preview'; @@ -23,6 +22,7 @@ import { ENTITY_FLYOUT_WITH_MISCONFIGURATION_VISIT, uiMetricService, } from '@kbn/cloud-security-posture-common/utils/ui_metrics'; +import { ExpandablePanel } from '../../../flyout/shared/components/expandable_panel'; import { CspInsightLeftPanelSubTab, EntityDetailsLeftPanelTab, diff --git a/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.tsx b/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.tsx index 2c162ba9db894..1caa740662ad8 100644 --- a/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.tsx +++ b/x-pack/plugins/security_solution/public/cloud_security_posture/components/vulnerabilities/vulnerabilities_preview.tsx @@ -12,7 +12,6 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, useEuiTheme, EuiTitle } import { FormattedMessage } from '@kbn/i18n-react'; import { DistributionBar } from '@kbn/security-solution-distribution-bar'; import { useVulnerabilitiesPreview } from '@kbn/cloud-security-posture/src/hooks/use_vulnerabilities_preview'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { buildEntityFlyoutPreviewQuery, getAbbreviatedNumber, @@ -25,6 +24,7 @@ import { uiMetricService, } from '@kbn/cloud-security-posture-common/utils/ui_metrics'; import { METRIC_TYPE } from '@kbn/analytics'; +import { ExpandablePanel } from '../../../flyout/shared/components/expandable_panel'; import { EntityDetailsLeftPanelTab } from '../../../flyout/entity_details/shared/components/left_panel/left_panel_header'; import { HostDetailsPanelKey } from '../../../flyout/entity_details/host_details_left'; import { useRiskScore } from '../../../entity_analytics/api/hooks/use_risk_score'; diff --git a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_panels.tsx b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_panels.tsx index 63ffcf7b9eae1..d70eb9fe34b51 100644 --- a/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_panels.tsx +++ b/x-pack/plugins/security_solution/public/entity_analytics/components/entity_store/components/dashboard_panels.tsx @@ -55,7 +55,7 @@ const EntityStoreDashboardPanelsComponent = () => { const { mutate: initRiskEngine } = useInitRiskEngineMutation(); - const callouts = entityStore.errors.map((err, i) => ( + const callouts = entityStore.errors.map((err) => ( { stopEntityEngineMutation.isLoading || deleteEntityEngineMutation.isLoading; + const callouts = entityStoreStatus.errors.map((error) => ( + + } + color="danger" + iconType="alert" + > +

{error.message}

+
+ )); + return ( <> { + {initEntityEngineMutation.isError && ( + + } + color="danger" + iconType="alert" + > +

+ {(initEntityEngineMutation.error as { body: { message: string } }).body.message} +

+
+ )} + {deleteEntityEngineMutation.isError && ( + + } + color="danger" + iconType="alert" + > +

+ {(deleteEntityEngineMutation.error as { body: { message: string } }).body.message} +

+
+ )} + {callouts} {!isEntityStoreFeatureFlagDisabled && canDeleteEntityEngine && }
diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/alert_reason/alert_reason.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/alert_reason/alert_reason.tsx index 03b84bc625552..62e6e9f492b2f 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/alert_reason/alert_reason.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/alert_reason/alert_reason.tsx @@ -10,11 +10,11 @@ import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import styled from '@emotion/styled'; import { euiThemeVars } from '@kbn/ui-theme'; import { FormattedMessage } from '@kbn/i18n-react'; -import { FlyoutError } from '@kbn/security-solution-common'; import { ALERT_REASON_BODY_TEST_ID } from './test_ids'; import { useAlertReasonPanelContext } from './context'; import { getRowRenderer } from '../../../timelines/components/timeline/body/renderers/get_row_renderer'; import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; +import { FlyoutError } from '../../shared/components/flyout_error'; const ReasonContainerWrapper = styled.div` overflow-x: auto; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/alert_reason/context.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/alert_reason/context.tsx index ec8096d60e72c..b67c9af508d96 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/alert_reason/context.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/alert_reason/context.tsx @@ -7,8 +7,9 @@ import React, { createContext, memo, useContext, useMemo } from 'react'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; -import { FlyoutError, FlyoutLoading } from '@kbn/security-solution-common'; import { useEventDetails } from '../shared/hooks/use_event_details'; +import { FlyoutError } from '../../shared/components/flyout_error'; +import { FlyoutLoading } from '../../shared/components/flyout_loading'; import type { AlertReasonPanelProps } from '.'; export interface AlertReasonPanelContext { diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/analyzer_panels/index.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/analyzer_panels/index.tsx index f61993da5321a..4fe9086c70a0e 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/analyzer_panels/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/analyzer_panels/index.tsx @@ -7,13 +7,13 @@ import React, { useCallback } from 'react'; import type { FlyoutPanelProps } from '@kbn/expandable-flyout'; -import { FlyoutBody } from '@kbn/security-solution-common'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import type { DocumentDetailsAnalyzerPanelKey } from '../shared/constants/panel_keys'; import { DetailsPanel } from '../../../resolver/view/details_panel'; import type { NodeEventOnClick } from '../../../resolver/view/panels/node_events_of_type'; import { DocumentDetailsPreviewPanelKey } from '../shared/constants/panel_keys'; import { ALERT_PREVIEW_BANNER, EVENT_PREVIEW_BANNER } from '../preview/constants'; +import { FlyoutBody } from '../../shared/components/flyout_body'; interface AnalyzerPanelProps extends Record { /** diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/content.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/content.tsx index 6ae172ca62556..0c9f05391d82a 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/content.tsx @@ -8,7 +8,6 @@ import type { FC } from 'react'; import React, { useCallback } from 'react'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { FlyoutBody } from '@kbn/security-solution-common'; import { DocumentDetailsRightPanelKey } from '../shared/constants/panel_keys'; import { useBasicDataFromDetailsData } from '../shared/hooks/use_basic_data_from_details_data'; import { @@ -17,6 +16,7 @@ import { } from '../../../common/components/endpoint/host_isolation'; import { useHostIsolation } from '../shared/hooks/use_host_isolation'; import { useIsolateHostPanelContext } from './context'; +import { FlyoutBody } from '../../shared/components/flyout_body'; /** * Document details expandable flyout section content for the isolate host component, displaying the form or the success banner diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/context.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/context.tsx index 6abfe1c4e8650..53393e2f8a79b 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/context.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/context.tsx @@ -8,8 +8,9 @@ import type { TimelineEventsDetailsItem } from '@kbn/timelines-plugin/common'; import React, { createContext, memo, useContext, useMemo } from 'react'; -import { FlyoutError, FlyoutLoading } from '@kbn/security-solution-common'; import { useEventDetails } from '../shared/hooks/use_event_details'; +import { FlyoutError } from '../../shared/components/flyout_error'; +import { FlyoutLoading } from '../../shared/components/flyout_loading'; import type { IsolateHostPanelProps } from '.'; export interface IsolateHostPanelContext { diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/header.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/header.tsx index d7effaea8016b..c0f4174cff95a 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/header.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/isolate_host/header.tsx @@ -8,11 +8,11 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui'; import type { FC } from 'react'; import React from 'react'; -import { FlyoutHeader } from '@kbn/security-solution-common'; import { AgentTypeIntegration } from '../../../common/components/endpoint/agents/agent_type_integration'; import { useAlertResponseActionsSupport } from '../../../common/hooks/endpoint/use_alert_response_actions_support'; import { useIsolateHostPanelContext } from './context'; import { FLYOUT_HEADER_TITLE_TEST_ID } from './test_ids'; +import { FlyoutHeader } from '../../shared/components/flyout_header'; import { ISOLATE_HOST, UNISOLATE_HOST } from '../../../common/components/endpoint'; /** diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.test.tsx index 859da37c4082d..b3b129a75c13d 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details.test.tsx @@ -28,7 +28,7 @@ import { useFetchRelatedAlertsBySameSourceEvent } from '../../shared/hooks/use_f import { useFetchRelatedCases } from '../../shared/hooks/use_fetch_related_cases'; import { mockContextValue } from '../../shared/mocks/mock_context'; import { useTimelineDataFilters } from '../../../../timelines/containers/use_timeline_data_filters'; -import { EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID } from '@kbn/security-solution-common'; +import { EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID } from '../../../shared/components/test_ids'; jest.mock('react-router-dom', () => { const actual = jest.requireActual('react-router-dom'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx index 20663b56dab39..d8497ca984ea8 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/correlations_details_alerts_table.tsx @@ -14,13 +14,13 @@ import { isRight } from 'fp-ts/lib/Either'; import { ALERT_REASON, ALERT_RULE_NAME } from '@kbn/rule-data-utils'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { CellTooltipWrapper } from '../../shared/components/cell_tooltip_wrapper'; import type { DataProvider } from '../../../../../common/types'; import { SeverityBadge } from '../../../../common/components/severity_badge'; import { usePaginatedAlerts } from '../hooks/use_paginated_alerts'; import { InvestigateInTimelineButton } from '../../../../common/components/event_details/investigate_in_timeline_button'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import { ACTION_INVESTIGATE_IN_TIMELINE } from '../../../../detections/components/alerts_table/translations'; import { getDataProvider } from '../../../../common/components/event_details/use_action_cell_data_provider'; import { AlertPreviewButton } from '../../../shared/components/alert_preview_button'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/entities_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/entities_details.test.tsx index 53936a5ed2e99..f79dfcec7b27b 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/entities_details.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/entities_details.test.tsx @@ -13,7 +13,7 @@ import { TestProviders } from '../../../../common/mock'; import { EntitiesDetails } from './entities_details'; import { ENTITIES_DETAILS_TEST_ID, HOST_DETAILS_TEST_ID, USER_DETAILS_TEST_ID } from './test_ids'; import { mockContextValue } from '../../shared/mocks/mock_context'; -import { EXPANDABLE_PANEL_CONTENT_TEST_ID } from '@kbn/security-solution-common'; +import { EXPANDABLE_PANEL_CONTENT_TEST_ID } from '../../../shared/components/test_ids'; import type { Anomalies } from '../../../../common/components/ml/types'; import { useMlCapabilities } from '../../../../common/components/ml/hooks/use_ml_capabilities'; import { mockAnomalies } from '../../../../common/components/ml/mock'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.test.tsx index 895ff3d1b7697..4eeabe67979a5 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.test.tsx @@ -30,7 +30,7 @@ import { HOST_DETAILS_VULNERABILITIES_TEST_ID, HOST_DETAILS_ALERT_COUNT_TEST_ID, } from './test_ids'; -import { EXPANDABLE_PANEL_CONTENT_TEST_ID } from '@kbn/security-solution-common'; +import { EXPANDABLE_PANEL_CONTENT_TEST_ID } from '../../../shared/components/test_ids'; import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; import { mockContextValue } from '../../shared/mocks/mock_context'; import { mockFlyoutApi } from '../../shared/mocks/mock_flyout_context'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx index 122caa657b039..f5a1e112afa80 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/host_details.tsx @@ -25,8 +25,8 @@ import type { EuiBasicTableColumn } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import type { RelatedUser } from '../../../../../common/search_strategy/security_solution/related_entities/related_users'; import type { RiskSeverity } from '../../../../../common/search_strategy'; import { HostOverview } from '../../../../overview/components/host_overview'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/investigation_guide.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/investigation_guide.tsx index f39057a16bfdb..ee1bebdb336ce 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/investigation_guide.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/investigation_guide.tsx @@ -7,11 +7,11 @@ import React from 'react'; import { EuiLink } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { FlyoutLoading } from '@kbn/security-solution-common'; import { useInvestigationGuide } from '../../shared/hooks/use_investigation_guide'; import { useDocumentDetailsContext } from '../../shared/context'; import { INVESTIGATION_GUIDE_TEST_ID, INVESTIGATION_GUIDE_LOADING_TEST_ID } from './test_ids'; import { InvestigationGuideView } from './investigation_guide_view'; +import { FlyoutLoading } from '../../../shared/components/flyout_loading'; /** * Investigation guide displayed in the left panel. diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.test.tsx index 62012b72052bc..52468f0aedbb9 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_ancestry.test.tsx @@ -20,7 +20,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; import { usePaginatedAlerts } from '../hooks/use_paginated_alerts'; jest.mock('../../shared/hooks/use_fetch_related_alerts_by_ancestry'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_same_source_event.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_same_source_event.test.tsx index f4244fcc59a04..3cf2d93896bc3 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_same_source_event.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_same_source_event.test.tsx @@ -20,7 +20,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; import { usePaginatedAlerts } from '../hooks/use_paginated_alerts'; jest.mock('../../shared/hooks/use_fetch_related_alerts_by_same_source_event'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_session.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_session.test.tsx index 54df7e8924f68..0120f462b9ac5 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_session.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_alerts_by_session.test.tsx @@ -21,7 +21,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; jest.mock('../../shared/hooks/use_fetch_related_alerts_by_session'); jest.mock('../hooks/use_paginated_alerts'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.test.tsx index 4d90cc7f56133..db9eb7bdfb3ae 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.test.tsx @@ -18,7 +18,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; jest.mock('../../shared/hooks/use_fetch_related_cases'); jest.mock('../../../../common/components/links', () => ({ diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.tsx index 8e00e0e65478b..13df33a2deb1b 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/related_cases.tsx @@ -10,7 +10,6 @@ import type { EuiBasicTableColumn } from '@elastic/eui'; import { EuiInMemoryTable } from '@elastic/eui'; import type { RelatedCase } from '@kbn/cases-plugin/common'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { CellTooltipWrapper } from '../../shared/components/cell_tooltip_wrapper'; import { CaseDetailsLink } from '../../../../common/components/links'; import { @@ -18,6 +17,7 @@ import { CORRELATIONS_DETAILS_CASES_SECTION_TEST_ID, } from './test_ids'; import { useFetchRelatedCases } from '../../shared/hooks/use_fetch_related_cases'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; const ICON = 'warning'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.test.tsx index a97a601f082dd..3b73199494187 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.test.tsx @@ -17,7 +17,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; import { DocumentDetailsContext } from '../../shared/context'; import { mockContextValue } from '../../shared/mocks/mock_context'; import { isSuppressionRuleInGA } from '../../../../../common/detection_engine/utils'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx index 2c24b5c595c52..c12c62733f4db 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/suppressed_alerts.tsx @@ -12,8 +12,8 @@ import { ALERT_RULE_TYPE } from '@kbn/rule-data-utils'; import { EuiBetaBadge, EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import { CORRELATIONS_DETAILS_SUPPRESSED_ALERTS_SECTION_TEST_ID, SUPPRESSED_ALERTS_SECTION_TECHNICAL_PREVIEW_TEST_ID, diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/threat_intelligence_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/threat_intelligence_details.tsx index 6ac43fbe5cd31..f473ae2c3262b 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/threat_intelligence_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/threat_intelligence_details.tsx @@ -9,7 +9,6 @@ import React, { memo } from 'react'; import { EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; import isEmpty from 'lodash/isEmpty'; import { groupBy } from 'lodash'; -import { FlyoutLoading } from '@kbn/security-solution-common'; import { EnrichmentSection } from './threat_details_view_enrichment_section'; import { ENRICHMENT_TYPES } from '../../../../../common/cti/constants'; import { EnrichmentRangePicker } from './threat_intelligence_view_enrichment_range_picker'; @@ -20,6 +19,7 @@ import { THREAT_INTELLIGENCE_ENRICHMENTS_TEST_ID, THREAT_INTELLIGENCE_MATCHES_TEST_ID, } from './test_ids'; +import { FlyoutLoading } from '../../../shared/components/flyout_loading'; export const THREAT_INTELLIGENCE_TAB_ID = 'threatIntelligence'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.test.tsx index d4150c01d06a6..966253b3d27ed 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.test.tsx @@ -28,7 +28,7 @@ import { USER_DETAILS_MISCONFIGURATIONS_TEST_ID, USER_DETAILS_ALERT_COUNT_TEST_ID, } from './test_ids'; -import { EXPANDABLE_PANEL_CONTENT_TEST_ID } from '@kbn/security-solution-common'; +import { EXPANDABLE_PANEL_CONTENT_TEST_ID } from '../../../shared/components/test_ids'; import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; import { mockContextValue } from '../../shared/mocks/mock_context'; import { mockFlyoutApi } from '../../shared/mocks/mock_flyout_context'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx index c90d11f4b8bc2..ed406d3b8c679 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/components/user_details.tsx @@ -25,8 +25,8 @@ import type { EuiBasicTableColumn } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import type { RelatedHost } from '../../../../../common/search_strategy/security_solution/related_entities/related_hosts'; import type { RiskSeverity } from '../../../../../common/search_strategy'; import { UserOverview } from '../../../../overview/components/user_overview'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/content.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/content.tsx index 226765e6c4e37..53d2efe883397 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/content.tsx @@ -9,9 +9,9 @@ import { useEuiBackgroundColor } from '@elastic/eui'; import type { FC } from 'react'; import React, { useMemo } from 'react'; import { css } from '@emotion/react'; -import { FlyoutBody } from '@kbn/security-solution-common'; import type { LeftPanelPaths } from '.'; import type { LeftPanelTabType } from './tabs'; +import { FlyoutBody } from '../../shared/components/flyout_body'; export interface PanelContentProps { /** diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/header.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/left/header.tsx index f276ccca842be..2b61a97577e06 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/header.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/header.tsx @@ -9,8 +9,8 @@ import { EuiTab, EuiTabs, useEuiBackgroundColor } from '@elastic/eui'; import type { FC } from 'react'; import React, { memo } from 'react'; import { css } from '@emotion/react'; -import { FlyoutHeader } from '@kbn/security-solution-common'; import type { LeftPanelPaths } from '.'; +import { FlyoutHeader } from '../../shared/components/flyout_header'; import type { LeftPanelTabType } from './tabs'; import { getField } from '../shared/utils'; import { EventKind } from '../shared/constants/event_kinds'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/left/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/document_details/left/test_ids.ts index 4e2c1be90b01c..9f5eeb035786c 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/left/test_ids.ts +++ b/x-pack/plugins/security_solution/public/flyout/document_details/left/test_ids.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { PREFIX } from '@kbn/security-solution-common'; +import { PREFIX } from '../../shared/test_ids'; export const VISUALIZE_TAB_TEST_ID = `${PREFIX}VisualizeTab` as const; export const INSIGHTS_TAB_TEST_ID = `${PREFIX}InsightsTab` as const; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/preview/footer.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/preview/footer.tsx index f437c9e77a158..0201332888675 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/preview/footer.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/preview/footer.tsx @@ -9,9 +9,9 @@ import { EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { FlyoutFooter } from '@kbn/security-solution-common'; import { getField } from '../shared/utils'; import { EventKind } from '../shared/constants/event_kinds'; +import { FlyoutFooter } from '../../shared/components/flyout_footer'; import { DocumentDetailsRightPanelKey } from '../shared/constants/panel_keys'; import { useDocumentDetailsContext } from '../shared/context'; import { PREVIEW_FOOTER_TEST_ID, PREVIEW_FOOTER_LINK_TEST_ID } from './test_ids'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/alert_header_title.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/alert_header_title.tsx index 931da6e8e57c8..cc7ef14585833 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/alert_header_title.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/alert_header_title.tsx @@ -9,7 +9,6 @@ import React, { memo, useCallback, useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiLink } from '@elastic/eui'; import { ALERT_WORKFLOW_ASSIGNEE_IDS } from '@kbn/rule-data-utils'; import { i18n } from '@kbn/i18n'; -import { FlyoutTitle } from '@kbn/security-solution-common'; import { useIsExperimentalFeatureEnabled } from '../../../../common/hooks/use_experimental_features'; import { Notes } from './notes'; import { useRuleDetailsLink } from '../../shared/hooks/use_rule_details_link'; @@ -22,6 +21,7 @@ import { useDocumentDetailsContext } from '../../shared/context'; import { PreferenceFormattedDate } from '../../../../common/components/formatted_date'; import { FLYOUT_ALERT_HEADER_TITLE_TEST_ID, ALERT_SUMMARY_PANEL_TEST_ID } from './test_ids'; import { Assignees } from './assignees'; +import { FlyoutTitle } from '../../../shared/components/flyout_title'; // minWidth for each block, allows to switch for a 1 row 4 blocks to 2 rows with 2 block each const blockStyles = { diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview_container.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview_container.test.tsx index f9179cecc6b5a..3e841da34a4fa 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview_container.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview_container.test.tsx @@ -21,7 +21,8 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_LINK_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; + import { useInvestigateInTimeline } from '../../../../detections/components/alerts_table/timeline_actions/use_investigate_in_timeline'; jest.mock( diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview_container.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview_container.tsx index 6896f15ca88cb..286394d16aadc 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview_container.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/analyzer_preview_container.tsx @@ -10,7 +10,6 @@ import { useDispatch } from 'react-redux'; import { TimelineTabs } from '@kbn/securitysolution-data-table'; import { EuiLink, EuiMark } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; import { ENABLE_VISUALIZATIONS_IN_FLYOUT_SETTING } from '../../../../../common/constants'; import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; @@ -23,6 +22,7 @@ import { useIsInvestigateInResolverActionEnabled } from '../../../../detections/ import { AnalyzerPreview } from './analyzer_preview'; import { ANALYZER_PREVIEW_TEST_ID } from './test_ids'; import { useNavigateToAnalyzer } from '../../shared/hooks/use_navigate_to_analyzer'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; const timelineId = 'timeline-1'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.test.tsx index 71292b73a68e0..c9d8606cf9343 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.test.tsx @@ -40,7 +40,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_LINK_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; import { useTourContext } from '../../../../common/components/guided_onboarding_tour'; import { AlertsCasesTourSteps } from '../../../../common/components/guided_onboarding_tour/tour_config'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.tsx index 9ab130cfc2de1..9ba55f0d041f6 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/correlations_overview.tsx @@ -12,8 +12,8 @@ import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { FormattedMessage } from '@kbn/i18n-react'; import { ALERT_RULE_TYPE } from '@kbn/rule-data-utils'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import type { Type } from '@kbn/securitysolution-io-ts-alerting-types'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import { useShowRelatedAlertsBySession } from '../../shared/hooks/use_show_related_alerts_by_session'; import { RelatedAlertsBySession } from './related_alerts_by_session'; import { useShowRelatedAlertsBySameSourceEvent } from '../../shared/hooks/use_show_related_alerts_by_same_source_event'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.test.tsx index e4975d3136424..92248c6de2828 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.test.tsx @@ -24,7 +24,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_LINK_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; import { useRiskScore } from '../../../../entity_analytics/api/hooks/use_risk_score'; const from = '2022-04-05T12:00:00.000Z'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.tsx index 60657a1346101..16fe6cbe1c1e0 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/entities_overview.tsx @@ -9,8 +9,8 @@ import React, { useCallback, useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { INSIGHTS_ENTITIES_TEST_ID } from './test_ids'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import { useDocumentDetailsContext } from '../../shared/context'; import { getField } from '../../shared/utils'; import { HostEntityOverview } from './host_entity_overview'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/event_header_title.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/event_header_title.tsx index f93b8451c744a..953a2371ffa88 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/event_header_title.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/event_header_title.tsx @@ -9,7 +9,7 @@ import React, { memo, useMemo } from 'react'; import { startCase } from 'lodash'; import { EuiSpacer } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FlyoutTitle } from '@kbn/security-solution-common'; +import { FlyoutTitle } from '../../../shared/components/flyout_title'; import { DocumentSeverity } from './severity'; import { useBasicDataFromDetailsData } from '../../shared/hooks/use_basic_data_from_details_data'; import { useDocumentDetailsContext } from '../../shared/context'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.test.tsx index 6b30e2127a2f8..d44321a4926bd 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.test.tsx @@ -14,14 +14,13 @@ import { GraphPreviewContainer } from './graph_preview_container'; import { GRAPH_PREVIEW_TEST_ID } from './test_ids'; import { useGraphPreview } from '../hooks/use_graph_preview'; import { useFetchGraphData } from '../hooks/use_fetch_graph_data'; - import { EXPANDABLE_PANEL_CONTENT_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_LINK_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; jest.mock('../hooks/use_graph_preview'); jest.mock('../hooks/use_fetch_graph_data', () => ({ diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.tsx index 1bc6a8dd7e547..be65593364593 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/graph_preview_container.tsx @@ -7,12 +7,12 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { useDocumentDetailsContext } from '../../shared/context'; import { GRAPH_PREVIEW_TEST_ID } from './test_ids'; import { GraphPreview } from './graph_preview'; import { useFetchGraphData } from '../hooks/use_fetch_graph_data'; import { useGraphPreview } from '../hooks/use_graph_preview'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; const DEFAULT_FROM = 'now-60d/d'; const DEFAULT_TO = 'now/d'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/prevalence_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/prevalence_overview.test.tsx index 527b9830b3948..57770b58e2fcb 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/prevalence_overview.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/prevalence_overview.test.tsx @@ -24,7 +24,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_LOADING_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; import { usePrevalence } from '../../shared/hooks/use_prevalence'; import { mockContextValue } from '../../shared/mocks/mock_context'; import { type ExpandableFlyoutApi, useExpandableFlyoutApi } from '@kbn/expandable-flyout'; @@ -42,7 +42,10 @@ const flyoutContextValue = { openLeftPanel: jest.fn(), } as unknown as ExpandableFlyoutApi; -jest.mock('@kbn/expandable-flyout'); +jest.mock('@kbn/expandable-flyout', () => ({ + useExpandableFlyoutApi: jest.fn(), + ExpandableFlyoutProvider: ({ children }: React.PropsWithChildren<{}>) => <>{children}, +})); const renderPrevalenceOverview = (contextValue: DocumentDetailsContext = mockContextValue) => render( diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/prevalence_overview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/prevalence_overview.tsx index adb660f67ce72..966df0293db77 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/prevalence_overview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/prevalence_overview.tsx @@ -10,7 +10,7 @@ import React, { useCallback, useMemo } from 'react'; import { EuiBadge, EuiFlexGroup } from '@elastic/eui'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ExpandablePanel } from '@kbn/security-solution-common'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import { usePrevalence } from '../../shared/hooks/use_prevalence'; import { PREVALENCE_TEST_ID } from './test_ids'; import { useDocumentDetailsContext } from '../../shared/context'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview_container.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview_container.test.tsx index db7f60938c0c3..9ccb512030b43 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview_container.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview_container.test.tsx @@ -19,7 +19,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_LINK_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; import { mockContextValue } from '../../shared/mocks/mock_context'; jest.mock('../hooks/use_session_preview'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview_container.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview_container.tsx index 974c74b995393..4098b35a0abfc 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview_container.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/session_preview_container.tsx @@ -9,7 +9,6 @@ import React, { type FC, useCallback } from 'react'; import { TimelineTabs } from '@kbn/securitysolution-data-table'; import { useDispatch } from 'react-redux'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { useUiSetting$ } from '@kbn/kibana-react-plugin/public'; import { ENABLE_VISUALIZATIONS_IN_FLYOUT_SETTING } from '../../../../../common/constants'; import { useLicense } from '../../../../common/hooks/use_license'; @@ -18,6 +17,7 @@ import { useSessionPreview } from '../hooks/use_session_preview'; import { useInvestigateInTimeline } from '../../../../detections/components/alerts_table/timeline_actions/use_investigate_in_timeline'; import { useDocumentDetailsContext } from '../../shared/context'; import { ALERTS_ACTIONS } from '../../../../common/lib/apm/user_actions'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import { SESSION_PREVIEW_TEST_ID } from './test_ids'; import { useStartTransaction } from '../../../../common/lib/apm/use_start_transaction'; import { setActiveTabTimeline } from '../../../../timelines/store/actions'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/threat_intelligence_overview.test.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/threat_intelligence_overview.test.tsx index f451862e0990e..1d19dacc39d42 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/threat_intelligence_overview.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/threat_intelligence_overview.test.tsx @@ -28,7 +28,7 @@ import { EXPANDABLE_PANEL_HEADER_TITLE_TEXT_TEST_ID, EXPANDABLE_PANEL_LOADING_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '@kbn/security-solution-common'; +} from '../../../shared/components/test_ids'; jest.mock('@kbn/expandable-flyout'); jest.mock('../../shared/context'); diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/threat_intelligence_overview.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/threat_intelligence_overview.tsx index 0a737a973ea2d..73dfc62520c32 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/components/threat_intelligence_overview.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/components/threat_intelligence_overview.tsx @@ -10,7 +10,7 @@ import React, { useCallback, useMemo } from 'react'; import { EuiFlexGroup } from '@elastic/eui'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; import { FormattedMessage } from '@kbn/i18n-react'; -import { ExpandablePanel } from '@kbn/security-solution-common'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import { useFetchThreatIntelligence } from '../hooks/use_fetch_threat_intelligence'; import { InsightsSummaryRow } from './insights_summary_row'; import { useDocumentDetailsContext } from '../../shared/context'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/content.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/content.tsx index 075921de192b8..dbc530a4dd3f6 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/content.tsx @@ -7,10 +7,10 @@ import type { FC } from 'react'; import React, { useMemo } from 'react'; -import { FlyoutBody } from '@kbn/security-solution-common'; import { FLYOUT_BODY_TEST_ID } from './test_ids'; import type { RightPanelPaths } from '.'; import type { RightPanelTabType } from './tabs'; +import { FlyoutBody } from '../../shared/components/flyout_body'; export interface PanelContentProps { /** diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/header.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/header.tsx index b7aea63ee9a24..aa1de9eda1b00 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/header.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/header.tsx @@ -9,9 +9,10 @@ import type { EuiFlyoutHeader } from '@elastic/eui'; import { EuiSpacer, EuiTab } from '@elastic/eui'; import type { FC } from 'react'; import React, { memo, useMemo } from 'react'; -import { FlyoutHeader, FlyoutHeaderTabs } from '@kbn/security-solution-common'; import type { RightPanelPaths } from '.'; import type { RightPanelTabType } from './tabs'; +import { FlyoutHeader } from '../../shared/components/flyout_header'; +import { FlyoutHeaderTabs } from '../../shared/components/flyout_header_tabs'; import { AlertHeaderTitle } from './components/alert_header_title'; import { EventHeaderTitle } from './components/event_header_title'; import { useDocumentDetailsContext } from '../shared/context'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/right/navigation.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/right/navigation.tsx index 79aad96c209db..b4f12fbabf94f 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/right/navigation.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/right/navigation.tsx @@ -8,9 +8,9 @@ import type { FC } from 'react'; import React, { memo, useCallback } from 'react'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { FlyoutNavigation } from '@kbn/security-solution-common'; import { useKibana } from '../../../common/lib/kibana'; import { HeaderActions } from './components/header_actions'; +import { FlyoutNavigation } from '../../shared/components/flyout_navigation'; import { DocumentDetailsLeftPanelKey } from '../shared/constants/panel_keys'; import { useDocumentDetailsContext } from '../shared/context'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/shared/context.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/shared/context.tsx index f2c5d8bfa530f..12e2ad4f2a0b6 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/shared/context.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/shared/context.tsx @@ -9,8 +9,9 @@ import type { BrowserFields, TimelineEventsDetailsItem } from '@kbn/timelines-pl import React, { createContext, memo, useContext, useMemo } from 'react'; import type { EcsSecurityExtension as Ecs } from '@kbn/securitysolution-ecs'; import { TableId } from '@kbn/securitysolution-data-table'; -import { FlyoutError, FlyoutLoading } from '@kbn/security-solution-common/src/flyout'; import { useEventDetails } from './hooks/use_event_details'; +import { FlyoutError } from '../../shared/components/flyout_error'; +import { FlyoutLoading } from '../../shared/components/flyout_loading'; import type { SearchHit } from '../../../../common/search_strategy'; import { useBasicDataFromDetailsData } from './hooks/use_basic_data_from_details_data'; import type { DocumentDetailsProps } from './types'; diff --git a/x-pack/plugins/security_solution/public/flyout/document_details/shared/utils/tour_step_config.tsx b/x-pack/plugins/security_solution/public/flyout/document_details/shared/utils/tour_step_config.tsx index 3f597e47c770c..7b850cca82450 100644 --- a/x-pack/plugins/security_solution/public/flyout/document_details/shared/utils/tour_step_config.tsx +++ b/x-pack/plugins/security_solution/public/flyout/document_details/shared/utils/tour_step_config.tsx @@ -9,7 +9,7 @@ import { EuiText, EuiCode, type EuiTourStepProps } from '@elastic/eui'; import React from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; -import { HEADER_NAVIGATION_BUTTON_TEST_ID } from '@kbn/security-solution-common'; +import { HEADER_NAVIGATION_BUTTON_TEST_ID } from '../../../shared/components/test_ids'; import { OVERVIEW_TAB_LABEL_TEST_ID } from '../../right/test_ids'; import { RULE_SUMMARY_BUTTON_TEST_ID } from '../../right/components/test_ids'; import { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/host_preview/footer.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/host_preview/footer.tsx index 3ea6d7a5e0438..e550da28b532a 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/host_preview/footer.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/host_preview/footer.tsx @@ -9,7 +9,7 @@ import { EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { FlyoutFooter } from '@kbn/security-solution-common'; +import { FlyoutFooter } from '../../shared/components/flyout_footer'; import { HostPanelKey } from '../host_right'; export interface HostPreviewPanelFooterProps { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx index 4538f53f0bd81..2e7c14fc38027 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/content.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { EuiHorizontalRule } from '@elastic/eui'; -import { FlyoutBody } from '@kbn/security-solution-common'; +import { FlyoutBody } from '../../shared/components/flyout_body'; import { EntityInsight } from '../../../cloud_security_posture/components/entity_insight'; import { AssetCriticalityAccordion } from '../../../entity_analytics/components/asset_criticality/asset_criticality_selector'; import { FlyoutRiskSummary } from '../../../entity_analytics/components/risk_summary_flyout/risk_summary'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/header.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/header.tsx index 706790770eb6c..b5df2f81d1b0a 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/header.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/header.tsx @@ -9,11 +9,12 @@ import { EuiSpacer, EuiBadge, EuiText, EuiFlexItem, EuiFlexGroup } from '@elasti import { FormattedMessage } from '@kbn/i18n-react'; import React, { useMemo } from 'react'; import { SecurityPageName } from '@kbn/security-solution-navigation'; -import { FlyoutHeader, FlyoutTitle } from '@kbn/security-solution-common'; import type { HostItem } from '../../../../common/search_strategy'; import { getHostDetailsUrl } from '../../../common/components/link_to'; import { SecuritySolutionLinkAnchor } from '../../../common/components/links'; import { PreferenceFormattedDate } from '../../../common/components/formatted_date'; +import { FlyoutHeader } from '../../shared/components/flyout_header'; +import { FlyoutTitle } from '../../shared/components/flyout_title'; import type { ObservedEntityData } from '../shared/components/observed_entity/types'; interface HostPanelHeaderProps { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/index.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/index.tsx index 9c75287ed0657..adc54b58f75cb 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/host_right/index.tsx @@ -9,7 +9,6 @@ import React, { useCallback, useMemo } from 'react'; import type { FlyoutPanelProps } from '@kbn/expandable-flyout'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { FlyoutLoading, FlyoutNavigation } from '@kbn/security-solution-common'; import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; import { useMisconfigurationPreview } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_preview'; import { useVulnerabilitiesPreview } from '@kbn/cloud-security-posture/src/hooks/use_vulnerabilities_preview'; @@ -26,6 +25,8 @@ import { useGlobalTime } from '../../../common/containers/use_global_time'; import type { HostItem } from '../../../../common/search_strategy'; import { buildHostNamesFilter } from '../../../../common/search_strategy'; import { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine'; +import { FlyoutLoading } from '../../shared/components/flyout_loading'; +import { FlyoutNavigation } from '../../shared/components/flyout_navigation'; import { HostPanelContent } from './content'; import { HostPanelHeader } from './header'; import { AnomalyTableProvider } from '../../../common/components/ml/anomaly/anomaly_table_provider'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/left_panel/left_panel_content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/left_panel/left_panel_content.tsx index f52480285a567..5a66a5b305611 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/left_panel/left_panel_content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/left_panel/left_panel_content.tsx @@ -9,7 +9,7 @@ import { useEuiBackgroundColor } from '@elastic/eui'; import type { VFC } from 'react'; import React, { useMemo } from 'react'; import { css } from '@emotion/react'; -import { FlyoutBody } from '@kbn/security-solution-common'; +import { FlyoutBody } from '../../../../shared/components/flyout_body'; import type { EntityDetailsLeftPanelTab, LeftPanelTabsType } from './left_panel_header'; export interface PanelContentProps { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/left_panel/left_panel_header.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/left_panel/left_panel_header.tsx index 438f75e7a4ccb..08623c941ba67 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/left_panel/left_panel_header.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/shared/components/left_panel/left_panel_header.tsx @@ -9,7 +9,7 @@ import { EuiTab, EuiTabs, useEuiBackgroundColor } from '@elastic/eui'; import type { ReactElement, VFC } from 'react'; import React, { memo } from 'react'; import { css } from '@emotion/react'; -import { FlyoutHeader } from '@kbn/security-solution-common'; +import { FlyoutHeader } from '../../../../shared/components/flyout_header'; export type LeftPanelTabsType = Array<{ id: EntityDetailsLeftPanelTab; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/index.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/index.tsx index ae3e99cc17cfe..8e6cf3a9ee9d2 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/index.tsx @@ -8,9 +8,9 @@ import React, { useMemo } from 'react'; import type { FlyoutPanelProps, PanelPath } from '@kbn/expandable-flyout'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { FlyoutLoading } from '@kbn/security-solution-common'; import { useManagedUser } from '../shared/hooks/use_managed_user'; import { useTabs } from './tabs'; +import { FlyoutLoading } from '../../shared/components/flyout_loading'; import type { EntityDetailsLeftPanelTab, LeftPanelTabsType, diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/asset_document.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/asset_document.tsx index 31053cf88d931..3aa4a72ffe898 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/asset_document.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_details_left/tabs/asset_document.tsx @@ -12,10 +12,10 @@ import { FormattedMessage } from '@kbn/i18n-react'; import type { EuiButtonGroupOptionProps } from '@elastic/eui'; import { EuiButtonGroup } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FlyoutBody } from '@kbn/security-solution-common'; import { JsonTab } from '../../../document_details/right/tabs/json_tab'; import { TableTab } from '../../../document_details/right/tabs/table_tab'; import { FLYOUT_BODY_TEST_ID, JSON_TAB_TEST_ID, TABLE_TAB_TEST_ID } from './test_ids'; +import { FlyoutBody } from '../../../shared/components/flyout_body'; export type RightPanelPaths = 'overview' | 'table' | 'json'; export interface AssetDocumentPanelProps extends FlyoutPanelProps { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_preview/footer.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_preview/footer.tsx index 6921d1a73d4e2..7f55feb7a347c 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_preview/footer.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_preview/footer.tsx @@ -9,7 +9,7 @@ import { EuiLink, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { FlyoutFooter } from '@kbn/security-solution-common'; +import { FlyoutFooter } from '../../shared/components/flyout_footer'; import { UserPanelKey } from '../user_right'; export interface UserPreviewPanelFooterProps { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/components/managed_user_accordion.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/components/managed_user_accordion.tsx index 84f6c96cb772b..8d9007713549e 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/components/managed_user_accordion.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/components/managed_user_accordion.tsx @@ -11,14 +11,13 @@ import React from 'react'; import { css } from '@emotion/react'; import { FormattedMessage } from '@kbn/i18n-react'; import { get } from 'lodash/fp'; -import { ExpandablePanel } from '@kbn/security-solution-common'; import { EntityDetailsLeftPanelTab } from '../../shared/components/left_panel/left_panel_header'; +import { ExpandablePanel } from '../../../shared/components/expandable_panel'; import type { ManagedUserFields } from '../../../../../common/search_strategy/security_solution/users/managed_details'; import { FormattedRelativePreferenceDate } from '../../../../common/components/formatted_date'; import { ONE_WEEK_IN_HOURS } from '../../shared/constants'; import { UserAssetTableType } from '../../../../explore/users/store/model'; - interface ManagedUserAccordionProps { children: React.ReactNode; title: string; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx index 8bcf5dd690200..0dbc1faa5cb42 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/content.tsx @@ -8,7 +8,6 @@ import { EuiHorizontalRule } from '@elastic/eui'; import React from 'react'; -import { FlyoutBody } from '@kbn/security-solution-common'; import { useIsExperimentalFeatureEnabled } from '../../../common/hooks/use_experimental_features'; import { AssetCriticalityAccordion } from '../../../entity_analytics/components/asset_criticality/asset_criticality_selector'; @@ -19,6 +18,7 @@ import { ManagedUser } from './components/managed_user'; import type { ManagedUserData } from './types'; import type { RiskScoreEntity, UserItem } from '../../../../common/search_strategy'; import { USER_PANEL_RISK_SCORE_QUERY_ID } from '.'; +import { FlyoutBody } from '../../shared/components/flyout_body'; import { ObservedEntity } from '../shared/components/observed_entity'; import type { ObservedEntityData } from '../shared/components/observed_entity/types'; import { useObservedUserItems } from './hooks/use_observed_user_items'; diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/header.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/header.tsx index 8fb54478b3c4f..e141779b559cf 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/header.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/header.tsx @@ -10,7 +10,6 @@ import { FormattedMessage } from '@kbn/i18n-react'; import React, { useMemo } from 'react'; import { max } from 'lodash/fp'; import { SecurityPageName } from '@kbn/security-solution-navigation'; -import { FlyoutHeader, FlyoutTitle } from '@kbn/security-solution-common'; import type { UserItem } from '../../../../common/search_strategy'; import { ManagedUserDatasetKey } from '../../../../common/search_strategy/security_solution/users/managed_details'; import { getUsersDetailsUrl } from '../../../common/components/link_to/redirect_to_users'; @@ -18,6 +17,8 @@ import type { ManagedUserData } from './types'; import { SecuritySolutionLinkAnchor } from '../../../common/components/links'; import { PreferenceFormattedDate } from '../../../common/components/formatted_date'; +import { FlyoutHeader } from '../../shared/components/flyout_header'; +import { FlyoutTitle } from '../../shared/components/flyout_title'; import type { ObservedEntityData } from '../shared/components/observed_entity/types'; interface UserPanelHeaderProps { diff --git a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx index ec55fb292abfd..3a60c06e3faea 100644 --- a/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/entity_details/user_right/index.tsx @@ -8,9 +8,8 @@ import React, { useCallback, useMemo } from 'react'; import type { FlyoutPanelProps } from '@kbn/expandable-flyout'; import { useExpandableFlyoutApi } from '@kbn/expandable-flyout'; -import { FlyoutLoading, FlyoutNavigation } from '@kbn/security-solution-common/src/flyout'; -import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; import { useMisconfigurationPreview } from '@kbn/cloud-security-posture/src/hooks/use_misconfiguration_preview'; +import { buildEntityFlyoutPreviewQuery } from '@kbn/cloud-security-posture-common'; import { useRefetchQueryById } from '../../../entity_analytics/api/hooks/use_refetch_query_by_id'; import type { Refetch } from '../../../common/types'; import { RISK_INPUTS_TAB_QUERY_ID } from '../../../entity_analytics/components/entity_details_flyout/tabs/risk_inputs/risk_inputs_tab'; @@ -26,6 +25,8 @@ import { useGlobalTime } from '../../../common/containers/use_global_time'; import { AnomalyTableProvider } from '../../../common/components/ml/anomaly/anomaly_table_provider'; import { buildUserNamesFilter } from '../../../../common/search_strategy'; import { RiskScoreEntity } from '../../../../common/entity_analytics/risk_engine'; +import { FlyoutLoading } from '../../shared/components/flyout_loading'; +import { FlyoutNavigation } from '../../shared/components/flyout_navigation'; import { UserPanelContent } from './content'; import { UserPanelHeader } from './header'; import { UserDetailsPanelKey } from '../user_details_left'; diff --git a/x-pack/plugins/security_solution/public/flyout/network_details/content.tsx b/x-pack/plugins/security_solution/public/flyout/network_details/content.tsx index 3634f73ef5a7f..8c9aa355ed43a 100644 --- a/x-pack/plugins/security_solution/public/flyout/network_details/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/network_details/content.tsx @@ -8,8 +8,8 @@ import type { FC } from 'react'; import React, { memo } from 'react'; import { EuiSpacer } from '@elastic/eui'; -import { FlyoutBody } from '@kbn/security-solution-common'; import { NetworkDetails } from './components/network_details'; +import { FlyoutBody } from '../shared/components/flyout_body'; import type { FlowTargetSourceDest } from '../../../common/search_strategy'; export interface PanelContentProps { diff --git a/x-pack/plugins/security_solution/public/flyout/network_details/header.tsx b/x-pack/plugins/security_solution/public/flyout/network_details/header.tsx index 1ef47c00689d9..8ffceb345b1e0 100644 --- a/x-pack/plugins/security_solution/public/flyout/network_details/header.tsx +++ b/x-pack/plugins/security_solution/public/flyout/network_details/header.tsx @@ -9,10 +9,11 @@ import type { FC } from 'react'; import React, { memo, useMemo } from 'react'; import type { EuiFlyoutHeader } from '@elastic/eui'; import { SecurityPageName } from '@kbn/deeplinks-security'; -import { FlyoutHeader, FlyoutTitle } from '@kbn/security-solution-common'; import { getNetworkDetailsUrl } from '../../common/components/link_to'; import { SecuritySolutionLinkAnchor } from '../../common/components/links'; import type { FlowTargetSourceDest } from '../../../common/search_strategy'; +import { FlyoutHeader } from '../shared/components/flyout_header'; +import { FlyoutTitle } from '../shared/components/flyout_title'; import { encodeIpv6 } from '../../common/lib/helpers'; export interface PanelHeaderProps extends React.ComponentProps { diff --git a/x-pack/plugins/security_solution/public/flyout/rule_details/preview/footer.tsx b/x-pack/plugins/security_solution/public/flyout/rule_details/preview/footer.tsx index 42c8c1a6d85b9..4440555e5fc53 100644 --- a/x-pack/plugins/security_solution/public/flyout/rule_details/preview/footer.tsx +++ b/x-pack/plugins/security_solution/public/flyout/rule_details/preview/footer.tsx @@ -8,9 +8,9 @@ import React, { memo } from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FlyoutFooter } from '@kbn/security-solution-common'; import { RULE_PREVIEW_FOOTER_TEST_ID, RULE_PREVIEW_OPEN_RULE_FLYOUT_TEST_ID } from './test_ids'; import { useRuleDetailsLink } from '../../document_details/shared/hooks/use_rule_details_link'; +import { FlyoutFooter } from '../../shared/components/flyout_footer'; /** * Footer in rule preview panel diff --git a/x-pack/plugins/security_solution/public/flyout/rule_details/right/content.tsx b/x-pack/plugins/security_solution/public/flyout/rule_details/right/content.tsx index 2778fc9c7ca22..8acc6cfe9b715 100644 --- a/x-pack/plugins/security_solution/public/flyout/rule_details/right/content.tsx +++ b/x-pack/plugins/security_solution/public/flyout/rule_details/right/content.tsx @@ -8,7 +8,6 @@ import React, { memo } from 'react'; import { EuiText, EuiHorizontalRule, EuiSpacer, EuiPanel } from '@elastic/eui'; import { css } from '@emotion/css'; import { FormattedMessage } from '@kbn/i18n-react'; -import { FlyoutBody } from '@kbn/security-solution-common'; import { ExpandableSection } from '../../document_details/right/components/expandable_section'; import { RuleAboutSection } from '../../../detection_engine/rule_management/components/rule_details/rule_about_section'; import { RuleScheduleSection } from '../../../detection_engine/rule_management/components/rule_details/rule_schedule_section'; @@ -23,6 +22,7 @@ import { ACTIONS_TEST_ID, } from './test_ids'; import type { RuleResponse } from '../../../../common/api/detection_engine'; +import { FlyoutBody } from '../../shared/components/flyout_body'; const panelViewStyle = css` dt { diff --git a/x-pack/plugins/security_solution/public/flyout/rule_details/right/header.tsx b/x-pack/plugins/security_solution/public/flyout/rule_details/right/header.tsx index 3dbbcc6b5b259..294870d6eebb7 100644 --- a/x-pack/plugins/security_solution/public/flyout/rule_details/right/header.tsx +++ b/x-pack/plugins/security_solution/public/flyout/rule_details/right/header.tsx @@ -15,7 +15,6 @@ import { EuiBadge, EuiLink, } from '@elastic/eui'; -import { FlyoutHeader, FlyoutTitle } from '@kbn/security-solution-common'; import { DELETED_RULE } from '../../../detection_engine/rule_details_ui/pages/rule_details/translations'; import { CreatedBy, UpdatedBy } from '../../../detections/components/rules/rule_info'; import { @@ -27,6 +26,8 @@ import { } from './test_ids'; import type { RuleResponse } from '../../../../common/api/detection_engine'; import { useRuleDetailsLink } from '../../document_details/shared/hooks/use_rule_details_link'; +import { FlyoutHeader } from '../../shared/components/flyout_header'; +import { FlyoutTitle } from '../../shared/components/flyout_title'; export interface PanelHeaderProps { /** diff --git a/x-pack/plugins/security_solution/public/flyout/rule_details/right/index.tsx b/x-pack/plugins/security_solution/public/flyout/rule_details/right/index.tsx index 958a2d4265186..10b22e22a575c 100644 --- a/x-pack/plugins/security_solution/public/flyout/rule_details/right/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/rule_details/right/index.tsx @@ -7,13 +7,15 @@ import React, { memo } from 'react'; import type { FlyoutPanelProps } from '@kbn/expandable-flyout'; -import { FlyoutLoading, FlyoutError, FlyoutNavigation } from '@kbn/security-solution-common'; import { i18n } from '@kbn/i18n'; import { PanelContent } from './content'; import { PanelHeader } from './header'; import { PreviewFooter } from '../preview/footer'; import { useRuleDetails } from '../hooks/use_rule_details'; import { LOADING_TEST_ID } from './test_ids'; +import { FlyoutLoading } from '../../shared/components/flyout_loading'; +import { FlyoutNavigation } from '../../shared/components/flyout_navigation'; +import { FlyoutError } from '../../shared/components/flyout_error'; export interface RulePanelExpandableFlyoutProps extends FlyoutPanelProps { key: 'rule-panel' | 'rule-preview-panel'; diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.stories.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.stories.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.stories.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.stories.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.test.tsx similarity index 99% rename from x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.test.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.test.tsx index cc282eb1156b5..87592b608613f 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.test.tsx @@ -13,7 +13,7 @@ import { EXPANDABLE_PANEL_CONTENT_TEST_ID, EXPANDABLE_PANEL_HEADER_TITLE_ICON_TEST_ID, EXPANDABLE_PANEL_TOGGLE_ICON_TEST_ID, -} from '../test_ids'; +} from './test_ids'; import { ThemeProvider } from '@emotion/react'; import { ExpandablePanel } from './expandable_panel'; diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.tsx similarity index 97% rename from x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.tsx index 383bbbb341c8e..88318ee2f2cfc 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/expandable_panel.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/expandable_panel.tsx @@ -110,7 +110,7 @@ export const ExpandablePanel: FC> = > = diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_body.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_body.test.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_body.test.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_body.test.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_body.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_body.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_body.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_body.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_error.stories.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.stories.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_error.stories.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.stories.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_error.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.test.tsx similarity index 94% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_error.test.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.test.tsx index f0565fe1df43f..e58d586a063b5 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_error.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.test.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { __IntlProvider as IntlProvider } from '@kbn/i18n-react'; import { render } from '@testing-library/react'; import { FlyoutError } from './flyout_error'; -import { FLYOUT_ERROR_TEST_ID } from '../test_ids'; +import { FLYOUT_ERROR_TEST_ID } from './test_ids'; describe('', () => { it('should render error title and body', () => { diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_error.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.tsx similarity index 84% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_error.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.tsx index f319d80dafe12..9ebef345540fe 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_error.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_error.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { EuiEmptyPrompt, EuiFlexItem } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { FLYOUT_ERROR_TEST_ID } from '../test_ids'; +import { FLYOUT_ERROR_TEST_ID } from './test_ids'; /** * Use this when you need to show an error state in the flyout @@ -21,7 +21,7 @@ export const FlyoutError: React.VFC = () => ( title={

@@ -30,7 +30,7 @@ export const FlyoutError: React.VFC = () => ( body={

diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_footer.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_footer.test.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_footer.test.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_footer.test.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_footer.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_footer.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_footer.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_footer.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_header.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_header.test.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_header.test.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_header.test.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_header.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_header.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_header.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_header.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_header_tabs.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_header_tabs.test.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_header_tabs.test.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_header_tabs.test.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_header_tabs.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_header_tabs.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_header_tabs.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_header_tabs.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_loading.stories.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.stories.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_loading.stories.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.stories.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_loading.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.test.tsx similarity index 94% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_loading.test.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.test.tsx index d55e85b3e978b..a164db8a6ce01 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_loading.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { render } from '@testing-library/react'; -import { FLYOUT_LOADING_TEST_ID } from '../test_ids'; +import { FLYOUT_LOADING_TEST_ID } from './test_ids'; import { FlyoutLoading } from './flyout_loading'; describe('', () => { diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_loading.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.tsx similarity index 94% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_loading.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.tsx index cffe17c8ccbf1..0c98957dd929b 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_loading.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_loading.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { EuiFlexItem, EuiLoadingSpinner } from '@elastic/eui'; import { css } from '@emotion/react'; -import { FLYOUT_LOADING_TEST_ID } from '../test_ids'; +import { FLYOUT_LOADING_TEST_ID } from './test_ids'; export interface FlyoutLoadingProps { /** diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_navigation.stories.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.stories.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_navigation.stories.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.stories.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_navigation.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.test.tsx similarity index 78% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_navigation.test.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.test.tsx index d010796008880..321245ccde86e 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_navigation.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.test.tsx @@ -8,61 +8,39 @@ import type { FC, PropsWithChildren } from 'react'; import React from 'react'; import { act, render } from '@testing-library/react'; +import { TestProviders } from '../../../common/mock'; import { FlyoutNavigation } from './flyout_navigation'; import { COLLAPSE_DETAILS_BUTTON_TEST_ID, EXPAND_DETAILS_BUTTON_TEST_ID, HEADER_ACTIONS_TEST_ID, -} from '../test_ids'; +} from './test_ids'; +import type { ExpandableFlyoutState } from '@kbn/expandable-flyout'; import { - ExpandableFlyoutApi, - ExpandableFlyoutProvider, - ExpandableFlyoutState, useExpandableFlyoutApi, + type ExpandableFlyoutApi, useExpandableFlyoutState, } from '@kbn/expandable-flyout'; -import { I18nProvider } from '@kbn/i18n-react'; const expandDetails = jest.fn(); -const mockFlyoutCloseLeftPanel = jest.fn(); + +const ExpandableFlyoutTestProviders: FC> = ({ children }) => { + return {children}; +}; jest.mock('@kbn/expandable-flyout', () => ({ - useExpandableFlyoutApi: jest.fn(() => { - return { - closeFlyout: jest.fn(), - closeLeftPanel: jest.fn(), - closePreviewPanel: jest.fn(), - closeRightPanel: jest.fn(), - previousPreviewPanel: jest.fn(), - openFlyout: jest.fn(), - openLeftPanel: jest.fn(), - openPreviewPanel: jest.fn(), - openRightPanel: jest.fn(), - }; - }), + useExpandableFlyoutApi: jest.fn(), useExpandableFlyoutState: jest.fn(), ExpandableFlyoutProvider: ({ children }: React.PropsWithChildren<{}>) => <>{children}, - withExpandableFlyoutProvider: (Component: React.ComponentType) => { - return (props: T) => { - return ; - }; - }, - ExpandableFlyout: jest.fn(), })); -const ExpandableFlyoutTestProviders: FC> = ({ children }) => { - return ( - - {children} - - ); -}; +const flyoutContextValue = { + closeLeftPanel: jest.fn(), +} as unknown as ExpandableFlyoutApi; describe('', () => { beforeEach(() => { - jest.mocked(useExpandableFlyoutApi).mockReturnValue({ - closeLeftPanel: mockFlyoutCloseLeftPanel, - } as unknown as ExpandableFlyoutApi); + jest.mocked(useExpandableFlyoutApi).mockReturnValue(flyoutContextValue); jest.mocked(useExpandableFlyoutState).mockReturnValue({} as unknown as ExpandableFlyoutState); }); @@ -97,7 +75,7 @@ describe('', () => { expect(queryByTestId(EXPAND_DETAILS_BUTTON_TEST_ID)).not.toBeInTheDocument(); getByTestId(COLLAPSE_DETAILS_BUTTON_TEST_ID).click(); - expect(mockFlyoutCloseLeftPanel).toHaveBeenCalled(); + expect(flyoutContextValue.closeLeftPanel).toHaveBeenCalled(); }); }); diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_navigation.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.tsx similarity index 91% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_navigation.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.tsx index 961629147d781..8f9f1604bf407 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_navigation.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_navigation.tsx @@ -23,7 +23,7 @@ import { COLLAPSE_DETAILS_BUTTON_TEST_ID, EXPAND_DETAILS_BUTTON_TEST_ID, HEADER_NAVIGATION_BUTTON_TEST_ID, -} from '../test_ids'; +} from './test_ids'; export interface FlyoutNavigationProps { /** @@ -63,14 +63,14 @@ export const FlyoutNavigation: FC = memo( size="s" data-test-subj={COLLAPSE_DETAILS_BUTTON_TEST_ID} aria-label={i18n.translate( - 'securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel', + 'xpack.securitySolution.flyout.right.header.collapseDetailButtonAriaLabel', { defaultMessage: 'Collapse details', } )} > @@ -87,14 +87,14 @@ export const FlyoutNavigation: FC = memo( size="s" data-test-subj={EXPAND_DETAILS_BUTTON_TEST_ID} aria-label={i18n.translate( - 'securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel', + 'xpack.securitySolution.flyout.right.header.expandDetailButtonAriaLabel', { defaultMessage: 'Expand details', } )} > diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_title.stories.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_title.stories.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_title.stories.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_title.stories.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_title.test.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_title.test.tsx similarity index 98% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_title.test.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_title.test.tsx index 3fde2b034219b..1f2d0c128f411 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_title.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_title.test.tsx @@ -12,7 +12,7 @@ import { TITLE_HEADER_ICON_TEST_ID, TITLE_HEADER_TEXT_TEST_ID, TITLE_LINK_ICON_TEST_ID, -} from '../test_ids'; +} from './test_ids'; const title = 'test title'; const TEST_ID = 'test'; diff --git a/x-pack/packages/security-solution/common/src/flyout/common/components/flyout_title.tsx b/x-pack/plugins/security_solution/public/flyout/shared/components/flyout_title.tsx similarity index 100% rename from x-pack/packages/security-solution/common/src/flyout/common/components/flyout_title.tsx rename to x-pack/plugins/security_solution/public/flyout/shared/components/flyout_title.tsx diff --git a/x-pack/packages/security-solution/common/src/flyout/common/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/shared/components/test_ids.ts similarity index 97% rename from x-pack/packages/security-solution/common/src/flyout/common/test_ids.ts rename to x-pack/plugins/security_solution/public/flyout/shared/components/test_ids.ts index 60ccb0a234fde..9df26dbfb694d 100644 --- a/x-pack/packages/security-solution/common/src/flyout/common/test_ids.ts +++ b/x-pack/plugins/security_solution/public/flyout/shared/components/test_ids.ts @@ -5,7 +5,7 @@ * 2.0. */ -export const PREFIX = 'securitySolutionFlyout' as const; +import { PREFIX } from '../test_ids'; export const FLYOUT_ERROR_TEST_ID = `${PREFIX}Error` as const; export const FLYOUT_LOADING_TEST_ID = `${PREFIX}Loading` as const; diff --git a/x-pack/plugins/security_solution/tsconfig.json b/x-pack/plugins/security_solution/tsconfig.json index a84f21c047ea8..f8fdcfcd8f438 100644 --- a/x-pack/plugins/security_solution/tsconfig.json +++ b/x-pack/plugins/security_solution/tsconfig.json @@ -15,11 +15,7 @@ "public/**/*.json", "../../../typings/**/*" ], - "exclude": [ - "target/**/*", - "**/cypress/**", - "public/management/cypress.config.ts" - ], + "exclude": ["target/**/*", "**/cypress/**", "public/management/cypress.config.ts"], "kbn_references": [ "@kbn/core", { @@ -209,7 +205,6 @@ "@kbn/core-theme-browser", "@kbn/integration-assistant-plugin", "@kbn/avc-banner", - "@kbn/security-solution-common", "@kbn/esql-ast", "@kbn/esql-validation-autocomplete", "@kbn/config", diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.test.ts index 77de60660a975..de5a94a4c39c9 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.test.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.test.ts @@ -758,7 +758,6 @@ describe('send_email module', () => { url: 'smtp://example.com:1025', ssl: { certificateAuthoritiesData: 'ca cert data goes here', - rejectUnauthorized: true, }, smtp: { ignoreTLS: true, @@ -786,7 +785,7 @@ describe('send_email module', () => { "secure": false, "tls": Object { "ca": "ca cert data goes here", - "rejectUnauthorized": true, + "rejectUnauthorized": false, }, }, ] @@ -811,7 +810,6 @@ describe('send_email module', () => { url: 'smtp://example.com:1025', ssl: { certificateAuthoritiesData: 'ca cert data goes here', - rejectUnauthorized: true, }, smtp: { requireTLS: true, @@ -837,7 +835,6 @@ describe('send_email module', () => { "secure": false, "tls": Object { "ca": "ca cert data goes here", - "rejectUnauthorized": true, }, }, ] diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.ts index 199d96f352389..06ae036f40b2c 100644 --- a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.ts +++ b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email.ts @@ -289,10 +289,7 @@ function getTransportConfig( tlsConfig.ca = sslSettings?.certificateAuthoritiesData; } - const sslSettingsFromConfig = getSSLSettingsFromConfig( - sslSettings?.verificationMode, - sslSettings?.rejectUnauthorized - ); + const sslSettingsFromConfig = getSSLSettingsFromConfig(sslSettings?.verificationMode); const nodeTLSOptions = getNodeSSLOptions(logger, sslSettingsFromConfig.verificationMode); if (!transportConfig.tls) { transportConfig.tls = { ...tlsConfig, ...nodeTLSOptions }; diff --git a/x-pack/plugins/transform/server/routes/api/audit_messages/register_route.ts b/x-pack/plugins/transform/server/routes/api/audit_messages/register_route.ts index 00dd124f1aa01..aef0183ef3571 100644 --- a/x-pack/plugins/transform/server/routes/api/audit_messages/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/audit_messages/register_route.ts @@ -35,6 +35,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { params: transformIdParamSchema, diff --git a/x-pack/plugins/transform/server/routes/api/delete_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/delete_transforms/register_route.ts index 20c169c79dda0..3a7af3313175a 100644 --- a/x-pack/plugins/transform/server/routes/api/delete_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/delete_transforms/register_route.ts @@ -34,6 +34,13 @@ export function registerRoute(routeDependencies: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: deleteTransformsRequestSchema, diff --git a/x-pack/plugins/transform/server/routes/api/field_histograms/register_route.ts b/x-pack/plugins/transform/server/routes/api/field_histograms/register_route.ts index c3fe803ba2366..03cee7befb151 100644 --- a/x-pack/plugins/transform/server/routes/api/field_histograms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/field_histograms/register_route.ts @@ -23,6 +23,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { params: dataViewTitleSchema, diff --git a/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/register_route.ts index 2826820f8d232..55d4f66e7dc90 100644 --- a/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/reauthorize_transforms/register_route.ts @@ -32,6 +32,13 @@ export function registerRoute(routeDependencies: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: reauthorizeTransformsRequestSchema, diff --git a/x-pack/plugins/transform/server/routes/api/reset_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/reset_transforms/register_route.ts index 5a239f0767fa4..de6c3e8408f62 100644 --- a/x-pack/plugins/transform/server/routes/api/reset_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/reset_transforms/register_route.ts @@ -33,6 +33,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: resetTransformsRequestSchema, diff --git a/x-pack/plugins/transform/server/routes/api/schedule_now_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/schedule_now_transforms/register_route.ts index 75000050ddebb..a19f0d0ef61af 100644 --- a/x-pack/plugins/transform/server/routes/api/schedule_now_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/schedule_now_transforms/register_route.ts @@ -33,6 +33,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: scheduleNowTransformsRequestSchema, diff --git a/x-pack/plugins/transform/server/routes/api/start_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/start_transforms/register_route.ts index 1ba1a0f098a78..ddff95471711f 100644 --- a/x-pack/plugins/transform/server/routes/api/start_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/start_transforms/register_route.ts @@ -33,6 +33,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: startTransformsRequestSchema, diff --git a/x-pack/plugins/transform/server/routes/api/stop_transforms/register_route.ts b/x-pack/plugins/transform/server/routes/api/stop_transforms/register_route.ts index 5fdc5a97dd55a..bb1c73482f525 100644 --- a/x-pack/plugins/transform/server/routes/api/stop_transforms/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/stop_transforms/register_route.ts @@ -33,6 +33,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: stopTransformsRequestSchema, diff --git a/x-pack/plugins/transform/server/routes/api/transforms_all/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_all/register_route.ts index 29cbd34bffd68..9bd95b02d60ae 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_all/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_all/register_route.ts @@ -32,6 +32,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: false, }, async (ctx, request, response) => { diff --git a/x-pack/plugins/transform/server/routes/api/transforms_create/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_create/register_route.ts index 7cfb0dc90a410..82df03077111b 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_create/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_create/register_route.ts @@ -43,6 +43,13 @@ export function registerRoute(routeDependencies: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { params: transformIdParamSchema, diff --git a/x-pack/plugins/transform/server/routes/api/transforms_nodes/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_nodes/register_route.ts index 701306ff6481c..f63e3412e24d8 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_nodes/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_nodes/register_route.ts @@ -27,6 +27,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: false, }, async (ctx, request, response) => { diff --git a/x-pack/plugins/transform/server/routes/api/transforms_preview/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_preview/register_route.ts index 21a902e575b04..386e50296317d 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_preview/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_preview/register_route.ts @@ -31,6 +31,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { body: postTransformsPreviewRequestSchema, diff --git a/x-pack/plugins/transform/server/routes/api/transforms_single/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_single/register_route.ts index 30b54b3847992..bdec2e5bd2836 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_single/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_single/register_route.ts @@ -30,6 +30,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { params: transformIdParamSchema, diff --git a/x-pack/plugins/transform/server/routes/api/transforms_stats_all/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_stats_all/register_route.ts index 3136163cf99f5..40f21ed1f84b5 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_stats_all/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_stats_all/register_route.ts @@ -37,6 +37,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { >( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { query: getTransformStatsQuerySchema, diff --git a/x-pack/plugins/transform/server/routes/api/transforms_stats_single/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_stats_single/register_route.ts index 5e784506ae57a..29178398ea631 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_stats_single/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_stats_single/register_route.ts @@ -34,6 +34,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { params: transformIdParamSchema, diff --git a/x-pack/plugins/transform/server/routes/api/transforms_update/register_route.ts b/x-pack/plugins/transform/server/routes/api/transforms_update/register_route.ts index 60719e68d596c..916b68a369098 100644 --- a/x-pack/plugins/transform/server/routes/api/transforms_update/register_route.ts +++ b/x-pack/plugins/transform/server/routes/api/transforms_update/register_route.ts @@ -35,6 +35,13 @@ export function registerRoute({ router, getLicense }: RouteDependencies) { .addVersion( { version: '1', + security: { + authz: { + enabled: false, + reason: + 'This route is opted out from authorization because permissions will be checked by elasticsearch', + }, + }, validate: { request: { params: transformIdParamSchema, diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 1c432e420d2a3..b3de99ebfdd3c 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -7077,14 +7077,6 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "Applications de confiance", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "Aide à atténuer les conflits avec d'autres logiciels, généralement d'autres applications d'antivirus ou de sécurité des points de terminaison.", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "\"Tous les espaces\" est requis pour l'accès aux applications de confiance.", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel": "Réduire les détails", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonLabel": "Réduire les détails", - "securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel": "Développer les détails", - "securitySolutionPackages.flyout.right.header.expandDetailButtonLabel": "Développer les détails", - "securitySolutionPackages.flyout.shared.errorDescription": "Une erreur est survenue lors de l'affichage de {message}.", - "securitySolutionPackages.flyout.shared.errorTitle": "Impossible d'afficher {title}.", - "securitySolutionPackages.flyout.shared.ExpandablePanelButtonIconAriaLabel": "Activer/Désactiver le panneau extensible", - "securitySolutionPackages.flyout.shared.expandablePanelLoadingAriaLabel": "panneau extensible", "securitySolutionPackages.markdown.insight.upsell": "Passez au niveau {requiredLicense} pour pouvoir utiliser les informations des guides d'investigation", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "Passez au niveau {requiredLicense} pour pouvoir utiliser les interactions des guides d'investigation", "securitySolutionPackages.navigation.landingLinks": "Vues de sécurité", @@ -7510,16 +7502,11 @@ "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.encodeDescription": "Si elle est activée, l'URL sera précédée de l’encodage-pourcent comme caractère d'échappement", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.encodeUrl": "Encoder l'URL", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.openInNewTabLabel": "Ouvrir l'URL dans un nouvel onglet", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewHelpText": "Veuillez noter que dans l'aperçu, les variables '{{event.*}}' sont remplacées par des valeurs factices.", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewLabel": "Aperçu de l'URL :", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewLinkText": "Aperçu", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateLabel": "Entrer l'URL", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplatePlaceholderText": "Exemple : {exampleUrl}", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateSyntaxHelpLinkText": "Aide pour la syntaxe", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateVariablesFilterPlaceholderText": "Variables de filtre", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateVariablesHelpLinkText": "Aide", - "uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatErrorMessage": "Format non valide : {message}", - "uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatGeneralErrorMessage": "Format non valide. Exemple : {exampleUrl}", + "uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatGeneralErrorMessage": "Format non valide.", "unifiedDataTable.advancedDiffModesTooltip": "Les modes avancés offrent des capacités de diffraction améliorées, mais ils fonctionnent sur des documents bruts et ne prennent donc pas en charge le formatage des champs.", "unifiedDataTable.clearSelection": "Effacer la sélection", "unifiedDataTable.compareSelectedRowsButtonLabel": "Comparer", @@ -38736,6 +38723,10 @@ "xpack.securitySolution.flyout.right.alertPreview.ariaLabel": "Voir un aperçu de l'alerte avec l'id {id}", "xpack.securitySolution.flyout.right.eventCategoryText": "Catégorie d'événement", "xpack.securitySolution.flyout.right.header.assignedTitle": "Utilisateurs affectés", + "xpack.securitySolution.flyout.right.header.collapseDetailButtonAriaLabel": "Réduire les détails", + "xpack.securitySolution.flyout.right.header.collapseDetailButtonLabel": "Réduire les détails", + "xpack.securitySolution.flyout.right.header.expandDetailButtonAriaLabel": "Développer les détails", + "xpack.securitySolution.flyout.right.header.expandDetailButtonLabel": "Développer les détails", "xpack.securitySolution.flyout.right.header.headerTitle": "Détails des documents", "xpack.securitySolution.flyout.right.header.jsonTabLabel": "JSON", "xpack.securitySolution.flyout.right.header.overviewTabLabel": "Aperçu", @@ -38814,6 +38805,10 @@ "xpack.securitySolution.flyout.right.visualizations.sessionPreview.sessionPreviewTitle": "Aperçu du visualiseur de session", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.sessionPreviewTooltip": "Investiguer dans la chronologie", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.timeDescription": "à", + "xpack.securitySolution.flyout.shared.errorDescription": "Une erreur est survenue lors de l'affichage de {message}.", + "xpack.securitySolution.flyout.shared.errorTitle": "Impossible d'afficher {title}.", + "xpack.securitySolution.flyout.shared.ExpandablePanelButtonIconAriaLabel": "Activer/Désactiver le panneau extensible", + "xpack.securitySolution.flyout.shared.expandablePanelLoadingAriaLabel": "panneau extensible", "xpack.securitySolution.flyout.tour.entities.description": "Consultez la vue {entities} étendue pour en savoir plus sur les hôtes et les utilisateurs liés à l'alerte.", "xpack.securitySolution.flyout.tour.entities.text": "Entités", "xpack.securitySolution.flyout.tour.entities.title": "De nouvelles informations sur les hôtes et les utilisateurs sont disponibles", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1293fddd55857..b813f2189ed3b 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6832,14 +6832,6 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "信頼できるアプリケーション", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "他のソフトウェア(通常は他のウイルス対策またはエンドポイントセキュリティアプリケーション)との競合を軽減することができます。", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "信頼できるアプリケーションのアクセスには、すべてのスペースが必要です。", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel": "詳細を折りたたむ", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonLabel": "詳細を折りたたむ", - "securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel": "詳細を展開", - "securitySolutionPackages.flyout.right.header.expandDetailButtonLabel": "詳細を展開", - "securitySolutionPackages.flyout.shared.errorDescription": "{message}の表示中にエラーが発生しました。", - "securitySolutionPackages.flyout.shared.errorTitle": "{title}を表示できません。", - "securitySolutionPackages.flyout.shared.ExpandablePanelButtonIconAriaLabel": "展開可能なパネルトグル", - "securitySolutionPackages.flyout.shared.expandablePanelLoadingAriaLabel": "展開可能なパネル", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "{requiredLicense}にアップグレードして、調査ガイドのインタラクションを利用", "securitySolutionPackages.navigation.landingLinks": "セキュリティビュー", "securitySolutionPackages.sideNav.betaBadge.label": "ベータ", @@ -7264,16 +7256,11 @@ "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.encodeDescription": "有効な場合、URLはパーセントエンコーディングを使用してエスケープされます", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.encodeUrl": "URLのエンコード", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.openInNewTabLabel": "URLを新しいタブで開く", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewHelpText": "プレビュー'{{event.*}}'では、変数にダミー値が代入されます。", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewLabel": "URLプレビュー:", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewLinkText": "プレビュー", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateLabel": "URLを入力", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplatePlaceholderText": "例:{exampleUrl}", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateSyntaxHelpLinkText": "構文ヘルプ", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateVariablesFilterPlaceholderText": "変数をフィルター", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateVariablesHelpLinkText": "ヘルプ", - "uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatErrorMessage": "無効な形式:{message}", - "uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatGeneralErrorMessage": "無効なフォーマット。例:{exampleUrl}", + "uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatGeneralErrorMessage": "無効なフォーマット。", "unifiedDataTable.advancedDiffModesTooltip": "高度なモードでは、拡張差異機能を利用できますが、未加工ドキュメントで動作するため、フィールド書式設定はサポートされません。", "unifiedDataTable.clearSelection": "選択した項目をクリア", "unifiedDataTable.compareSelectedRowsButtonLabel": "比較", @@ -38479,6 +38466,10 @@ "xpack.securitySolution.flyout.right.alertPreview.ariaLabel": "ID {id}のアラートをプレビュー", "xpack.securitySolution.flyout.right.eventCategoryText": "イベントカテゴリ", "xpack.securitySolution.flyout.right.header.assignedTitle": "担当者", + "xpack.securitySolution.flyout.right.header.collapseDetailButtonAriaLabel": "詳細を折りたたむ", + "xpack.securitySolution.flyout.right.header.collapseDetailButtonLabel": "詳細を折りたたむ", + "xpack.securitySolution.flyout.right.header.expandDetailButtonAriaLabel": "詳細を展開", + "xpack.securitySolution.flyout.right.header.expandDetailButtonLabel": "詳細を展開", "xpack.securitySolution.flyout.right.header.headerTitle": "ドキュメント詳細", "xpack.securitySolution.flyout.right.header.jsonTabLabel": "JSON", "xpack.securitySolution.flyout.right.header.overviewTabLabel": "概要", @@ -38557,6 +38548,10 @@ "xpack.securitySolution.flyout.right.visualizations.sessionPreview.sessionPreviewTitle": "セッションビューアープレビュー", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.sessionPreviewTooltip": "タイムラインで調査", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.timeDescription": "に", + "xpack.securitySolution.flyout.shared.errorDescription": "{message}の表示中にエラーが発生しました。", + "xpack.securitySolution.flyout.shared.errorTitle": "{title}を表示できません。", + "xpack.securitySolution.flyout.shared.ExpandablePanelButtonIconAriaLabel": "展開可能なパネルトグル", + "xpack.securitySolution.flyout.shared.expandablePanelLoadingAriaLabel": "展開可能なパネル", "xpack.securitySolution.flyout.tour.entities.description": "アラートに関連付けられたホストとユーザーの詳細については、展開された{entities}ビューを確認してください。", "xpack.securitySolution.flyout.tour.entities.text": "エンティティ", "xpack.securitySolution.flyout.tour.entities.title": "新しいホストとユーザーのインサイトがあります", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index c1df2f95c5384..5fbe2d35b72a6 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6846,14 +6846,7 @@ "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications": "受信任的应用程序", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.description": "帮助减少与其他软件(通常指其他防病毒或终端安全应用程序)的冲突。", "securitySolutionPackages.features.featureRegistry.subFeatures.trustedApplications.privilegesTooltip": "访问受信任的应用程序需要所有工作区。", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonAriaLabel": "折叠详情", - "securitySolutionPackages.flyout.right.header.collapseDetailButtonLabel": "折叠详情", - "securitySolutionPackages.flyout.right.header.expandDetailButtonAriaLabel": "展开详情", - "securitySolutionPackages.flyout.right.header.expandDetailButtonLabel": "展开详情", - "securitySolutionPackages.flyout.shared.errorDescription": "显示 {message} 时出现错误。", - "securitySolutionPackages.flyout.shared.errorTitle": "无法显示 {title}。", - "securitySolutionPackages.flyout.shared.ExpandablePanelButtonIconAriaLabel": "可展开面板切换按钮", - "securitySolutionPackages.flyout.shared.expandablePanelLoadingAriaLabel": "可展开面板", + "sgcuritySolutionPackages.flyout.shared.errorDescription": "显示 {message} 时出现错误。", "securitySolutionPackages.markdown.insight.upsell": "升级到{requiredLicense}以利用调查指南中的洞见", "securitySolutionPackages.markdown.investigationGuideInteractions.upsell": "升级到 {requiredLicense} 以利用调查指南交互", "securitySolutionPackages.navigation.landingLinks": "安全视图", @@ -7280,16 +7273,11 @@ "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.encodeDescription": "如果启用,将使用百分比编码转义 URL", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.encodeUrl": "编码 URL", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.openInNewTabLabel": "在新选项卡中打开 URL", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewHelpText": "请注意,在预览模式下,'{{event.*}}' 变量将替换为虚拟值。", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewLabel": "URL 预览:", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlPreviewLinkText": "预览", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateLabel": "输入 URL", - "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplatePlaceholderText": "例如:{exampleUrl}", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateSyntaxHelpLinkText": "语法帮助", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateVariablesFilterPlaceholderText": "筛选变量", "uiActionsEnhanced.drilldowns.urlDrilldownCollectConfig.urlTemplateVariablesHelpLinkText": "帮助", - "uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatErrorMessage": "格式无效:{message}", - "uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatGeneralErrorMessage": "格式无效。例如:{exampleUrl}", + "uiActionsEnhanced.drilldowns.urlDrilldownValidation.urlFormatGeneralErrorMessage": "格式无效。", "unifiedDataTable.advancedDiffModesTooltip": "高级模式提供了增强型差异功能,但在原始文档上运行,因此不支持字段格式化。", "unifiedDataTable.clearSelection": "清除所选内容", "unifiedDataTable.compareSelectedRowsButtonLabel": "比较", @@ -38525,6 +38513,10 @@ "xpack.securitySolution.flyout.right.alertPreview.ariaLabel": "预览 ID 为 {id} 的告警", "xpack.securitySolution.flyout.right.eventCategoryText": "事件类别", "xpack.securitySolution.flyout.right.header.assignedTitle": "被分配人", + "xpack.securitySolution.flyout.right.header.collapseDetailButtonAriaLabel": "折叠详情", + "xpack.securitySolution.flyout.right.header.collapseDetailButtonLabel": "折叠详情", + "xpack.securitySolution.flyout.right.header.expandDetailButtonAriaLabel": "展开详情", + "xpack.securitySolution.flyout.right.header.expandDetailButtonLabel": "展开详情", "xpack.securitySolution.flyout.right.header.headerTitle": "文档详情", "xpack.securitySolution.flyout.right.header.jsonTabLabel": "JSON", "xpack.securitySolution.flyout.right.header.overviewTabLabel": "概览", @@ -38602,6 +38594,10 @@ "xpack.securitySolution.flyout.right.visualizations.sessionPreview.sessionPreviewTitle": "会话查看器预览", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.sessionPreviewTooltip": "在时间线中调查", "xpack.securitySolution.flyout.right.visualizations.sessionPreview.timeDescription": "处于", + "xpack.securitySolution.flyout.shared.errorDescription": "显示 {message} 时出现错误。", + "xpack.securitySolution.flyout.shared.errorTitle": "无法显示 {title}。", + "xpack.securitySolution.flyout.shared.ExpandablePanelButtonIconAriaLabel": "可展开面板切换按钮", + "xpack.securitySolution.flyout.shared.expandablePanelLoadingAriaLabel": "可展开面板", "xpack.securitySolution.flyout.tour.entities.description": "请查阅展开的 {entities} 视图以了解与该告警有关的主机和用户的更多信息。", "xpack.securitySolution.flyout.tour.entities.text": "实体", "xpack.securitySolution.flyout.tour.entities.title": "有新主机和用户洞见可用", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_table.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_table.tsx index ee3ee18152e47..88f22f9687ea6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_table.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list_table.tsx @@ -750,6 +750,7 @@ export const RulesListTable = (props: RulesListTableProps) => { 'xpack.triggersActionsUI.sections.rulesList.rulesListTable.columns.editAriaLabel', { defaultMessage: 'Edit' } )} + disabled={!rule.enabledInLicense} /> ) : null} diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 3ff3def3f4b70..b8a576f99b8d0 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -88,7 +88,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) verificationMode = 'full', preconfiguredAlertHistoryEsIndex = false, customizeLocalHostSsl = false, - rejectUnauthorized = true, // legacy emailDomainsAllowed = undefined, testFiles = undefined, reportName = undefined, @@ -128,7 +127,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ? [ `--xpack.actions.proxyUrl=http://localhost:${proxyPort}`, `--xpack.actions.proxyOnlyHosts=${JSON.stringify(proxyHosts)}`, - '--xpack.actions.proxyRejectUnauthorizedCertificates=false', ] : [ `--xpack.actions.proxyUrl=http://elastic.co`, @@ -212,7 +210,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) `--xpack.alerting.enableFrameworkAlerts=true`, `--xpack.alerting.rulesSettings.cacheInterval=10000`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, - `--xpack.actions.rejectUnauthorized=${rejectUnauthorized}`, `--xpack.actions.microsoftGraphApiUrl=${servers.kibana.protocol}://${servers.kibana.hostname}:${servers.kibana.port}/api/_actions-FTS-external-service-simulators/exchange/users/test@/sendMail`, `--xpack.actions.ssl.verificationMode=${verificationMode}`, ...actionsProxyUrl, diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/webhook.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/webhook.ts index 03cdc6b966a75..d25ac1a5f135f 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/webhook.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/connector_types/stack/webhook.ts @@ -100,24 +100,6 @@ export default function webhookTest({ getService }: FtrProviderContext) { }); describe('ssl customization', () => { - it('should handle the xpack.actions.rejectUnauthorized: false', async () => { - const connectorId = 'custom.ssl.noCustom'; - const port = await getPortOfConnector(connectorId); - const server = await createTlsWebhookServer(port); - const { status, body } = await supertest - .post(`/api/actions/connector/${connectorId}/_execute`) - .set('kbn-xsrf', 'test') - .send({ - params: { - body: 'foo', - }, - }); - expect(status).to.eql(200); - server.close(); - - expect(body.status).to.eql('ok'); - }); - it('should handle the customized rejectUnauthorized: false', async () => { const connectorId = 'custom.ssl.rejectUnauthorizedFalse'; const port = await getPortOfConnector(connectorId); diff --git a/x-pack/test/alerting_api_integration/spaces_only_legacy/tests/actions/connector_types/stack/webhook.ts b/x-pack/test/alerting_api_integration/spaces_only_legacy/tests/actions/connector_types/stack/webhook.ts index d0865e5160fe5..b1d56f600585d 100644 --- a/x-pack/test/alerting_api_integration/spaces_only_legacy/tests/actions/connector_types/stack/webhook.ts +++ b/x-pack/test/alerting_api_integration/spaces_only_legacy/tests/actions/connector_types/stack/webhook.ts @@ -126,24 +126,6 @@ export default function webhookTest({ getService }: FtrProviderContext) { }); describe('ssl customization', () => { - it('should handle the xpack.actions.rejectUnauthorized: false', async () => { - const connectorId = 'custom.ssl.noCustom'; - const port = await getPortOfConnector(connectorId); - const server = await createTlsWebhookServer(port); - const { status, body } = await supertest - .post(`/api/actions/connector/${connectorId}/_execute`) - .set('kbn-xsrf', 'test') - .send({ - params: { - body: 'foo', - }, - }); - expect(status).to.eql(200); - server.close(); - - expect(body.status).to.eql('ok'); - }); - it('should handle the customized rejectUnauthorized: false', async () => { const connectorId = 'custom.ssl.rejectUnauthorizedFalse'; const port = await getPortOfConnector(connectorId); diff --git a/x-pack/test/functional/apps/aiops/change_point_detection.ts b/x-pack/test/functional/apps/aiops/change_point_detection.ts index 96628c143077c..22177a0a9166d 100644 --- a/x-pack/test/functional/apps/aiops/change_point_detection.ts +++ b/x-pack/test/functional/apps/aiops/change_point_detection.ts @@ -16,8 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { // aiops lives in the ML UI so we need some related services. const ml = getService('ml'); - // Failing: See https://github.com/elastic/kibana/issues/178258 - describe.skip('change point detection', function () { + describe('change point detection', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); await ml.testResources.createDataViewIfNeeded('ft_ecommerce', 'order_date'); diff --git a/x-pack/test/functional/apps/lens/group1/multiple_data_views.ts b/x-pack/test/functional/apps/lens/group1/multiple_data_views.ts index d65b10d0056e1..0164aa745fc8e 100644 --- a/x-pack/test/functional/apps/lens/group1/multiple_data_views.ts +++ b/x-pack/test/functional/apps/lens/group1/multiple_data_views.ts @@ -103,13 +103,13 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await testSubjects.click('fieldToggle-DistanceKilometers'); const data = await lens.getCurrentChartDebugState('xyVisChart'); - assertMatchesExpectedData(data, [expectedLogstashData, expectedFlightsData], 'lines'); + assertMatchesExpectedData(data, [expectedLogstashData, expectedFlightsData]); }); it('ignores global filters on layers using a data view without the filter field', async () => { await filterBar.addFilter({ field: 'Carrier', operation: 'exists' }); const data = await lens.getCurrentChartDebugState('xyVisChart'); - assertMatchesExpectedData(data, [expectedLogstashData, expectedFlightsData], 'lines'); + assertMatchesExpectedData(data, [expectedLogstashData, expectedFlightsData]); await lens.save(visTitle); }); @@ -120,7 +120,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await visualize.openSavedVisualization(visTitle); const data = await lens.getCurrentChartDebugState('xyVisChart'); - assertMatchesExpectedData(data, [expectedFlightsData], 'lines'); + assertMatchesExpectedData(data, [expectedFlightsData]); }); }); } diff --git a/x-pack/test/functional/apps/search_playground/playground_overview.ess.ts b/x-pack/test/functional/apps/search_playground/playground_overview.ess.ts index e64fafd4b010f..34b223075667d 100644 --- a/x-pack/test/functional/apps/search_playground/playground_overview.ess.ts +++ b/x-pack/test/functional/apps/search_playground/playground_overview.ess.ts @@ -110,6 +110,7 @@ export default function (ftrContext: FtrProviderContext) { before(async () => { await createConnector(); await createIndex(); + await pageObjects.searchPlayground.session.setSession(); await browser.refresh(); }); diff --git a/x-pack/test/functional/services/aiops/change_point_detection_page.ts b/x-pack/test/functional/services/aiops/change_point_detection_page.ts index 50c4278a9293e..79bc4c378fb1a 100644 --- a/x-pack/test/functional/services/aiops/change_point_detection_page.ts +++ b/x-pack/test/functional/services/aiops/change_point_detection_page.ts @@ -131,6 +131,12 @@ export function ChangePointDetectionPageProvider( }, async openPanelContextMenu(panelIndex: number) { + // Check if already open + const isOpen = await testSubjects.exists('aiopsChangePointDetectionAttachButton'); + if (isOpen) { + return; + } + await testSubjects.click( `aiopsChangePointPanel_${panelIndex} > aiopsChangePointDetectionContextMenuButton` ); diff --git a/x-pack/test/security_solution_api_integration/test_suites/edr_workflows/policy/trial_license_complete_tier/datastream_index_creation.ts b/x-pack/test/security_solution_api_integration/test_suites/edr_workflows/policy/trial_license_complete_tier/datastream_index_creation.ts index bc029369f3fe4..0fa75d7cfb989 100644 --- a/x-pack/test/security_solution_api_integration/test_suites/edr_workflows/policy/trial_license_complete_tier/datastream_index_creation.ts +++ b/x-pack/test/security_solution_api_integration/test_suites/edr_workflows/policy/trial_license_complete_tier/datastream_index_creation.ts @@ -28,8 +28,7 @@ export default function ({ getService }: FtrProviderContext) { const config = getService('config'); const isServerless = config.get('serverless'); - // FIXME:PT Remove @skipInServerlessMKI and enable it for MKI - describe('@ess @serverless @skipInServerlessMKI Creation of DOT indices for elastic defend policies', function () { + describe('@ess @serverless Creation of DOT indices for elastic defend policies', function () { let testData: PolicyTestResourceInfo; const getExpectedIndexList = (namespace: string): string[] => { diff --git a/x-pack/test_serverless/functional/test_suites/search/search_playground/playground_overview.ts b/x-pack/test_serverless/functional/test_suites/search/search_playground/playground_overview.ts index 44d96d565fec2..e1570d2191378 100644 --- a/x-pack/test_serverless/functional/test_suites/search/search_playground/playground_overview.ts +++ b/x-pack/test_serverless/functional/test_suites/search/search_playground/playground_overview.ts @@ -117,11 +117,11 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/189314 - describe.skip('with existing indices', () => { + describe('with existing indices', () => { before(async () => { await createConnector(); await createIndex(); + await pageObjects.searchPlayground.session.setSession(); await browser.refresh(); }); diff --git a/yarn.lock b/yarn.lock index 57ffec1e0a278..cbd5dd93a43fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6416,10 +6416,6 @@ version "0.0.0" uid "" -"@kbn/security-solution-common@link:x-pack/packages/security-solution/common": - version "0.0.0" - uid "" - "@kbn/security-solution-distribution-bar@link:x-pack/packages/security-solution/distribution_bar": version "0.0.0" uid "" @@ -7316,33 +7312,32 @@ resolved "https://registry.yarnpkg.com/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz#8ace5259254426ccef57f3175bc64ed7095ed919" integrity sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw== -"@langchain/community@0.2.18": - version "0.2.18" - resolved "https://registry.yarnpkg.com/@langchain/community/-/community-0.2.18.tgz#127a7ac53a30dd6dedede887811fdd992061e2d2" - integrity sha512-UsCB97dMG87giQLniKx4bjv7OnMw2vQeavSt9gqOnGCnfb5IQBAgdjX4SjwFPbVGMz1HQoQKVlNqQ64ozCdgNg== +"@langchain/community@0.3.11": + version "0.3.11" + resolved "https://registry.yarnpkg.com/@langchain/community/-/community-0.3.11.tgz#cb0f188f4e72c00beb1efdbd1fc7d7f47b70e636" + integrity sha512-hgnqsgWAhfUj9Kp0y+FGxlKot/qJFxat9GfIPJSJU4ViN434PgeMAQK53tkGZ361E2Zoo1V4RoGlSw4AjJILiA== dependencies: - "@langchain/core" "~0.2.11" - "@langchain/openai" "~0.1.0" + "@langchain/openai" ">=0.2.0 <0.4.0" binary-extensions "^2.2.0" expr-eval "^2.0.2" flat "^5.0.2" js-yaml "^4.1.0" - langchain "0.2.3" - langsmith "~0.1.30" + langchain ">=0.2.3 <0.3.0 || >=0.3.4 <0.4.0" + langsmith "^0.2.0" uuid "^10.0.0" zod "^3.22.3" zod-to-json-schema "^3.22.5" -"@langchain/core@>0.1.0 <0.3.0", "@langchain/core@>=0.2.11 <0.3.0", "@langchain/core@>=0.2.20 <0.3.0", "@langchain/core@>=0.2.5 <0.3.0", "@langchain/core@^0.2.18", "@langchain/core@~0.2.11": - version "0.2.32" - resolved "https://registry.yarnpkg.com/@langchain/core/-/core-0.2.32.tgz#a5dfbc49f8b6c15c8082763b93aeae8f9f4ca1a0" - integrity sha512-S27M+9Qou2qtcLfFGEvANkJ/zHq5XApeQsR6Q4I7C6v9x07eoYr558h6vVy6WQmKcksgbCIJ854ikwp173wBjA== +"@langchain/core@>0.1.0 <0.3.0", "@langchain/core@^0.3.16": + version "0.3.16" + resolved "https://registry.yarnpkg.com/@langchain/core/-/core-0.3.16.tgz#60ece9762c2830eb8e5731c70b24e1707178fc67" + integrity sha512-g83M2Z1XlhECFUtT4C7XLsVVGt2Hk3Y/KhS5tZSsz+Gqtxwd790/MD7MxdUHpZj0VKkvrFuWARWpJmNKlkiY+g== dependencies: ansi-styles "^5.0.0" camelcase "6" decamelize "1.2.0" js-tiktoken "^1.0.12" - langsmith "^0.1.43" + langsmith "^0.2.0" mustache "^4.2.0" p-queue "^6.6.2" p-retry "4" @@ -7366,10 +7361,10 @@ "@langchain/google-common" "~0.1.0" google-auth-library "^8.9.0" -"@langchain/google-genai@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@langchain/google-genai/-/google-genai-0.1.0.tgz#89552873210d72a5834de20fcbef3e6753283344" - integrity sha512-6rIba77zJVMj+048tLfkCBrkFbfAMiT+AfLEsu5s+CFoFmXMiI/dbKeDL4vhUWrJVb9uL4ZZyrnl0nKxyEKYgA== +"@langchain/google-genai@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@langchain/google-genai/-/google-genai-0.1.2.tgz#23387d7027b4a787b542fc5cfb7a2469e9f4c845" + integrity sha512-oePFjTurY4O2tJiU4cJ3Wu9L+JGVwYib2LovI+SxGJImVyVlQQ1HV2SVek03vqG4d0kiX0XLQTEC7mJ7EBySkg== dependencies: "@google/generative-ai" "^0.7.0" zod-to-json-schema "^3.22.4" @@ -7381,27 +7376,45 @@ dependencies: "@langchain/google-gauth" "~0.1.0" -"@langchain/langgraph@0.0.34": - version "0.0.34" - resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-0.0.34.tgz#1504c29ce524d08d6f076c34e0623c6de1f1246c" - integrity sha512-cuig46hGmZkf+eXw1Cx2CtkAWgsAbIpa5ABLxn9oe1rbtvHXmfekqHZA6tGE0DipEmsN4H64zFcDEJydll6Sdw== +"@langchain/langgraph-checkpoint@~0.0.10": + version "0.0.11" + resolved "https://registry.yarnpkg.com/@langchain/langgraph-checkpoint/-/langgraph-checkpoint-0.0.11.tgz#65c40bc175faca98ed0901df9e76682585710e8d" + integrity sha512-nroHHkAi/UPn9LqqZcgOydfB8qZw5TXuXDFc43MIydnW4lb8m9hVHnQ3lgb2WGSgtbZJnsIx0TzL19oemJBRKg== dependencies: - "@langchain/core" ">=0.2.20 <0.3.0" + uuid "^10.0.0" + +"@langchain/langgraph-sdk@~0.0.20": + version "0.0.20" + resolved "https://registry.yarnpkg.com/@langchain/langgraph-sdk/-/langgraph-sdk-0.0.20.tgz#5cb75d83408a8dd3aab0d8923956672746d1b499" + integrity sha512-58iGYL0PppSiIHtIUNAN+x6TCl+Vb0dAmlToSMJHUng8W53ffXHQTNqVNxJlPsHO6zdgPJm4DRl53z6vkSUZpw== + dependencies: + "@types/json-schema" "^7.0.15" + p-queue "^6.6.2" + p-retry "4" + uuid "^9.0.0" + +"@langchain/langgraph@0.2.19": + version "0.2.19" + resolved "https://registry.yarnpkg.com/@langchain/langgraph/-/langgraph-0.2.19.tgz#1a855ee0e63683a085b41e9b8cbc01e836ebf168" + integrity sha512-dgFdnEokC5zY32skZ6rcBYJNTH3WQXVY0LRI1zBGvbmK/nPfanIB1URwNxqRFjj/qHRKofxoehqYr1ww1zB+zA== + dependencies: + "@langchain/langgraph-checkpoint" "~0.0.10" + "@langchain/langgraph-sdk" "~0.0.20" + double-ended-queue "^2.1.0-0" uuid "^10.0.0" zod "^3.23.8" -"@langchain/openai@>=0.1.0 <0.3.0", "@langchain/openai@^0.1.3", "@langchain/openai@~0.1.0": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@langchain/openai/-/openai-0.1.3.tgz#6eb0994e970d85ffa9aaeafb94449024ccf6ca63" - integrity sha512-riv/JC9x2A8b7GcHu8sx+mlZJ8KAwSSi231IPTlcciYnKozmrQ5H0vrtiD31fxiDbaRsk7tyCpkSBIOQEo7CyQ== +"@langchain/openai@>=0.1.0 <0.4.0", "@langchain/openai@>=0.2.0 <0.4.0", "@langchain/openai@^0.3.11": + version "0.3.11" + resolved "https://registry.yarnpkg.com/@langchain/openai/-/openai-0.3.11.tgz#c93ee298a87318562a1da6c2915a180fe5155ac4" + integrity sha512-mEFbpJ8w8NPArsquUlCwxvZTKNkXxqwzvTEYzv6Jb7gUoBDOZtwLg6AdcngTJ+w5VFh3wxgPy0g3zb9Aw0Qbpw== dependencies: - "@langchain/core" ">=0.2.5 <0.3.0" js-tiktoken "^1.0.12" - openai "^4.49.1" + openai "^4.68.0" zod "^3.22.4" zod-to-json-schema "^3.22.3" -"@langchain/textsplitters@~0.0.0": +"@langchain/textsplitters@>=0.0.0 <0.2.0": version "0.0.2" resolved "https://registry.yarnpkg.com/@langchain/textsplitters/-/textsplitters-0.0.2.tgz#500baa8341fb7fc86fca531a4192665a319504a3" integrity sha512-6bQOuYHTGYlkgPY/8M5WPq4nnXZpEysGzRopQCYjg2WLcEoIPUMMrXsAaNNdvU3BOeMrhin8izvpDPD165hX6Q== @@ -10745,7 +10758,7 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== -"@types/json-schema@^7.0.7": +"@types/json-schema@^7.0.15", "@types/json-schema@^7.0.7": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -13411,7 +13424,7 @@ binary-extensions@^2.0.0, binary-extensions@^2.2.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -binary-search@^1.3.3, binary-search@^1.3.5: +binary-search@^1.3.3: version "1.3.6" resolved "https://registry.yarnpkg.com/binary-search/-/binary-search-1.3.6.tgz#e32426016a0c5092f0f3598836a1c7da3560565c" integrity sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA== @@ -16544,6 +16557,11 @@ dotignore@^0.1.2: dependencies: minimatch "^3.0.4" +double-ended-queue@^2.1.0-0: + version "2.1.0-0" + resolved "https://registry.yarnpkg.com/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz#103d3527fd31528f40188130c841efdd78264e5c" + integrity sha512-+BNfZ+deCo8hMNpDqDnvT+c0XpJ5cUa6mqYq89bho2Ifze4URTqRkcwR399hWoTrTkbZ/XJYDgP6rc7pRgffEQ== + downshift@^3.2.10: version "3.4.8" resolved "https://registry.yarnpkg.com/downshift/-/downshift-3.4.8.tgz#06b7ad9e9c423a58e8a9049b2a00a5d19c7ef954" @@ -20367,11 +20385,6 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" -is-any-array@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-any-array/-/is-any-array-2.0.1.tgz#9233242a9c098220290aa2ec28f82ca7fa79899e" - integrity sha512-UtilS7hLRu++wb/WBAw9bNuP1Eg04Ivn1vERJck8zJthEvXCBEBpGR/33u/xLKWEQf95803oalHrVDptcAvFdQ== - is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" @@ -22127,21 +22140,17 @@ kuler@^2.0.0: resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== -langchain@0.2.3, langchain@^0.2.11: - version "0.2.11" - resolved "https://registry.yarnpkg.com/langchain/-/langchain-0.2.11.tgz#d97e5bbd57e8954f21356fd85603aa39e3efe03f" - integrity sha512-6FQWKNAXuTmwuhHHMOmurLo8pydSRu5C/FwCYvYbR4ulCLqcsj+jre/kfXvA5BdHOZHNo6oQn0/5kxDNnhxMUA== +"langchain@>=0.2.3 <0.3.0 || >=0.3.4 <0.4.0", langchain@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/langchain/-/langchain-0.3.5.tgz#87b282454bc215b12b920d4dd5e35ed58030bad1" + integrity sha512-Gq0xC45Sq6nszS8kQG9suCrmBsuXH0INMmiF7D2TwPb6mtG35Jiq4grCk9ykpwPsarTHdty3SzUbII/FqiYSSw== dependencies: - "@langchain/core" ">=0.2.11 <0.3.0" - "@langchain/openai" ">=0.1.0 <0.3.0" - "@langchain/textsplitters" "~0.0.0" - binary-extensions "^2.2.0" + "@langchain/openai" ">=0.1.0 <0.4.0" + "@langchain/textsplitters" ">=0.0.0 <0.2.0" js-tiktoken "^1.0.12" js-yaml "^4.1.0" jsonpointer "^5.0.1" - langchainhub "~0.0.8" - langsmith "~0.1.30" - ml-distance "^4.0.0" + langsmith "^0.2.0" openapi-types "^12.1.3" p-retry "4" uuid "^10.0.0" @@ -22149,15 +22158,10 @@ langchain@0.2.3, langchain@^0.2.11: zod "^3.22.4" zod-to-json-schema "^3.22.3" -langchainhub@~0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/langchainhub/-/langchainhub-0.0.8.tgz#fd4b96dc795e22e36c1a20bad31b61b0c33d3110" - integrity sha512-Woyb8YDHgqqTOZvWIbm2CaFDGfZ4NTSyXV687AG4vXEfoNo7cGQp7nhl7wL3ehenKWmNEmcxCLgOZzW8jE6lOQ== - -langsmith@^0.1.43, langsmith@^0.1.55, langsmith@~0.1.30: - version "0.1.55" - resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.1.55.tgz#bdbb8015a28093f4a248c0ee9b8937731c5baa93" - integrity sha512-6NVtI04UUnIY59I/imOX02FG/QMGfqStu8tiJtyyreKMv2GAN0EE9Z5Ap1wzOe6v8ukEcV3NwEO2LYOPwup1PQ== +langsmith@^0.2.0, langsmith@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/langsmith/-/langsmith-0.2.3.tgz#91c5b4e3d5b030d8a995e9acaac43dba4b9b225c" + integrity sha512-SPMYPVqR9kwXZVmJ2PXC61HeBnXIFHrjfjDxQ14H0+n5p4gqjLzgSHIQyxBlFeWQUQzArJxe65Ap+s+Xo1cZog== dependencies: "@types/uuid" "^10.0.0" commander "^10.0.1" @@ -23524,42 +23528,6 @@ mkdirp@^3.0.1: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-3.0.1.tgz#e44e4c5607fb279c168241713cc6e0fea9adcb50" integrity sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg== -ml-array-mean@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/ml-array-mean/-/ml-array-mean-1.1.6.tgz#d951a700dc8e3a17b3e0a583c2c64abd0c619c56" - integrity sha512-MIdf7Zc8HznwIisyiJGRH9tRigg3Yf4FldW8DxKxpCCv/g5CafTw0RRu51nojVEOXuCQC7DRVVu5c7XXO/5joQ== - dependencies: - ml-array-sum "^1.1.6" - -ml-array-sum@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/ml-array-sum/-/ml-array-sum-1.1.6.tgz#d1d89c20793cd29c37b09d40e85681aa4515a955" - integrity sha512-29mAh2GwH7ZmiRnup4UyibQZB9+ZLyMShvt4cH4eTK+cL2oEMIZFnSyB3SS8MlsTh6q/w/yh48KmqLxmovN4Dw== - dependencies: - is-any-array "^2.0.0" - -ml-distance-euclidean@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ml-distance-euclidean/-/ml-distance-euclidean-2.0.0.tgz#3a668d236649d1b8fec96380b9435c6f42c9a817" - integrity sha512-yC9/2o8QF0A3m/0IXqCTXCzz2pNEzvmcE/9HFKOZGnTjatvBbsn4lWYJkxENkA4Ug2fnYl7PXQxnPi21sgMy/Q== - -ml-distance@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/ml-distance/-/ml-distance-4.0.1.tgz#4741d17a1735888c5388823762271dfe604bd019" - integrity sha512-feZ5ziXs01zhyFUUUeZV5hwc0f5JW0Sh0ckU1koZe/wdVkJdGxcP06KNQuF0WBTj8FttQUzcvQcpcrOp/XrlEw== - dependencies: - ml-array-mean "^1.1.6" - ml-distance-euclidean "^2.0.0" - ml-tree-similarity "^1.0.0" - -ml-tree-similarity@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ml-tree-similarity/-/ml-tree-similarity-1.0.0.tgz#24705a107e32829e24d945e87219e892159c53f0" - integrity sha512-XJUyYqjSuUQkNQHMscr6tcjldsOoAekxADTplt40QKfwW6nd++1wHWV9AArl0Zvw/TIHgNaZZNvr8QGvE8wLRg== - dependencies: - binary-search "^1.3.5" - num-sort "^2.0.0" - mobx-react-lite@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/mobx-react-lite/-/mobx-react-lite-4.0.7.tgz#f4e21e18d05c811010dcb1d3007e797924c4d90b" @@ -24378,11 +24346,6 @@ null-loader@^3.0.0: loader-utils "^1.2.3" schema-utils "^1.0.0" -num-sort@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/num-sort/-/num-sort-2.1.0.tgz#1cbb37aed071329fdf41151258bc011898577a9b" - integrity sha512-1MQz1Ed8z2yckoBeSfkQHHO9K1yDRxxtotKSJ9yvcTUUxSvfvzEq5GwBrjjHEpMlq/k5gvXdmJ1SbYxWtpNoVg== - num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" @@ -24708,10 +24671,10 @@ open@^8.0.9, open@^8.4.0, open@~8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" -openai@^4.24.1, openai@^4.49.1: - version "4.51.0" - resolved "https://registry.yarnpkg.com/openai/-/openai-4.51.0.tgz#8ab08bba2441375e8e4ce6161f9ac987d2b2c157" - integrity sha512-UKuWc3/qQyklqhHM8CbdXCv0Z0obap6T0ECdcO5oATQxAbKE5Ky3YCXFQY207z+eGG6ez4U9wvAcuMygxhmStg== +openai@^4.68.0: + version "4.69.0" + resolved "https://registry.yarnpkg.com/openai/-/openai-4.69.0.tgz#ac2463719280987e506e4bd62dd477337e2406a1" + integrity sha512-S3hOHSkk609KqwgH+7dwFrSvO3Gm3Nk0YWGyPHNscoMH/Y2tH1qunMi7gtZnLbUv4/N1elqCp6bDior2401kCQ== dependencies: "@types/node" "^18.11.18" "@types/node-fetch" "^2.6.4" @@ -24720,7 +24683,6 @@ openai@^4.24.1, openai@^4.49.1: form-data-encoder "1.7.2" formdata-node "^4.3.2" node-fetch "^2.6.7" - web-streams-polyfill "^3.2.1" openapi-sampler@^1.5.0: version "1.5.1" @@ -32139,7 +32101,7 @@ web-streams-polyfill@4.0.0-beta.3: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz#2898486b74f5156095e473efe989dcf185047a38" integrity sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug== -web-streams-polyfill@^3.0.3, web-streams-polyfill@^3.2.1: +web-streams-polyfill@^3.0.3: version "3.2.1" resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==