diff --git a/.bazelversion b/.bazelversion index 91ff57278e37e..ac14c3dfaa865 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -5.2.0 +5.1.1 diff --git a/.buildkite/pipelines/performance/daily.yml b/.buildkite/pipelines/performance/daily.yml index fdc4ae17d69a2..28f58d6c814ef 100644 --- a/.buildkite/pipelines/performance/daily.yml +++ b/.buildkite/pipelines/performance/daily.yml @@ -19,11 +19,11 @@ steps: depends_on: build key: tests - # - label: ':shipit: Performance Tests dataset extraction for scalability benchmarking' - # command: .buildkite/scripts/steps/functional/scalability_dataset_extraction.sh - # agents: - # queue: n2-2 - # depends_on: tests + - label: ':shipit: Performance Tests dataset extraction for scalability benchmarking' + command: .buildkite/scripts/steps/functional/scalability_dataset_extraction.sh + agents: + queue: n2-2 + depends_on: tests - label: ':chart_with_upwards_trend: Report performance metrics to ci-stats' command: .buildkite/scripts/steps/functional/report_performance_metrics.sh diff --git a/.buildkite/scripts/steps/functional/performance_playwright.sh b/.buildkite/scripts/steps/functional/performance_playwright.sh index 9436552326d93..fbbd028f96adf 100644 --- a/.buildkite/scripts/steps/functional/performance_playwright.sh +++ b/.buildkite/scripts/steps/functional/performance_playwright.sh @@ -15,6 +15,21 @@ node scripts/es snapshot& esPid=$! +# unset env vars defined in other parts of CI for automatic APM collection of +# Kibana. We manage APM config in our FTR config and performance service, and +# APM treats config in the ENV with a very high precedence. +unset ELASTIC_APM_ENVIRONMENT +unset ELASTIC_APM_TRANSACTION_SAMPLE_RATE +unset ELASTIC_APM_SERVER_URL +unset ELASTIC_APM_SECRET_TOKEN +unset ELASTIC_APM_ACTIVE +unset ELASTIC_APM_CONTEXT_PROPAGATION_ONLY +unset ELASTIC_APM_ACTIVE +unset ELASTIC_APM_SERVER_URL +unset ELASTIC_APM_SECRET_TOKEN +unset ELASTIC_APM_GLOBAL_LABELS + + export TEST_ES_URL=http://elastic:changeme@localhost:9200 export TEST_ES_DISABLE_STARTUP=true @@ -30,19 +45,19 @@ for i in "${journeys[@]}"; do checks-reporter-with-killswitch "Run Performance Tests with Playwright Config (Journey:${i},Phase: WARMUP)" \ node scripts/functional_tests \ - --config "x-pack/test/performance/journeys/${i}/config.ts" \ - --kibana-install-dir "$KIBANA_BUILD_LOCATION" \ - --debug \ - --bail + --config "x-pack/test/performance/journeys/${i}/config.ts" \ + --kibana-install-dir "$KIBANA_BUILD_LOCATION" \ + --debug \ + --bail export TEST_PERFORMANCE_PHASE=TEST checks-reporter-with-killswitch "Run Performance Tests with Playwright Config (Journey:${i},Phase: TEST)" \ node scripts/functional_tests \ - --config "x-pack/test/performance/journeys/${i}/config.ts" \ - --kibana-install-dir "$KIBANA_BUILD_LOCATION" \ - --debug \ - --bail + --config "x-pack/test/performance/journeys/${i}/config.ts" \ + --kibana-install-dir "$KIBANA_BUILD_LOCATION" \ + --debug \ + --bail done kill "$esPid" diff --git a/.buildkite/scripts/steps/functional/report_performance_metrics.sh b/.buildkite/scripts/steps/functional/report_performance_metrics.sh index 66a5ac27a8dff..da76ae1e0599b 100644 --- a/.buildkite/scripts/steps/functional/report_performance_metrics.sh +++ b/.buildkite/scripts/steps/functional/report_performance_metrics.sh @@ -7,7 +7,7 @@ source .buildkite/scripts/common/util.sh # TODO: Add new user and change lines accordingly USER_FROM_VAULT="$(retry 5 5 vault read -field=username secret/kibana-issues/dev/ci_stats_performance_metrics)" PASS_FROM_VAULT="$(retry 5 5 vault read -field=password secret/kibana-issues/dev/ci_stats_performance_metrics)" -APM_SERVER_URL="https://kibana-ops-e2e-perf.es.us-central1.gcp.cloud.es.io:9243/internal/apm" +APM_SERVER_URL="https://kibana-ops-e2e-perf.kb.us-central1.gcp.cloud.es.io:9243/internal/apm" BUILD_ID=${BUILDKITE_BUILD_ID} .buildkite/scripts/bootstrap.sh diff --git a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh index 1a8bd77bd2893..177dd69eb59e5 100755 --- a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh +++ b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh @@ -13,14 +13,14 @@ GCS_BUCKET="gs://kibana-performance/scalability-tests" .buildkite/scripts/bootstrap.sh echo "--- Extract APM metrics" -journeys=("login" "ecommerce_dashboard" "flight_dashboard" "web_logs_dashboard" "promotion_tracking_dashboard" "many_fields_discover") +scalabilityJourneys=("login" "promotion_tracking_dashboard") -for i in "${journeys[@]}"; do +for i in "${scalabilityJourneys[@]}"; do JOURNEY_NAME="${i}" echo "Looking for JOURNEY=${JOURNEY_NAME} and BUILD_ID=${BUILD_ID} in APM traces" node scripts/extract_performance_testing_dataset \ - --journeyName "${JOURNEY_NAME}" \ + --config "x-pack/test/performance/journeys/${i}/config.ts" \ \ --buildId "${BUILD_ID}" \ --es-url "${ES_SERVER_URL}" \ --es-username "${USER_FROM_VAULT}" \ @@ -39,4 +39,4 @@ echo "${BUILDKITE_COMMIT}" > "${BUILD_ID}/KIBANA_COMMIT_HASH" gsutil -m cp -r "${BUILD_ID}" "${GCS_BUCKET}" echo "--- Update reference to the latest CI build" echo "${BUILD_ID}" > LATEST -gsutil cp LATEST "${GCS_BUCKET}" \ No newline at end of file +gsutil cp LATEST "${GCS_BUCKET}" diff --git a/.eslintrc.js b/.eslintrc.js index f88b514b514a2..36927ac4219a0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1442,6 +1442,8 @@ module.exports = { 'import/newline-after-import': 'error', 'react-hooks/exhaustive-deps': 'off', 'react/jsx-boolean-value': ['error', 'never'], + 'sort-keys': 1, // warning + '@typescript-eslint/member-ordering': [1, { default: { order: 'alphabetically' } }], // warning '@typescript-eslint/no-unused-vars': [ 'error', { vars: 'all', args: 'after-used', ignoreRestSiblings: true, varsIgnorePattern: '^_' }, diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6813dcaa33c09..fc715aad73467 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -203,7 +203,6 @@ /x-pack/test/functional/services/transform/ @elastic/ml-ui /x-pack/test/functional_basic/apps/transform/ @elastic/ml-ui /x-pack/packages/ml/ @elastic/ml-ui -/packages/kbn-aiops-utils @elastic/ml-ui /examples/response_stream/ @elastic/ml-ui # Maps diff --git a/.i18nrc.json b/.i18nrc.json index 8c98fc415c910..88c1ecb5106bc 100644 --- a/.i18nrc.json +++ b/.i18nrc.json @@ -7,7 +7,11 @@ "bfetch": "src/plugins/bfetch", "charts": "src/plugins/charts", "console": "src/plugins/console", - "core": ["src/core", "packages/core/i18n/core-i18n-browser-internal"], + "core": [ + "src/core", + "packages/core/i18n/core-i18n-browser-internal", + "packages/core/fatal-errors/core-fatal-errors-browser-internal" + ], "customIntegrations": "src/plugins/custom_integrations", "dashboard": "src/plugins/dashboard", "controls": "src/plugins/controls", diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index aa8d70b3f87a3..ca9e750f826b0 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github summary: API docs for the actions plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index b4359ef0e6fac..18c1b2c188548 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github summary: API docs for the advancedSettings plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx index b84273128b873..c4e4ad98a65b1 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github summary: API docs for the aiops plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx index c660f149a18f7..f079efd67e26b 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github summary: API docs for the alerting plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json index 602ed47c913e3..b4480c7dbe868 100644 --- a/api_docs/apm.devdocs.json +++ b/api_docs/apm.devdocs.json @@ -790,7 +790,7 @@ "label": "APIEndpoint", "description": [], "signature": [ - "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/dynamic\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"POST /internal/apm/latency/overall_distribution\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/ux/page-load-distribution\" | \"GET /internal/apm/ux/page-load-distribution/breakdown\" | \"GET /internal/apm/ux/page-view-trends\" | \"GET /internal/apm/ux/visitor-breakdown\" | \"GET /internal/apm/ux/long-task-metrics\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/backend\" | \"GET /internal/apm/services/{serviceName}/serviceNodes\" | \"GET /internal/apm/services\" | \"GET /internal/apm/services/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/metadata/details\" | \"GET /internal/apm/services/{serviceName}/metadata/icons\" | \"GET /internal/apm/services/{serviceName}/agent\" | \"GET /internal/apm/services/{serviceName}/transaction_types\" | \"GET /internal/apm/services/{serviceName}/node/{serviceNodeName}/metadata\" | \"GET /api/apm/services/{serviceName}/annotation/search\" | \"POST /api/apm/services/{serviceName}/annotation\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/details/{serviceNodeName}\" | \"GET /internal/apm/services/{serviceName}/throughput\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/dependencies\" | \"GET /internal/apm/services/{serviceName}/dependencies/breakdown\" | \"GET /internal/apm/services/{serviceName}/profiling/timeline\" | \"GET /internal/apm/services/{serviceName}/profiling/statistics\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes_for_logs\" | \"GET /internal/apm/services/{serviceName}/anomaly_charts\" | \"GET /internal/apm/sorted_and_filtered_services\" | \"GET /internal/apm/service-groups\" | \"GET /internal/apm/service-group\" | \"POST /internal/apm/service-group\" | \"DELETE /internal/apm/service-group\" | \"GET /internal/apm/service-group/services\" | \"GET /internal/apm/suggestions\" | \"GET /internal/apm/traces/{traceId}\" | \"GET /internal/apm/traces\" | \"GET /internal/apm/traces/{traceId}/root_transaction\" | \"GET /internal/apm/transactions/{transactionId}\" | \"GET /internal/apm/traces/find\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/latency\" | \"GET /internal/apm/services/{serviceName}/transactions/traces/samples\" | \"GET /internal/apm/services/{serviceName}/transaction/charts/breakdown\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/error_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate_by_transaction_name\" | \"GET /internal/apm/alerts/chart_preview/transaction_error_rate\" | \"GET /internal/apm/alerts/chart_preview/transaction_duration\" | \"GET /internal/apm/alerts/chart_preview/transaction_error_count\" | \"GET /api/apm/settings/agent-configuration\" | \"GET /api/apm/settings/agent-configuration/view\" | \"DELETE /api/apm/settings/agent-configuration\" | \"PUT /api/apm/settings/agent-configuration\" | \"POST /api/apm/settings/agent-configuration/search\" | \"GET /api/apm/settings/agent-configuration/environments\" | \"GET /api/apm/settings/agent-configuration/agent_name\" | \"GET /internal/apm/settings/anomaly-detection/jobs\" | \"POST /internal/apm/settings/anomaly-detection/jobs\" | \"GET /internal/apm/settings/anomaly-detection/environments\" | \"POST /internal/apm/settings/anomaly-detection/update_to_v3\" | \"GET /internal/apm/settings/apm-index-settings\" | \"GET /internal/apm/settings/apm-indices\" | \"POST /internal/apm/settings/apm-indices/save\" | \"GET /internal/apm/settings/custom_links/transaction\" | \"GET /internal/apm/settings/custom_links\" | \"POST /internal/apm/settings/custom_links\" | \"PUT /internal/apm/settings/custom_links/{id}\" | \"DELETE /internal/apm/settings/custom_links/{id}\" | \"GET /api/apm/sourcemaps\" | \"POST /api/apm/sourcemaps\" | \"DELETE /api/apm/sourcemaps/{id}\" | \"GET /internal/apm/fleet/has_apm_policies\" | \"GET /internal/apm/fleet/agents\" | \"POST /api/apm/fleet/apm_server_schema\" | \"GET /internal/apm/fleet/apm_server_schema/unsupported\" | \"GET /internal/apm/fleet/migration_check\" | \"POST /internal/apm/fleet/cloud_apm_package_policy\" | \"GET /internal/apm/backends/top_backends\" | \"GET /internal/apm/backends/upstream_services\" | \"GET /internal/apm/backends/metadata\" | \"GET /internal/apm/backends/charts/latency\" | \"GET /internal/apm/backends/charts/throughput\" | \"GET /internal/apm/backends/charts/error_rate\" | \"GET /internal/apm/backends/operations\" | \"GET /internal/apm/backends/operations/spans\" | \"POST /internal/apm/correlations/p_values\" | \"GET /internal/apm/correlations/field_candidates\" | \"POST /internal/apm/correlations/field_stats\" | \"GET /internal/apm/correlations/field_value_stats\" | \"POST /internal/apm/correlations/field_value_pairs\" | \"POST /internal/apm/correlations/significant_correlations\" | \"GET /internal/apm/fallback_to_transactions\" | \"GET /internal/apm/has_data\" | \"GET /internal/apm/event_metadata/{processorEvent}/{id}\" | \"GET /internal/apm/agent_keys\" | \"GET /internal/apm/agent_keys/privileges\" | \"POST /internal/apm/api_key/invalidate\" | \"POST /api/apm/agent_keys\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/children\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes\" | \"GET /internal/apm/debug-telemetry\" | \"GET /internal/apm/time_range_metadata\"" + "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/dynamic\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"POST /internal/apm/latency/overall_distribution/transactions\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/ux/page-load-distribution\" | \"GET /internal/apm/ux/page-load-distribution/breakdown\" | \"GET /internal/apm/ux/page-view-trends\" | \"GET /internal/apm/ux/visitor-breakdown\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/backend\" | \"GET /internal/apm/services/{serviceName}/serviceNodes\" | \"GET /internal/apm/services\" | \"POST /internal/apm/services/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/metadata/details\" | \"GET /internal/apm/services/{serviceName}/metadata/icons\" | \"GET /internal/apm/services/{serviceName}/agent\" | \"GET /internal/apm/services/{serviceName}/transaction_types\" | \"GET /internal/apm/services/{serviceName}/node/{serviceNodeName}/metadata\" | \"GET /api/apm/services/{serviceName}/annotation/search\" | \"POST /api/apm/services/{serviceName}/annotation\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/details/{serviceNodeName}\" | \"GET /internal/apm/services/{serviceName}/throughput\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/main_statistics\" | \"GET /internal/apm/services/{serviceName}/service_overview_instances/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/dependencies\" | \"GET /internal/apm/services/{serviceName}/dependencies/breakdown\" | \"GET /internal/apm/services/{serviceName}/profiling/timeline\" | \"GET /internal/apm/services/{serviceName}/profiling/statistics\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes_for_logs\" | \"GET /internal/apm/services/{serviceName}/anomaly_charts\" | \"GET /internal/apm/sorted_and_filtered_services\" | \"GET /internal/apm/service-groups\" | \"GET /internal/apm/service-group\" | \"POST /internal/apm/service-group\" | \"DELETE /internal/apm/service-group\" | \"GET /internal/apm/service-group/services\" | \"GET /internal/apm/suggestions\" | \"GET /internal/apm/traces/{traceId}\" | \"GET /internal/apm/traces\" | \"GET /internal/apm/traces/{traceId}/root_transaction\" | \"GET /internal/apm/transactions/{transactionId}\" | \"GET /internal/apm/traces/find\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/latency\" | \"GET /internal/apm/services/{serviceName}/transactions/traces/samples\" | \"GET /internal/apm/services/{serviceName}/transaction/charts/breakdown\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/error_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate\" | \"GET /internal/apm/services/{serviceName}/transactions/charts/coldstart_rate_by_transaction_name\" | \"GET /internal/apm/alerts/chart_preview/transaction_error_rate\" | \"GET /internal/apm/alerts/chart_preview/transaction_duration\" | \"GET /internal/apm/alerts/chart_preview/transaction_error_count\" | \"GET /api/apm/settings/agent-configuration\" | \"GET /api/apm/settings/agent-configuration/view\" | \"DELETE /api/apm/settings/agent-configuration\" | \"PUT /api/apm/settings/agent-configuration\" | \"POST /api/apm/settings/agent-configuration/search\" | \"GET /api/apm/settings/agent-configuration/environments\" | \"GET /api/apm/settings/agent-configuration/agent_name\" | \"GET /internal/apm/settings/anomaly-detection/jobs\" | \"POST /internal/apm/settings/anomaly-detection/jobs\" | \"GET /internal/apm/settings/anomaly-detection/environments\" | \"POST /internal/apm/settings/anomaly-detection/update_to_v3\" | \"GET /internal/apm/settings/apm-index-settings\" | \"GET /internal/apm/settings/apm-indices\" | \"POST /internal/apm/settings/apm-indices/save\" | \"GET /internal/apm/settings/custom_links/transaction\" | \"GET /internal/apm/settings/custom_links\" | \"POST /internal/apm/settings/custom_links\" | \"PUT /internal/apm/settings/custom_links/{id}\" | \"DELETE /internal/apm/settings/custom_links/{id}\" | \"GET /api/apm/sourcemaps\" | \"POST /api/apm/sourcemaps\" | \"DELETE /api/apm/sourcemaps/{id}\" | \"GET /internal/apm/fleet/has_apm_policies\" | \"GET /internal/apm/fleet/agents\" | \"POST /api/apm/fleet/apm_server_schema\" | \"GET /internal/apm/fleet/apm_server_schema/unsupported\" | \"GET /internal/apm/fleet/migration_check\" | \"POST /internal/apm/fleet/cloud_apm_package_policy\" | \"GET /internal/apm/backends/top_backends\" | \"GET /internal/apm/backends/upstream_services\" | \"GET /internal/apm/backends/metadata\" | \"GET /internal/apm/backends/charts/latency\" | \"GET /internal/apm/backends/charts/throughput\" | \"GET /internal/apm/backends/charts/error_rate\" | \"GET /internal/apm/backends/operations\" | \"GET /internal/apm/backends/charts/distribution\" | \"GET /internal/apm/backends/operations/spans\" | \"GET /internal/apm/correlations/field_candidates/transactions\" | \"POST /internal/apm/correlations/field_stats/transactions\" | \"GET /internal/apm/correlations/field_value_stats/transactions\" | \"POST /internal/apm/correlations/field_value_pairs/transactions\" | \"POST /internal/apm/correlations/significant_correlations/transactions\" | \"POST /internal/apm/correlations/p_values/transactions\" | \"GET /internal/apm/fallback_to_transactions\" | \"GET /internal/apm/has_data\" | \"GET /internal/apm/event_metadata/{processorEvent}/{id}\" | \"GET /internal/apm/agent_keys\" | \"GET /internal/apm/agent_keys/privileges\" | \"POST /internal/apm/api_key/invalidate\" | \"POST /api/apm/agent_keys\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/parents\" | \"GET /internal/apm/traces/{traceId}/span_links/{spanId}/children\" | \"GET /internal/apm/services/{serviceName}/infrastructure_attributes\" | \"GET /internal/apm/debug-telemetry\" | \"GET /internal/apm/time_range_metadata\"" ], "path": "x-pack/plugins/apm/server/routes/apm_routes/get_global_apm_server_route_repository.ts", "deprecated": false, @@ -1192,9 +1192,67 @@ }, ", { fallbackToTransactions: boolean; }, ", "APMRouteCreateOptions", - ">; \"POST /internal/apm/correlations/significant_correlations\": ", + ">; \"POST /internal/apm/correlations/p_values/transactions\": ", "ServerRoute", - "<\"POST /internal/apm/correlations/significant_correlations\", ", + "<\"POST /internal/apm/correlations/p_values/transactions\", ", + "TypeC", + "<{ body: ", + "IntersectionC", + "<[", + "PartialC", + "<{ serviceName: ", + "StringC", + "; transactionName: ", + "StringC", + "; transactionType: ", + "StringC", + "; }>, ", + "TypeC", + "<{ environment: ", + "UnionC", + "<[", + "LiteralC", + "<\"ENVIRONMENT_NOT_DEFINED\">, ", + "LiteralC", + "<\"ENVIRONMENT_ALL\">, ", + "BrandC", + "<", + "StringC", + ", ", + "NonEmptyStringBrand", + ">]>; }>, ", + "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>, ", + "TypeC", + "<{ fieldCandidates: ", + "ArrayC", + "<", + "StringC", + ">; }>]>; }>, ", + { + "pluginId": "apm", + "scope": "server", + "docId": "kibApmPluginApi", + "section": "def-server.APMRouteHandlerResources", + "text": "APMRouteHandlerResources" + }, + ", { failedTransactionsCorrelations: ", + "FailedTransactionsCorrelation", + "[]; ccsWarning: boolean; fallbackResult?: ", + "FailedTransactionsCorrelation", + " | undefined; }, ", + "APMRouteCreateOptions", + ">; \"POST /internal/apm/correlations/significant_correlations/transactions\": ", + "ServerRoute", + "<\"POST /internal/apm/correlations/significant_correlations/transactions\", ", "TypeC", "<{ body: ", "IntersectionC", @@ -1258,9 +1316,9 @@ "LatencyCorrelation", " | undefined; }, ", "APMRouteCreateOptions", - ">; \"POST /internal/apm/correlations/field_value_pairs\": ", + ">; \"POST /internal/apm/correlations/field_value_pairs/transactions\": ", "ServerRoute", - "<\"POST /internal/apm/correlations/field_value_pairs\", ", + "<\"POST /internal/apm/correlations/field_value_pairs/transactions\", ", "TypeC", "<{ body: ", "IntersectionC", @@ -1314,9 +1372,9 @@ "FieldValuePair", "[]; errors: any[]; }, ", "APMRouteCreateOptions", - ">; \"GET /internal/apm/correlations/field_value_stats\": ", + ">; \"GET /internal/apm/correlations/field_value_stats/transactions\": ", "ServerRoute", - "<\"GET /internal/apm/correlations/field_value_stats\", ", + "<\"GET /internal/apm/correlations/field_value_stats/transactions\", ", "TypeC", "<{ query: ", "IntersectionC", @@ -1374,9 +1432,9 @@ "TopValuesStats", ", ", "APMRouteCreateOptions", - ">; \"POST /internal/apm/correlations/field_stats\": ", + ">; \"POST /internal/apm/correlations/field_stats/transactions\": ", "ServerRoute", - "<\"POST /internal/apm/correlations/field_stats\", ", + "<\"POST /internal/apm/correlations/field_stats/transactions\", ", "TypeC", "<{ body: ", "IntersectionC", @@ -1430,9 +1488,9 @@ "FieldStats", "[]; errors: any[]; }, ", "APMRouteCreateOptions", - ">; \"GET /internal/apm/correlations/field_candidates\": ", + ">; \"GET /internal/apm/correlations/field_candidates/transactions\": ", "ServerRoute", - "<\"GET /internal/apm/correlations/field_candidates\", ", + "<\"GET /internal/apm/correlations/field_candidates/transactions\", ", "TypeC", "<{ query: ", "IntersectionC", @@ -1478,21 +1536,19 @@ }, ", { fieldCandidates: string[]; }, ", "APMRouteCreateOptions", - ">; \"POST /internal/apm/correlations/p_values\": ", + ">; \"GET /internal/apm/backends/operations/spans\": ", "ServerRoute", - "<\"POST /internal/apm/correlations/p_values\", ", + "<\"GET /internal/apm/backends/operations/spans\", ", "TypeC", - "<{ body: ", + "<{ query: ", "IntersectionC", "<[", - "PartialC", - "<{ serviceName: ", - "StringC", - "; transactionName: ", - "StringC", - "; transactionType: ", - "StringC", - "; }>, ", + "TypeC", + "<{ start: ", + "Type", + "; end: ", + "Type", + "; }>, ", "TypeC", "<{ environment: ", "UnionC", @@ -1512,17 +1568,17 @@ "StringC", "; }>, ", "TypeC", - "<{ start: ", + "<{ backendName: ", + "StringC", + "; spanName: ", + "StringC", + "; }>, ", + "PartialC", + "<{ sampleRangeFrom: ", "Type", - "; end: ", + "; sampleRangeTo: ", "Type", - "; }>, ", - "TypeC", - "<{ fieldCandidates: ", - "ArrayC", - "<", - "StringC", - ">; }>]>; }>, ", + "; }>]>; }>, ", { "pluginId": "apm", "scope": "server", @@ -1530,26 +1586,36 @@ "section": "def-server.APMRouteHandlerResources", "text": "APMRouteHandlerResources" }, - ", { failedTransactionsCorrelations: ", - "FailedTransactionsCorrelation", - "[]; ccsWarning: boolean; fallbackResult?: ", - "FailedTransactionsCorrelation", - " | undefined; }, ", + ", { spans: ", + "BackendSpan", + "[]; }, ", "APMRouteCreateOptions", - ">; \"GET /internal/apm/backends/operations/spans\": ", + ">; \"GET /internal/apm/backends/charts/distribution\": ", "ServerRoute", - "<\"GET /internal/apm/backends/operations/spans\", ", + "<\"GET /internal/apm/backends/charts/distribution\", ", "TypeC", "<{ query: ", "IntersectionC", "<[", "TypeC", + "<{ backendName: ", + "StringC", + "; spanName: ", + "StringC", + "; percentileThreshold: ", + "Type", + "; }>, ", + "TypeC", "<{ start: ", "Type", "; end: ", "Type", "; }>, ", "TypeC", + "<{ kuery: ", + "StringC", + "; }>, ", + "TypeC", "<{ environment: ", "UnionC", "<[", @@ -1562,17 +1628,7 @@ "StringC", ", ", "NonEmptyStringBrand", - ">]>; }>, ", - "TypeC", - "<{ kuery: ", - "StringC", - "; }>, ", - "TypeC", - "<{ backendName: ", - "StringC", - "; spanName: ", - "StringC", - "; }>]>; }>, ", + ">]>; }>]>; }>, ", { "pluginId": "apm", "scope": "server", @@ -1580,9 +1636,11 @@ "section": "def-server.APMRouteHandlerResources", "text": "APMRouteHandlerResources" }, - ", { spans: ", - "BackendSpan", - "[]; }, ", + ", { allSpansDistribution: ", + "OverallLatencyDistributionResponse", + "; failedSpansDistribution: ", + "OverallLatencyDistributionResponse", + "; }, ", "APMRouteCreateOptions", ">; \"GET /internal/apm/backends/operations\": ", "ServerRoute", @@ -4432,15 +4490,13 @@ "ServiceMetadataDetails", ", ", "APMRouteCreateOptions", - ">; \"GET /internal/apm/services/detailed_statistics\": ", + ">; \"POST /internal/apm/services/detailed_statistics\": ", "ServerRoute", - "<\"GET /internal/apm/services/detailed_statistics\", ", + "<\"POST /internal/apm/services/detailed_statistics\", ", "TypeC", "<{ query: ", "IntersectionC", "<[", - "IntersectionC", - "<[", "TypeC", "<{ environment: ", "UnionC", @@ -4472,11 +4528,11 @@ "TypeC", "<{ probability: ", "Type", - "; }>]>, ", + "; }>]>; body: ", "TypeC", "<{ serviceNames: ", "Type", - "; }>]>; }>, ", + "; }>; }>, ", { "pluginId": "apm", "scope": "server", @@ -4734,38 +4790,6 @@ "ServiceAnomalyStats", " | undefined; label: string | undefined; id?: string | undefined; parent?: string | undefined; position?: cytoscape.Position | undefined; } | { 'span.destination.service.resource': string; 'span.type': string; 'span.subtype': string; label: string | undefined; id?: string | undefined; parent?: string | undefined; position?: cytoscape.Position | undefined; } | { id: string; source: string | undefined; target: string | undefined; label: string | undefined; bidirectional?: boolean | undefined; isInverseEdge?: boolean | undefined; } | undefined)[]; }; } | { data: { id: string; source: string; target: string; }; })[]; }, ", "APMRouteCreateOptions", - ">; \"GET /internal/apm/ux/long-task-metrics\": ", - "ServerRoute", - "<\"GET /internal/apm/ux/long-task-metrics\", ", - "TypeC", - "<{ query: ", - "IntersectionC", - "<[", - "TypeC", - "<{ uiFilters: ", - "StringC", - "; }>, ", - "TypeC", - "<{ start: ", - "Type", - "; end: ", - "Type", - "; }>, ", - "PartialC", - "<{ urlQuery: ", - "StringC", - "; percentile: ", - "StringC", - "; }>]>; }>, ", - { - "pluginId": "apm", - "scope": "server", - "docId": "kibApmPluginApi", - "section": "def-server.APMRouteHandlerResources", - "text": "APMRouteHandlerResources" - }, - ", { noOfLongTasks: number; sumOfLongTasks: number; longestLongTask: number; }, ", - "APMRouteCreateOptions", ">; \"GET /internal/apm/ux/visitor-breakdown\": ", "ServerRoute", "<\"GET /internal/apm/ux/visitor-breakdown\", ", @@ -5018,9 +5042,9 @@ "ChartType", "; color: string; overallValue: number; data: { x: number; y: number | null; }[]; }[]; }[]; }, ", "APMRouteCreateOptions", - ">; \"POST /internal/apm/latency/overall_distribution\": ", + ">; \"POST /internal/apm/latency/overall_distribution/transactions\": ", "ServerRoute", - "<\"POST /internal/apm/latency/overall_distribution\", ", + "<\"POST /internal/apm/latency/overall_distribution/transactions\", ", "TypeC", "<{ body: ", "IntersectionC", @@ -5188,9 +5212,9 @@ "APMError", "; occurrencesCount: number; }, ", "APMRouteCreateOptions", - ">; \"GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\": ", + ">; \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\": ", "ServerRoute", - "<\"GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\", ", + "<\"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\", ", "TypeC", "<{ path: ", "TypeC", @@ -5230,9 +5254,11 @@ "TypeC", "<{ numBuckets: ", "Type", - "; groupIds: ", + "; }>]>; body: ", + "TypeC", + "<{ groupIds: ", "Type", - "; }>]>; }>, ", + "; }>; }>, ", { "pluginId": "apm", "scope": "server", diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 6100122ca8cb1..622721cbebf58 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github summary: API docs for the apm plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 9efb27bdf70d3..aaaeb84897ad8 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github summary: API docs for the banners plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx index 75a4484d9dbca..9c9ed7781fdcd 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github summary: API docs for the bfetch plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx index d15bfd331d410..baae8a1f94b12 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github summary: API docs for the canvas plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx index 8e6b7ff04c30a..a7dca4120979d 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github summary: API docs for the cases plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx index 2d9fe262fab2b..0218dddcf4afa 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github summary: API docs for the charts plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 015725fc4b46b..3354c32086dd3 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github summary: API docs for the cloud plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/cloud_security_posture.devdocs.json b/api_docs/cloud_security_posture.devdocs.json index ceb52e2ee8fbf..5f991959da895 100644 --- a/api_docs/cloud_security_posture.devdocs.json +++ b/api_docs/cloud_security_posture.devdocs.json @@ -40,114 +40,7 @@ "interfaces": [], "enums": [], "misc": [], - "objects": [ - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-server.cspRuleTemplateAssetType", - "type": "Object", - "tags": [], - "label": "cspRuleTemplateAssetType", - "description": [], - "path": "x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-server.cspRuleTemplateAssetType.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "path": "x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts", - "deprecated": false - }, - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-server.cspRuleTemplateAssetType.hidden", - "type": "boolean", - "tags": [], - "label": "hidden", - "description": [], - "signature": [ - "false" - ], - "path": "x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts", - "deprecated": false - }, - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-server.cspRuleTemplateAssetType.management", - "type": "Object", - "tags": [], - "label": "management", - "description": [], - "path": "x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-server.cspRuleTemplateAssetType.management.importableAndExportable", - "type": "boolean", - "tags": [], - "label": "importableAndExportable", - "description": [], - "signature": [ - "true" - ], - "path": "x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts", - "deprecated": false - }, - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-server.cspRuleTemplateAssetType.management.visibleInManagement", - "type": "boolean", - "tags": [], - "label": "visibleInManagement", - "description": [], - "signature": [ - "true" - ], - "path": "x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts", - "deprecated": false - } - ] - }, - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-server.cspRuleTemplateAssetType.namespaceType", - "type": "string", - "tags": [], - "label": "namespaceType", - "description": [], - "signature": [ - "\"agnostic\"" - ], - "path": "x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts", - "deprecated": false - }, - { - "parentPluginId": "cloudSecurityPosture", - "id": "def-server.cspRuleTemplateAssetType.mappings", - "type": "Object", - "tags": [], - "label": "mappings", - "description": [], - "signature": [ - { - "pluginId": "core", - "scope": "server", - "docId": "kibCoreSavedObjectsPluginApi", - "section": "def-server.SavedObjectsTypeMappingDefinition", - "text": "SavedObjectsTypeMappingDefinition" - } - ], - "path": "x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts", - "deprecated": false - } - ], - "initialIsOpen": false - } - ], + "objects": [], "setup": { "parentPluginId": "cloudSecurityPosture", "id": "def-server.CspServerPluginSetup", diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx index 552c5f84bbb6a..15eeef6dd5641 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github summary: API docs for the cloudSecurityPosture plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-pos | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 14 | 0 | 14 | 0 | +| 6 | 0 | 6 | 0 | ## Client @@ -36,9 +36,6 @@ Contact [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-pos ### Start -### Objects - - ## Common ### Consts, variables and types diff --git a/api_docs/console.mdx b/api_docs/console.mdx index ecd66045beb20..62b4175bde651 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github summary: API docs for the console plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 67400c3730c05..140189f96b697 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github summary: API docs for the controls plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/core.devdocs.json b/api_docs/core.devdocs.json index c1181b59c80c0..9dd9014fbdfab 100644 --- a/api_docs/core.devdocs.json +++ b/api_docs/core.devdocs.json @@ -1267,13 +1267,7 @@ "{@link FatalErrorsSetup}" ], "signature": [ - { - "pluginId": "core", - "scope": "public", - "docId": "kibCorePluginApi", - "section": "def-public.FatalErrorsSetup", - "text": "FatalErrorsSetup" - } + "FatalErrorsSetup" ], "path": "src/core/public/index.ts", "deprecated": false @@ -1661,13 +1655,7 @@ "{@link FatalErrorsStart}" ], "signature": [ - { - "pluginId": "core", - "scope": "public", - "docId": "kibCorePluginApi", - "section": "def-public.FatalErrorsSetup", - "text": "FatalErrorsSetup" - } + "FatalErrorsSetup" ], "path": "src/core/public/index.ts", "deprecated": false @@ -2511,9 +2499,9 @@ "tags": [], "label": "FatalErrorInfo", "description": [ - "\nRepresents the `message` and `stack` of a fatal Error\n" + "\r\nRepresents the `message` and `stack` of a fatal Error\r\n" ], - "path": "src/core/public/fatal_errors/get_error_info.ts", + "path": "node_modules/@types/kbn__core-fatal-errors-browser/index.d.ts", "deprecated": false, "children": [ { @@ -2523,7 +2511,7 @@ "tags": [], "label": "message", "description": [], - "path": "src/core/public/fatal_errors/get_error_info.ts", + "path": "node_modules/@types/kbn__core-fatal-errors-browser/index.d.ts", "deprecated": false }, { @@ -2536,7 +2524,7 @@ "signature": [ "string | undefined" ], - "path": "src/core/public/fatal_errors/get_error_info.ts", + "path": "node_modules/@types/kbn__core-fatal-errors-browser/index.d.ts", "deprecated": false } ], @@ -2549,9 +2537,9 @@ "tags": [], "label": "FatalErrorsSetup", "description": [ - "\nFatalErrors stop the Kibana Public Core and displays a fatal error screen\nwith details about the Kibana build and the error.\n" + "\r\nFatalErrors stop the Kibana Public Core and displays a fatal error screen\r\nwith details about the Kibana build and the error.\r\n" ], - "path": "src/core/public/fatal_errors/fatal_errors_service.tsx", + "path": "node_modules/@types/kbn__core-fatal-errors-browser/index.d.ts", "deprecated": false, "children": [ { @@ -2561,12 +2549,12 @@ "tags": [], "label": "add", "description": [ - "\nAdd a new fatal error. This will stop the Kibana Public Core and display\na fatal error screen with details about the Kibana build and the error.\n" + "\r\nAdd a new fatal error. This will stop the Kibana Public Core and display\r\na fatal error screen with details about the Kibana build and the error.\r\n" ], "signature": [ "(error: string | Error, source?: string | undefined) => never" ], - "path": "src/core/public/fatal_errors/fatal_errors_service.tsx", + "path": "node_modules/@types/kbn__core-fatal-errors-browser/index.d.ts", "deprecated": false, "children": [ { @@ -2581,7 +2569,7 @@ "signature": [ "string | Error" ], - "path": "src/core/public/fatal_errors/fatal_errors_service.tsx", + "path": "node_modules/@types/kbn__core-fatal-errors-browser/index.d.ts", "deprecated": false, "isRequired": true }, @@ -2597,7 +2585,7 @@ "signature": [ "string | undefined" ], - "path": "src/core/public/fatal_errors/fatal_errors_service.tsx", + "path": "node_modules/@types/kbn__core-fatal-errors-browser/index.d.ts", "deprecated": false, "isRequired": false } @@ -2611,22 +2599,16 @@ "tags": [], "label": "get$", "description": [ - "\nAn Observable that will emit whenever a fatal error is added with `add()`" + "\r\nAn Observable that will emit whenever a fatal error is added with `add()`" ], "signature": [ "() => ", "Observable", "<", - { - "pluginId": "core", - "scope": "public", - "docId": "kibCorePluginApi", - "section": "def-public.FatalErrorInfo", - "text": "FatalErrorInfo" - }, + "FatalErrorInfo", ">" ], - "path": "src/core/public/fatal_errors/fatal_errors_service.tsx", + "path": "node_modules/@types/kbn__core-fatal-errors-browser/index.d.ts", "deprecated": false, "children": [], "returnComment": [] @@ -7627,18 +7609,12 @@ "tags": [], "label": "FatalErrorsStart", "description": [ - "\nFatalErrors stop the Kibana Public Core and displays a fatal error screen\nwith details about the Kibana build and the error.\n" + "\r\nFatalErrors stop the Kibana Public Core and displays a fatal error screen\r\nwith details about the Kibana build and the error.\r\n" ], "signature": [ - { - "pluginId": "core", - "scope": "public", - "docId": "kibCorePluginApi", - "section": "def-public.FatalErrorsSetup", - "text": "FatalErrorsSetup" - } + "FatalErrorsSetup" ], - "path": "src/core/public/fatal_errors/fatal_errors_service.tsx", + "path": "node_modules/@types/kbn__core-fatal-errors-browser/index.d.ts", "deprecated": false, "initialIsOpen": false }, diff --git a/api_docs/core.mdx b/api_docs/core.mdx index e3b2da5c430d1..28684f80aa617 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github summary: API docs for the core plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2527 | 15 | 938 | 29 | +| 2527 | 15 | 936 | 29 | ## Client diff --git a/api_docs/core_application.mdx b/api_docs/core_application.mdx index ccd83243240cc..0b94342267058 100644 --- a/api_docs/core_application.mdx +++ b/api_docs/core_application.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core-application title: "core.application" image: https://source.unsplash.com/400x175/?github summary: API docs for the core.application plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.application'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2527 | 15 | 938 | 29 | +| 2527 | 15 | 936 | 29 | ## Client diff --git a/api_docs/core_chrome.mdx b/api_docs/core_chrome.mdx index a9682a8e3b4a1..1ddbc6dc2f650 100644 --- a/api_docs/core_chrome.mdx +++ b/api_docs/core_chrome.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core-chrome title: "core.chrome" image: https://source.unsplash.com/400x175/?github summary: API docs for the core.chrome plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.chrome'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2527 | 15 | 938 | 29 | +| 2527 | 15 | 936 | 29 | ## Client diff --git a/api_docs/core_http.mdx b/api_docs/core_http.mdx index dbe127e3f003d..9ca3c0ad69f35 100644 --- a/api_docs/core_http.mdx +++ b/api_docs/core_http.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core-http title: "core.http" image: https://source.unsplash.com/400x175/?github summary: API docs for the core.http plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.http'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2527 | 15 | 938 | 29 | +| 2527 | 15 | 936 | 29 | ## Client diff --git a/api_docs/core_saved_objects.mdx b/api_docs/core_saved_objects.mdx index a4443c941dd86..2f9e04205ccfa 100644 --- a/api_docs/core_saved_objects.mdx +++ b/api_docs/core_saved_objects.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/core-savedObjects title: "core.savedObjects" image: https://source.unsplash.com/400x175/?github summary: API docs for the core.savedObjects plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core.savedObjects'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2527 | 15 | 938 | 29 | +| 2527 | 15 | 936 | 29 | ## Client diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index f7586442664bc..76b4ebee3dcbc 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github summary: API docs for the customIntegrations plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index 8dc6d7fdcfb6f..3f5273bfb5b73 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github summary: API docs for the dashboard plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index e8953c4281e28..6f17f5e0e8792 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github summary: API docs for the dashboardEnhanced plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index 0c8ca92075473..648e50bf75c1b 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -6750,7 +6750,7 @@ "tags": [], "label": "id", "description": [ - "\nSaved object id" + "\nSaved object id (or generated id if in-memory only)" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": false @@ -11047,10 +11047,6 @@ "plugin": "stackAlerts", "path": "x-pack/plugins/stack_alerts/public/alert_types/threshold/expression.tsx" }, - { - "plugin": "lens", - "path": "x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/droppable.test.ts" - }, { "plugin": "visTypeTable", "path": "src/plugins/vis_types/table/public/plugin.ts" @@ -11861,6 +11857,21 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "data", + "id": "def-server.DataView.isPersisted", + "type": "Function", + "tags": [], + "label": "isPersisted", + "description": [], + "signature": [ + "() => boolean" + ], + "path": "src/plugins/data_views/common/data_views/data_view.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "data", "id": "def-server.DataView.toSpec", @@ -13796,7 +13807,7 @@ "\nCreate a new data view instance." ], "signature": [ - "(spec: ", + "({ id, ...restOfSpec }: ", { "pluginId": "dataViews", "scope": "common", @@ -13822,10 +13833,8 @@ "id": "def-server.DataViewsService.create.$1", "type": "Object", "tags": [], - "label": "spec", - "description": [ - "data view spec" - ], + "label": "{ id, ...restOfSpec }", + "description": [], "signature": [ { "pluginId": "dataViews", @@ -14027,7 +14036,7 @@ "tags": [], "label": "updateSavedObject", "description": [ - "\nSave existing dat aview. Will attempt to merge differences if there are conflicts." + "\nSave existing data view. Will attempt to merge differences if there are conflicts." ], "signature": [ "(indexPattern: ", @@ -18275,6 +18284,21 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "data", + "id": "def-common.DataView.isPersisted", + "type": "Function", + "tags": [], + "label": "isPersisted", + "description": [], + "signature": [ + "() => boolean" + ], + "path": "src/plugins/data_views/common/data_views/data_view.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "data", "id": "def-common.DataView.toSpec", @@ -20917,7 +20941,7 @@ "\nCreate a new data view instance." ], "signature": [ - "(spec: ", + "({ id, ...restOfSpec }: ", { "pluginId": "dataViews", "scope": "common", @@ -20943,10 +20967,8 @@ "id": "def-common.DataViewsService.create.$1", "type": "Object", "tags": [], - "label": "spec", - "description": [ - "data view spec" - ], + "label": "{ id, ...restOfSpec }", + "description": [], "signature": [ { "pluginId": "dataViews", @@ -21148,7 +21170,7 @@ "tags": [], "label": "updateSavedObject", "description": [ - "\nSave existing dat aview. Will attempt to merge differences if there are conflicts." + "\nSave existing data view. Will attempt to merge differences if there are conflicts." ], "signature": [ "(indexPattern: ", @@ -22145,7 +22167,7 @@ "tags": [], "label": "id", "description": [ - "\nSaved object id" + "\nSaved object id (or generated id if in-memory only)" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": false @@ -23084,7 +23106,7 @@ "\nData views service interface" ], "signature": [ - "{ create: (spec: ", + "{ create: ({ id, ...restOfSpec }: ", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 9e2ff20a26ccb..d20909f244d50 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github summary: API docs for the data plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3072 | 34 | 2399 | 22 | +| 3074 | 34 | 2403 | 22 | ## Client diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 97cb36245b0df..b683ab2e7e58b 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github summary: API docs for the data.query plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3072 | 34 | 2399 | 22 | +| 3074 | 34 | 2403 | 22 | ## Client diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index badce42c47a6f..0a9075c2bc41a 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github summary: API docs for the data.search plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 3072 | 34 | 2399 | 22 | +| 3074 | 34 | 2403 | 22 | ## Client diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 6ff647d20d447..6e885bd986edf 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataViewEditor plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index ce0cac3a3ace3..b05c2973ece91 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataViewFieldEditor plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 8a0db6bb2066e..88e5e16a840e4 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataViewManagement plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/data_views.devdocs.json b/api_docs/data_views.devdocs.json index 459b3dcde752b..4eaf225000756 100644 --- a/api_docs/data_views.devdocs.json +++ b/api_docs/data_views.devdocs.json @@ -425,6 +425,21 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "dataViews", + "id": "def-public.DataView.isPersisted", + "type": "Function", + "tags": [], + "label": "isPersisted", + "description": [], + "signature": [ + "() => boolean" + ], + "path": "src/plugins/data_views/common/data_views/data_view.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "dataViews", "id": "def-public.DataView.toSpec", @@ -3429,7 +3444,7 @@ "\nCreate a new data view instance." ], "signature": [ - "(spec: ", + "({ id, ...restOfSpec }: ", { "pluginId": "dataViews", "scope": "common", @@ -3455,10 +3470,8 @@ "id": "def-public.DataViewsService.create.$1", "type": "Object", "tags": [], - "label": "spec", - "description": [ - "data view spec" - ], + "label": "{ id, ...restOfSpec }", + "description": [], "signature": [ { "pluginId": "dataViews", @@ -3660,7 +3673,7 @@ "tags": [], "label": "updateSavedObject", "description": [ - "\nSave existing dat aview. Will attempt to merge differences if there are conflicts." + "\nSave existing data view. Will attempt to merge differences if there are conflicts." ], "signature": [ "(indexPattern: ", @@ -4726,7 +4739,7 @@ "tags": [], "label": "id", "description": [ - "\nSaved object id" + "\nSaved object id (or generated id if in-memory only)" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": false @@ -6505,6 +6518,21 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "dataViews", + "id": "def-server.DataView.isPersisted", + "type": "Function", + "tags": [], + "label": "isPersisted", + "description": [], + "signature": [ + "() => boolean" + ], + "path": "src/plugins/data_views/common/data_views/data_view.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "dataViews", "id": "def-server.DataView.toSpec", @@ -8720,7 +8748,7 @@ "\nCreate a new data view instance." ], "signature": [ - "(spec: ", + "({ id, ...restOfSpec }: ", { "pluginId": "dataViews", "scope": "common", @@ -8746,10 +8774,8 @@ "id": "def-server.DataViewsService.create.$1", "type": "Object", "tags": [], - "label": "spec", - "description": [ - "data view spec" - ], + "label": "{ id, ...restOfSpec }", + "description": [], "signature": [ { "pluginId": "dataViews", @@ -8951,7 +8977,7 @@ "tags": [], "label": "updateSavedObject", "description": [ - "\nSave existing dat aview. Will attempt to merge differences if there are conflicts." + "\nSave existing data view. Will attempt to merge differences if there are conflicts." ], "signature": [ "(indexPattern: ", @@ -12504,6 +12530,21 @@ "children": [], "returnComment": [] }, + { + "parentPluginId": "dataViews", + "id": "def-common.DataView.isPersisted", + "type": "Function", + "tags": [], + "label": "isPersisted", + "description": [], + "signature": [ + "() => boolean" + ], + "path": "src/plugins/data_views/common/data_views/data_view.ts", + "deprecated": false, + "children": [], + "returnComment": [] + }, { "parentPluginId": "dataViews", "id": "def-common.DataView.toSpec", @@ -15161,7 +15202,7 @@ "\nCreate a new data view instance." ], "signature": [ - "(spec: ", + "({ id, ...restOfSpec }: ", { "pluginId": "dataViews", "scope": "common", @@ -15187,10 +15228,8 @@ "id": "def-common.DataViewsService.create.$1", "type": "Object", "tags": [], - "label": "spec", - "description": [ - "data view spec" - ], + "label": "{ id, ...restOfSpec }", + "description": [], "signature": [ { "pluginId": "dataViews", @@ -15392,7 +15431,7 @@ "tags": [], "label": "updateSavedObject", "description": [ - "\nSave existing dat aview. Will attempt to merge differences if there are conflicts." + "\nSave existing data view. Will attempt to merge differences if there are conflicts." ], "signature": [ "(indexPattern: ", @@ -16055,7 +16094,7 @@ "tags": [], "label": "id", "description": [ - "\nSaved object id" + "\nSaved object id (or generated id if in-memory only)" ], "path": "src/plugins/data_views/common/data_views/data_views.ts", "deprecated": false @@ -16357,7 +16396,7 @@ "tags": [], "label": "onNotification", "description": [ - "\nHander for service notifications" + "\nHandler for service notifications" ], "signature": [ "(toastInputFields: ", @@ -16518,6 +16557,23 @@ "deprecated": false, "children": [], "returnComment": [] + }, + { + "parentPluginId": "dataViews", + "id": "def-common.DataViewsServiceDeps.getCanSaveAdvancedSettings", + "type": "Function", + "tags": [], + "label": "getCanSaveAdvancedSettings", + "description": [ + "\nDetermines whether the user can save advancedSettings (used for defaultIndex)" + ], + "signature": [ + "() => Promise" + ], + "path": "src/plugins/data_views/common/data_views/data_views.ts", + "deprecated": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false @@ -19528,7 +19584,7 @@ "\nData views service interface" ], "signature": [ - "{ create: (spec: ", + "{ create: ({ id, ...restOfSpec }: ", { "pluginId": "dataViews", "scope": "common", diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 8d2ffe07ca1e9..beed35f6fe28c 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataViews plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 924 | 1 | 186 | 1 | +| 928 | 1 | 192 | 1 | ## Client diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 4761b678c4b82..9433fd0c94029 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github summary: API docs for the dataVisualizer plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 5683d95bd30fe..9029ad72fed88 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -3,7 +3,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API summary: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 75ca037c25bb2..83704f225f2cd 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -3,7 +3,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin summary: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. --- @@ -306,7 +306,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=syncQueryStateWithUrl), [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=syncQueryStateWithUrl) | - | -| | [ranges.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx#:~:text=fieldFormats), [droppable.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/droppable.test.ts#:~:text=fieldFormats) | - | +| | [ranges.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx#:~:text=fieldFormats) | - | | | [workspace_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx#:~:text=RedirectAppLinks), [workspace_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx#:~:text=RedirectAppLinks), [workspace_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx#:~:text=RedirectAppLinks) | - | | | [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [display_duplicate_title_confirm_modal.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/display_duplicate_title_confirm_modal.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject), [check_for_duplicate_title.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/persistence/saved_objects_utils/check_for_duplicate_title.ts#:~:text=SavedObject) | 8.8.0 | | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/types.ts#:~:text=onAppLeave), [mounter.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/mounter.tsx#:~:text=onAppLeave) | 8.8.0 | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 38244e76f344c..fd493450d8edc 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -3,7 +3,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team summary: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index bca811b137130..a12b054ab3963 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github summary: API docs for the devTools plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index 738d6255dc1fd..207987c00b311 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github summary: API docs for the discover plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index afd26d8f4c263..089ed3978e28a 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github summary: API docs for the discoverEnhanced plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/elastic_apm_synthtrace.mdx b/api_docs/elastic_apm_synthtrace.mdx index bf80df96fbcc5..5d5c70d6888d3 100644 --- a/api_docs/elastic_apm_synthtrace.mdx +++ b/api_docs/elastic_apm_synthtrace.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/elastic-apm-synthtrace title: "@elastic/apm-synthtrace" image: https://source.unsplash.com/400x175/?github summary: API docs for the @elastic/apm-synthtrace plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@elastic/apm-synthtrace'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index ae626a79b9444..a1b3695eaf33c 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github summary: API docs for the embeddable plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index 7a04080e707ce..0b36b2b90e9d7 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github summary: API docs for the embeddableEnhanced plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index f80624d76f739..deba7f2f92ee1 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github summary: API docs for the encryptedSavedObjects plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/enterprise_search.devdocs.json b/api_docs/enterprise_search.devdocs.json index 84333035657ad..221913d864e2f 100644 --- a/api_docs/enterprise_search.devdocs.json +++ b/api_docs/enterprise_search.devdocs.json @@ -27,6 +27,20 @@ "path": "x-pack/plugins/enterprise_search/server/index.ts", "deprecated": false, "initialIsOpen": false + }, + { + "parentPluginId": "enterpriseSearch", + "id": "def-server.CONNECTORS_INDEX", + "type": "string", + "tags": [], + "label": "CONNECTORS_INDEX", + "description": [], + "signature": [ + "\".ent-search-connectors\"" + ], + "path": "x-pack/plugins/enterprise_search/server/index.ts", + "deprecated": false, + "initialIsOpen": false } ], "objects": [ diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 89c9d98c5a85b..7eb383a28b556 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github summary: API docs for the enterpriseSearch plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Enterprise Search](https://github.com/orgs/elastic/teams/enterprise-sea | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 2 | 0 | 2 | 0 | +| 3 | 0 | 3 | 0 | ## Server diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index 71748ba2c183e..ca49a2d75071c 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github summary: API docs for the esUiShared plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index 5c7f4d4392176..985569160dcfc 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github summary: API docs for the eventAnnotation plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index c0f5673c3e4a5..3e06110ffbaf2 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github summary: API docs for the eventLog plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 972a3099e2ee5..a9a758c2b896a 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionError plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index c738384c60305..455e2b7519f5a 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionGauge plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index aa27f9360b628..1f2f285ce0688 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionHeatmap plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 452d5166377c2..ea6ac57bde2e9 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionImage plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index ceb63f6fdc9d5..c14b99ed025e7 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionMetric plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index be5ffab9f5e45..6fa7eb004b7de 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionMetricVis plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 5260a7add6010..c8b4eeaca7803 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionPartitionVis plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index 51bd5c3790838..dfa9fa10455b8 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionRepeatImage plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 7e9db0b0f0c70..d1b4b444ce782 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionRevealImage plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index cf4f2a7ae3ebb..2773a4b99a38d 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionShape plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index 4f8f87e51555d..c32e6d6f5cf59 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionTagcloud plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/expression_x_y.devdocs.json b/api_docs/expression_x_y.devdocs.json index 6d1532cf5989b..befebac94be4d 100644 --- a/api_docs/expression_x_y.devdocs.json +++ b/api_docs/expression_x_y.devdocs.json @@ -120,16 +120,6 @@ "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, "children": [ - { - "parentPluginId": "expressionXY", - "id": "def-common.AxesSettingsConfig.x", - "type": "boolean", - "tags": [], - "label": "x", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, { "parentPluginId": "expressionXY", "id": "def-common.AxesSettingsConfig.yLeft", @@ -170,6 +160,9 @@ "tags": [], "label": "title", "description": [], + "signature": [ + "string | undefined" + ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, @@ -185,6 +178,157 @@ ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.position", + "type": "CompoundType", + "tags": [], + "label": "position", + "description": [], + "signature": [ + "Position", + " | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.labelColor", + "type": "string", + "tags": [], + "label": "labelColor", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.showOverlappingLabels", + "type": "CompoundType", + "tags": [], + "label": "showOverlappingLabels", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.showDuplicates", + "type": "CompoundType", + "tags": [], + "label": "showDuplicates", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.labelsOrientation", + "type": "number", + "tags": [], + "label": "labelsOrientation", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.truncate", + "type": "number", + "tags": [], + "label": "truncate", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.showLabels", + "type": "CompoundType", + "tags": [], + "label": "showLabels", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.showTitle", + "type": "CompoundType", + "tags": [], + "label": "showTitle", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.showGridLines", + "type": "CompoundType", + "tags": [], + "label": "showGridLines", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.AxisConfig.extent", + "type": "CompoundType", + "tags": [], + "label": "extent", + "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.AxisExtentConfigResult", + "text": "AxisExtentConfigResult" + }, + " | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false } ], "initialIsOpen": false @@ -281,10 +425,10 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.CollectiveConfig.axisMode", + "id": "def-common.CollectiveConfig.position", "type": "string", "tags": [], - "label": "axisMode", + "label": "position", "description": [], "signature": [ "\"bottom\"" @@ -322,6 +466,55 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "expressionXY", + "id": "def-common.DataDecorationConfig", + "type": "Interface", + "tags": [], + "label": "DataDecorationConfig", + "description": [], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "expressionXY", + "id": "def-common.DataDecorationConfig.forAccessor", + "type": "string", + "tags": [], + "label": "forAccessor", + "description": [], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.DataDecorationConfig.color", + "type": "string", + "tags": [], + "label": "color", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.DataDecorationConfig.axisId", + "type": "string", + "tags": [], + "label": "axisId", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "expressionXY", "id": "def-common.DataLayerArgs", @@ -361,7 +554,7 @@ "label": "seriesType", "description": [], "signature": [ - "\"area\" | \"line\" | \"bar\" | \"bar_stacked\" | \"area_stacked\" | \"bar_horizontal\" | \"bar_percentage_stacked\" | \"bar_horizontal_stacked\" | \"area_percentage_stacked\" | \"bar_horizontal_percentage_stacked\"" + "\"area\" | \"line\" | \"bar\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false @@ -530,6 +723,36 @@ "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, + { + "parentPluginId": "expressionXY", + "id": "def-common.DataLayerArgs.isPercentage", + "type": "boolean", + "tags": [], + "label": "isPercentage", + "description": [], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.DataLayerArgs.isStacked", + "type": "boolean", + "tags": [], + "label": "isStacked", + "description": [], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.DataLayerArgs.isHorizontal", + "type": "boolean", + "tags": [], + "label": "isHorizontal", + "description": [], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, { "parentPluginId": "expressionXY", "id": "def-common.DataLayerArgs.palette", @@ -546,13 +769,13 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.DataLayerArgs.yConfig", + "id": "def-common.DataLayerArgs.decorations", "type": "Array", "tags": [], - "label": "yConfig", + "label": "decorations", "description": [], "signature": [ - "YConfigResult", + "DataDecorationConfigResult", "[] | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", @@ -563,319 +786,298 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.ExtendedYConfig", + "id": "def-common.LegendConfig", "type": "Interface", "tags": [], - "label": "ExtendedYConfig", + "label": "LegendConfig", "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.ExtendedYConfig", - "text": "ExtendedYConfig" - }, - " extends ", - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.YConfig", - "text": "YConfig" - } - ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, "children": [ { "parentPluginId": "expressionXY", - "id": "def-common.ExtendedYConfig.icon", - "type": "CompoundType", + "id": "def-common.LegendConfig.isVisible", + "type": "boolean", "tags": [], - "label": "icon", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AvailableReferenceLineIcon", - "text": "AvailableReferenceLineIcon" - }, - " | undefined" + "label": "isVisible", + "description": [ + "\nFlag whether the legend should be shown. If there is just a single series, it will be hidden" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.ExtendedYConfig.lineWidth", - "type": "number", + "id": "def-common.LegendConfig.position", + "type": "CompoundType", "tags": [], - "label": "lineWidth", - "description": [], + "label": "position", + "description": [ + "\nPosition of the legend relative to the chart" + ], "signature": [ - "number | undefined" + "\"top\" | \"bottom\" | \"left\" | \"right\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.ExtendedYConfig.lineStyle", + "id": "def-common.LegendConfig.showSingleSeries", "type": "CompoundType", "tags": [], - "label": "lineStyle", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.LineStyle", - "text": "LineStyle" - }, - " | undefined" + "label": "showSingleSeries", + "description": [ + "\nFlag whether the legend should be shown even with just a single series" + ], + "signature": [ + "boolean | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.ExtendedYConfig.fill", + "id": "def-common.LegendConfig.isInside", "type": "CompoundType", "tags": [], - "label": "fill", - "description": [], + "label": "isInside", + "description": [ + "\nFlag whether the legend is inside the chart" + ], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.FillStyle", - "text": "FillStyle" - }, - " | undefined" + "boolean | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.ExtendedYConfig.iconPosition", + "id": "def-common.LegendConfig.horizontalAlignment", "type": "CompoundType", "tags": [], - "label": "iconPosition", - "description": [], + "label": "horizontalAlignment", + "description": [ + "\nHorizontal Alignment of the legend when it is set inside chart" + ], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.IconPosition", - "text": "IconPosition" - }, - " | undefined" + "\"left\" | \"right\" | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.ExtendedYConfig.textVisibility", + "id": "def-common.LegendConfig.verticalAlignment", "type": "CompoundType", "tags": [], - "label": "textVisibility", - "description": [], + "label": "verticalAlignment", + "description": [ + "\nVertical Alignment of the legend when it is set inside chart" + ], "signature": [ - "boolean | undefined" + "\"top\" | \"bottom\" | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.LabelsOrientationConfig", - "type": "Interface", - "tags": [], - "label": "LabelsOrientationConfig", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionXY", - "id": "def-common.LabelsOrientationConfig.x", - "type": "number", - "tags": [], - "label": "x", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.LabelsOrientationConfig.yLeft", + "id": "def-common.LegendConfig.floatingColumns", "type": "number", "tags": [], - "label": "yLeft", - "description": [], + "label": "floatingColumns", + "description": [ + "\nNumber of columns when legend is set inside chart" + ], + "signature": [ + "number | undefined" + ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.LabelsOrientationConfig.yRight", + "id": "def-common.LegendConfig.maxLines", "type": "number", "tags": [], - "label": "yRight", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig", - "type": "Interface", - "tags": [], - "label": "LegendConfig", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.isVisible", - "type": "boolean", - "tags": [], - "label": "isVisible", + "label": "maxLines", "description": [ - "\nFlag whether the legend should be shown. If there is just a single series, it will be hidden" + "\nMaximum number of lines per legend item" + ], + "signature": [ + "number | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.position", + "id": "def-common.LegendConfig.shouldTruncate", "type": "CompoundType", "tags": [], - "label": "position", + "label": "shouldTruncate", "description": [ - "\nPosition of the legend relative to the chart" + "\nFlag whether the legend items are truncated or not" ], "signature": [ - "\"top\" | \"bottom\" | \"left\" | \"right\"" + "boolean | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.showSingleSeries", + "id": "def-common.LegendConfig.legendSize", "type": "CompoundType", "tags": [], - "label": "showSingleSeries", + "label": "legendSize", "description": [ - "\nFlag whether the legend should be shown even with just a single series" + "\nExact legend width (vertical) or height (horizontal)\nLimited to max of 70% of the chart container dimension Vertical legends limited to min of 30% of computed width" ], "signature": [ - "boolean | undefined" + { + "pluginId": "visualizations", + "scope": "common", + "docId": "kibVisualizationsPluginApi", + "section": "def-common.LegendSize", + "text": "LegendSize" + }, + " | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.ReferenceLineDecorationConfig", + "type": "Interface", + "tags": [], + "label": "ReferenceLineDecorationConfig", + "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.ReferenceLineDecorationConfig", + "text": "ReferenceLineDecorationConfig" }, + " extends ", + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.DataDecorationConfig", + "text": "DataDecorationConfig" + } + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false, + "children": [ { "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.isInside", + "id": "def-common.ReferenceLineDecorationConfig.icon", "type": "CompoundType", "tags": [], - "label": "isInside", - "description": [ - "\nFlag whether the legend is inside the chart" - ], + "label": "icon", + "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.AvailableReferenceLineIcon", + "text": "AvailableReferenceLineIcon" + }, + " | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.horizontalAlignment", - "type": "CompoundType", + "id": "def-common.ReferenceLineDecorationConfig.lineWidth", + "type": "number", "tags": [], - "label": "horizontalAlignment", - "description": [ - "\nHorizontal Alignment of the legend when it is set inside chart" - ], + "label": "lineWidth", + "description": [], "signature": [ - "\"left\" | \"right\" | undefined" + "number | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.verticalAlignment", + "id": "def-common.ReferenceLineDecorationConfig.lineStyle", "type": "CompoundType", "tags": [], - "label": "verticalAlignment", - "description": [ - "\nVertical Alignment of the legend when it is set inside chart" - ], + "label": "lineStyle", + "description": [], "signature": [ - "\"top\" | \"bottom\" | undefined" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.LineStyle", + "text": "LineStyle" + }, + " | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.floatingColumns", - "type": "number", + "id": "def-common.ReferenceLineDecorationConfig.fill", + "type": "CompoundType", "tags": [], - "label": "floatingColumns", - "description": [ - "\nNumber of columns when legend is set inside chart" - ], + "label": "fill", + "description": [], "signature": [ - "number | undefined" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.FillStyle", + "text": "FillStyle" + }, + " | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.maxLines", - "type": "number", + "id": "def-common.ReferenceLineDecorationConfig.iconPosition", + "type": "CompoundType", "tags": [], - "label": "maxLines", - "description": [ - "\nMaximum number of lines per legend item" - ], + "label": "iconPosition", + "description": [], "signature": [ - "number | undefined" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.IconPosition", + "text": "IconPosition" + }, + " | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.shouldTruncate", + "id": "def-common.ReferenceLineDecorationConfig.textVisibility", "type": "CompoundType", "tags": [], - "label": "shouldTruncate", - "description": [ - "\nFlag whether the legend items are truncated or not" - ], + "label": "textVisibility", + "description": [], "signature": [ "boolean | undefined" ], @@ -884,21 +1086,13 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.LegendConfig.legendSize", + "id": "def-common.ReferenceLineDecorationConfig.position", "type": "CompoundType", "tags": [], - "label": "legendSize", - "description": [ - "\nExact legend width (vertical) or height (horizontal)\nLimited to max of 70% of the chart container dimension Vertical legends limited to min of 30% of computed width" - ], + "label": "position", + "description": [], "signature": [ - { - "pluginId": "visualizations", - "scope": "common", - "docId": "kibVisualizationsPluginApi", - "section": "def-common.LegendSize", - "text": "LegendSize" - }, + "Position", " | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", @@ -958,18 +1152,18 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.ReferenceLineLayerArgs.yConfig", + "id": "def-common.ReferenceLineLayerArgs.decorations", "type": "Array", "tags": [], - "label": "yConfig", + "label": "decorations", "description": [], "signature": [ { "pluginId": "expressionXY", "scope": "common", "docId": "kibExpressionXYPluginApi", - "section": "def-common.ExtendedYConfigResult", - "text": "ExtendedYConfigResult" + "section": "def-common.ReferenceLineDecorationConfigResult", + "text": "ReferenceLineDecorationConfigResult" }, "[] | undefined" ], @@ -1055,143 +1249,27 @@ "type": "Interface", "tags": [], "label": "XYArgs", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.XYArgs", - "text": "XYArgs" - }, - " extends ", - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.DataLayerArgs", - "text": "DataLayerArgs" - } - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.xTitle", - "type": "string", - "tags": [], - "label": "xTitle", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.yTitle", - "type": "string", - "tags": [], - "label": "yTitle", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.yRightTitle", - "type": "string", - "tags": [], - "label": "yRightTitle", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.xExtent", - "type": "CompoundType", - "tags": [], - "label": "xExtent", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxisExtentConfigResult", - "text": "AxisExtentConfigResult" - }, - " | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.yLeftExtent", - "type": "CompoundType", - "tags": [], - "label": "yLeftExtent", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxisExtentConfig", - "text": "AxisExtentConfig" - }, - " & { type: \"axisExtentConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.yRightExtent", - "type": "CompoundType", - "tags": [], - "label": "yRightExtent", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxisExtentConfig", - "text": "AxisExtentConfig" - }, - " & { type: \"axisExtentConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.yLeftScale", - "type": "CompoundType", - "tags": [], - "label": "yLeftScale", - "description": [], - "signature": [ - "\"time\" | \"log\" | \"linear\" | \"sqrt\"" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, + "description": [], + "signature": [ { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.yRightScale", - "type": "CompoundType", - "tags": [], - "label": "yRightScale", - "description": [], - "signature": [ - "\"time\" | \"log\" | \"linear\" | \"sqrt\"" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.XYArgs", + "text": "XYArgs" }, + " extends ", + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.DataLayerArgs", + "text": "DataLayerArgs" + } + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false, + "children": [ { "parentPluginId": "expressionXY", "id": "def-common.XYArgs.legend", @@ -1308,38 +1386,18 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.axisTitlesVisibilitySettings", - "type": "CompoundType", - "tags": [], - "label": "axisTitlesVisibilitySettings", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxisTitlesVisibilityConfigResult", - "text": "AxisTitlesVisibilityConfigResult" - }, - " | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.tickLabelsVisibilitySettings", + "id": "def-common.XYArgs.curveType", "type": "CompoundType", "tags": [], - "label": "tickLabelsVisibilitySettings", + "label": "curveType", "description": [], "signature": [ { "pluginId": "expressionXY", "scope": "common", "docId": "kibExpressionXYPluginApi", - "section": "def-common.TickLabelsConfigResult", - "text": "TickLabelsConfigResult" + "section": "def-common.XYCurveType", + "text": "XYCurveType" }, " | undefined" ], @@ -1348,112 +1406,92 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.gridlinesVisibilitySettings", - "type": "CompoundType", + "id": "def-common.XYArgs.fillOpacity", + "type": "number", "tags": [], - "label": "gridlinesVisibilitySettings", + "label": "fillOpacity", "description": [], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.GridlinesConfigResult", - "text": "GridlinesConfigResult" - }, - " | undefined" + "number | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.labelsOrientation", + "id": "def-common.XYArgs.hideEndzones", "type": "CompoundType", "tags": [], - "label": "labelsOrientation", + "label": "hideEndzones", "description": [], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.LabelsOrientationConfigResult", - "text": "LabelsOrientationConfigResult" - }, - " | undefined" + "boolean | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.curveType", + "id": "def-common.XYArgs.valuesInLegend", "type": "CompoundType", "tags": [], - "label": "curveType", + "label": "valuesInLegend", "description": [], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.XYCurveType", - "text": "XYCurveType" - }, - " | undefined" + "boolean | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.fillOpacity", - "type": "number", + "id": "def-common.XYArgs.ariaLabel", + "type": "string", "tags": [], - "label": "fillOpacity", + "label": "ariaLabel", "description": [], "signature": [ - "number | undefined" + "string | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.hideEndzones", - "type": "CompoundType", + "id": "def-common.XYArgs.yAxisConfigs", + "type": "Array", "tags": [], - "label": "hideEndzones", + "label": "yAxisConfigs", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.YAxisConfigResult", + "text": "YAxisConfigResult" + }, + "[] | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.valuesInLegend", + "id": "def-common.XYArgs.xAxisConfig", "type": "CompoundType", "tags": [], - "label": "valuesInLegend", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.XYArgs.ariaLabel", - "type": "string", - "tags": [], - "label": "ariaLabel", + "label": "xAxisConfig", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.XAxisConfigResult", + "text": "XAxisConfigResult" + }, + " | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false @@ -1664,38 +1702,45 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.YConfig", + "id": "def-common.YAxisConfig", "type": "Interface", "tags": [], - "label": "YConfig", + "label": "YAxisConfig", "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.YAxisConfig", + "text": "YAxisConfig" + }, + " extends ", + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.AxisConfig", + "text": "AxisConfig" + } + ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, "children": [ { "parentPluginId": "expressionXY", - "id": "def-common.YConfig.forAccessor", - "type": "string", - "tags": [], - "label": "forAccessor", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "expressionXY", - "id": "def-common.YConfig.axisMode", + "id": "def-common.YAxisConfig.mode", "type": "CompoundType", "tags": [], - "label": "axisMode", + "label": "mode", "description": [], "signature": [ { "pluginId": "expressionXY", "scope": "common", "docId": "kibExpressionXYPluginApi", - "section": "def-common.YAxisMode", - "text": "YAxisMode" + "section": "def-common.AxisMode", + "text": "AxisMode" }, " | undefined" ], @@ -1704,13 +1749,33 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.YConfig.color", - "type": "string", + "id": "def-common.YAxisConfig.boundsMargin", + "type": "number", "tags": [], - "label": "color", + "label": "boundsMargin", "description": [], "signature": [ - "string | undefined" + "number | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "expressionXY", + "id": "def-common.YAxisConfig.scaleType", + "type": "CompoundType", + "tags": [], + "label": "scaleType", + "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.YScaleType", + "text": "YScaleType" + }, + " | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false @@ -1772,20 +1837,13 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.AxisTitlesVisibilityConfigResult", + "id": "def-common.AxisMode", "type": "Type", "tags": [], - "label": "AxisTitlesVisibilityConfigResult", + "label": "AxisMode", "description": [], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", - "text": "AxesSettingsConfig" - }, - " & { type: \"axisTitlesVisibilityConfig\"; }" + "\"normal\" | \"percentage\" | \"wiggle\" | \"silhouette\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, @@ -2022,27 +2080,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "expressionXY", - "id": "def-common.ExtendedYConfigResult", - "type": "Type", - "tags": [], - "label": "ExtendedYConfigResult", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.ExtendedYConfig", - "text": "ExtendedYConfig" - }, - " & { type: \"extendedYConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "expressionXY", "id": "def-common.FillStyle", @@ -2071,27 +2108,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "expressionXY", - "id": "def-common.GridlinesConfigResult", - "type": "Type", - "tags": [], - "label": "GridlinesConfigResult", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", - "text": "AxesSettingsConfig" - }, - " & { type: \"gridlinesConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "expressionXY", "id": "def-common.IconPosition", @@ -2106,27 +2122,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "expressionXY", - "id": "def-common.LabelsOrientationConfigResult", - "type": "Type", - "tags": [], - "label": "LabelsOrientationConfigResult", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.LabelsOrientationConfig", - "text": "LabelsOrientationConfig" - }, - " & { type: \"labelsOrientationConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "expressionXY", "id": "def-common.LayerType", @@ -2204,6 +2199,27 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "expressionXY", + "id": "def-common.ReferenceLineDecorationConfigResult", + "type": "Type", + "tags": [], + "label": "ReferenceLineDecorationConfigResult", + "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.ReferenceLineDecorationConfig", + "text": "ReferenceLineDecorationConfig" + }, + " & { type: \"referenceLineDecorationConfig\"; }" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "expressionXY", "id": "def-common.ReferenceLineLayerConfig", @@ -2271,7 +2287,7 @@ "label": "SeriesType", "description": [], "signature": [ - "\"area\" | \"line\" | \"bar\" | \"bar_stacked\" | \"area_stacked\" | \"bar_horizontal\" | \"bar_percentage_stacked\" | \"bar_horizontal_stacked\" | \"area_percentage_stacked\" | \"bar_horizontal_percentage_stacked\"" + "\"area\" | \"line\" | \"bar\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, @@ -2279,20 +2295,13 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.TickLabelsConfigResult", + "id": "def-common.ValueLabelMode", "type": "Type", "tags": [], - "label": "TickLabelsConfigResult", + "label": "ValueLabelMode", "description": [], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", - "text": "AxesSettingsConfig" - }, - " & { type: \"tickLabelsConfig\"; }" + "\"show\" | \"hide\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, @@ -2300,13 +2309,20 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.ValueLabelMode", + "id": "def-common.XAxisConfigResult", "type": "Type", "tags": [], - "label": "ValueLabelMode", + "label": "XAxisConfigResult", "description": [], "signature": [ - "\"show\" | \"hide\"" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.AxisConfig", + "text": "AxisConfig" + }, + " & { type: \"xAxisConfig\"; }" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, @@ -2402,13 +2418,20 @@ }, { "parentPluginId": "expressionXY", - "id": "def-common.YAxisMode", + "id": "def-common.YAxisConfigResult", "type": "Type", "tags": [], - "label": "YAxisMode", + "label": "YAxisConfigResult", "description": [], "signature": [ - "\"bottom\" | \"left\" | \"right\" | \"auto\"" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.YAxisConfig", + "text": "YAxisConfig" + }, + " & { type: \"yAxisConfig\"; }" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index bc48042555b6f..6e1b934066aa9 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressionXY plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 148 | 0 | 138 | 14 | +| 150 | 0 | 140 | 14 | ## Client diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 7ceb36224bb14..aa125ecab6a1d 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github summary: API docs for the expressions plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/features.mdx b/api_docs/features.mdx index f66bc3d55d9a3..6d06252d166f3 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github summary: API docs for the features plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 5021dd2eea449..a789501accca1 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github summary: API docs for the fieldFormats plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index 729b43555dc75..c7d1128a8c2d2 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github summary: API docs for the fileUpload plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/fleet.devdocs.json b/api_docs/fleet.devdocs.json index f060abd995232..72dd49585690d 100644 --- a/api_docs/fleet.devdocs.json +++ b/api_docs/fleet.devdocs.json @@ -50,6 +50,100 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamMappings", + "type": "Function", + "tags": [], + "label": "PackagePolicyEditorDatastreamMappings", + "description": [], + "signature": [ + "({ dataStream, packageInfo }: React.PropsWithChildren<", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyEditorDatastreamMappingsProps", + "text": "PackagePolicyEditorDatastreamMappingsProps" + }, + ">) => JSX.Element" + ], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamMappings.$1", + "type": "CompoundType", + "tags": [], + "label": "{ dataStream, packageInfo }", + "description": [], + "signature": [ + "React.PropsWithChildren<", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyEditorDatastreamMappingsProps", + "text": "PackagePolicyEditorDatastreamMappingsProps" + }, + ">" + ], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamPipelines", + "type": "Function", + "tags": [], + "label": "PackagePolicyEditorDatastreamPipelines", + "description": [], + "signature": [ + "({ dataStream, packageInfo }: React.PropsWithChildren<", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyEditorDatastreamPipelinesProps", + "text": "PackagePolicyEditorDatastreamPipelinesProps" + }, + ">) => JSX.Element | null" + ], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamPipelines.$1", + "type": "CompoundType", + "tags": [], + "label": "{ dataStream, packageInfo }", + "description": [], + "signature": [ + "React.PropsWithChildren<", + { + "pluginId": "fleet", + "scope": "public", + "docId": "kibFleetPluginApi", + "section": "def-public.PackagePolicyEditorDatastreamPipelinesProps", + "text": "PackagePolicyEditorDatastreamPipelinesProps" + }, + ">" + ], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-public.pkgKeyFromPackageInfo", @@ -1285,6 +1379,178 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamMappingsProps", + "type": "Interface", + "tags": [], + "label": "PackagePolicyEditorDatastreamMappingsProps", + "description": [], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamMappingsProps.packageInfo", + "type": "CompoundType", + "tags": [], + "label": "packageInfo", + "description": [], + "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.Installable", + "text": "Installable" + }, + "> | ", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.Installable", + "text": "Installable" + }, + ">" + ], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings.tsx", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamMappingsProps.dataStream", + "type": "Object", + "tags": [], + "label": "dataStream", + "description": [], + "signature": [ + "{ dataset: string; type: string; }" + ], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings.tsx", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamPipelinesProps", + "type": "Interface", + "tags": [], + "label": "PackagePolicyEditorDatastreamPipelinesProps", + "description": [], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamPipelinesProps.packageInfo", + "type": "CompoundType", + "tags": [], + "label": "packageInfo", + "description": [], + "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.Installable", + "text": "Installable" + }, + "> | ", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.Installable", + "text": "Installable" + }, + ">" + ], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.tsx", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-public.PackagePolicyEditorDatastreamPipelinesProps.dataStream", + "type": "Object", + "tags": [], + "label": "dataStream", + "description": [], + "signature": [ + "{ dataset: string; type: string; }" + ], + "path": "x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.tsx", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-public.PackagePolicyEditTabsExtension", @@ -8772,44 +9038,173 @@ }, { "parentPluginId": "fleet", - "id": "def-common.getExperimentalAllowedValues", + "id": "def-common.getComponentTemplateNameForDatastream", "type": "Function", "tags": [], - "label": "getExperimentalAllowedValues", - "description": [], - "signature": [ - "() => string[]" + "label": "getComponentTemplateNameForDatastream", + "description": [ + "\nReturn the name for a component template" ], - "path": "x-pack/plugins/fleet/common/experimental_features.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "fleet", - "id": "def-common.getMaxPackageName", - "type": "Function", - "tags": [], - "label": "getMaxPackageName", - "description": [], "signature": [ - "(packageName: string, packagePolicies: { name: string; }[] | undefined) => string" + "(dataStream: { dataset: string; type: string; hidden?: boolean | undefined; }, suffix: \"@package\" | \"@custom\" | undefined) => string" ], - "path": "x-pack/plugins/fleet/common/services/max_package_name.ts", + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", "deprecated": false, "children": [ { "parentPluginId": "fleet", - "id": "def-common.getMaxPackageName.$1", - "type": "string", + "id": "def-common.getComponentTemplateNameForDatastream.$1", + "type": "Object", "tags": [], - "label": "packageName", + "label": "dataStream", "description": [], - "signature": [ - "string" - ], - "path": "x-pack/plugins/fleet/common/services/max_package_name.ts", + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.getComponentTemplateNameForDatastream.$1.dataset", + "type": "string", + "tags": [], + "label": "dataset", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getComponentTemplateNameForDatastream.$1.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getComponentTemplateNameForDatastream.$1.hidden", + "type": "CompoundType", + "tags": [], + "label": "hidden", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + } + ] + }, + { + "parentPluginId": "fleet", + "id": "def-common.getComponentTemplateNameForDatastream.$2", + "type": "CompoundType", + "tags": [], + "label": "suffix", + "description": [], + "signature": [ + "\"@package\" | \"@custom\" | undefined" + ], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getCustomPipelineNameForDatastream", + "type": "Function", + "tags": [], + "label": "getCustomPipelineNameForDatastream", + "description": [ + "\nReturn the custom user ingest pipeline name for a datastream" + ], + "signature": [ + "(dataStream: { dataset: string; type: string; }) => string" + ], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.getCustomPipelineNameForDatastream.$1", + "type": "Object", + "tags": [], + "label": "dataStream", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.getCustomPipelineNameForDatastream.$1.dataset", + "type": "string", + "tags": [], + "label": "dataset", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getCustomPipelineNameForDatastream.$1.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getExperimentalAllowedValues", + "type": "Function", + "tags": [], + "label": "getExperimentalAllowedValues", + "description": [], + "signature": [ + "() => string[]" + ], + "path": "x-pack/plugins/fleet/common/experimental_features.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getMaxPackageName", + "type": "Function", + "tags": [], + "label": "getMaxPackageName", + "description": [], + "signature": [ + "(packageName: string, packagePolicies: { name: string; }[] | undefined) => string" + ], + "path": "x-pack/plugins/fleet/common/services/max_package_name.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.getMaxPackageName.$1", + "type": "string", + "tags": [], + "label": "packageName", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/fleet/common/services/max_package_name.ts", "deprecated": false, "isRequired": true }, @@ -8893,6 +9288,124 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.getPipelineNameForDatastream", + "type": "Function", + "tags": [], + "label": "getPipelineNameForDatastream", + "description": [ + "\nReturn the ingest pipeline name for a datastream" + ], + "signature": [ + "({ dataStream, packageVersion, }: { dataStream: { dataset: string; type: string; }; packageVersion: string; }) => string" + ], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.getPipelineNameForDatastream.$1", + "type": "Object", + "tags": [], + "label": "{\n dataStream,\n packageVersion,\n}", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.getPipelineNameForDatastream.$1.dataStream", + "type": "Object", + "tags": [], + "label": "dataStream", + "description": [], + "signature": [ + "{ dataset: string; type: string; }" + ], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getPipelineNameForDatastream.$1.packageVersion", + "type": "string", + "tags": [], + "label": "packageVersion", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getRegistryDataStreamAssetBaseName", + "type": "Function", + "tags": [], + "label": "getRegistryDataStreamAssetBaseName", + "description": [ + "\nCreates the base name for Elasticsearch assets in the form of\n{type}-{dataset}" + ], + "signature": [ + "(dataStream: { dataset: string; type: string; hidden?: boolean | undefined; }) => string" + ], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.getRegistryDataStreamAssetBaseName.$1", + "type": "Object", + "tags": [], + "label": "dataStream", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.getRegistryDataStreamAssetBaseName.$1.dataset", + "type": "string", + "tags": [], + "label": "dataset", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getRegistryDataStreamAssetBaseName.$1.type", + "type": "string", + "tags": [], + "label": "type", + "description": [], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.getRegistryDataStreamAssetBaseName.$1.hidden", + "type": "CompoundType", + "tags": [], + "label": "hidden", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/fleet/common/services/datastream_es_name.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.getStreamsForInputType", @@ -9841,6 +10354,19 @@ ], "path": "x-pack/plugins/fleet/common/types/models/agent.ts", "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.Agent.sort", + "type": "Array", + "tags": [], + "label": "sort", + "description": [], + "signature": [ + "(string | number | null)[] | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/models/agent.ts", + "deprecated": false } ], "initialIsOpen": false @@ -11063,6 +11589,29 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.DeleteDownloadSourceResponse", + "type": "Interface", + "tags": [], + "label": "DeleteDownloadSourceResponse", + "description": [], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.DeleteDownloadSourceResponse.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.DeleteEnrollmentAPIKeyRequest", @@ -11240,6 +11789,49 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.DownloadSourceBase", + "type": "Interface", + "tags": [], + "label": "DownloadSourceBase", + "description": [], + "path": "x-pack/plugins/fleet/common/types/models/download_sources.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.DownloadSourceBase.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/plugins/fleet/common/types/models/download_sources.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DownloadSourceBase.host", + "type": "string", + "tags": [], + "label": "host", + "description": [], + "path": "x-pack/plugins/fleet/common/types/models/download_sources.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DownloadSourceBase.is_default", + "type": "boolean", + "tags": [], + "label": "is_default", + "description": [], + "path": "x-pack/plugins/fleet/common/types/models/download_sources.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.EnrollmentAPIKey", @@ -11647,6 +12239,19 @@ "path": "x-pack/plugins/fleet/common/types/index.ts", "deprecated": false }, + { + "parentPluginId": "fleet", + "id": "def-common.FleetConfigType.packageVerification", + "type": "Object", + "tags": [], + "label": "packageVerification", + "description": [], + "signature": [ + "{ gpgKeyPath?: string | undefined; } | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/index.ts", + "deprecated": false + }, { "parentPluginId": "fleet", "id": "def-common.FleetConfigType.developer", @@ -13847,6 +14452,64 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.GetOneDownloadSourceRequest", + "type": "Interface", + "tags": [], + "label": "GetOneDownloadSourceRequest", + "description": [], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.GetOneDownloadSourceRequest.params", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "{ outputId: string; }" + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.GetOneDownloadSourceResponse", + "type": "Interface", + "tags": [], + "label": "GetOneDownloadSourceResponse", + "description": [], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.GetOneDownloadSourceResponse.item", + "type": "Object", + "tags": [], + "label": "item", + "description": [], + "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.DownloadSourceBase", + "text": "DownloadSourceBase" + } + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.GetOneEnrollmentAPIKeyRequest", @@ -15475,6 +16138,19 @@ ], "path": "x-pack/plugins/fleet/common/types/models/agent_policy.ts", "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.NewAgentPolicy.download_source_id", + "type": "CompoundType", + "tags": [], + "label": "download_source_id", + "description": [], + "signature": [ + "string | null | undefined" + ], + "path": "x-pack/plugins/fleet/common/types/models/agent_policy.ts", + "deprecated": false } ], "initialIsOpen": false @@ -16918,6 +17594,32 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.PostDownloadSourceRequest", + "type": "Interface", + "tags": [], + "label": "PostDownloadSourceRequest", + "description": [], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.PostDownloadSourceRequest.body", + "type": "Object", + "tags": [], + "label": "body", + "description": [], + "signature": [ + "{ id: string; name: string; hosts: string; is_default?: boolean | undefined; }" + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.PostEnrollmentAPIKeyRequest", @@ -17391,6 +18093,77 @@ "children": [], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.PutDownloadSourceRequest", + "type": "Interface", + "tags": [], + "label": "PutDownloadSourceRequest", + "description": [], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.PutDownloadSourceRequest.params", + "type": "Object", + "tags": [], + "label": "params", + "description": [], + "signature": [ + "{ outputId: string; }" + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.PutDownloadSourceRequest.body", + "type": "Object", + "tags": [], + "label": "body", + "description": [], + "signature": [ + "{ id: string; name: string; hosts: string; is_default?: boolean | undefined; }" + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.PutDownloadSourceResponse", + "type": "Interface", + "tags": [], + "label": "PutDownloadSourceResponse", + "description": [], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.PutDownloadSourceResponse.item", + "type": "Object", + "tags": [], + "label": "item", + "description": [], + "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.DownloadSourceBase", + "text": "DownloadSourceBase" + } + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.PutOutputRequest", @@ -19303,7 +20076,7 @@ "section": "def-common.ValueOf", "text": "ValueOf" }, - "<{ readonly Active: \"active\"; readonly Inactive: \"inactive\"; }>; description?: string | undefined; name: string; updated_at: string; namespace: string; updated_by: string; is_default?: boolean | undefined; is_default_fleet_server?: boolean | undefined; has_fleet_server?: boolean | undefined; is_managed: boolean; monitoring_enabled?: (\"metrics\" | \"logs\")[] | undefined; unenroll_timeout?: number | undefined; is_preconfigured?: boolean | undefined; data_output_id?: string | null | undefined; monitoring_output_id?: string | null | undefined; package_policies: string[] | ", + "<{ readonly Active: \"active\"; readonly Inactive: \"inactive\"; }>; description?: string | undefined; name: string; updated_at: string; namespace: string; updated_by: string; is_default?: boolean | undefined; is_default_fleet_server?: boolean | undefined; has_fleet_server?: boolean | undefined; is_managed: boolean; monitoring_enabled?: (\"metrics\" | \"logs\")[] | undefined; unenroll_timeout?: number | undefined; is_preconfigured?: boolean | undefined; data_output_id?: string | null | undefined; monitoring_output_id?: string | null | undefined; download_source_id?: string | null | undefined; package_policies: string[] | ", { "pluginId": "fleet", "scope": "common", @@ -19424,7 +20197,7 @@ "section": "def-common.RegistryPackage", "text": "RegistryPackage" }, - ", \"internal\" | \"data_streams\" | \"elasticsearch\" | \"assets\" | \"readme\">" + ", \"internal\" | \"data_streams\" | \"assets\" | \"readme\" | \"elasticsearch\">" ], "path": "x-pack/plugins/fleet/common/types/models/epm.ts", "deprecated": false, @@ -19683,6 +20456,34 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.DEFAULT_DOWNLOAD_SOURCE", + "type": "string", + "tags": [], + "label": "DEFAULT_DOWNLOAD_SOURCE", + "description": [], + "signature": [ + "\"artifactory.elastic.co\"" + ], + "path": "x-pack/plugins/fleet/common/constants/download_source.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DEFAULT_DOWNLOAD_SOURCE_ID", + "type": "string", + "tags": [], + "label": "DEFAULT_DOWNLOAD_SOURCE_ID", + "description": [], + "signature": [ + "\"fleet-default-download-source\"" + ], + "path": "x-pack/plugins/fleet/common/constants/download_source.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.DEFAULT_OUTPUT_ID", @@ -19747,6 +20548,73 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.DOWNLOAD_SOURCE_API_ROOT", + "type": "string", + "tags": [], + "label": "DOWNLOAD_SOURCE_API_ROOT", + "description": [], + "path": "x-pack/plugins/fleet/common/constants/routes.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE", + "type": "string", + "tags": [], + "label": "DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE", + "description": [], + "signature": [ + "\"ingest-download-sources\"" + ], + "path": "x-pack/plugins/fleet/common/constants/download_source.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DownloadSource", + "type": "Type", + "tags": [], + "label": "DownloadSource", + "description": [], + "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.DownloadSourceBase", + "text": "DownloadSourceBase" + }, + " & { id: string; }" + ], + "path": "x-pack/plugins/fleet/common/types/models/download_sources.ts", + "deprecated": false, + "initialIsOpen": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DownloadSourceAttributes", + "type": "Type", + "tags": [], + "label": "DownloadSourceAttributes", + "description": [], + "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.DownloadSourceBase", + "text": "DownloadSourceBase" + }, + " & { source_id?: string | undefined; }" + ], + "path": "x-pack/plugins/fleet/common/types/models/download_sources.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.DryRunPackagePolicy", @@ -20226,6 +21094,35 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.GetDownloadSourceResponse", + "type": "Type", + "tags": [], + "label": "GetDownloadSourceResponse", + "description": [], + "signature": [ + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.ListResult", + "text": "ListResult" + }, + "<", + { + "pluginId": "fleet", + "scope": "common", + "docId": "kibFleetPluginApi", + "section": "def-common.DownloadSourceBase", + "text": "DownloadSourceBase" + }, + ">" + ], + "path": "x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.GetEnrollmentAPIKeysResponse", @@ -21012,6 +21909,20 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.PACKAGE_TEMPLATE_SUFFIX", + "type": "string", + "tags": [], + "label": "PACKAGE_TEMPLATE_SUFFIX", + "description": [], + "signature": [ + "\"@package\"" + ], + "path": "x-pack/plugins/fleet/common/constants/epm.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.PackageAssetReference", @@ -21206,23 +22117,23 @@ "section": "def-common.PackagePolicyPackage", "text": "PackagePolicyPackage" }, - " | undefined; description?: string | undefined; name: string; enabled: boolean; updated_at: string; namespace: string; created_at: string; created_by: string; updated_by: string; inputs: ", + " | undefined; description?: string | undefined; name: string; enabled: boolean; updated_at: string; namespace: string; created_at: string; created_by: string; updated_by: string; vars?: ", { "pluginId": "fleet", "scope": "common", "docId": "kibFleetPluginApi", - "section": "def-common.PackagePolicyInput", - "text": "PackagePolicyInput" + "section": "def-common.PackagePolicyConfigRecord", + "text": "PackagePolicyConfigRecord" }, - "[]; policy_id: string; output_id: string; vars?: ", + " | undefined; elasticsearch?: { privileges?: { cluster?: string[] | undefined; } | undefined; } | undefined; inputs: ", { "pluginId": "fleet", "scope": "common", "docId": "kibFleetPluginApi", - "section": "def-common.PackagePolicyConfigRecord", - "text": "PackagePolicyConfigRecord" + "section": "def-common.PackagePolicyInput", + "text": "PackagePolicyInput" }, - " | undefined; elasticsearch?: { privileges?: { cluster?: string[] | undefined; } | undefined; } | undefined; revision: number; }" + "[]; policy_id: string; output_id: string; revision: number; }" ], "path": "x-pack/plugins/fleet/common/types/models/package_policy.ts", "deprecated": false, @@ -21853,6 +22764,20 @@ "deprecated": false, "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.USER_SETTINGS_TEMPLATE_SUFFIX", + "type": "string", + "tags": [], + "label": "USER_SETTINGS_TEMPLATE_SUFFIX", + "description": [], + "signature": [ + "\"@custom\"" + ], + "path": "x-pack/plugins/fleet/common/constants/epm.ts", + "deprecated": false, + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.UUID_V5_NAMESPACE", @@ -23114,6 +24039,69 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "fleet", + "id": "def-common.DOWNLOAD_SOURCE_API_ROUTES", + "type": "Object", + "tags": [], + "label": "DOWNLOAD_SOURCE_API_ROUTES", + "description": [], + "path": "x-pack/plugins/fleet/common/constants/routes.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "fleet", + "id": "def-common.DOWNLOAD_SOURCE_API_ROUTES.LIST_PATTERN", + "type": "string", + "tags": [], + "label": "LIST_PATTERN", + "description": [], + "path": "x-pack/plugins/fleet/common/constants/routes.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DOWNLOAD_SOURCE_API_ROUTES.INFO_PATTERN", + "type": "string", + "tags": [], + "label": "INFO_PATTERN", + "description": [], + "path": "x-pack/plugins/fleet/common/constants/routes.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DOWNLOAD_SOURCE_API_ROUTES.CREATE_PATTERN", + "type": "string", + "tags": [], + "label": "CREATE_PATTERN", + "description": [], + "path": "x-pack/plugins/fleet/common/constants/routes.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DOWNLOAD_SOURCE_API_ROUTES.UPDATE_PATTERN", + "type": "string", + "tags": [], + "label": "UPDATE_PATTERN", + "description": [], + "path": "x-pack/plugins/fleet/common/constants/routes.ts", + "deprecated": false + }, + { + "parentPluginId": "fleet", + "id": "def-common.DOWNLOAD_SOURCE_API_ROUTES.DELETE_PATTERN", + "type": "string", + "tags": [], + "label": "DELETE_PATTERN", + "description": [], + "path": "x-pack/plugins/fleet/common/constants/routes.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, { "parentPluginId": "fleet", "id": "def-common.ENROLLMENT_API_KEY_ROUTES", diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 3bb51cbf90196..9f566e1c96639 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github summary: API docs for the fleet plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Fleet](https://github.com/orgs/elastic/teams/fleet) for questions regar | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 1435 | 8 | 1308 | 10 | +| 1499 | 8 | 1368 | 10 | ## Client diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index 2f2009cdb8a90..008ec51e7a43d 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github summary: API docs for the globalSearch plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/home.devdocs.json b/api_docs/home.devdocs.json index 587747c8fcfc9..5555cbb412958 100644 --- a/api_docs/home.devdocs.json +++ b/api_docs/home.devdocs.json @@ -180,7 +180,7 @@ "\nConvert instruction variant id into display text.\n" ], "signature": [ - "(id: \"ESC\" | \"OSX\" | \"DEB\" | \"RPM\" | \"DOCKER\" | \"WINDOWS\" | \"NODE\" | \"DJANGO\" | \"FLASK\" | \"RAILS\" | \"RACK\" | \"JS\" | \"GO\" | \"JAVA\" | \"DOTNET\" | \"LINUX\" | \"PHP\" | \"FLEET\") => string" + "(id: \"ESC\" | \"OSX\" | \"DEB\" | \"RPM\" | \"DOCKER\" | \"WINDOWS\" | \"NODE\" | \"DJANGO\" | \"FLASK\" | \"RAILS\" | \"RACK\" | \"JS\" | \"GO\" | \"JAVA\" | \"DOTNET\" | \"LINUX\" | \"PHP\" | \"FLEET\" | \"OPEN_TELEMETRY\") => string" ], "path": "src/plugins/home/common/instruction_variant.ts", "deprecated": false, @@ -193,7 +193,7 @@ "label": "id", "description": [], "signature": [ - "\"ESC\" | \"OSX\" | \"DEB\" | \"RPM\" | \"DOCKER\" | \"WINDOWS\" | \"NODE\" | \"DJANGO\" | \"FLASK\" | \"RAILS\" | \"RACK\" | \"JS\" | \"GO\" | \"JAVA\" | \"DOTNET\" | \"LINUX\" | \"PHP\" | \"FLEET\"" + "\"ESC\" | \"OSX\" | \"DEB\" | \"RPM\" | \"DOCKER\" | \"WINDOWS\" | \"NODE\" | \"DJANGO\" | \"FLASK\" | \"RAILS\" | \"RACK\" | \"JS\" | \"GO\" | \"JAVA\" | \"DOTNET\" | \"LINUX\" | \"PHP\" | \"FLEET\" | \"OPEN_TELEMETRY\"" ], "path": "src/plugins/home/common/instruction_variant.ts", "deprecated": false, @@ -1081,6 +1081,16 @@ "description": [], "path": "src/plugins/home/common/instruction_variant.ts", "deprecated": false + }, + { + "parentPluginId": "home", + "id": "def-public.INSTRUCTION_VARIANT.OPEN_TELEMETRY", + "type": "string", + "tags": [], + "label": "OPEN_TELEMETRY", + "description": [], + "path": "src/plugins/home/common/instruction_variant.ts", + "deprecated": false } ], "initialIsOpen": false @@ -1939,6 +1949,16 @@ "description": [], "path": "src/plugins/home/common/instruction_variant.ts", "deprecated": false + }, + { + "parentPluginId": "home", + "id": "def-server.INSTRUCTION_VARIANT.OPEN_TELEMETRY", + "type": "string", + "tags": [], + "label": "OPEN_TELEMETRY", + "description": [], + "path": "src/plugins/home/common/instruction_variant.ts", + "deprecated": false } ], "initialIsOpen": false diff --git a/api_docs/home.mdx b/api_docs/home.mdx index bc34d629ae8ac..6c50e4182300d 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github summary: API docs for the home plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) for que | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 141 | 0 | 102 | 0 | +| 143 | 0 | 104 | 0 | ## Client diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 1f34605863969..96a762c4faaec 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the indexLifecycleManagement plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 29f9caea1d449..0abc7d5258cfd 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the indexManagement plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index fb3cb5242d85c..ce5044e1906d8 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github summary: API docs for the infra plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 95f83c9fa5bc1..1f748b757b205 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github summary: API docs for the inspector plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 7edb48d5d7919..d66d845bdab12 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github summary: API docs for the interactiveSetup plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index f78923593d2ec..eff5ffa27b782 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/ace plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_aiops_utils.devdocs.json b/api_docs/kbn_aiops_utils.devdocs.json index a81c6d0146764..7001056b26d3b 100644 --- a/api_docs/kbn_aiops_utils.devdocs.json +++ b/api_docs/kbn_aiops_utils.devdocs.json @@ -31,7 +31,7 @@ "signature": [ "(headers: Headers) => StreamFactoryReturnType" ], - "path": "packages/kbn-aiops-utils/src/lib/stream_factory.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/stream_factory.ts", "deprecated": false, "children": [ { @@ -46,7 +46,7 @@ "signature": [ "Headers" ], - "path": "packages/kbn-aiops-utils/src/lib/stream_factory.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/stream_factory.ts", "deprecated": false, "isRequired": true } @@ -68,7 +68,7 @@ "signature": [ "(headers: Headers) => StreamFactoryReturnType" ], - "path": "packages/kbn-aiops-utils/src/lib/stream_factory.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/stream_factory.ts", "deprecated": false, "children": [ { @@ -83,7 +83,7 @@ "signature": [ "Headers" ], - "path": "packages/kbn-aiops-utils/src/lib/stream_factory.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/stream_factory.ts", "deprecated": false, "isRequired": true } @@ -103,7 +103,7 @@ "signature": [ "(endpoint: `${BasePath}${I[\"endpoint\"]}`, body: I[\"body\"]) => UseFetchStreamReturnType>" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "children": [ { @@ -116,7 +116,7 @@ "signature": [ "`${BasePath}${I[\"endpoint\"]}`" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "isRequired": true }, @@ -130,7 +130,7 @@ "signature": [ "I[\"body\"]" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "isRequired": true } @@ -148,7 +148,7 @@ "signature": [ "(endpoint: `${BasePath}${I[\"endpoint\"]}`, body: I[\"body\"], options: { reducer: I[\"reducer\"]; initialState: React.ReducerState; }) => UseFetchStreamReturnType, React.ReducerAction>" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "children": [ { @@ -161,7 +161,7 @@ "signature": [ "`${BasePath}${I[\"endpoint\"]}`" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "isRequired": true }, @@ -175,7 +175,7 @@ "signature": [ "I[\"body\"]" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "isRequired": true }, @@ -186,7 +186,7 @@ "tags": [], "label": "options", "description": [], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "children": [ { @@ -199,7 +199,7 @@ "signature": [ "I[\"reducer\"]" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "returnComment": [], "children": [ @@ -241,7 +241,7 @@ "signature": [ "I[\"reducer\"] extends React.Reducer ? S : never" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false } ] @@ -262,7 +262,7 @@ "signature": [ "(endpoint: `${BasePath}${I[\"endpoint\"]}`, body: I[\"body\"], options: { reducer: I[\"reducer\"]; initialState: React.ReducerState; } | undefined) => UseFetchStreamReturnType, React.ReducerAction>" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "children": [ { @@ -277,7 +277,7 @@ "signature": [ "`${BasePath}${I[\"endpoint\"]}`" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "isRequired": true }, @@ -293,7 +293,7 @@ "signature": [ "I[\"body\"]" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "isRequired": true }, @@ -304,7 +304,7 @@ "tags": [], "label": "options", "description": [], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "children": [ { @@ -317,7 +317,7 @@ "signature": [ "I[\"reducer\"]" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "returnComment": [], "children": [ @@ -359,7 +359,7 @@ "signature": [ "I[\"reducer\"] extends React.Reducer ? S : never" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false } ] @@ -381,7 +381,7 @@ "description": [ "\nCustom hook type definition of the base params for an NDJSON stream with custom reducer." ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "children": [ { @@ -391,7 +391,7 @@ "tags": [], "label": "endpoint", "description": [], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false }, { @@ -404,7 +404,7 @@ "signature": [ "object" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false }, { @@ -417,7 +417,7 @@ "signature": [ "(prevState: any, action: any) => any" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "returnComment": [], "children": [ @@ -461,7 +461,7 @@ "description": [ "\nCustom hook type definition of the base params for a string base stream without a custom reducer." ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "children": [ { @@ -471,7 +471,7 @@ "tags": [], "label": "endpoint", "description": [], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false }, { @@ -484,7 +484,7 @@ "signature": [ "object" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false }, { @@ -497,7 +497,7 @@ "signature": [ "(prevState: string, action: StringReducerPayload) => string" ], - "path": "packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts", + "path": "x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts", "deprecated": false, "returnComment": [], "children": [ diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index c44c318c2ff69..fc9532b06aab5 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -4,15 +4,15 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/aiops-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; +Static utilities for AIOps related efforts. - -Contact [Owner missing] for questions regarding this plugin. +Contact Machine Learning UI for questions regarding this plugin. **Code health stats** diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index 8226fde3fee3a..91f17fb672386 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/alerts plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index f44200ef97bfe..1c2e7cf69d807 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/analytics plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 84315fff01c2c..c4d419632a120 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/analytics-client plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index 47602a63dcc83..3f9d6e477d386 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index e061874d47be4..866713e059337 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index 4fe9239d5d670..062b3407f552d 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index 72814b9f92bea..b93c95d01bcd0 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index e0ebf664398e4..bee9d41b3d9c3 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/apm-config-loader plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index fe2c5f5459cfb..0045f71afa67d 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/apm-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index c155bf54291d8..5d58a62efe8e0 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/axe-config plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_bazel_packages.mdx b/api_docs/kbn_bazel_packages.mdx index 4fbac5adf9133..ce44e3c0105ad 100644 --- a/api_docs/kbn_bazel_packages.mdx +++ b/api_docs/kbn_bazel_packages.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-bazel-packages title: "@kbn/bazel-packages" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/bazel-packages plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bazel-packages'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_bazel_runner.mdx b/api_docs/kbn_bazel_runner.mdx index 82ceb55e52a60..dda3381f00416 100644 --- a/api_docs/kbn_bazel_runner.mdx +++ b/api_docs/kbn_bazel_runner.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-bazel-runner title: "@kbn/bazel-runner" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/bazel-runner plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/bazel-runner'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 319f32b8fcb66..18373114020c9 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/ci-stats-core plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 7c492a4f3179f..c846f4f6efa72 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 8bfd1bacb1ebc..802264647c0d9 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/ci-stats-reporter plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index d14d05cb69613..17684b8729ece 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/cli-dev-mode plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 1c1853a813f82..3687e042206ef 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/coloring plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index de9304b37fa96..d2c5361fe6720 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/config plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 43479e7f25abb..61a40a044103e 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/config-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index dd452f8e7f0ba..8450e365985ee 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/config-schema plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 34ca1ad7c523a..3cd80a6cb13a3 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-analytics-browser plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index 415c5c8dbef4e..bc3b0fe3dd0b5 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index 06a3419da43d1..a27c3dcd38ee7 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index 453ba67379d04..85343c66a30d0 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-analytics-server plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index b033e3316a624..37bb129638d96 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-analytics-server-internal plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index 8df7dd430ee41..83b67e46421fb 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 1d672c961f10d..84b6e52f627ee 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-base-browser-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index e5e75b54734ce..7ea915d285f33 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-base-common plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index 86cb682ec482e..9caf77a11741b 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-base-server-internal plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index 5a9657f828551..3c77569588ff0 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-base-server-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index b6cbf0d678888..cc57cabba73da 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-config-server-internal plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 619374b571b77..e6c32f3f15bd6 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-doc-links-browser plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index 4dd6b03d0161c..46c2be0835f92 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index b5343541902fb..2847c0bd94a8e 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-doc-links-server plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index d9d3756d07cbd..79620da24f162 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_fatal_errors_browser.devdocs.json b/api_docs/kbn_core_fatal_errors_browser.devdocs.json new file mode 100644 index 0000000000000..ec4c9747e5a9b --- /dev/null +++ b/api_docs/kbn_core_fatal_errors_browser.devdocs.json @@ -0,0 +1,181 @@ +{ + "id": "@kbn/core-fatal-errors-browser", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [ + { + "parentPluginId": "@kbn/core-fatal-errors-browser", + "id": "def-common.FatalErrorInfo", + "type": "Interface", + "tags": [], + "label": "FatalErrorInfo", + "description": [ + "\nRepresents the `message` and `stack` of a fatal Error\n" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser/src/get_error_info.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-fatal-errors-browser", + "id": "def-common.FatalErrorInfo.message", + "type": "string", + "tags": [], + "label": "message", + "description": [], + "path": "packages/core/fatal-errors/core-fatal-errors-browser/src/get_error_info.ts", + "deprecated": false + }, + { + "parentPluginId": "@kbn/core-fatal-errors-browser", + "id": "def-common.FatalErrorInfo.stack", + "type": "string", + "tags": [], + "label": "stack", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser/src/get_error_info.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/core-fatal-errors-browser", + "id": "def-common.FatalErrorsSetup", + "type": "Interface", + "tags": [], + "label": "FatalErrorsSetup", + "description": [ + "\nFatalErrors stop the Kibana Public Core and displays a fatal error screen\nwith details about the Kibana build and the error.\n" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser/src/contract.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-fatal-errors-browser", + "id": "def-common.FatalErrorsSetup.add", + "type": "Function", + "tags": [], + "label": "add", + "description": [ + "\nAdd a new fatal error. This will stop the Kibana Public Core and display\na fatal error screen with details about the Kibana build and the error.\n" + ], + "signature": [ + "(error: string | Error, source?: string | undefined) => never" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser/src/contract.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-fatal-errors-browser", + "id": "def-common.FatalErrorsSetup.add.$1", + "type": "CompoundType", + "tags": [], + "label": "error", + "description": [ + "- The error to display" + ], + "signature": [ + "string | Error" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser/src/contract.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/core-fatal-errors-browser", + "id": "def-common.FatalErrorsSetup.add.$2", + "type": "string", + "tags": [], + "label": "source", + "description": [ + "- Adds a prefix of the form `${source}: ` to the error message" + ], + "signature": [ + "string | undefined" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser/src/contract.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [] + }, + { + "parentPluginId": "@kbn/core-fatal-errors-browser", + "id": "def-common.FatalErrorsSetup.get$", + "type": "Function", + "tags": [], + "label": "get$", + "description": [ + "\nAn Observable that will emit whenever a fatal error is added with `add()`" + ], + "signature": [ + "() => ", + "Observable", + "<", + { + "pluginId": "@kbn/core-fatal-errors-browser", + "scope": "common", + "docId": "kibKbnCoreFatalErrorsBrowserPluginApi", + "section": "def-common.FatalErrorInfo", + "text": "FatalErrorInfo" + }, + ">" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser/src/contract.ts", + "deprecated": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + } + ], + "enums": [], + "misc": [ + { + "parentPluginId": "@kbn/core-fatal-errors-browser", + "id": "def-common.FatalErrorsStart", + "type": "Type", + "tags": [], + "label": "FatalErrorsStart", + "description": [ + "\nFatalErrors stop the Kibana Public Core and displays a fatal error screen\nwith details about the Kibana build and the error.\n" + ], + "signature": [ + { + "pluginId": "@kbn/core-fatal-errors-browser", + "scope": "common", + "docId": "kibKbnCoreFatalErrorsBrowserPluginApi", + "section": "def-common.FatalErrorsSetup", + "text": "FatalErrorsSetup" + } + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser/src/contract.ts", + "deprecated": false, + "initialIsOpen": false + } + ], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx new file mode 100644 index 0000000000000..541cc788f2770 --- /dev/null +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -0,0 +1,30 @@ +--- +id: kibKbnCoreFatalErrorsBrowserPluginApi +slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser +title: "@kbn/core-fatal-errors-browser" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/core-fatal-errors-browser plugin +date: 2022-06-27 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 9 | 0 | 2 | 0 | + +## Common + +### Interfaces + + +### Consts, variables and types + + diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.devdocs.json b/api_docs/kbn_core_fatal_errors_browser_mocks.devdocs.json new file mode 100644 index 0000000000000..e9eb42d013efe --- /dev/null +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.devdocs.json @@ -0,0 +1,90 @@ +{ + "id": "@kbn/core-fatal-errors-browser-mocks", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [ + { + "parentPluginId": "@kbn/core-fatal-errors-browser-mocks", + "id": "def-common.fatalErrorsServiceMock", + "type": "Object", + "tags": [], + "label": "fatalErrorsServiceMock", + "description": [], + "path": "packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/fatal_errors_service.mock.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-fatal-errors-browser-mocks", + "id": "def-common.fatalErrorsServiceMock.create", + "type": "Function", + "tags": [], + "label": "create", + "description": [], + "signature": [ + "() => jest.Mocked" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/fatal_errors_service.mock.ts", + "deprecated": false, + "returnComment": [], + "children": [] + }, + { + "parentPluginId": "@kbn/core-fatal-errors-browser-mocks", + "id": "def-common.fatalErrorsServiceMock.createSetupContract", + "type": "Function", + "tags": [], + "label": "createSetupContract", + "description": [], + "signature": [ + "() => jest.Mocked<", + "FatalErrorsSetup", + ">" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/fatal_errors_service.mock.ts", + "deprecated": false, + "returnComment": [], + "children": [] + }, + { + "parentPluginId": "@kbn/core-fatal-errors-browser-mocks", + "id": "def-common.fatalErrorsServiceMock.createStartContract", + "type": "Function", + "tags": [], + "label": "createStartContract", + "description": [], + "signature": [ + "() => jest.Mocked<", + "FatalErrorsSetup", + ">" + ], + "path": "packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/fatal_errors_service.mock.ts", + "deprecated": false, + "returnComment": [], + "children": [] + } + ], + "initialIsOpen": false + } + ] + } +} \ No newline at end of file diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx new file mode 100644 index 0000000000000..2be6c8bcacda9 --- /dev/null +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnCoreFatalErrorsBrowserMocksPluginApi +slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks +title: "@kbn/core-fatal-errors-browser-mocks" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/core-fatal-errors-browser-mocks plugin +date: 2022-06-27 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 4 | 0 | 4 | 0 | + +## Common + +### Objects + + diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index fe2b0abb4b4cc..b4a846ace1afc 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-i18n-browser plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 715b38c4aef94..ffa46cb59fe8e 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_injected_metadata_browser.mdx b/api_docs/kbn_core_injected_metadata_browser.mdx index 0dfa95e8653ac..e2fd23331f55a 100644 --- a/api_docs/kbn_core_injected_metadata_browser.mdx +++ b/api_docs/kbn_core_injected_metadata_browser.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser title: "@kbn/core-injected-metadata-browser" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-injected-metadata-browser plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index 18dd111b5bdea..4c704edb74aa6 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index b7d51a892cad4..ccb2352a40e3e 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-logging-server plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 24787602fd826..490911333f468 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-logging-server-internal plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index 596ae2e2d0c87..5a5d0abb679f9 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-logging-server-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index 73ec2992c6056..4e87168791253 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-theme-browser plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_core_theme_browser_internal.devdocs.json b/api_docs/kbn_core_theme_browser_internal.devdocs.json new file mode 100644 index 0000000000000..d1fdbd153181b --- /dev/null +++ b/api_docs/kbn_core_theme_browser_internal.devdocs.json @@ -0,0 +1,61 @@ +{ + "id": "@kbn/core-theme-browser-internal", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/core-theme-browser-internal", + "id": "def-common.CoreContextProvider", + "type": "Function", + "tags": [], + "label": "CoreContextProvider", + "description": [ + "\nutility component exposing all the context providers required by core when integrating with react" + ], + "signature": [ + "({ i18n, theme, children, globalStyles, }: React.PropsWithChildren) => JSX.Element" + ], + "path": "packages/core/theme/core-theme-browser-internal/src/core_context_provider.tsx", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/core-theme-browser-internal", + "id": "def-common.CoreContextProvider.$1", + "type": "CompoundType", + "tags": [], + "label": "{\n i18n,\n theme,\n children,\n globalStyles = false,\n}", + "description": [], + "signature": [ + "React.PropsWithChildren" + ], + "path": "packages/core/theme/core-theme-browser-internal/src/core_context_provider.tsx", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_core_theme_browser_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx new file mode 100644 index 0000000000000..168181a9100a9 --- /dev/null +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnCoreThemeBrowserInternalPluginApi +slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal +title: "@kbn/core-theme-browser-internal" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/core-theme-browser-internal plugin +date: 2022-06-27 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; + + + +Contact [Owner missing] for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 2 | 0 | 1 | 0 | + +## Common + +### Functions + + diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index fa6b098cf25ac..faf5b1a082f6a 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index 05421434cb5b9..1989726a50c9c 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/crypto plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 3507ad5af0a3f..1d10ed46f39ac 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/datemath plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index c7fc9e821a93f..3e7a25098f689 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/dev-cli-errors plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index ccf27f5dc4907..57e623346d032 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/dev-cli-runner plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index 613bddfbc0e6a..d15a5d3e0c6b6 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/dev-proc-runner plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 80ede3a8f2ce5..ed7e81dd647da 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/dev-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index 6c5cd99cc6bce..c50316d8d36b3 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -295,7 +295,7 @@ "label": "workplaceSearch", "description": [], "signature": [ - "{ readonly apiKeys: string; readonly box: string; readonly confluenceCloud: string; readonly confluenceCloudConnectorPackage: string; readonly confluenceServer: string; readonly customConnectorPackage: string; readonly customSources: string; readonly customSourcePermissions: string; readonly documentPermissions: string; readonly dropbox: string; readonly externalSharePointOnline: string; readonly externalIdentities: string; readonly gitHub: string; readonly gettingStarted: string; readonly gmail: string; readonly googleDrive: string; readonly indexingSchedule: string; readonly jiraCloud: string; readonly jiraServer: string; readonly networkDrive: string; readonly oneDrive: string; readonly outlook: string; readonly permissions: string; readonly salesforce: string; readonly security: string; readonly serviceNow: string; readonly sharePoint: string; readonly sharePointServer: string; readonly slack: string; readonly synch: string; readonly teams: string; readonly zendesk: string; readonly zoom: string; }" + "{ readonly apiKeys: string; readonly box: string; readonly confluenceCloud: string; readonly confluenceCloudConnectorPackage: string; readonly confluenceServer: string; readonly customConnectorPackage: string; readonly customSources: string; readonly customSourcePermissions: string; readonly documentPermissions: string; readonly dropbox: string; readonly externalSharePointOnline: string; readonly externalIdentities: string; readonly gitHub: string; readonly gettingStarted: string; readonly gmail: string; readonly googleDrive: string; readonly indexingSchedule: string; readonly jiraCloud: string; readonly jiraServer: string; readonly networkDrive: string; readonly oneDrive: string; readonly permissions: string; readonly salesforce: string; readonly security: string; readonly serviceNow: string; readonly sharePoint: string; readonly sharePointServer: string; readonly slack: string; readonly synch: string; readonly zendesk: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index f35f2a788324c..8f5392d68d4e7 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/doc-links plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 5425bf061fc86..f29ad1d6e6f61 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/docs-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index fea0955a22e95..367f730f5708d 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/es-archiver plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index a6869f197252d..7d9aefdb1aac6 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/es-query plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 9bdfd637706b9..494bc80a0443c 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/eslint-plugin-imports plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index fd68af1589767..f4cf3a0e9e8f0 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/field-types plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 9c2f9020578e2..be4ba1ee3999f 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/find-used-node-modules plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 4c8ed429da1c2..b49f92a1ac107 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/generate plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 321c9000cd1d7..356405bc0119c 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/handlebars plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 55782575d4a2d..84727cbd663d1 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/i18n plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index cfc5f243f43d7..03dc140ef7137 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/import-resolver plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 4e73e2c5ace40..2743208e2c48f 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/interpreter plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index ef11b76adc992..f158d859f1119 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/io-ts-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 1380af516f2d0..beaa8fa382dc6 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/jest-serializers plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_kibana_json_schema.mdx b/api_docs/kbn_kibana_json_schema.mdx index a3d937b8ee946..3f266aff01da3 100644 --- a/api_docs/kbn_kibana_json_schema.mdx +++ b/api_docs/kbn_kibana_json_schema.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-json-schema title: "@kbn/kibana-json-schema" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/kibana-json-schema plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-json-schema'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 54487887fbc56..ee10e0bb9cfdb 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/logging plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index b4188f4410c64..fcc335c40ba26 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/logging-mocks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index d031ab2e997bd..5ff9bc2e3e423 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/mapbox-gl plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_ml_agg_utils.devdocs.json b/api_docs/kbn_ml_agg_utils.devdocs.json new file mode 100644 index 0000000000000..db456a2c0fec0 --- /dev/null +++ b/api_docs/kbn_ml_agg_utils.devdocs.json @@ -0,0 +1,216 @@ +{ + "id": "@kbn/ml-agg-utils", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.buildSamplerAggregation", + "type": "Function", + "tags": [], + "label": "buildSamplerAggregation", + "description": [ + "\nWraps the supplied aggregations in a sampler aggregation.\nA supplied samplerShardSize (the shard_size parameter of the sampler aggregation)\nof less than 1 indicates no sampling, and the aggs are returned as-is." + ], + "signature": [ + "(aggs: any, samplerShardSize: number) => Record" + ], + "path": "x-pack/packages/ml/agg_utils/src/build_sampler_aggregation.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.buildSamplerAggregation.$1", + "type": "Any", + "tags": [], + "label": "aggs", + "description": [], + "signature": [ + "any" + ], + "path": "x-pack/packages/ml/agg_utils/src/build_sampler_aggregation.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.buildSamplerAggregation.$2", + "type": "number", + "tags": [], + "label": "samplerShardSize", + "description": [], + "signature": [ + "number" + ], + "path": "x-pack/packages/ml/agg_utils/src/build_sampler_aggregation.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.getAggIntervals", + "type": "Function", + "tags": [], + "label": "getAggIntervals", + "description": [ + "\nReturns aggregation intervals for the supplied document fields." + ], + "signature": [ + "(client: ElasticsearchClient, indexPattern: string, query: ", + "QueryDslQueryContainer", + ", fields: HistogramField[], samplerShardSize: number, runtimeMappings?: ", + "MappingRuntimeFields", + " | undefined) => Promise" + ], + "path": "x-pack/packages/ml/agg_utils/src/get_agg_intervals.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.getAggIntervals.$1", + "type": "Object", + "tags": [], + "label": "client", + "description": [], + "signature": [ + "ElasticsearchClient" + ], + "path": "x-pack/packages/ml/agg_utils/src/get_agg_intervals.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.getAggIntervals.$2", + "type": "string", + "tags": [], + "label": "indexPattern", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/packages/ml/agg_utils/src/get_agg_intervals.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.getAggIntervals.$3", + "type": "Object", + "tags": [], + "label": "query", + "description": [], + "signature": [ + "QueryDslQueryContainer" + ], + "path": "x-pack/packages/ml/agg_utils/src/get_agg_intervals.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.getAggIntervals.$4", + "type": "Array", + "tags": [], + "label": "fields", + "description": [], + "signature": [ + "HistogramField[]" + ], + "path": "x-pack/packages/ml/agg_utils/src/get_agg_intervals.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.getAggIntervals.$5", + "type": "number", + "tags": [], + "label": "samplerShardSize", + "description": [], + "signature": [ + "number" + ], + "path": "x-pack/packages/ml/agg_utils/src/get_agg_intervals.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.getAggIntervals.$6", + "type": "Object", + "tags": [], + "label": "runtimeMappings", + "description": [], + "signature": [ + "MappingRuntimeFields", + " | undefined" + ], + "path": "x-pack/packages/ml/agg_utils/src/get_agg_intervals.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.getSamplerAggregationsResponsePath", + "type": "Function", + "tags": [], + "label": "getSamplerAggregationsResponsePath", + "description": [], + "signature": [ + "(samplerShardSize: number) => string[]" + ], + "path": "x-pack/packages/ml/agg_utils/src/get_sampler_aggregations_response_path.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ml-agg-utils", + "id": "def-server.getSamplerAggregationsResponsePath.$1", + "type": "number", + "tags": [], + "label": "samplerShardSize", + "description": [], + "signature": [ + "number" + ], + "path": "x-pack/packages/ml/agg_utils/src/get_sampler_aggregations_response_path.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx new file mode 100644 index 0000000000000..c3618f4d119d6 --- /dev/null +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnMlAggUtilsPluginApi +slug: /kibana-dev-docs/api/kbn-ml-agg-utils +title: "@kbn/ml-agg-utils" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/ml-agg-utils plugin +date: 2022-06-27 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; + +This package includes utility functions related to creating elasticsearch aggregation queries, data manipulation and verification. + +Contact Machine Learning UI for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 12 | 1 | 10 | 0 | + +## Server + +### Functions + + diff --git a/api_docs/kbn_ml_is_populated_object.devdocs.json b/api_docs/kbn_ml_is_populated_object.devdocs.json new file mode 100644 index 0000000000000..c9570aa14dbf0 --- /dev/null +++ b/api_docs/kbn_ml_is_populated_object.devdocs.json @@ -0,0 +1,75 @@ +{ + "id": "@kbn/ml-is-populated-object", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/ml-is-populated-object", + "id": "def-server.isPopulatedObject", + "type": "Function", + "tags": [], + "label": "isPopulatedObject", + "description": [ + "\nA type guard to check record like object structures.\n\nExamples:\n- `isPopulatedObject({...})`\n Limits type to Record\n\n- `isPopulatedObject({...}, ['attribute'])`\n Limits type to Record<'attribute', unknown>\n\n- `isPopulatedObject({...})`\n Limits type to a record with keys of the given interface.\n Note that you might want to add keys from the interface to the\n array of requiredAttributes to satisfy runtime requirements.\n Otherwise you'd just satisfy TS requirements but might still\n run into runtime issues." + ], + "signature": [ + "(arg: unknown, requiredAttributes?: U[]) => arg is Record" + ], + "path": "x-pack/packages/ml/is_populated_object/src/is_populated_object.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ml-is-populated-object", + "id": "def-server.isPopulatedObject.$1", + "type": "Unknown", + "tags": [], + "label": "arg", + "description": [], + "signature": [ + "unknown" + ], + "path": "x-pack/packages/ml/is_populated_object/src/is_populated_object.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@kbn/ml-is-populated-object", + "id": "def-server.isPopulatedObject.$2", + "type": "Array", + "tags": [], + "label": "requiredAttributes", + "description": [], + "signature": [ + "U[]" + ], + "path": "x-pack/packages/ml/is_populated_object/src/is_populated_object.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx new file mode 100644 index 0000000000000..fcbaae2ed4081 --- /dev/null +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnMlIsPopulatedObjectPluginApi +slug: /kibana-dev-docs/api/kbn-ml-is-populated-object +title: "@kbn/ml-is-populated-object" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/ml-is-populated-object plugin +date: 2022-06-27 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; + +A type guard to check record like object structures. + +Contact Machine Learning UI for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 3 | 0 | 2 | 0 | + +## Server + +### Functions + + diff --git a/api_docs/kbn_ml_string_hash.devdocs.json b/api_docs/kbn_ml_string_hash.devdocs.json new file mode 100644 index 0000000000000..a6a3ccb30be3c --- /dev/null +++ b/api_docs/kbn_ml_string_hash.devdocs.json @@ -0,0 +1,61 @@ +{ + "id": "@kbn/ml-string-hash", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@kbn/ml-string-hash", + "id": "def-server.stringHash", + "type": "Function", + "tags": [], + "label": "stringHash", + "description": [ + "\nCreates a deterministic number based hash out of a string." + ], + "signature": [ + "(str: string) => number" + ], + "path": "x-pack/packages/ml/string_hash/src/string_hash.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@kbn/ml-string-hash", + "id": "def-server.stringHash.$1", + "type": "string", + "tags": [], + "label": "str", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/packages/ml/string_hash/src/string_hash.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx new file mode 100644 index 0000000000000..55500c3c8578f --- /dev/null +++ b/api_docs/kbn_ml_string_hash.mdx @@ -0,0 +1,27 @@ +--- +id: kibKbnMlStringHashPluginApi +slug: /kibana-dev-docs/api/kbn-ml-string-hash +title: "@kbn/ml-string-hash" +image: https://source.unsplash.com/400x175/?github +summary: API docs for the @kbn/ml-string-hash plugin +date: 2022-06-27 +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] +warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. +--- +import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; + +Creates a deterministic number based hash out of a string. + +Contact Machine Learning UI for questions regarding this plugin. + +**Code health stats** + +| Public API count | Any count | Items lacking comments | Missing exports | +|-------------------|-----------|------------------------|-----------------| +| 2 | 0 | 1 | 0 | + +## Server + +### Functions + + diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 339350026a676..f7a259ac8d8ea 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/monaco plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index d6c3951da8a48..525e1feaf33e4 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/optimizer plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index 73e3151761d74..8d8655c0fe0ca 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 5be0ada3b19e4..76a71a3169aa0 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_plugin_discovery.mdx b/api_docs/kbn_plugin_discovery.mdx index 90e958b824606..742d3328ac79a 100644 --- a/api_docs/kbn_plugin_discovery.mdx +++ b/api_docs/kbn_plugin_discovery.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-discovery title: "@kbn/plugin-discovery" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/plugin-discovery plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-discovery'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index 619141948aebe..ea399427c5d92 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/plugin-generator plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 9030770483370..aaa3d276213fe 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/plugin-helpers plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_pm.mdx b/api_docs/kbn_pm.mdx index 8ed75da929b79..2987862476c4a 100644 --- a/api_docs/kbn_pm.mdx +++ b/api_docs/kbn_pm.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-pm title: "@kbn/pm" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/pm plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/pm'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 429c623648380..4cdcc79c62ba0 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/react-field plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index 9c72ccef64e2f..c1590114aac0b 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/rule-data-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_scalability_simulation_generator.mdx b/api_docs/kbn_scalability_simulation_generator.mdx index 0c9777f519007..0684c93dc0bc6 100644 --- a/api_docs/kbn_scalability_simulation_generator.mdx +++ b/api_docs/kbn_scalability_simulation_generator.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-scalability-simulation-generator title: "@kbn/scalability-simulation-generator" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/scalability-simulation-generator plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/scalability-simulation-generator'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index 6a6308e1ffae9..9b6a9efd3c198 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 2ee30c0656dcf..4ae157a2fce53 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-es-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index dcc8bf31d9049..5cfbdaad79b97 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 117a1eb2c5159..6b6089bd22fc9 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index 9c5752b203eb0..7602dd35441ea 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index 48fd0ca8ed815..599ae1772e23e 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 571a2f9303ccb..0d8ca9bf39b6e 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index a0bcd043d61d4..88cc10e11cf4c 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-list-api plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index 993f080fcc193..33dbf405a2d2a 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-list-constants plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 85234c585d286..e1dadb808ea21 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index c8d5be6aad2c5..483575a3806e1 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-list-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 96b51f9113c2e..9a9e044448eb9 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-rules plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index 789760a4208e4..273d1e64b5367 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-t-grid plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index f07604490c02d..6db7b9fdb1180 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/securitysolution-utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 3b15b68770eda..e5e873ba1a794 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/server-http-tools plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index af36112b1cda2..264590805bd47 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/server-route-repository plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index f6f742628e522..d7e1d7a561add 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index baa5703955597..6d6b787512970 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_components.mdx b/api_docs/kbn_shared_ux_components.mdx index c856e7de45b63..ea9fd98494df7 100644 --- a/api_docs/kbn_shared_ux_components.mdx +++ b/api_docs/kbn_shared_ux_components.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-components title: "@kbn/shared-ux-components" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-components plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-components'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 4723ab64fc68e..ba996ae0be744 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 214a878423a93..33401f5ff90c9 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index b7fb30739d2b8..a4eb89d90adf2 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_services.mdx b/api_docs/kbn_shared_ux_services.mdx index 5f60e287b33d3..b246d401c20ed 100644 --- a/api_docs/kbn_shared_ux_services.mdx +++ b/api_docs/kbn_shared_ux_services.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-services title: "@kbn/shared-ux-services" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-services plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-services'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_storybook.mdx b/api_docs/kbn_shared_ux_storybook.mdx index eb278f6594d12..a3f5a457ca9ce 100644 --- a/api_docs/kbn_shared_ux_storybook.mdx +++ b/api_docs/kbn_shared_ux_storybook.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook title: "@kbn/shared-ux-storybook" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-storybook plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index 3cee3986320d0..d2b23836834ff 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/shared-ux-utility plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx index 42b1a1ec4b1b1..5d44f4590064a 100644 --- a/api_docs/kbn_sort_package_json.mdx +++ b/api_docs/kbn_sort_package_json.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-sort-package-json title: "@kbn/sort-package-json" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/sort-package-json plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 7807dfb8faf19..923c7058a1394 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/std plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index dcdbeeba9fa5c..965da9ecd3968 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/stdio-dev-helpers plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index 72da8a866e68b..4087601531128 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/storybook plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index 6af8cd22263d4..dd22d0adb9877 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/telemetry-tools plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 5b96789883cea..29949e35dd984 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/test plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 8b3b115917f5f..83c9a4cdc1e12 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/test-jest-helpers plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index d5d72ee68eb46..7ea1e8e73a18a 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/tooling-log plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx index d9a99bc918996..7977a69229a05 100644 --- a/api_docs/kbn_type_summarizer.mdx +++ b/api_docs/kbn_type_summarizer.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer title: "@kbn/type-summarizer" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/type-summarizer plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 0d47f81985c33..a108bce8fe04c 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/typed-react-router-config plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index afad507cc268f..9dce26e330cf9 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/ui-theme plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index bd4ac2c281582..b2ae29bef746c 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/utility-types plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index ef3e2bead5c0e..ccf4087f3f1cf 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/utility-types-jest plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index 09a812a5932a1..cbb356d6b8501 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github summary: API docs for the @kbn/utils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 6b55b014d810e..8727096e696cf 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github summary: API docs for the kibanaOverview plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kibana_react.devdocs.json b/api_docs/kibana_react.devdocs.json index 30705843ab0f9..e7d64f10fa0c3 100644 --- a/api_docs/kibana_react.devdocs.json +++ b/api_docs/kibana_react.devdocs.json @@ -4413,13 +4413,7 @@ "text": "IUiSettingsClient" }, " | undefined; fatalErrors?: ", - { - "pluginId": "core", - "scope": "public", - "docId": "kibCorePluginApi", - "section": "def-public.FatalErrorsSetup", - "text": "FatalErrorsSetup" - }, + "FatalErrorsSetup", " | undefined; deprecations?: ", { "pluginId": "core", diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 9a57e86eb9534..6c792f601617c 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github summary: API docs for the kibanaReact plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index e7d76168b35b4..b15148e6960b7 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github summary: API docs for the kibanaUtils plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 3533959bd49bd..8db8f870dd499 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github summary: API docs for the kubernetesSecurity plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/lens.devdocs.json b/api_docs/lens.devdocs.json index 706e10de5bdf5..98529c430485a 100644 --- a/api_docs/lens.devdocs.json +++ b/api_docs/lens.devdocs.json @@ -602,16 +602,6 @@ "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, "children": [ - { - "parentPluginId": "lens", - "id": "def-public.AxesSettingsConfig.x", - "type": "boolean", - "tags": [], - "label": "x", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, { "parentPluginId": "lens", "id": "def-public.AxesSettingsConfig.yLeft", @@ -652,6 +642,9 @@ "tags": [], "label": "title", "description": [], + "signature": [ + "string | undefined" + ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, @@ -667,6 +660,157 @@ ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.id", + "type": "string", + "tags": [], + "label": "id", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.position", + "type": "CompoundType", + "tags": [], + "label": "position", + "description": [], + "signature": [ + "Position", + " | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.labelColor", + "type": "string", + "tags": [], + "label": "labelColor", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.showOverlappingLabels", + "type": "CompoundType", + "tags": [], + "label": "showOverlappingLabels", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.showDuplicates", + "type": "CompoundType", + "tags": [], + "label": "showDuplicates", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.labelsOrientation", + "type": "number", + "tags": [], + "label": "labelsOrientation", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.truncate", + "type": "number", + "tags": [], + "label": "truncate", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.showLabels", + "type": "CompoundType", + "tags": [], + "label": "showLabels", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.showTitle", + "type": "CompoundType", + "tags": [], + "label": "showTitle", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.showGridLines", + "type": "CompoundType", + "tags": [], + "label": "showGridLines", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.AxisConfig.extent", + "type": "CompoundType", + "tags": [], + "label": "extent", + "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.AxisExtentConfigResult", + "text": "AxisExtentConfigResult" + }, + " | undefined" + ], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false } ], "initialIsOpen": false @@ -820,7 +964,7 @@ "label": "seriesType", "description": [], "signature": [ - "\"area\" | \"line\" | \"bar\" | \"bar_stacked\" | \"area_stacked\" | \"bar_horizontal\" | \"bar_percentage_stacked\" | \"bar_horizontal_stacked\" | \"area_percentage_stacked\" | \"bar_horizontal_percentage_stacked\"" + "\"area\" | \"line\" | \"bar\"" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false @@ -989,6 +1133,36 @@ "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, + { + "parentPluginId": "lens", + "id": "def-public.DataLayerArgs.isPercentage", + "type": "boolean", + "tags": [], + "label": "isPercentage", + "description": [], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.DataLayerArgs.isStacked", + "type": "boolean", + "tags": [], + "label": "isStacked", + "description": [], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.DataLayerArgs.isHorizontal", + "type": "boolean", + "tags": [], + "label": "isHorizontal", + "description": [], + "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "deprecated": false + }, { "parentPluginId": "lens", "id": "def-public.DataLayerArgs.palette", @@ -1005,13 +1179,13 @@ }, { "parentPluginId": "lens", - "id": "def-public.DataLayerArgs.yConfig", + "id": "def-public.DataLayerArgs.decorations", "type": "Array", "tags": [], - "label": "yConfig", + "label": "decorations", "description": [], "signature": [ - "YConfigResult", + "DataDecorationConfigResult", "[] | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", @@ -1381,142 +1555,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-public.ExtendedYConfig", - "type": "Interface", - "tags": [], - "label": "ExtendedYConfig", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.ExtendedYConfig", - "text": "ExtendedYConfig" - }, - " extends ", - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.YConfig", - "text": "YConfig" - } - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-public.ExtendedYConfig.icon", - "type": "CompoundType", - "tags": [], - "label": "icon", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AvailableReferenceLineIcon", - "text": "AvailableReferenceLineIcon" - }, - " | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.ExtendedYConfig.lineWidth", - "type": "number", - "tags": [], - "label": "lineWidth", - "description": [], - "signature": [ - "number | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.ExtendedYConfig.lineStyle", - "type": "CompoundType", - "tags": [], - "label": "lineStyle", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.LineStyle", - "text": "LineStyle" - }, - " | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.ExtendedYConfig.fill", - "type": "CompoundType", - "tags": [], - "label": "fill", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.FillStyle", - "text": "FillStyle" - }, - " | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.ExtendedYConfig.iconPosition", - "type": "CompoundType", - "tags": [], - "label": "iconPosition", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.IconPosition", - "text": "IconPosition" - }, - " | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.ExtendedYConfig.textVisibility", - "type": "CompoundType", - "tags": [], - "label": "textVisibility", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-public.FieldBasedIndexPatternColumn", @@ -1673,7 +1711,7 @@ "\nMethod which Lens consumer can import and given a formula string,\nreturn a parsed result as list of columns to use as Embeddable attributes.\n" ], "signature": [ - "(id: string, column: { formula: string; label?: string | undefined; }, layer: ", + "(id: string, column: { formula: string; label?: string | undefined; format?: { id: string; params?: { decimals: number; } | undefined; } | undefined; }, layer: ", { "pluginId": "lens", "scope": "public", @@ -1750,6 +1788,19 @@ ], "path": "x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.ts", "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.FormulaPublicApi.insertOrReplaceFormulaColumn.$2.format", + "type": "Object", + "tags": [], + "label": "format", + "description": [], + "signature": [ + "{ id: string; params?: { decimals: number; } | undefined; } | undefined" + ], + "path": "x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.ts", + "deprecated": false } ] }, @@ -1954,49 +2005,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-public.LabelsOrientationConfig", - "type": "Interface", - "tags": [], - "label": "LabelsOrientationConfig", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "lens", - "id": "def-public.LabelsOrientationConfig.x", - "type": "number", - "tags": [], - "label": "x", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.LabelsOrientationConfig.yLeft", - "type": "number", - "tags": [], - "label": "yLeft", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.LabelsOrientationConfig.yRight", - "type": "number", - "tags": [], - "label": "yRight", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-public.LastValueIndexPatternColumn", @@ -3103,18 +3111,18 @@ }, { "parentPluginId": "lens", - "id": "def-public.ReferenceLineLayerArgs.yConfig", + "id": "def-public.ReferenceLineLayerArgs.decorations", "type": "Array", "tags": [], - "label": "yConfig", + "label": "decorations", "description": [], "signature": [ { "pluginId": "expressionXY", "scope": "common", "docId": "kibExpressionXYPluginApi", - "section": "def-common.ExtendedYConfigResult", - "text": "ExtendedYConfigResult" + "section": "def-common.ReferenceLineDecorationConfigResult", + "text": "ReferenceLineDecorationConfigResult" }, "[] | undefined" ], @@ -4497,6 +4505,127 @@ ], "returnComment": [] }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.onDrop", + "type": "Function", + "tags": [], + "label": "onDrop", + "description": [ + "\nAllow defining custom behavior for the visualization when the drop action occurs." + ], + "signature": [ + "((props: { prevState: T; target: ", + "DragDropOperation", + "; source: ", + "DragDropIdentifier", + "; frame: ", + "FramePublicAPI", + "; dropType: ", + "DropType", + "; group?: ", + "VisualizationDimensionGroupConfig", + " | undefined; }) => T) | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.onDrop.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.Visualization.onDrop.$1.prevState", + "type": "Uncategorized", + "tags": [], + "label": "prevState", + "description": [], + "signature": [ + "T" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.onDrop.$1.target", + "type": "Object", + "tags": [], + "label": "target", + "description": [], + "signature": [ + "DragDropOperation" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.onDrop.$1.source", + "type": "CompoundType", + "tags": [], + "label": "source", + "description": [], + "signature": [ + "Record & { id: string; humanData: ", + "HumanData", + "; }" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.onDrop.$1.frame", + "type": "Object", + "tags": [], + "label": "frame", + "description": [], + "signature": [ + "FramePublicAPI" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.onDrop.$1.dropType", + "type": "CompoundType", + "tags": [], + "label": "dropType", + "description": [], + "signature": [ + "\"reorder\" | \"field_add\" | \"field_replace\" | \"move_compatible\" | \"replace_compatible\" | \"move_incompatible\" | \"replace_incompatible\" | \"replace_duplicate_compatible\" | \"duplicate_compatible\" | \"swap_compatible\" | \"replace_duplicate_incompatible\" | \"duplicate_incompatible\" | \"swap_incompatible\" | \"field_combine\" | \"combine_compatible\" | \"combine_incompatible\"" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.Visualization.onDrop.$1.group", + "type": "CompoundType", + "tags": [], + "label": "group", + "description": [], + "signature": [ + "VisualizationDimensionGroupConfig", + " | undefined" + ], + "path": "x-pack/plugins/lens/public/types.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [] + }, { "parentPluginId": "lens", "id": "def-public.Visualization.updateLayersConfigurationFromContext", @@ -5291,122 +5420,6 @@ "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false, "children": [ - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.xTitle", - "type": "string", - "tags": [], - "label": "xTitle", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.yTitle", - "type": "string", - "tags": [], - "label": "yTitle", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.yRightTitle", - "type": "string", - "tags": [], - "label": "yRightTitle", - "description": [], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.xExtent", - "type": "CompoundType", - "tags": [], - "label": "xExtent", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxisExtentConfigResult", - "text": "AxisExtentConfigResult" - }, - " | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.yLeftExtent", - "type": "CompoundType", - "tags": [], - "label": "yLeftExtent", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxisExtentConfig", - "text": "AxisExtentConfig" - }, - " & { type: \"axisExtentConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.yRightExtent", - "type": "CompoundType", - "tags": [], - "label": "yRightExtent", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxisExtentConfig", - "text": "AxisExtentConfig" - }, - " & { type: \"axisExtentConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.yLeftScale", - "type": "CompoundType", - "tags": [], - "label": "yLeftScale", - "description": [], - "signature": [ - "\"time\" | \"log\" | \"linear\" | \"sqrt\"" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.yRightScale", - "type": "CompoundType", - "tags": [], - "label": "yRightScale", - "description": [], - "signature": [ - "\"time\" | \"log\" | \"linear\" | \"sqrt\"" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, { "parentPluginId": "lens", "id": "def-public.XYArgs.legend", @@ -5523,38 +5536,18 @@ }, { "parentPluginId": "lens", - "id": "def-public.XYArgs.axisTitlesVisibilitySettings", - "type": "CompoundType", - "tags": [], - "label": "axisTitlesVisibilitySettings", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxisTitlesVisibilityConfigResult", - "text": "AxisTitlesVisibilityConfigResult" - }, - " | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.tickLabelsVisibilitySettings", + "id": "def-public.XYArgs.curveType", "type": "CompoundType", "tags": [], - "label": "tickLabelsVisibilitySettings", + "label": "curveType", "description": [], "signature": [ { "pluginId": "expressionXY", "scope": "common", "docId": "kibExpressionXYPluginApi", - "section": "def-common.TickLabelsConfigResult", - "text": "TickLabelsConfigResult" + "section": "def-common.XYCurveType", + "text": "XYCurveType" }, " | undefined" ], @@ -5563,112 +5556,92 @@ }, { "parentPluginId": "lens", - "id": "def-public.XYArgs.gridlinesVisibilitySettings", - "type": "CompoundType", + "id": "def-public.XYArgs.fillOpacity", + "type": "number", "tags": [], - "label": "gridlinesVisibilitySettings", + "label": "fillOpacity", "description": [], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.GridlinesConfigResult", - "text": "GridlinesConfigResult" - }, - " | undefined" + "number | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "lens", - "id": "def-public.XYArgs.labelsOrientation", + "id": "def-public.XYArgs.hideEndzones", "type": "CompoundType", "tags": [], - "label": "labelsOrientation", + "label": "hideEndzones", "description": [], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.LabelsOrientationConfigResult", - "text": "LabelsOrientationConfigResult" - }, - " | undefined" + "boolean | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "lens", - "id": "def-public.XYArgs.curveType", + "id": "def-public.XYArgs.valuesInLegend", "type": "CompoundType", "tags": [], - "label": "curveType", + "label": "valuesInLegend", "description": [], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.XYCurveType", - "text": "XYCurveType" - }, - " | undefined" + "boolean | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "lens", - "id": "def-public.XYArgs.fillOpacity", - "type": "number", + "id": "def-public.XYArgs.ariaLabel", + "type": "string", "tags": [], - "label": "fillOpacity", + "label": "ariaLabel", "description": [], "signature": [ - "number | undefined" + "string | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "lens", - "id": "def-public.XYArgs.hideEndzones", - "type": "CompoundType", + "id": "def-public.XYArgs.yAxisConfigs", + "type": "Array", "tags": [], - "label": "hideEndzones", + "label": "yAxisConfigs", "description": [], "signature": [ - "boolean | undefined" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.YAxisConfigResult", + "text": "YAxisConfigResult" + }, + "[] | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false }, { "parentPluginId": "lens", - "id": "def-public.XYArgs.valuesInLegend", + "id": "def-public.XYArgs.xAxisConfig", "type": "CompoundType", "tags": [], - "label": "valuesInLegend", - "description": [], - "signature": [ - "boolean | undefined" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false - }, - { - "parentPluginId": "lens", - "id": "def-public.XYArgs.ariaLabel", - "type": "string", - "tags": [], - "label": "ariaLabel", + "label": "xAxisConfig", "description": [], "signature": [ - "string | undefined" + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.XAxisConfigResult", + "text": "XAxisConfigResult" + }, + " | undefined" ], "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", "deprecated": false @@ -5913,10 +5886,10 @@ "description": [], "signature": [ { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.YConfig", + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.YConfig", "text": "YConfig" }, "[] | undefined" @@ -6055,11 +6028,11 @@ "description": [], "signature": [ { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.ExtendedYConfig", - "text": "ExtendedYConfig" + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.YConfig", + "text": "YConfig" }, "[] | undefined" ], @@ -6423,10 +6396,10 @@ "description": [], "signature": [ { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.AxesSettingsConfig", "text": "AxesSettingsConfig" }, " | undefined" @@ -6443,10 +6416,10 @@ "description": [], "signature": [ { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.AxesSettingsConfig", "text": "AxesSettingsConfig" }, " | undefined" @@ -6463,10 +6436,10 @@ "description": [], "signature": [ { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.AxesSettingsConfig", "text": "AxesSettingsConfig" }, " | undefined" @@ -6482,13 +6455,7 @@ "label": "labelsOrientation", "description": [], "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.LabelsOrientationConfig", - "text": "LabelsOrientationConfig" - }, + "LabelsOrientationConfig", " | undefined" ], "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", @@ -6555,6 +6522,161 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "lens", + "id": "def-public.YConfig", + "type": "Interface", + "tags": [], + "label": "YConfig", + "description": [], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "lens", + "id": "def-public.YConfig.forAccessor", + "type": "string", + "tags": [], + "label": "forAccessor", + "description": [], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.YConfig.color", + "type": "string", + "tags": [], + "label": "color", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.YConfig.icon", + "type": "string", + "tags": [], + "label": "icon", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.YConfig.lineWidth", + "type": "number", + "tags": [], + "label": "lineWidth", + "description": [], + "signature": [ + "number | undefined" + ], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.YConfig.lineStyle", + "type": "CompoundType", + "tags": [], + "label": "lineStyle", + "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.LineStyle", + "text": "LineStyle" + }, + " | undefined" + ], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.YConfig.fill", + "type": "CompoundType", + "tags": [], + "label": "fill", + "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.FillStyle", + "text": "FillStyle" + }, + " | undefined" + ], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.YConfig.iconPosition", + "type": "CompoundType", + "tags": [], + "label": "iconPosition", + "description": [], + "signature": [ + { + "pluginId": "expressionXY", + "scope": "common", + "docId": "kibExpressionXYPluginApi", + "section": "def-common.IconPosition", + "text": "IconPosition" + }, + " | undefined" + ], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.YConfig.textVisibility", + "type": "CompoundType", + "tags": [], + "label": "textVisibility", + "description": [], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false + }, + { + "parentPluginId": "lens", + "id": "def-public.YConfig.axisMode", + "type": "CompoundType", + "tags": [], + "label": "axisMode", + "description": [], + "signature": [ + { + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.YAxisMode", + "text": "YAxisMode" + }, + " | undefined" + ], + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", + "deprecated": false + } + ], + "initialIsOpen": false } ], "enums": [], @@ -6617,27 +6739,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-public.AxisTitlesVisibilityConfigResult", - "type": "Type", - "tags": [], - "label": "AxisTitlesVisibilityConfigResult", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", - "text": "AxesSettingsConfig" - }, - " & { type: \"axisTitlesVisibilityConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-public.CounterRateIndexPatternColumn", @@ -6792,27 +6893,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-public.ExtendedYConfigResult", - "type": "Type", - "tags": [], - "label": "ExtendedYConfigResult", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.ExtendedYConfig", - "text": "ExtendedYConfig" - }, - " & { type: \"extendedYConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-public.FillStyle", @@ -6895,27 +6975,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-public.GridlinesConfigResult", - "type": "Type", - "tags": [], - "label": "GridlinesConfigResult", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", - "text": "AxesSettingsConfig" - }, - " & { type: \"gridlinesConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-public.HeatmapVisualizationState", @@ -6961,27 +7020,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-public.LabelsOrientationConfigResult", - "type": "Type", - "tags": [], - "label": "LabelsOrientationConfigResult", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.LabelsOrientationConfig", - "text": "LabelsOrientationConfig" - }, - " & { type: \"labelsOrientationConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-public.LayerType", @@ -7285,7 +7323,7 @@ "signature": [ "\"area\" | \"line\" | \"bar\" | \"bar_stacked\" | \"area_stacked\" | \"bar_horizontal\" | \"bar_percentage_stacked\" | \"bar_horizontal_stacked\" | \"area_percentage_stacked\" | \"bar_horizontal_percentage_stacked\"" ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", "deprecated": false, "initialIsOpen": false }, @@ -7312,27 +7350,6 @@ "deprecated": false, "initialIsOpen": false }, - { - "parentPluginId": "lens", - "id": "def-public.TickLabelsConfigResult", - "type": "Type", - "tags": [], - "label": "TickLabelsConfigResult", - "description": [], - "signature": [ - { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", - "text": "AxesSettingsConfig" - }, - " & { type: \"tickLabelsConfig\"; }" - ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", - "deprecated": false, - "initialIsOpen": false - }, { "parentPluginId": "lens", "id": "def-public.TimeScaleIndexPatternColumn", @@ -7540,7 +7557,7 @@ "signature": [ "\"bottom\" | \"left\" | \"right\" | \"auto\"" ], - "path": "src/plugins/chart_expressions/expression_xy/common/types/expression_functions.ts", + "path": "x-pack/plugins/lens/public/xy_visualization/types.ts", "deprecated": false, "initialIsOpen": false }, diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 94aad70595690..02aba0b35a524 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github summary: API docs for the lens plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 594 | 0 | 517 | 35 | +| 600 | 0 | 522 | 40 | ## Client diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index 67ab1d0b38048..ed9ea1f9db993 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github summary: API docs for the licenseApiGuard plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index b9ca3227c0186..4e85b1569175e 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the licenseManagement plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 7768b99acd2d8..00b17d52f626a 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github summary: API docs for the licensing plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 0ad5f14873cda..c6d9fd5a2b4f2 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github summary: API docs for the lists plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/management.mdx b/api_docs/management.mdx index f32d58cf2a204..98e322d0effb0 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github summary: API docs for the management plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index c0ba7a0faca21..a38f18c169e1b 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github summary: API docs for the maps plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 9e2359a5d964e..66ea77bc05d8c 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github summary: API docs for the mapsEms plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/ml.devdocs.json b/api_docs/ml.devdocs.json index 4eca0b6ef73f7..9ea813207c22a 100644 --- a/api_docs/ml.devdocs.json +++ b/api_docs/ml.devdocs.json @@ -3082,51 +3082,6 @@ "returnComment": [], "initialIsOpen": false }, - { - "parentPluginId": "ml", - "id": "def-common.isPopulatedObject", - "type": "Function", - "tags": [], - "label": "isPopulatedObject", - "description": [], - "signature": [ - "(arg: unknown, requiredAttributes?: U[]) => arg is Record" - ], - "path": "x-pack/plugins/ml/common/util/object_utils.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "ml", - "id": "def-common.isPopulatedObject.$1", - "type": "Unknown", - "tags": [], - "label": "arg", - "description": [], - "signature": [ - "unknown" - ], - "path": "x-pack/plugins/ml/common/util/object_utils.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "ml", - "id": "def-common.isPopulatedObject.$2", - "type": "Array", - "tags": [], - "label": "requiredAttributes", - "description": [], - "signature": [ - "U[]" - ], - "path": "x-pack/plugins/ml/common/util/object_utils.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, { "parentPluginId": "ml", "id": "def-common.isRuntimeField", diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index c1df1686a8069..bdc8d25348556 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github summary: API docs for the ml plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 254 | 10 | 81 | 31 | +| 251 | 10 | 78 | 31 | ## Client diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 13e932aff2c8c..3d77273fd6d4b 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github summary: API docs for the monitoring plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index 1cdd404bf76bf..0e4b1fa5685fb 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github summary: API docs for the monitoringCollection plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 165f0f335d986..9a372febc44c7 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github summary: API docs for the navigation plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index a39288cf3cd8d..66048ce2d955a 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github summary: API docs for the newsfeed plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index fe47345018d5f..23f64b0a56ac6 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -1978,10 +1978,10 @@ "description": [], "signature": [ { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.AxesSettingsConfig", + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.AxesSettingsConfig", "text": "AxesSettingsConfig" }, " | undefined" @@ -3617,10 +3617,10 @@ "description": [], "signature": [ { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.SeriesType", + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.SeriesType", "text": "SeriesType" }, "[]" @@ -3764,11 +3764,11 @@ "description": [], "signature": [ { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.ExtendedYConfig", - "text": "ExtendedYConfig" + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.YConfig", + "text": "YConfig" }, "[] | undefined" ], @@ -3860,10 +3860,10 @@ "description": [], "signature": [ { - "pluginId": "expressionXY", - "scope": "common", - "docId": "kibExpressionXYPluginApi", - "section": "def-common.SeriesType", + "pluginId": "lens", + "scope": "public", + "docId": "kibLensPluginApi", + "section": "def-public.SeriesType", "text": "SeriesType" }, " | undefined" @@ -4711,7 +4711,7 @@ "signature": [ "Pick<", "KibanaPageTemplateProps", - ", \"children\" | \"data-test-subj\" | \"paddingSize\" | \"restrictWidth\" | \"template\" | \"noDataConfig\" | \"pageHeader\" | \"pageBodyProps\" | \"pageContentProps\" | \"pageContentBodyProps\" | \"isEmptyState\"> & { showSolutionNav?: boolean | undefined; }" + ", \"children\" | \"data-test-subj\" | \"paddingSize\" | \"restrictWidth\" | \"template\" | \"noDataConfig\" | \"pageHeader\" | \"pageBodyProps\" | \"pageContentProps\" | \"pageContentBodyProps\" | \"isEmptyState\"> & { showSolutionNav?: boolean | undefined; isPageDataLoaded?: boolean | undefined; }" ], "path": "x-pack/plugins/observability/public/components/shared/page_template/lazy_page_template.tsx", "deprecated": false, diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index e2dcae516b104..a85fa532d1abb 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github summary: API docs for the observability plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index f86a267e95cec..65ba7b1fa3bed 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github summary: API docs for the osquery plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index c71faef8e65e0..16c7800c14088 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -3,7 +3,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory summary: Directory of public APIs available through plugins or packages. -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -12,13 +12,13 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Count | Plugins or Packages with a
public API | Number of teams | |--------------|----------|------------------------| -| 300 | 243 | 35 | +| 306 | 249 | 36 | ### Public API health stats | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 26416 | 171 | 19085 | 1248 | +| 26538 | 172 | 19191 | 1258 | ## Plugin Directory @@ -35,19 +35,19 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [ResponseOps](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 66 | 0 | 52 | 22 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 272 | 2 | 253 | 9 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 29 | 0 | 24 | 0 | -| | [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-posture-security) | The cloud security posture plugin | 14 | 0 | 14 | 0 | +| | [Cloud Security Posture](https://github.com/orgs/elastic/teams/cloud-posture-security) | The cloud security posture plugin | 6 | 0 | 6 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 13 | 0 | 13 | 1 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Controls Plugin contains embeddable components intended to create a simple query interface for end users, and a powerful editing suite that allows dashboard authors to build controls | 206 | 0 | 198 | 7 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2527 | 15 | 938 | 29 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2527 | 15 | 936 | 29 | | crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 101 | 0 | 82 | 1 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 143 | 0 | 141 | 12 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 52 | 0 | 51 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3072 | 34 | 2399 | 22 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3074 | 34 | 2403 | 22 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | This plugin provides the ability to create data views via a modal flyout from any kibana app | 15 | 0 | 7 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Reusable data view field editor across Kibana | 42 | 0 | 37 | 3 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data view management app | 2 | 0 | 2 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 924 | 1 | 186 | 1 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 928 | 1 | 192 | 1 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 28 | 3 | 24 | 1 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 10 | 0 | 8 | 2 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 78 | 0 | 62 | 7 | @@ -55,7 +55,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 488 | 0 | 398 | 3 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides encryption and decryption utilities for saved objects containing sensitive information. | 51 | 0 | 44 | 0 | -| | [Enterprise Search](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 2 | 0 | 2 | 0 | +| | [Enterprise Search](https://github.com/orgs/elastic/teams/enterprise-search-frontend) | Adds dashboards for discovering and managing Enterprise Search products. | 3 | 0 | 3 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 114 | 3 | 110 | 3 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | The Event Annotation service contains expressions for event annotations | 90 | 0 | 90 | 5 | | | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 100 | 0 | 100 | 9 | @@ -70,18 +70,18 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'revealImage' function and renderer to expressions | 14 | 0 | 14 | 3 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'shape' function and renderer to expressions | 148 | 0 | 146 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Tagcloud plugin adds a `tagcloud` renderer and function to the expression plugin. The renderer will display the `Wordcloud` chart. | 7 | 0 | 7 | 0 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 148 | 0 | 138 | 14 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression XY plugin adds a `xy` renderer and function to the expression plugin. The renderer will display the `xy` chart. | 150 | 0 | 140 | 14 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2180 | 17 | 1726 | 5 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 222 | 0 | 95 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 5 | 249 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | -| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1435 | 8 | 1308 | 10 | +| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1499 | 8 | 1368 | 10 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | globalSearchProviders | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | graph | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 0 | 0 | 0 | 0 | | grokdebugger | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 141 | 0 | 102 | 0 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 143 | 0 | 104 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 4 | 0 | 4 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 175 | 0 | 170 | 3 | | | [Logs and Metrics UI](https://github.com/orgs/elastic/teams/logs-metrics-ui) | This plugin visualizes data from Filebeat and Metricbeat, and integrates with other Observability solutions | 42 | 0 | 39 | 8 | @@ -94,7 +94,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | kibanaUsageCollection | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 0 | 0 | 0 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 615 | 3 | 420 | 9 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 594 | 0 | 517 | 35 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 600 | 0 | 522 | 40 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 8 | 0 | 8 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 3 | 0 | 3 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 10 | @@ -103,7 +103,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 41 | 0 | 41 | 6 | | | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 238 | 0 | 237 | 24 | | | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 67 | 0 | 67 | 0 | -| | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 254 | 10 | 81 | 31 | +| | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the machine learning features provided by Elastic. | 251 | 10 | 78 | 31 | | | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 11 | 0 | 9 | 1 | | | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 34 | 0 | 34 | 2 | @@ -115,7 +115,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 4 | 0 | 4 | 0 | | | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 36 | 0 | 16 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 21 | 0 | 21 | 0 | -| | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 202 | 0 | 174 | 10 | +| | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 205 | 0 | 177 | 10 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 24 | 0 | 19 | 2 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 192 | 2 | 151 | 5 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 125 | 0 | 112 | 0 | @@ -127,7 +127,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 197 | 0 | 100 | 0 | | | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 52 | 0 | 51 | 21 | | | [Security Team](https://github.com/orgs/elastic/teams/security-team) | - | 3 | 0 | 3 | 1 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds URL Service and sharing capabilities to Kibana | 113 | 0 | 54 | 10 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds URL Service and sharing capabilities to Kibana | 114 | 0 | 55 | 10 | | | [Shared UX](https://github.com/orgs/elastic/teams/shared-ux) | A plugin providing components and services for shared user experiences in Kibana. | 4 | 0 | 0 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 22 | 1 | 22 | 1 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides the Spaces feature, which allows saved objects to be organized into meaningful categories. | 260 | 0 | 64 | 0 | @@ -138,10 +138,10 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 32 | 0 | 32 | 6 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 1 | 0 | 1 | 0 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 11 | 0 | 10 | 0 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 436 | 1 | 332 | 35 | +| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 452 | 1 | 347 | 35 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [Kibana Localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | -| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 389 | 0 | 375 | 35 | +| | [Response Ops](https://github.com/orgs/elastic/teams/response-ops) | - | 389 | 0 | 375 | 36 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 130 | 0 | 91 | 11 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 205 | 0 | 142 | 9 | | | [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 82 | 2 | 78 | 13 | @@ -172,7 +172,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex |--------------|----------------|-----------|--------------|----------|---------------|--------| | | [Owner missing] | Elastic APM trace data generator | 74 | 0 | 74 | 11 | | | [Owner missing] | - | 11 | 5 | 11 | 0 | -| | [Owner missing] | - | 35 | 0 | 18 | 0 | +| | Machine Learning UI | Static utilities for AIOps related efforts. | 35 | 0 | 18 | 0 | | | [Owner missing] | Alerts components and hooks | 9 | 1 | 9 | 0 | | | Ahmad Bamieh ahmadbamieh@gmail.com | Kibana Analytics tool | 69 | 0 | 69 | 2 | | | [Owner missing] | - | 96 | 0 | 0 | 0 | @@ -208,6 +208,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Owner missing] | - | 4 | 0 | 4 | 0 | | | [Owner missing] | - | 5 | 0 | 2 | 0 | | | [Owner missing] | - | 4 | 0 | 4 | 0 | +| | [Owner missing] | - | 9 | 0 | 2 | 0 | +| | [Owner missing] | - | 4 | 0 | 4 | 0 | | | [Owner missing] | - | 4 | 0 | 2 | 0 | | | [Owner missing] | - | 3 | 0 | 3 | 0 | | | [Owner missing] | - | 8 | 2 | 6 | 0 | @@ -216,6 +218,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Owner missing] | - | 9 | 0 | 5 | 1 | | | [Owner missing] | - | 13 | 0 | 12 | 0 | | | [Owner missing] | - | 6 | 0 | 4 | 0 | +| | [Owner missing] | - | 2 | 0 | 1 | 0 | | | [Owner missing] | - | 6 | 0 | 6 | 0 | | | [Owner missing] | - | 13 | 0 | 7 | 0 | | | [Owner missing] | elasticsearch datemath parser, used in kibana | 44 | 0 | 43 | 0 | @@ -241,6 +244,9 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Owner missing] | - | 30 | 0 | 5 | 36 | | | [Owner missing] | - | 8 | 0 | 8 | 0 | | | [Owner missing] | - | 494 | 1 | 1 | 0 | +| | Machine Learning UI | This package includes utility functions related to creating elasticsearch aggregation queries, data manipulation and verification. | 12 | 1 | 10 | 0 | +| | Machine Learning UI | A type guard to check record like object structures. | 3 | 0 | 2 | 0 | +| | Machine Learning UI | Creates a deterministic number based hash out of a string. | 2 | 0 | 1 | 0 | | | [Owner missing] | - | 55 | 0 | 55 | 2 | | | [Owner missing] | - | 47 | 0 | 46 | 10 | | | [Owner missing] | - | 51 | 5 | 34 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 19052227c3c90..16ba6eee591cc 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github summary: API docs for the presentationUtil plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index 3729b362ce583..21f951af6ee98 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github summary: API docs for the remoteClusters plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 13556c6e80806..3ad6808668bd3 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github summary: API docs for the reporting plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index f4fda7540b8a0..1004f6021c64f 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github summary: API docs for the rollup plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/rule_registry.devdocs.json b/api_docs/rule_registry.devdocs.json index 7878a8f8c1ca4..b6f84a0d17d2c 100644 --- a/api_docs/rule_registry.devdocs.json +++ b/api_docs/rule_registry.devdocs.json @@ -566,14 +566,15 @@ "label": "getWriter", "description": [], "signature": [ - "(options?: { namespace?: string | undefined; }) => ", + "(options?: { namespace?: string | undefined; }) => Promise<", { "pluginId": "ruleRegistry", "scope": "server", "docId": "kibRuleRegistryPluginApi", "section": "def-server.IRuleDataWriter", "text": "IRuleDataWriter" - } + }, + ">" ], "path": "x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts", "deprecated": false, @@ -1047,16 +1048,53 @@ { "parentPluginId": "ruleRegistry", "id": "def-server.RuleDataWriteDisabledError.Unnamed.$1", - "type": "string", + "type": "Object", "tags": [], - "label": "message", + "label": "{\n reason,\n registrationContext,\n message,\n }", "description": [], - "signature": [ - "string | undefined" - ], "path": "x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts", "deprecated": false, - "isRequired": false + "children": [ + { + "parentPluginId": "ruleRegistry", + "id": "def-server.RuleDataWriteDisabledError.Unnamed.$1.reason", + "type": "CompoundType", + "tags": [], + "label": "reason", + "description": [], + "signature": [ + "\"error\" | \"config\"" + ], + "path": "x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts", + "deprecated": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-server.RuleDataWriteDisabledError.Unnamed.$1.registrationContext", + "type": "string", + "tags": [], + "label": "registrationContext", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts", + "deprecated": false + }, + { + "parentPluginId": "ruleRegistry", + "id": "def-server.RuleDataWriteDisabledError.Unnamed.$1.message", + "type": "string", + "tags": [], + "label": "message", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts", + "deprecated": false + } + ] } ], "returnComment": [] @@ -2022,14 +2060,15 @@ "label": "getWriter", "description": [], "signature": [ - "(options?: { namespace?: string | undefined; } | undefined) => ", + "(options?: { namespace?: string | undefined; } | undefined) => Promise<", { "pluginId": "ruleRegistry", "scope": "server", "docId": "kibRuleRegistryPluginApi", "section": "def-server.IRuleDataWriter", "text": "IRuleDataWriter" - } + }, + ">" ], "path": "x-pack/plugins/rule_registry/server/rule_data_client/types.ts", "deprecated": false, diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index 272a8758c5ab1..6a3c1e419350c 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github summary: API docs for the ruleRegistry plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [RAC](https://github.com/orgs/elastic/teams/rac) for questions regarding | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 202 | 0 | 174 | 10 | +| 205 | 0 | 177 | 10 | ## Server diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index fabadde1d3537..020f3e6279482 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github summary: API docs for the runtimeFields plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index d9fac2851b6d2..ca834e9a65404 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github summary: API docs for the savedObjects plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 79f1d2c7a2b4a..45be210e3cca0 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github summary: API docs for the savedObjectsManagement plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 38e12b4aed2cf..a910791008b6f 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github summary: API docs for the savedObjectsTagging plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index 400d7bca2e21b..7bbe3c8870415 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github summary: API docs for the savedObjectsTaggingOss plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index 97e6cd138ec62..f1730ccb6b519 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github summary: API docs for the screenshotMode plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index 2f4e0440757c1..2ae08e6a06f02 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github summary: API docs for the screenshotting plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/security.mdx b/api_docs/security.mdx index 99283269165de..cf771cf6b6e89 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github summary: API docs for the security plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index f9c4373d9fb2d..d4cc2a61126ea 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github summary: API docs for the securitySolution plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 47a076253b042..119c6533ee788 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github summary: API docs for the sessionView plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/share.devdocs.json b/api_docs/share.devdocs.json index 9733101e0dd11..3f00f53554941 100644 --- a/api_docs/share.devdocs.json +++ b/api_docs/share.devdocs.json @@ -1127,6 +1127,21 @@ ], "path": "src/plugins/share/public/types.ts", "deprecated": false + }, + { + "parentPluginId": "share", + "id": "def-public.ShowShareMenuOptions.onClose", + "type": "Function", + "tags": [], + "label": "onClose", + "description": [], + "signature": [ + "(() => void) | undefined" + ], + "path": "src/plugins/share/public/types.ts", + "deprecated": false, + "children": [], + "returnComment": [] } ], "initialIsOpen": false diff --git a/api_docs/share.mdx b/api_docs/share.mdx index cd8bb647f2b8d..b5d12e15731d9 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github summary: API docs for the share plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [App Services](https://github.com/orgs/elastic/teams/kibana-app-services | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 113 | 0 | 54 | 10 | +| 114 | 0 | 55 | 10 | ## Client diff --git a/api_docs/shared_u_x.mdx b/api_docs/shared_u_x.mdx index d73c5303e9b74..4da1e5d97264c 100644 --- a/api_docs/shared_u_x.mdx +++ b/api_docs/shared_u_x.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/sharedUX title: "sharedUX" image: https://source.unsplash.com/400x175/?github summary: API docs for the sharedUX plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sharedUX'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index 417c2500ed8cc..9627dc0b89182 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github summary: API docs for the snapshotRestore plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index af5231f6d3cd3..4044de7bbd1b5 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github summary: API docs for the spaces plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 4395c11d84e4c..40f7b543f11c0 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github summary: API docs for the stackAlerts plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index b734c5bfc99a0..d5fb47efcdcdf 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github summary: API docs for the taskManager plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index b2a40aa42d368..d39e4e7a0d3a6 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github summary: API docs for the telemetry plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index a277dd510cb85..04b1595765dc1 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github summary: API docs for the telemetryCollectionManager plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index fa058e7406b50..8d0178d48c94f 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github summary: API docs for the telemetryCollectionXpack plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index 3e673801c2faf..895ee913a704f 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github summary: API docs for the telemetryManagementSection plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/timelines.devdocs.json b/api_docs/timelines.devdocs.json index 664e1dc94366d..be4e80fe87c57 100644 --- a/api_docs/timelines.devdocs.json +++ b/api_docs/timelines.devdocs.json @@ -247,6 +247,200 @@ ], "initialIsOpen": false }, + { + "parentPluginId": "timelines", + "id": "def-public.convertKueryToDslFilter", + "type": "Function", + "tags": [], + "label": "convertKueryToDslFilter", + "description": [], + "signature": [ + "(kueryExpression: string, indexPattern: ", + "DataViewBase", + ") => ", + "QueryDslQueryContainer" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "timelines", + "id": "def-public.convertKueryToDslFilter.$1", + "type": "string", + "tags": [], + "label": "kueryExpression", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "timelines", + "id": "def-public.convertKueryToDslFilter.$2", + "type": "Object", + "tags": [], + "label": "indexPattern", + "description": [], + "signature": [ + "DataViewBase" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "timelines", + "id": "def-public.convertKueryToElasticSearchQuery", + "type": "Function", + "tags": [], + "label": "convertKueryToElasticSearchQuery", + "description": [], + "signature": [ + "(kueryExpression: string, indexPattern?: ", + "DataViewBase", + " | undefined) => string" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "timelines", + "id": "def-public.convertKueryToElasticSearchQuery.$1", + "type": "string", + "tags": [], + "label": "kueryExpression", + "description": [], + "signature": [ + "string" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "timelines", + "id": "def-public.convertKueryToElasticSearchQuery.$2", + "type": "Object", + "tags": [], + "label": "indexPattern", + "description": [], + "signature": [ + "DataViewBase", + " | undefined" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "isRequired": false + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "timelines", + "id": "def-public.convertToBuildEsQuery", + "type": "Function", + "tags": [], + "label": "convertToBuildEsQuery", + "description": [], + "signature": [ + "({ config, indexPattern, queries, filters, }: { config: ", + "EsQueryConfig", + "; indexPattern: ", + "DataViewBase", + "; queries: ", + "Query", + "[]; filters: ", + "Filter", + "[]; }) => [string, undefined] | [undefined, Error]" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "timelines", + "id": "def-public.convertToBuildEsQuery.$1", + "type": "Object", + "tags": [], + "label": "{\n config,\n indexPattern,\n queries,\n filters,\n}", + "description": [], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "timelines", + "id": "def-public.convertToBuildEsQuery.$1.config", + "type": "CompoundType", + "tags": [], + "label": "config", + "description": [], + "signature": [ + "KueryQueryOptions", + " & ", + "EsQueryFiltersConfig", + " & { allowLeadingWildcards?: boolean | undefined; queryStringOptions?: ", + "SerializableRecord", + " | undefined; }" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false + }, + { + "parentPluginId": "timelines", + "id": "def-public.convertToBuildEsQuery.$1.indexPattern", + "type": "Object", + "tags": [], + "label": "indexPattern", + "description": [], + "signature": [ + "{ fields: ", + "DataViewFieldBase", + "[]; id?: string | undefined; title: string; }" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false + }, + { + "parentPluginId": "timelines", + "id": "def-public.convertToBuildEsQuery.$1.queries", + "type": "Array", + "tags": [], + "label": "queries", + "description": [], + "signature": [ + "Query", + "[]" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false + }, + { + "parentPluginId": "timelines", + "id": "def-public.convertToBuildEsQuery.$1.filters", + "type": "Array", + "tags": [], + "label": "filters", + "description": [], + "signature": [ + "Filter", + "[]" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "timelines", "id": "def-public.elementOrChildrenHasFocus", @@ -280,6 +474,67 @@ "returnComment": [], "initialIsOpen": false }, + { + "parentPluginId": "timelines", + "id": "def-public.escapeKuery", + "type": "Function", + "tags": [], + "label": "escapeKuery", + "description": [], + "signature": [ + "(val: string) => string" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "timelines", + "id": "def-public.escapeKuery.$1", + "type": "Uncategorized", + "tags": [], + "label": "args", + "description": [], + "signature": [ + "A" + ], + "path": "node_modules/@types/lodash/ts3.1/fp.d.ts", + "deprecated": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "timelines", + "id": "def-public.escapeQueryValue", + "type": "Function", + "tags": [], + "label": "escapeQueryValue", + "description": [], + "signature": [ + "(val?: string | number) => string | number" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "timelines", + "id": "def-public.escapeQueryValue.$1", + "type": "CompoundType", + "tags": [], + "label": "val", + "description": [], + "signature": [ + "string | number" + ], + "path": "x-pack/plugins/timelines/public/components/utils/keury/index.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, { "parentPluginId": "timelines", "id": "def-public.focusColumn", diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 1f32392bafbb5..6ae285d81ace0 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github summary: API docs for the timelines plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Security solution](https://github.com/orgs/elastic/teams/security-solut | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 436 | 1 | 332 | 35 | +| 452 | 1 | 347 | 35 | ## Client diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 2789c007d9ebd..f972d078adeb2 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github summary: API docs for the transform plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/triggers_actions_ui.devdocs.json b/api_docs/triggers_actions_ui.devdocs.json index 0b434e11ba237..bc16f735f6e55 100644 --- a/api_docs/triggers_actions_ui.devdocs.json +++ b/api_docs/triggers_actions_ui.devdocs.json @@ -5503,11 +5503,13 @@ "label": "getRuleTagBadge", "description": [], "signature": [ - "(props: ", + "(props: ", "RuleTagBadgeProps", - ") => React.ReactElement<", + ") => React.ReactElement<", "RuleTagBadgeProps", - ", string | React.JSXElementConstructor>" + ", string | React.JSXElementConstructor>" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, @@ -5515,12 +5517,13 @@ { "parentPluginId": "triggersActionsUi", "id": "def-public.TriggersAndActionsUIPublicPluginStart.getRuleTagBadge.$1", - "type": "Object", + "type": "Uncategorized", "tags": [], "label": "props", "description": [], "signature": [ - "RuleTagBadgeProps" + "RuleTagBadgeProps", + "" ], "path": "x-pack/plugins/triggers_actions_ui/public/plugin.ts", "deprecated": false, diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index af6efe1d4420a..cd3bb5007ad4a 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github summary: API docs for the triggersActionsUi plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- @@ -18,7 +18,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 389 | 0 | 375 | 35 | +| 389 | 0 | 375 | 36 | ## Client diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index f242a77c877ca..4ac49e782bf8f 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github summary: API docs for the uiActions plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index d59b3f8d53f0e..b4ddb457e7df0 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github summary: API docs for the uiActionsEnhanced plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index d6df7ac389983..21a0953b3435b 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github summary: API docs for the unifiedSearch plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index c2ea826c491b8..fd8fb31e34892 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github summary: API docs for the unifiedSearch.autocomplete plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 016ef659b8ba9..bb3a3906615e4 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github summary: API docs for the urlForwarding plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index de91ebeef3794..ce6d61ef2baee 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github summary: API docs for the usageCollection plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index 6b85fe44c412e..72c6f66dcc65b 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github summary: API docs for the ux plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index d7f1cffbb3585..e477a83ff4c10 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github summary: API docs for the visDefaultEditor plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index e874cf81ef824..a43001b184d80 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeGauge plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index 724f26293f5e7..db27aa75a4483 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeHeatmap plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index 1535dda901b09..0c41f742c0f29 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypePie plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index eb1432e796dbd..ba5d2274e7be1 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeTable plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index abebd148d2620..049d322dcb3d5 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeTimelion plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index ef935085bd0e4..9a7b6b601b81f 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeTimeseries plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index fde1cd3bcebd4..62a0bfe31ae9b 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeVega plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index e06824be95340..9684427ea27f0 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeVislib plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index b34bd6b4905dd..35b516ffc6534 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github summary: API docs for the visTypeXy plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index a41c9bd8bbb59..ca801f02515aa 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -4,7 +4,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github summary: API docs for the visualizations plugin -date: 2022-06-23 +date: 2022-06-27 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- diff --git a/dev_docs/contributing/best_practices.mdx b/dev_docs/contributing/best_practices.mdx index e1f3b5ad4dbb8..3e7fca5539d77 100644 --- a/dev_docs/contributing/best_practices.mdx +++ b/dev_docs/contributing/best_practices.mdx @@ -134,7 +134,26 @@ When experimenting with code, it's completely fine to create a separate GitHub r There are some exceptions where a separate repo makes sense. However, they are exceptions to the rule. A separate repo has proven beneficial when there's a dedicated team collaborating on a package which has multiple consumers, for example [EUI](https://github.com/elastic/eui). -It may be tempting to get caught up in the dream of writing the next package which is published to npm and downloaded millions of times a week. Knowing the quality of developers that are working on Kibana, this is a real possibility. However, knowing which packages will see mass adoption is impossible to predict. Instead of jumping directly to writing code in a separate repo and accepting all of the complications that come along with it, prefer keeping code inside the Kibana repo. A [Kibana package](https://github.com/elastic/kibana/tree/main/packages) can be used to publish a package to npm, while still keeping the code inside the Kibana repo. Move code to an external repo only when there is a good reason, for example to enable external contributions. +It may be tempting to get caught up in the dream of writing the next package which is published to npm and downloaded millions of times a week. Knowing the quality of developers that are working on Kibana, this is a real possibility. However, knowing which packages will see mass adoption is impossible to predict. Instead of jumping directly to writing code in a separate repo and accepting all the complications that come along with it, prefer keeping code inside the Kibana repo. A Kibana package follows the npm idioms and can be later converted into a npm package, moved into an external repo and be published into the npm if a good reason for it was found (for example to enable external contributions). + +## Breaking up packages + +We are currently working to fully leverage change-based tasks across the repository and this functionality works best when the dependency tree is made of small packages focused around a single responsibility. Having said that, we do not think that contributors should break up their packages into single functions from day one; having 10k packages that contain a single function would also be a problem. Instead, breaking up packages over time will be a common practice used to address bottlenecks in the dependency tree and will be a valuable tool if build performance is being compromised. + +### When should a package be broken-up into smaller packages? +The goal when designing your package should be to mainly ensure that it has a single responsibility, and that anyone depending on your package would reasonably need everything exposed by it. This is +important for bundle sizes (the entire package will be loaded every time it is imported) and for change-based tasks (any time this package changes all dependent tasks will need to be run). +Packages should be broken into smaller packages if they have multiple responsibilities or serve as a collection of related things which usually won't be necessary at the same time. + +### What is a package's "responsibility"? How do I know that my package has a single responsibility? +The "responsibilities" of a package are defined by the features, utilities, and components exposed by your package. If a developer tries to use your package, is it likely that they will use every +part of it or just some of it? If most people would only need part of your package, then we would argue that your package has multiple responsibilities. At this point it is probably time to break up +your package. + +### How do we manage the transition from one package to many smaller packages? +When making a change like this, import statements that previously pointed to the now broken-up package need to be updated to point to the smaller packages, so we have written an ESLint rule +called `@kbn/imports/exports_moved_packages` which allows contributors to define the exports previously available from one package as now being available from another package and leverage +auto-fixing to migration all existing and new uses of this export to the proper package. ## Licensing diff --git a/docs/api/actions-and-connectors/execute.asciidoc b/docs/api/actions-and-connectors/execute.asciidoc index 97612d88ed035..29e9bfa4cf224 100644 --- a/docs/api/actions-and-connectors/execute.asciidoc +++ b/docs/api/actions-and-connectors/execute.asciidoc @@ -13,13 +13,6 @@ Runs a connector by ID. `POST :/s//api/actions/connector//_execute` -[[execute-connector-api-desc]] -=== {api-description-title} - -You can use this API to test an <> that -involves interaction with Kibana services or integrations with third-party -systems. - [[execute-connector-api-prereq]] === {api-prereq-title} @@ -30,6 +23,13 @@ You must have `read` privileges for the *Actions and Connectors* feature in the If you use an index connector, you must also have `all`, `create`, `index`, or `write` {ref}/security-privileges.html[indices privileges]. +[[execute-connector-api-desc]] +=== {api-description-title} + +You can use this API to test an <> that +involves interaction with Kibana services or integrations with third-party +systems. + [[execute-connector-api-params]] === {api-path-parms-title} @@ -50,6 +50,16 @@ depending on the connector type. For information about the parameter properties, refer to <>. + -- +.Index connectors +[%collapsible%open] +==== +`documents`:: +(Required, array of objects) The documents to index in JSON format. + +For more information, refer to +{kibana-ref}/index-action-type.html[Index connector and action]. +==== + .Jira connectors [%collapsible%open] ==== diff --git a/docs/management/advanced-options.asciidoc b/docs/management/advanced-options.asciidoc index 120617ea4de94..5ed2d734a81c2 100644 --- a/docs/management/advanced-options.asciidoc +++ b/docs/management/advanced-options.asciidoc @@ -374,9 +374,21 @@ value is 10000. [[apm-enable-service-overview]]`apm:enableServiceOverview`:: When enabled, displays the *Overview* tab for services in *APM*. +[[observability-apm-optimized-sort]]`observability:apmServiceInventoryOptimizedSorting`:: +preview:[] Sorts services without anomaly detection rules on the APM Service inventory page by service name. + +[[observability-apm-enable-comparison]]`observability:enableComparisonByDefault`:: +Enables the comparison feature in the APM app. + +[[observability-apm-enable-infra-view]]`observability:enableInfrastructureView`:: +Enables the Infrastructure view in the APM app. + [[observability-enable-inspect-es-queries]]`observability:enableInspectEsQueries`:: When enabled, allows you to inspect {es} queries in API responses. +[[observability-apm-enable-service-groups]]`observability:enableServiceGroups`:: +preview:[] When enabled, allows users to create Service Groups from the APM Service Inventory page. + [float] [[kibana-reporting-settings]] ==== Reporting diff --git a/docs/management/connectors/action-types/servicenow-itom.asciidoc b/docs/management/connectors/action-types/servicenow-itom.asciidoc index 3fd3682dc1ad9..07ede3ef0d3cb 100644 --- a/docs/management/connectors/action-types/servicenow-itom.asciidoc +++ b/docs/management/connectors/action-types/servicenow-itom.asciidoc @@ -1,24 +1,25 @@ -[role="xpack"] [[servicenow-itom-action-type]] -=== ServiceNow ITOM connector and action +== {sn-itom} connector and action ++++ -ServiceNow ITOM +{sn-itom} ++++ -The {sn} ITOM connector uses the https://docs.servicenow.com/bundle/rome-it-operations-management/page/product/event-management/task/send-events-via-web-service.html[Event API] to create {sn} events. +The {sn-itom} connector uses the +https://docs.servicenow.com/bundle/rome-it-operations-management/page/product/event-management/task/send-events-via-web-service.html[event API] +to create {sn} events. [float] [[servicenow-itom-connector-prerequisites]] -==== Prerequisites -* Create a {sn} integration user and assign it the appropriate roles. +=== Prerequisites -If you use open authorization (OAuth), you must also: - -* Create an RSA keypair and add an X.509 Certificate. -* Create an OAuth JWT API endpoint for external clients with a JWT Verifiers Map. +. <> +. If you use open authorization (OAuth), you must also: +.. <>. +.. <>. [float] -===== Create a {sn} integration user +[[servicenow-itom-connector-prerequisites-integration-user]] +==== Create a {sn} integration user To ensure authenticated communication between Elastic and {sn}, create a {sn} integration user and assign it the appropriate roles. @@ -26,104 +27,32 @@ To ensure authenticated communication between Elastic and {sn}, create a {sn} in . Click *New*. . Complete the form, then right-click on the menu bar and click *Save*. . Go to the *Roles* tab and click *Edit*. -. Assign the integration user the following roles:  +. Assign the integration user the following roles: * `personalize_choices`: Allows the user to retrieve Choice element options, such as Severity. * `evt_mgmt_integration`: Enables integration with external event sources by allowing the user to create events. . Click *Save*. [float] -===== Create an RSA keypair and add an X.509 Certificate +[[servicenow-itom-connector-prerequisites-rsa-key]] +==== Create an RSA keypair and add an X.509 Certificate This step is required to use OAuth for authentication between Elastic and {sn}. -*Create an RSA keypair:* +include::servicenow.asciidoc[tag=servicenow-rsa-key] -. Use https://www.openssl.org/docs/man1.0.2/man1/genrsa.html[OpenSSL] to generate an RSA private key: -+ --- -[source,sh] ----- -openssl genrsa -out example-private-key.pem 3072 -openssl genrsa -passout pass:foobar -out example-private-key-with-password.pem 3072 <1> ----- -<1> Use the `passout` option to set a password on your private key. This is optional but remember your password if you set one. --- - -. Use https://www.openssl.org/docs/man1.0.2/man1/req.html[OpenSSL] to generate the matching public key: -+ --- -[source,sh] ----- -openssl req -new -x509 -key example-private-key.pem -out example-sn-cert.pem -days 360 ----- --- - -*Add an X.509 Certificate to ServiceNow:* - -. In your {sn} instance, go to *Certificates* and select *New*. -. Configure the certificate as follows: -+ --- -* *Name*: Name the certificate. -* *PEM Certificate*: Copy the generated public key into this text field. - -[role="screenshot"] -image::management/connectors/images/servicenow-new-certificate.png[Shows new certificate form in ServiceNow] --- - -. Click *Submit* to create the certificate. +include::servicenow.asciidoc[tag=servicenow-certificate] [float] -===== Create an OAuth JWT API endpoint for external clients with a JWT Verifiers Map +[[servicenow-itom-connector-prerequisites-endpoint]] +==== Create an OAuth JWT API endpoint for external clients with a JWT Verifiers Map -This step is required to use OAuth for authentication between Elastic and {sn}. - -. In your {sn} instance, go to *Application Registry* and select *New*. -. Select *Create an OAuth JWT API endpoint for external clients* from the list of options. -+ --- -[role="screenshot"] -image::management/connectors/images/servicenow-jwt-endpoint.png[Shows application type selection] --- - -. Configure the application as follows: -+ --- -* *Name*: Name the application. -* *User field*: Select the field to use as the user identifier. - -[role="screenshot"] -image::management/connectors/images/servicenow-new-application.png[Shows new application form in ServiceNow] - -IMPORTANT: Remember the selected user field. You will use this as the *User Identifier Value* when creating the connector. For example, if you selected *Email* for *User field*, you will use the user's email for the *User Identifier Value*. --- - -. Click *Submit* to create the application. You will be redirected to the list of applications. -. Select the application you just created. -. Find the *Jwt Verifier Maps* tab and click *New*. -. Configure the new record as follows: -+ --- -* *Name*: Name the JWT Verifier Map. -* *Sys certificate*: Click the search icon and select the name of the certificate created in the previous step. - -[role="screenshot"] -image::management/connectors/images/servicenow-new-jwt-verifier-map.png[Shows new JWT Verifier Map form in ServiceNow] --- - -. Click *Submit* to create the application. -. Note the *Client ID*, *Client Secret* and *JWT Key ID*. You will need these values to create your {sn} connector. -+ --- -[role="screenshot"] -image::management/connectors/images/servicenow-oauth-values.png[Shows where to find OAuth values in ServiceNow] --- +include::servicenow.asciidoc[tag=servicenow-endpoint] [float] [[servicenow-itom-connector-configuration]] -==== Connector configuration +=== Connector configuration -{sn} ITOM connectors have the following configuration properties. +{sn-itom} connectors have the following configuration properties. Name:: The name of the connector. The name is used to identify a connector in the **Stack Management** connector listing, and in the connector list when configuring an action. Is OAuth:: The type of authentication to use. @@ -139,13 +68,13 @@ Private Key Password:: The password for the RSA private key generated during set [float] [[servicenow-itom-connector-networking-configuration]] -==== Connector networking configuration +=== Connector networking configuration Use the <> to customize connector networking configurations, such as proxies, certificates, or TLS settings. You can set configurations that apply to all your connectors or use `xpack.actions.customHostSettings` to set per-host configurations. [float] [[Preconfigured-servicenow-itom-configuration]] -==== Preconfigured connector type +=== Preconfigured connector type Connector using Basic Authentication [source,text] @@ -196,26 +125,26 @@ Secrets defines sensitive information for the connector type. [float] [[define-servicenow-itom-ui]] -==== Define connector in Stack Management +=== Define connector in Stack Management -Define {sn} ITOM connector properties. Choose whether to use OAuth for authentication. +Define {sn-itom} connector properties. Choose whether to use OAuth for authentication. [role="screenshot"] -image::management/connectors/images/servicenow-itom-connector-basic.png[ServiceNow ITOM connector using basic auth] +image::management/connectors/images/servicenow-itom-connector-basic.png[{sn-itom} connector using basic auth] [role="screenshot"] -image::management/connectors/images/servicenow-itom-connector-oauth.png[ServiceNow ITOM connector using OAuth] +image::management/connectors/images/servicenow-itom-connector-oauth.png[{sn-itom} connector using OAuth] -Test {sn} ITOM action parameters. +Test {sn-itom} action parameters. [role="screenshot"] -image::management/connectors/images/servicenow-itom-params-test.png[ServiceNow ITOM params test] +image::management/connectors/images/servicenow-itom-params-test.png[{sn-itom} params test] [float] [[servicenow-itom-action-configuration]] -==== Action configuration +=== Action configuration -{sn} ITOM actions have the following configuration properties. +{sn-itom} actions have the following configuration properties. Source:: The name of the event source type. Node:: The Host that the event was triggered for. @@ -227,10 +156,10 @@ Message key:: All actions sharing this key will be associated with the same {sn Severity:: The severity of the event. Description:: The details about the event. -Refer to https://docs.servicenow.com/bundle/rome-it-operations-management/page/product/event-management/task/send-events-via-web-service.html[ServiceNow documentation] for more information about the properties. +Refer to https://docs.servicenow.com/bundle/rome-it-operations-management/page/product/event-management/task/send-events-via-web-service.html[{sn} documentation] for more information about the properties. [float] [[configuring-servicenow-itom]] -==== Configure {sn} ITOM +=== Configure {sn-itom} {sn} offers free https://developer.servicenow.com/dev.do#!/guides/madrid/now-platform/pdi-guide/obtaining-a-pdi[Personal Developer Instances], which you can use to test incidents. diff --git a/docs/management/connectors/action-types/servicenow-sir.asciidoc b/docs/management/connectors/action-types/servicenow-sir.asciidoc index a3618d626d8be..06639a077bf89 100644 --- a/docs/management/connectors/action-types/servicenow-sir.asciidoc +++ b/docs/management/connectors/action-types/servicenow-sir.asciidoc @@ -1,28 +1,28 @@ -[role="xpack"] [[servicenow-sir-action-type]] -=== ServiceNow SecOps connector and action +== {sn-sir} connector and action ++++ -ServiceNow SecOps +{sn-sir} ++++ -The {sn} SecOps connector uses the https://developer.servicenow.com/dev.do#!/reference/api/sandiego/rest/c_ImportSetAPI[Import Set API] to create {sn} security incidents. +The {sn-sir} connector uses the +https://developer.servicenow.com/dev.do#!/reference/api/sandiego/rest/c_ImportSetAPI[import set API] +to create {sn} security incidents. [float] [[servicenow-sir-connector-prerequisites]] -==== Prerequisites -After upgrading from {stack} version 7.15.0 or earlier to version 7.16.0 or later, you must complete the following within your {sn} instance before creating a new {sn} SecOps connector or <>: +=== Prerequisites +After upgrading from {stack} version 7.15.0 or earlier to version 7.16.0 or later, you must complete the following within your {sn} instance before creating a new {sn-sir} connector or <>: -* Install https://store.servicenow.com/sn_appstore_store.do#!/store/application/2f0746801baeb01019ae54e4604bcb0f[Elastic for Security Operations (SecOps)] from the {sn} Store. -* Create a {sn} integration user and assign it the appropriate roles. -* Create a Cross-Origin Resource Sharing (CORS) rule. - -If you use open authorization (OAuth), you must also: - -* Create an RSA keypair and add an X.509 Certificate. -* Create an OAuth JWT API endpoint for external clients with a JWT Verifiers Map. +. Install https://store.servicenow.com/sn_appstore_store.do#!/store/application/2f0746801baeb01019ae54e4604bcb0f[Elastic for Security Operations (SecOps)] from the {sn} Store. +. <>. +. <>. +. If you use open authorization (OAuth), you must also: +.. <>. +.. <>. [float] -===== Create a {sn} integration user +[[servicenow-sir-connector-prerequisites-integration-user]] +==== Create a {sn} integration user To ensure authenticated communication between Elastic and {sn}, create a {sn} integration user and assign it the appropriate roles.  @@ -39,7 +39,8 @@ To ensure authenticated communication between Elastic and {sn}, create a {sn} in . Click *Save*. [float] -===== Create a CORS rule +[[servicenow-sir-connector-prerequisites-cors-rule]] +==== Create a CORS rule A CORS rule is required for communication between Elastic and {sn}. To create a CORS rule: @@ -53,98 +54,26 @@ A CORS rule is required for communication between Elastic and {sn}. To create a . Click *Submit* to create the rule. [float] -===== Create an RSA keypair and add an X.509 Certificate +[[servicenow-sir-connector-prerequisites-rsa-key]] +==== Create an RSA keypair and add an X.509 Certificate This step is required to use OAuth for authentication between Elastic and {sn}. -*Create an RSA keypair:* +include::servicenow.asciidoc[tag=servicenow-rsa-key] -. Use https://www.openssl.org/docs/man1.0.2/man1/genrsa.html[OpenSSL] to generate an RSA private key: -+ --- -[source,sh] ----- -openssl genrsa -out example-private-key.pem 3072 -openssl genrsa -passout pass:foobar -out example-private-key-with-password.pem 3072 <1> ----- -<1> Use the `passout` option to set a password on your private key. This is optional but remember your password if you set one. --- - -. Use https://www.openssl.org/docs/man1.0.2/man1/req.html[OpenSSL] to generate the matching public key: -+ --- -[source,sh] ----- -openssl req -new -x509 -key example-private-key.pem -out example-sn-cert.pem -days 360 ----- --- - -*Add an X.509 Certificate to ServiceNow:* - -. In your {sn} instance, go to *Certificates* and select *New*. -. Configure the certificate as follows: -+ --- -* *Name*: Name the certificate. -* *PEM Certificate*: Copy the generated public key into this text field. - -[role="screenshot"] -image::management/connectors/images/servicenow-new-certificate.png[Shows new certificate form in ServiceNow] --- - -. Click *Submit* to create the certificate. +include::servicenow.asciidoc[tag=servicenow-certificate] [float] -===== Create an OAuth JWT API endpoint for external clients with a JWT Verifiers Map - -This step is required to use OAuth for authentication between Elastic and {sn}. - -. In your {sn} instance, go to *Application Registry* and select *New*. -. Select *Create an OAuth JWT API endpoint for external clients* from the list of options. -+ --- -[role="screenshot"] -image::management/connectors/images/servicenow-jwt-endpoint.png[Shows application type selection] --- - -. Configure the application as follows: -+ --- -* *Name*: Name the application. -* *User field*: Select the field to use as the user identifier. - -[role="screenshot"] -image::management/connectors/images/servicenow-new-application.png[Shows new application form in ServiceNow] - -IMPORTANT: Remember the selected user field. You will use this as the *User Identifier Value* when creating the connector. For example, if you selected *Email* for *User field*, you will use the user's email for the *User Identifier Value*. --- +[[servicenow-sir-connector-prerequisites-endpoint]] +==== Create an OAuth JWT API endpoint for external clients with a JWT Verifiers Map -. Click *Submit* to create the application. You will be redirected to the list of applications. -. Select the application you just created. -. Find the *Jwt Verifier Maps* tab and click *New*. -. Configure the new record as follows: -+ --- -* *Name*: Name the JWT Verifier Map. -* *Sys certificate*: Click the search icon and select the name of the certificate created in the previous step. - -[role="screenshot"] -image::management/connectors/images/servicenow-new-jwt-verifier-map.png[Shows new JWT Verifier Map form in ServiceNow] --- - -. Click *Submit* to create the verifier map. -. Note the *Client ID*, *Client Secret* and *JWT Key ID*. You will need these values to create your {sn} connector. -+ --- -[role="screenshot"] -image::management/connectors/images/servicenow-oauth-values.png[Shows where to find OAuth values in ServiceNow] --- +include::servicenow.asciidoc[tag=servicenow-endpoint] [float] [[servicenow-sir-connector-update]] -==== Update a deprecated {sn} SecOps connector +=== Update a deprecated {sn-sir} connector -{sn} SecOps connectors created in {stack} version 7.15.0 or earlier are marked as deprecated after you upgrade to version 7.16.0 or later. Deprecated connectors have a yellow icon after their name and display a warning message when selected. +{sn-sir} connectors created in {stack} version 7.15.0 or earlier are marked as deprecated after you upgrade to version 7.16.0 or later. Deprecated connectors have a yellow icon after their name and display a warning message when selected. [role="screenshot"] image::management/connectors/images/servicenow-sir-update-connector.png[Shows deprecated ServiceNow connectors] @@ -164,9 +93,9 @@ To update a deprecated connector: [float] [[servicenow-sir-connector-configuration]] -==== Connector configuration +=== Connector configuration -{sn} SecOps connectors have the following configuration properties. +{sn-sir} connectors have the following configuration properties. Name:: The name of the connector. The name is used to identify a connector in the **Stack Management** UI connector listing, and in the connector list when configuring an action. Is OAuth:: The type of authentication to use. @@ -182,13 +111,13 @@ Private Key Password:: The password for the RSA private key generated during set [float] [[servicenow-sir-connector-networking-configuration]] -==== Connector networking configuration +=== Connector networking configuration Use the <> to customize connector networking configurations, such as proxies, certificates, or TLS settings. You can set configurations that apply to all your connectors or use `xpack.actions.customHostSettings` to set per-host configurations. [float] [[Preconfigured-servicenow-sir-configuration]] -==== Preconfigured connector type +=== Preconfigured connector type Connector using Basic Authentication [source,text] @@ -244,26 +173,26 @@ Secrets defines sensitive information for the connector type. [float] [[define-servicenow-sir-ui]] -==== Define connector in Stack Management +=== Define connector in Stack Management Define {sn} SecOps connector properties. Choose whether to use OAuth for authentication. [role="screenshot"] -image::management/connectors/images/servicenow-sir-connector-basic.png[ServiceNow SecOps connector using basic auth] +image::management/connectors/images/servicenow-sir-connector-basic.png[{sn-sir} connector using basic auth] [role="screenshot"] -image::management/connectors/images/servicenow-sir-connector-oauth.png[ServiceNow SecOps connector using OAuth] +image::management/connectors/images/servicenow-sir-connector-oauth.png[{sn-sir} connector using OAuth] -Test {sn} SecOps action parameters. +Test {sn-sir} action parameters. [role="screenshot"] -image::management/connectors/images/servicenow-sir-params-test.png[ServiceNow SecOps params test] +image::management/connectors/images/servicenow-sir-params-test.png[{sn-sir} params test] [float] [[servicenow-sir-action-configuration]] -==== Action configuration +=== Action configuration -ServiceNow SecOps actions have the following configuration properties. +{sn-sir} actions have the following configuration properties. Short description:: A short description for the incident, used for searching the contents of the knowledge base. Priority:: The priority of the incident. @@ -279,6 +208,6 @@ Additional comments:: Additional information for the client, such as how to tro [float] [[configuring-servicenow-sir]] -==== Configure {sn} SecOps +=== Configure {sn-sir} {sn} offers free https://developer.servicenow.com/dev.do#!/guides/madrid/now-platform/pdi-guide/obtaining-a-pdi[Personal Developer Instances], which you can use to test incidents. diff --git a/docs/management/connectors/action-types/servicenow.asciidoc b/docs/management/connectors/action-types/servicenow.asciidoc index 99ed4f0bec32f..613935a7ac4d0 100644 --- a/docs/management/connectors/action-types/servicenow.asciidoc +++ b/docs/management/connectors/action-types/servicenow.asciidoc @@ -1,28 +1,34 @@ -[role="xpack"] [[servicenow-action-type]] -=== ServiceNow ITSM connector and action +== {sn-itsm} connector and action ++++ -ServiceNow ITSM +{sn-itsm} ++++ -The {sn} ITSM connector uses the https://developer.servicenow.com/dev.do#!/reference/api/sandiego/rest/c_ImportSetAPI[Import Set API] to create {sn} incidents. +The {sn-itsm} connector uses the +https://developer.servicenow.com/dev.do#!/reference/api/sandiego/rest/c_ImportSetAPI[import set API] +to create {sn} incidents. [float] [[servicenow-itsm-connector-prerequisites]] -==== Prerequisites -After upgrading from {stack} version 7.15.0 or earlier to version 7.16.0 or later, you must complete the following within your {sn} instance before creating a new {sn} ITSM connector or <>: - -* Install https://store.servicenow.com/sn_appstore_store.do#!/store/application/7148dbc91bf1f450ced060a7234bcb88[Elastic for ITSM] from the {sn} Store. -* Create a {sn} integration user and assign it the appropriate roles. -* Create a Cross-Origin Resource Sharing (CORS) rule. - -If you use open authorization (OAuth), you must also: - -* Create an RSA keypair and add an X.509 Certificate. -* Create an OAuth JWT API endpoint for external clients with a JWT Verifiers Map. +=== Prerequisites + +After upgrading from {stack} version 7.15.0 or earlier to version 7.16.0 or +later, you must complete the following steps within your {sn} instance before +creating a new {sn-itsm} connector or +<>: + +. Install +https://store.servicenow.com/sn_appstore_store.do#!/store/application/7148dbc91bf1f450ced060a7234bcb88[Elastic for ITSM] +from the {sn} Store. +. <>. +. <>. +. If you use open authorization (OAuth), you must also: +.. <>. +.. <>. [float] -===== Create a {sn} integration user +[[servicenow-itsm-connector-prerequisites-integration-user]] +==== Create a {sn} integration user To ensure authenticated communication between Elastic and {sn}, create a {sn} integration user and assign it the appropriate roles. @@ -38,7 +44,8 @@ To ensure authenticated communication between Elastic and {sn}, create a {sn} in . Click *Save*. [float] -===== Create a CORS rule +[[servicenow-itsm-connector-prerequisites-cors-rule]] +==== Create a CORS rule A CORS rule is required for communication between Elastic and {sn}. To create a CORS rule: @@ -52,10 +59,12 @@ A CORS rule is required for communication between Elastic and {sn}. To create a . Click *Submit* to create the rule. [float] -===== Create an RSA keypair and add an X.509 Certificate +[[servicenow-itsm-connector-prerequisites-rsa-key]] +==== Create an RSA keypair and add an X.509 certificate This step is required to use OAuth for authentication between Elastic and {sn}. +// tag::servicenow-rsa-key[] *Create an RSA keypair:* . Use https://www.openssl.org/docs/man1.0.2/man1/genrsa.html[OpenSSL] to generate an RSA private key: @@ -77,8 +86,9 @@ openssl genrsa -passout pass:foobar -out example-private-key-with-password.pem 3 openssl req -new -x509 -key example-private-key.pem -out example-sn-cert.pem -days 360 ---- -- - -*Add an X.509 Certificate to ServiceNow:* +// end::servicenow-rsa-key[] +// tag::servicenow-certificate[] +*Add an X.509 certificate to ServiceNow:* . In your {sn} instance, go to *Certificates* and select *New*. . Configure the certificate as follows: @@ -92,10 +102,13 @@ image::management/connectors/images/servicenow-new-certificate.png[Shows new cer -- . Click *Submit* to create the certificate. +// end::servicenow-certificate[] [float] -===== Create an OAuth JWT API endpoint for external clients with a JWT Verifiers Map +[[servicenow-itsm-connector-prerequisites-endpoint]] +==== Create an OAuth JWT API endpoint for external clients with a JWT Verifiers Map +// tag::servicenow-endpoint[] This step is required to use OAuth for authentication between Elastic and {sn}. . In your {sn} instance, go to *Application Registry* and select *New*. @@ -138,12 +151,13 @@ image::management/connectors/images/servicenow-new-jwt-verifier-map.png[Shows ne [role="screenshot"] image::management/connectors/images/servicenow-oauth-values.png[Shows where to find OAuth values in ServiceNow] -- +// end::servicenow-endpoint[] [float] [[servicenow-itsm-connector-update]] -==== Update a deprecated {sn} ITSM connector +=== Update a deprecated {sn-itsm} connector -{sn} ITSM connectors created in {stack} version 7.15.0 or earlier are marked as deprecated after you upgrade to version 7.16.0 or later. Deprecated connectors have a yellow icon after their name and display a warning message when selected. +{sn-itsm} connectors created in {stack} version 7.15.0 or earlier are marked as deprecated after you upgrade to version 7.16.0 or later. Deprecated connectors have a yellow icon after their name and display a warning message when selected. [role="screenshot"] image::management/connectors/images/servicenow-sir-update-connector.png[Shows deprecated ServiceNow connectors] @@ -163,9 +177,9 @@ To update a deprecated connector: [float] [[servicenow-connector-configuration]] -==== Connector configuration +=== Connector configuration -{sn} ITSM connectors have the following configuration properties. +{sn-itsm} connectors have the following configuration properties. Name:: The name of the connector. The name is used to identify a connector in the **Stack Management** UI connector listing, and in the connector list when configuring an action. Is OAuth:: The type of authentication to use. @@ -181,13 +195,13 @@ Private Key Password:: The password for the RSA private key generated during set [float] [[servicenow-connector-networking-configuration]] -==== Connector networking configuration +=== Connector networking configuration Use the <> to customize connector networking configurations, such as proxies, certificates, or TLS settings. You can set configurations that apply to all your connectors or use `xpack.actions.customHostSettings` to set per-host configurations. [float] [[Preconfigured-servicenow-configuration]] -==== Preconfigured connector type +=== Preconfigured connector type Connector using Basic Authentication [source,text] @@ -243,9 +257,9 @@ Secrets defines sensitive information for the connector type. [float] [[define-servicenow-ui]] -==== Define connector in Stack Management +=== Define connector in Stack Management -Define {sn} ITSM connector properties. Choose whether to use OAuth for authentication. +Define {sn-itsm} connector properties. Choose whether to use OAuth for authentication. [role="screenshot"] image::management/connectors/images/servicenow-connector-basic.png[ServiceNow connector using basic auth] @@ -253,16 +267,16 @@ image::management/connectors/images/servicenow-connector-basic.png[ServiceNow co [role="screenshot"] image::management/connectors/images/servicenow-connector-oauth.png[ServiceNow connector using OAuth] -Test {sn} ITSM action parameters. +Test {sn-itsm} action parameters. [role="screenshot"] image::management/connectors/images/servicenow-params-test.png[ServiceNow params test] [float] [[servicenow-action-configuration]] -==== Action configuration +=== Action configuration -{sn} ITSM actions have the following configuration properties. +{sn-itsm} actions have the following configuration properties. Urgency:: The extent to which the incident resolution can delay. Severity:: The severity of the incident. @@ -280,6 +294,6 @@ Additional comments:: Additional information for the client, such as how to tro [float] [[configuring-servicenow]] -==== Configure {sn} +=== Configure {sn} {sn} offers free https://developer.servicenow.com/dev.do#!/guides/madrid/now-platform/pdi-guide/obtaining-a-pdi[Personal Developer Instances], which you can use to test incidents. diff --git a/docs/management/connectors/index.asciidoc b/docs/management/connectors/index.asciidoc index c895c4450aace..322f248e4ca8c 100644 --- a/docs/management/connectors/index.asciidoc +++ b/docs/management/connectors/index.asciidoc @@ -5,9 +5,9 @@ include::action-types/jira.asciidoc[] include::action-types/teams.asciidoc[] include::action-types/pagerduty.asciidoc[] include::action-types/server-log.asciidoc[] -include::action-types/servicenow.asciidoc[] -include::action-types/servicenow-sir.asciidoc[] -include::action-types/servicenow-itom.asciidoc[] +include::action-types/servicenow.asciidoc[leveloffset=+1] +include::action-types/servicenow-sir.asciidoc[leveloffset=+1] +include::action-types/servicenow-itom.asciidoc[leveloffset=+1] include::action-types/swimlane.asciidoc[] include::action-types/slack.asciidoc[] include::action-types/webhook.asciidoc[] diff --git a/docs/osquery/images/enter-query.png b/docs/osquery/images/enter-query.png index 154d2dcad4857..efcf8fa58a7a8 100644 Binary files a/docs/osquery/images/enter-query.png and b/docs/osquery/images/enter-query.png differ diff --git a/docs/osquery/images/live-query-check-results.png b/docs/osquery/images/live-query-check-results.png index 33e31f0ce54f0..cd1362e7e977d 100644 Binary files a/docs/osquery/images/live-query-check-results.png and b/docs/osquery/images/live-query-check-results.png differ diff --git a/docs/osquery/images/scheduled-pack.png b/docs/osquery/images/scheduled-pack.png index 608730e371ade..f48f5be333aa2 100644 Binary files a/docs/osquery/images/scheduled-pack.png and b/docs/osquery/images/scheduled-pack.png differ diff --git a/docs/osquery/manage-integration.asciidoc b/docs/osquery/manage-integration.asciidoc index e35b9ffcc2473..34b96d84e4dc7 100644 --- a/docs/osquery/manage-integration.asciidoc +++ b/docs/osquery/manage-integration.asciidoc @@ -35,6 +35,7 @@ you can create roles for users who can only run live or saved queries, but who c This is useful for teams who need in-depth and detailed control. [float] +[[osquery-custom-config]] === Customize Osquery configuration experimental[] By default, all Osquery Manager integrations share the same osquery configuration. However, you can customize how Osquery is configured by editing the Osquery Manager integration for each agent policy you want to adjust. The custom configuration is then applied to all agents in the policy. @@ -76,8 +77,41 @@ As an example, the following configuration disables two tables. + ```ts { - "options":{ - "disable_tables":"curl,process_envs" + "options": { + "disable_tables":"file,process_envs" + } +} +``` + +[float] +[[enable-curl-table]] +==== Enabling the `curl` table +By default, the https://osquery.io/schema/#curl[curl table] is disabled. +If preferred, you can enable it using the Advanced *Osquery config*. + +*Why is the `curl` table disabled?* + +When you query the https://osquery.io/schema/#curl[curl table], this results in an HTTP request. +The query results include the response to the request. As a simple example, if you run the query +`SELECT * FROM curl WHERE url='https://www.elastic.co/';`, the `result` field contains the +webpage content. + +This table can be misused in some environments, for example, when used to issue HTTP requests +to an AWS metadata service or to services on your internal network. + +Out of an abundance of caution, we have opted to disable access to this table by default. +However, if you need access to the table for your own monitoring purposes, you can enable it +as needed. + +*How to enable the `curl` table:* + +For each agent policy where you want to allow `curl` table queries, edit the +Osquery Manager integration to add the following Advanced *Osquery config*: + +```ts +{ + "options": { + "enable_tables":"curl" } } ``` @@ -88,7 +122,7 @@ As an example, the following configuration disables two tables. The https://github.com/osquery/osquery/releases[Osquery version] available on an Elastic Agent is associated to the version of Osquery Beat on the Agent. To get the latest version of Osquery Beat, -https://www.elastic.co/guide/en/fleet/master/upgrade-elastic-agent.html[upgrade your Elastic Agent]. +{fleet-guide}/upgrade-elastic-agent.html[upgrade your Elastic Agent]. [float] === Debug issues diff --git a/docs/osquery/osquery-faq.asciidoc b/docs/osquery/osquery-faq.asciidoc new file mode 100644 index 0000000000000..0c353474a51c6 --- /dev/null +++ b/docs/osquery/osquery-faq.asciidoc @@ -0,0 +1,84 @@ +[[osquery-faq]] +== Osquery FAQ + +This list of frequently asked questions answers common questions about +using Osquery in {kib}. + +[float] +[[osquery-differences]] +=== How is Osquery Manager different from Osquery? + +The Osquery Manager integration brings https://osquery.io/[Osquery] capabilities to the Elastic Stack and +makes it easier to manage Osquery across a large number of hosts. +Most Osquery functionality works the same way in {kib} as it does when you deploy Osquery yourself. +However, there are a few differences and known issues, outlined below. + +[float] +[[osquery-fda]] +=== How do I grant Full Disk Access? + +Full Disk Access (FDA) is required to fully query some tables on MacOS. Granting FDA is +not yet supported for Osquery Manager. This impacts a small set +of tables that access file directories that are restricted due to heightened permissions from Apple, +including https://osquery.io/schema/current#file[file], +https://osquery.io/schema/current#file_events[file_events], +https://osquery.io/schema/current#es_process_events[es_process_events], +and any custom tables configured with +https://osquery.readthedocs.io/en/stable/deployment/configuration/#automatic-table-construction[ATC] +that require access to these directories. +When querying these tables, you won't get results from the restricted directories. + +[float] +[[osquery-carves]] +=== Why can't I query the carves table? + +File carving is not yet supported in the Elastic Stack, and +https://osquery.io/schema/current#carves[carves] table queries do not return results. + +[float] +[[osquery-help-command]] +=== Does the Osquery `.help` command work in {kib}? + +The https://osquery.readthedocs.io/en/stable/introduction/sql/#shell-help[Osquery `.help` command] +is not available when running live queries in {kib}. Instead, refer to the +https://osquery.io/schema/[Osquery schema] for all available tables, fields, +and supported Operating Systems for each. + +[float] +[[osquery-extensions]] +=== Can I use Osquery extensions in {kib}? + +Osquery Manager does not currently support +https://osquery.readthedocs.io/en/stable/deployment/extensions/[Osquery extensions]. + +[float] +[[osquery-fim]] +=== Can I do File Integrity Monitoring (FIM)? +Yes, you can set up +https://osquery.readthedocs.io/en/stable/deployment/file-integrity-monitoring/[Osquery FIM] using +the Advanced configuration option for Osquery Manager (see <>). +However, Elastic also provides a File Integrity Monitoring integration for Elastic Agent, which might prove +to be easier to configure than the current options available for Osquery Manager. + +[float] +[[osquery-syntax]] +=== Where can I get help with osquery syntax? + +Osquery uses a superset of SQLite for queries. +To get started with osquery SQL, refer to the +https://osquery.readthedocs.io/en/stable/introduction/sql/[Osquery documentation]. +For help with more advanced questions, the Osquery community has an active +Slack workspace and GitHub project. You can find links for both at https://osquery.io/[osquery.io]. + +[float] +[[osquery-updates]] +=== How often is Osquery updated for Osquery Manager? +When a new https://github.com/osquery/osquery/releases[version of Osquery is released], +it is included in a subsequent Elastic Agent release and applied when the agent is upgraded. +After that, when running queries from Osquery Manager in {kib}, the updated Osquery version is used. +Refer to the Fleet and Elastic Agent Guide for help with +{fleet-guide}/upgrade-elastic-agent.html[upgrading Fleet-managed Elastic Agents]. + +To check what Osquery version is installed on an Elastic Agent, you can run +`SELECT version FROM osquery_info;` as a live query in {kib}. The `version` in the +response is the Osquery version installed on the agent. \ No newline at end of file diff --git a/docs/osquery/osquery.asciidoc b/docs/osquery/osquery.asciidoc index 9e384d79a4d6b..a068755a81454 100644 --- a/docs/osquery/osquery.asciidoc +++ b/docs/osquery/osquery.asciidoc @@ -62,9 +62,10 @@ description, and other <>. [[osquery-view-history]] == View or rerun previous live queries -From the *Live queries history* section on the *Live queries* tab: +The *Live queries history* section on the *Live queries* tab shows a log of queries run over the last 30 days. +Each query has the following options: -* Click image:images/play-icon.png[Right-pointing triangle] to replay a query. +* Click image:images/play-icon.png[Right-pointing triangle] to rerun a query. * Click image:images/table-icon.png[Table icon] to view the query <> and <>. + @@ -120,10 +121,66 @@ image::images/scheduled-pack.png[Shows queries in the pack and details about eac . View scheduled query results in <> or the drag-and-drop <> editor. [float] -[[osquery-prebuilt-packs]] -== Prebuilt Elastic packs +[[osquery-manage-query]] +== Save queries + +You can save queries in two ways: + +* After running a live query, click the *Save for later* link. +* From the *Saved queries* tab, click **Add saved query**. + +Once you save a query, you can only edit it from the *Saved queries* tab: + +. Go to *Saved queries*, and then click **Add saved query** or the edit icon. +. Provide the following fields: + +* The unique identifier. + +* A brief description. + +* The SQL query. + +* The <> to populate when the query is run. These fields are also copied in when you add this query to a pack. + +* The defaults to set when you add the query to a pack. + +** The frequency to run the query. + +** The minimum https://github.com/osquery/osquery/releases)[version of Osquery] required to run the query. + +** The operating system required to run the query. For information about supported platforms per table, refer to the https://osquery.io/schema[Osquery schema]. + +. Click *Test configuration* to test the query and any mapped fields: + +* From the *Test query* panel, select agents or groups to test the query, then click *Submit* to run a live query. Result columns with the image:images/mapped-icon.png[mapping] icon are mapped. Hover over the icon to see the mapped ECS field. + +. Click *Save* or *Update*. + +[float] +[[osquery-prebuilt-packs-queries]] +== Prebuilt Elastic packs and queries +Osquery Manager includes a set of prebuilt Osquery packs and saved queries +that can help you get started using the integration. + +[float] +[[osquery-prebuilt-queries]] +=== Prebuilt queries +A set of saved queries are included with the integration and available to run as a live query. +Note the following about the prebuilt queries: + +* The queries are not editable. + +* Several of the queries include default ECS mappings to standardize the results. + +* The prebuilt Elastic queries all follow the same naming convention and identify +what type of information is being queried, what operating system it supports if it's limited to one or more, +and that these are Elastic queries. For example, `firewall_rules_windows_elastic`. -The Osquery Manager integration includes a set of prebuilt Osquery packs that you can optionally load. Once added, you can then activate and schedule the packs. +[float] +[[osquery-prebuilt-packs]] +=== Prebuilt packs +The prebuilt Osquery packs are included with the integration and can be optionally loaded. +Once added, you can then activate and schedule the packs. You can modify the scheduled agent policies for a prebuilt pack, but you cannot edit queries in the pack. To edit the queries, you must first create a copy of the pack. @@ -131,7 +188,7 @@ For information about the prebuilt packs that are available, refer to <> to populate when the query is run. These fields are also copied in when you add this query to a pack. - -* The defaults to set when you add the query to a pack. - -** The frequency to run the query. - -** The minimum https://github.com/osquery/osquery/releases)[version of Osquery] required to run the query. - -** The operating system required to run the query. For information about supported platforms per table, refer to the https://osquery.io/schema[Osquery schema]. - -. Click *Test configuration* to test the query and any mapped fields: - -* From the *Test query* panel, select agents or groups to test the query, then click *Submit* to run a live query. Result columns with the image:images/mapped-icon.png[mapping] icon are mapped. Hover over the icon to see the mapped ECS field. - -. Click *Save* or *Update*. - - [float] [[osquery-map-fields]] == Map result fields to ECS @@ -276,9 +293,8 @@ A query can have the following status: |=== NOTE: If an agent is offline, the request status remains **pending** as {kib} retries the request. -By default, a query request times out after five minutes. The time out applies to the time it takes -to deliver the action request to an agent to run a query. If the action completes after the timeout period, -the results are still returned. +By default, a query request times out after one minute. An action timeout error is returned when +the query does not complete within that interval. [float] @@ -314,3 +330,5 @@ include::manage-integration.asciidoc[] include::exported-fields-reference.asciidoc[] include::prebuilt-packs.asciidoc[] + +include::osquery-faq.asciidoc[] diff --git a/package.json b/package.json index 717392523c956..e587a4947eb8e 100644 --- a/package.json +++ b/package.json @@ -130,10 +130,8 @@ "@hapi/inert": "^6.0.4", "@hapi/wreck": "^17.1.0", "@kbn/ace": "link:bazel-bin/packages/kbn-ace", - "@kbn/aiops-utils": "link:bazel-bin/packages/kbn-aiops-utils", + "@kbn/aiops-utils": "link:bazel-bin/x-pack/packages/ml/aiops_utils", "@kbn/alerts": "link:bazel-bin/packages/kbn-alerts", - "@kbn/ambient-storybook-types": "link:bazel-bin/packages/kbn-ambient-storybook-types", - "@kbn/ambient-ui-types": "link:bazel-bin/packages/kbn-ambient-ui-types", "@kbn/analytics": "link:bazel-bin/packages/kbn-analytics", "@kbn/analytics-client": "link:bazel-bin/packages/analytics/client", "@kbn/analytics-shippers-elastic-v3-browser": "link:bazel-bin/packages/analytics/shippers/elastic_v3/browser", @@ -142,7 +140,6 @@ "@kbn/analytics-shippers-fullstory": "link:bazel-bin/packages/analytics/shippers/fullstory", "@kbn/apm-config-loader": "link:bazel-bin/packages/kbn-apm-config-loader", "@kbn/apm-utils": "link:bazel-bin/packages/kbn-apm-utils", - "@kbn/ci-stats-performance-metrics": "link:bazel-bin/packages/kbn-ci-stats-performance-metrics", "@kbn/coloring": "link:bazel-bin/packages/kbn-coloring", "@kbn/config": "link:bazel-bin/packages/kbn-config", "@kbn/config-mocks": "link:bazel-bin/packages/kbn-config-mocks", @@ -167,6 +164,9 @@ "@kbn/core-doc-links-server": "link:bazel-bin/packages/core/doc-links/core-doc-links-server", "@kbn/core-doc-links-server-internal": "link:bazel-bin/packages/core/doc-links/core-doc-links-server-internal", "@kbn/core-doc-links-server-mocks": "link:bazel-bin/packages/core/doc-links/core-doc-links-server-mocks", + "@kbn/core-fatal-errors-browser": "link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser", + "@kbn/core-fatal-errors-browser-internal": "link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser-internal", + "@kbn/core-fatal-errors-browser-mocks": "link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser-mocks", "@kbn/core-i18n-browser": "link:bazel-bin/packages/core/i18n/core-i18n-browser", "@kbn/core-i18n-browser-internal": "link:bazel-bin/packages/core/i18n/core-i18n-browser-internal", "@kbn/core-i18n-browser-mocks": "link:bazel-bin/packages/core/i18n/core-i18n-browser-mocks", @@ -192,7 +192,6 @@ "@kbn/i18n-react": "link:bazel-bin/packages/kbn-i18n-react", "@kbn/interpreter": "link:bazel-bin/packages/kbn-interpreter", "@kbn/io-ts-utils": "link:bazel-bin/packages/kbn-io-ts-utils", - "@kbn/kbn-ci-stats-performance-metrics": "link:bazel-bin/packages/kbn-kbn-ci-stats-performance-metrics", "@kbn/kibana-json-schema": "link:bazel-bin/packages/kbn-kibana-json-schema", "@kbn/logging": "link:bazel-bin/packages/kbn-logging", "@kbn/logging-mocks": "link:bazel-bin/packages/kbn-logging-mocks", @@ -262,11 +261,6 @@ "@turf/distance": "6.0.1", "@turf/helpers": "6.0.1", "@turf/length": "^6.0.2", - "@types/jsonwebtoken": "^8.5.6", - "@types/mapbox__vector-tile": "1.3.0", - "@types/moment-duration-format": "^2.2.3", - "@types/react-is": "^16.7.2", - "@types/rrule": "^2.2.9", "JSONStream": "1.3.5", "abort-controller": "^3.0.0", "antlr4ts": "^0.5.0-alpha.3", @@ -278,7 +272,6 @@ "canvg": "^3.0.9", "chalk": "^4.1.0", "cheerio": "^1.0.0-rc.10", - "chokidar": "^3.4.3", "chroma-js": "^1.4.1", "classnames": "2.2.6", "color": "^4.2.3", @@ -305,7 +298,6 @@ "elastic-apm-node": "^3.35.0", "email-addresses": "^5.0.0", "execa": "^4.0.2", - "exit-hook": "^2.2.0", "expiry-js": "0.1.7", "extract-zip": "^2.0.1", "fast-deep-equal": "^3.1.1", @@ -366,14 +358,12 @@ "memoize-one": "^6.0.0", "mime": "^2.4.4", "mime-types": "^2.1.27", - "mini-css-extract-plugin": "1.1.0", "minimatch": "^3.1.2", "moment": "^2.29.2", "moment-duration-format": "^2.3.2", "moment-timezone": "^0.5.27", "monaco-editor": "^0.22.3", "mustache": "^2.3.2", - "nock": "12.0.3", "node-fetch": "^2.6.7", "node-forge": "^1.3.1", "nodemailer": "^6.6.2", @@ -389,9 +379,7 @@ "pbf": "3.2.1", "pdfjs-dist": "^2.13.216", "pdfmake": "^0.2.4", - "peggy": "^1.2.0", "pluralize": "3.1.0", - "pngjs": "^3.4.0", "polished": "^3.7.2", "pretty-ms": "6.0.0", "prop-types": "^15.7.2", @@ -400,8 +388,6 @@ "puppeteer": "^10.2.0", "qs": "^6.10.5", "query-string": "^6.13.2", - "random-word-slugs": "^0.0.5", - "raw-loader": "^3.1.0", "rbush": "^3.0.1", "re-resizable": "^6.1.1", "re2": "1.17.4", @@ -470,7 +456,6 @@ "tar": "^6.1.11", "tinycolor2": "1.4.1", "tinygradient": "0.4.3", - "tree-kill": "^1.2.2", "ts-easing": "^0.2.0", "tslib": "^2.0.0", "type-detect": "^4.0.8", @@ -530,12 +515,15 @@ "@istanbuljs/schema": "^0.1.2", "@jest/console": "^26.6.2", "@jest/reporters": "^26.6.2", + "@kbn/ambient-storybook-types": "link:bazel-bin/packages/kbn-ambient-storybook-types", + "@kbn/ambient-ui-types": "link:bazel-bin/packages/kbn-ambient-ui-types", "@kbn/axe-config": "link:bazel-bin/packages/kbn-axe-config", "@kbn/babel-plugin-synthetic-packages": "link:bazel-bin/packages/kbn-babel-plugin-synthetic-packages", "@kbn/babel-preset": "link:bazel-bin/packages/kbn-babel-preset", "@kbn/bazel-packages": "link:bazel-bin/packages/kbn-bazel-packages", "@kbn/bazel-runner": "link:bazel-bin/packages/kbn-bazel-runner", "@kbn/ci-stats-core": "link:bazel-bin/packages/kbn-ci-stats-core", + "@kbn/ci-stats-performance-metrics": "link:bazel-bin/packages/kbn-ci-stats-performance-metrics", "@kbn/ci-stats-reporter": "link:bazel-bin/packages/kbn-ci-stats-reporter", "@kbn/cli-dev-mode": "link:bazel-bin/packages/kbn-cli-dev-mode", "@kbn/dev-cli-errors": "link:bazel-bin/packages/kbn-dev-cli-errors", @@ -660,8 +648,9 @@ "@types/jsdom": "^16.2.14", "@types/json-stable-stringify": "^1.0.32", "@types/json5": "^0.0.30", + "@types/jsonwebtoken": "^8.5.6", "@types/kbn__ace": "link:bazel-bin/packages/kbn-ace/npm_module_types", - "@types/kbn__aiops-utils": "link:bazel-bin/packages/kbn-aiops-utils/npm_module_types", + "@types/kbn__aiops-utils": "link:bazel-bin/x-pack/packages/ml/aiops_utils/npm_module_types", "@types/kbn__alerts": "link:bazel-bin/packages/kbn-alerts/npm_module_types", "@types/kbn__analytics": "link:bazel-bin/packages/kbn-analytics/npm_module_types", "@types/kbn__analytics-client": "link:bazel-bin/packages/analytics/client/npm_module_types", @@ -705,6 +694,9 @@ "@types/kbn__core-doc-links-server": "link:bazel-bin/packages/core/doc-links/core-doc-links-server/npm_module_types", "@types/kbn__core-doc-links-server-internal": "link:bazel-bin/packages/core/doc-links/core-doc-links-server-internal/npm_module_types", "@types/kbn__core-doc-links-server-mocks": "link:bazel-bin/packages/core/doc-links/core-doc-links-server-mocks/npm_module_types", + "@types/kbn__core-fatal-errors-browser": "link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser/npm_module_types", + "@types/kbn__core-fatal-errors-browser-internal": "link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser-internal/npm_module_types", + "@types/kbn__core-fatal-errors-browser-mocks": "link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser-mocks/npm_module_types", "@types/kbn__core-i18n-browser": "link:bazel-bin/packages/core/i18n/core-i18n-browser/npm_module_types", "@types/kbn__core-i18n-browser-internal": "link:bazel-bin/packages/core/i18n/core-i18n-browser-internal/npm_module_types", "@types/kbn__core-i18n-browser-mocks": "link:bazel-bin/packages/core/i18n/core-i18n-browser-mocks/npm_module_types", @@ -808,6 +800,7 @@ "@types/lodash": "^4.14.159", "@types/lru-cache": "^5.1.0", "@types/lz-string": "^1.3.34", + "@types/mapbox__vector-tile": "1.3.0", "@types/markdown-it": "^12.2.3", "@types/md5": "^2.2.0", "@types/micromatch": "^4.0.2", @@ -817,6 +810,7 @@ "@types/minimist": "^1.2.2", "@types/mocha": "^9.1.0", "@types/mock-fs": "^4.13.1", + "@types/moment-duration-format": "^2.2.3", "@types/moment-timezone": "^0.5.12", "@types/mustache": "^0.8.31", "@types/ncp": "^2.0.1", @@ -843,6 +837,7 @@ "@types/react-dom": "^16.9.15", "@types/react-grid-layout": "^0.16.7", "@types/react-intl": "^2.3.15", + "@types/react-is": "^16.7.2", "@types/react-redux": "^7.1.9", "@types/react-resize-detector": "^4.0.1", "@types/react-router": "^5.1.7", @@ -857,6 +852,7 @@ "@types/redux-actions": "^2.6.1", "@types/redux-logger": "^3.0.8", "@types/resolve": "^1.20.1", + "@types/rrule": "^2.2.9", "@types/seedrandom": ">=2.0.0 <4.0.0", "@types/selenium-webdriver": "^4.1.1", "@types/semver": "^7", @@ -913,6 +909,7 @@ "callsites": "^3.1.0", "chai": "3.5.0", "chance": "1.0.18", + "chokidar": "^3.4.3", "chromedriver": "^102.0.0", "clean-webpack-plugin": "^3.0.0", "cmd-shim": "^2.1.0", @@ -958,6 +955,7 @@ "eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-perf": "^3.3.0", "eslint-traverse": "^1.0.0", + "exit-hook": "^2.2.0", "expect": "^28.1.1", "expose-loader": "^0.7.5", "faker": "^5.1.0", @@ -1005,6 +1003,7 @@ "lmdb-store": "^1.6.11", "marge": "^1.0.1", "micromatch": "3.1.10", + "mini-css-extract-plugin": "1.1.0", "minimist": "^1.2.6", "mocha": "^9.1.0", "mocha-junit-reporter": "^2.0.2", @@ -1015,20 +1014,24 @@ "multimatch": "^4.0.0", "mutation-observer": "^1.0.3", "ncp": "^2.0.0", + "nock": "12.0.3", "node-sass": "6.0.1", "null-loader": "^3.0.0", "nyc": "^15.1.0", "oboe": "^2.1.4", "openapi-types": "^10.0.0", "pbf": "3.2.1", + "peggy": "^1.2.0", "pirates": "^4.0.1", "playwright": "^1.17.1", + "pngjs": "^3.4.0", "postcss": "^7.0.32", "postcss-loader": "^3.0.0", "postcss-prefix-selector": "^1.7.2", "prettier": "^2.6.2", "pretty-format": "^27.5.1", "q": "^1.5.1", + "raw-loader": "^3.1.0", "react-test-renderer": "^16.14.0", "read-pkg": "^5.2.0", "regenerate": "^1.4.0", @@ -1055,6 +1058,7 @@ "terser": "^5.7.1", "terser-webpack-plugin": "^4.2.3", "tough-cookie": "^4.0.0", + "tree-kill": "^1.2.2", "ts-loader": "^7.0.5", "ts-morph": "^13.0.2", "tsd": "^0.20.0", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 253c5cc2b4fb3..4c026c0f1f931 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -33,6 +33,9 @@ filegroup( "//packages/core/doc-links/core-doc-links-server-internal:build", "//packages/core/doc-links/core-doc-links-server-mocks:build", "//packages/core/doc-links/core-doc-links-server:build", + "//packages/core/fatal-errors/core-fatal-errors-browser-internal:build", + "//packages/core/fatal-errors/core-fatal-errors-browser-mocks:build", + "//packages/core/fatal-errors/core-fatal-errors-browser:build", "//packages/core/i18n/core-i18n-browser-internal:build", "//packages/core/i18n/core-i18n-browser-mocks:build", "//packages/core/i18n/core-i18n-browser:build", @@ -49,7 +52,6 @@ filegroup( "//packages/elastic-apm-synthtrace:build", "//packages/elastic-safer-lodash-set:build", "//packages/kbn-ace:build", - "//packages/kbn-aiops-utils:build", "//packages/kbn-alerts:build", "//packages/kbn-ambient-storybook-types:build", "//packages/kbn-ambient-ui-types:build", @@ -160,6 +162,7 @@ filegroup( "//packages/shared-ux/page/kibana_no_data:build", "//packages/shared-ux/prompt/no_data_views:build", "//x-pack/packages/ml/agg_utils:build", + "//x-pack/packages/ml/aiops_utils:build", "//x-pack/packages/ml/is_populated_object:build", "//x-pack/packages/ml/string_hash:build", ], @@ -193,6 +196,9 @@ filegroup( "//packages/core/doc-links/core-doc-links-server-internal:build_types", "//packages/core/doc-links/core-doc-links-server-mocks:build_types", "//packages/core/doc-links/core-doc-links-server:build_types", + "//packages/core/fatal-errors/core-fatal-errors-browser-internal:build_types", + "//packages/core/fatal-errors/core-fatal-errors-browser-mocks:build_types", + "//packages/core/fatal-errors/core-fatal-errors-browser:build_types", "//packages/core/i18n/core-i18n-browser-internal:build_types", "//packages/core/i18n/core-i18n-browser-mocks:build_types", "//packages/core/i18n/core-i18n-browser:build_types", @@ -209,7 +215,6 @@ filegroup( "//packages/elastic-apm-synthtrace:build_types", "//packages/elastic-safer-lodash-set:build_types", "//packages/kbn-ace:build_types", - "//packages/kbn-aiops-utils:build_types", "//packages/kbn-alerts:build_types", "//packages/kbn-analytics:build_types", "//packages/kbn-apm-config-loader:build_types", @@ -305,6 +310,7 @@ filegroup( "//packages/shared-ux/page/kibana_no_data:build_types", "//packages/shared-ux/prompt/no_data_views:build_types", "//x-pack/packages/ml/agg_utils:build_types", + "//x-pack/packages/ml/aiops_utils:build_types", "//x-pack/packages/ml/is_populated_object:build_types", "//x-pack/packages/ml/string_hash:build_types", ], diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-internal/BUILD.bazel b/packages/core/fatal-errors/core-fatal-errors-browser-internal/BUILD.bazel new file mode 100644 index 0000000000000..e79c856654b0c --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/BUILD.bazel @@ -0,0 +1,125 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-fatal-errors-browser-internal" +PKG_REQUIRE_NAME = "@kbn/core-fatal-errors-browser-internal" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + ], + exclude = [ + "**/*.test.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ + "@npm//react", + "@npm//react-dom", + "@npm//rxjs", + "@npm//@elastic/eui", + "//packages/core/theme/core-theme-browser-internal", + "//packages/core/theme/core-theme-browser-mocks", + "//packages/core/injected-metadata/core-injected-metadata-browser-mocks", + "//packages/kbn-i18n-react", + "//packages/kbn-test-jest-helpers", + "//packages/kbn-test-subj-selector", +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/react", + "@npm//@types/react-dom", + "@npm//rxjs", + "@npm//@elastic/eui", + "//packages/core/injected-metadata/core-injected-metadata-browser-internal:npm_module_types", + "//packages/core/theme/core-theme-browser:npm_module_types", + "//packages/core/theme/core-theme-browser-internal:npm_module_types", + "//packages/core/i18n/core-i18n-browser:npm_module_types", + "//packages/core/fatal-errors/core-fatal-errors-browser:npm_module_types", + "//packages/kbn-i18n-react:npm_module_types", + "//packages/kbn-test-jest-helpers", + "//packages/kbn-test-subj-selector", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + web = True, +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node", ":target_web"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-internal/README.md b/packages/core/fatal-errors/core-fatal-errors-browser-internal/README.md new file mode 100644 index 0000000000000..bc14a6611b730 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/README.md @@ -0,0 +1,3 @@ +# @kbn/core-fatal-errors-browser-internal + +This package contains the implementation and internal types of the browser-side fatalErrors service. diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-internal/jest.config.js b/packages/core/fatal-errors/core-fatal-errors-browser-internal/jest.config.js new file mode 100644 index 0000000000000..4098eeba3befd --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/jest.config.js @@ -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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + roots: ['/packages/core/fatal-errors/core-fatal-errors-browser-internal'], +}; diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-internal/package.json b/packages/core/fatal-errors/core-fatal-errors-browser-internal/package.json new file mode 100644 index 0000000000000..fc5c13485540e --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/core-fatal-errors-browser-internal", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "browser": "./target_web/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/__snapshots__/fatal_errors_screen.test.tsx.snap similarity index 100% rename from src/core/public/fatal_errors/__snapshots__/fatal_errors_screen.test.tsx.snap rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/__snapshots__/fatal_errors_screen.test.tsx.snap diff --git a/src/core/public/fatal_errors/__snapshots__/fatal_errors_service.test.ts.snap b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/__snapshots__/fatal_errors_service.test.ts.snap similarity index 100% rename from src/core/public/fatal_errors/__snapshots__/fatal_errors_service.test.ts.snap rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/__snapshots__/fatal_errors_service.test.ts.snap diff --git a/src/core/public/fatal_errors/fatal_errors_screen.test.tsx b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.test.tsx similarity index 96% rename from src/core/public/fatal_errors/fatal_errors_screen.test.tsx rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.test.tsx index b460e62b1151d..1849517c8cf3f 100644 --- a/src/core/public/fatal_errors/fatal_errors_screen.test.tsx +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.test.tsx @@ -9,7 +9,7 @@ import { EuiCallOut } from '@elastic/eui'; import testSubjSelector from '@kbn/test-subj-selector'; import React from 'react'; -import * as Rx from 'rxjs'; +import { of, ReplaySubject } from 'rxjs'; import { mountWithIntl, shallowWithIntl } from '@kbn/test-jest-helpers'; import { FatalErrorsScreen } from './fatal_errors_screen'; @@ -27,7 +27,7 @@ describe('FatalErrorsScreen', () => { const defaultProps = { buildNumber: 123, kibanaVersion: 'bar', - errorInfo$: Rx.of(errorInfoFoo, errorInfoBar), + errorInfo$: of(errorInfoFoo, errorInfoBar), }; const noop = () => { @@ -67,7 +67,7 @@ describe('FatalErrorsScreen', () => { }); it('rerenders when errorInfo$ emits more errors', () => { - const errorInfo$ = new Rx.ReplaySubject(); + const errorInfo$ = new ReplaySubject(); const el = shallowWithIntl(); diff --git a/src/core/public/fatal_errors/fatal_errors_screen.tsx b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.tsx similarity index 93% rename from src/core/public/fatal_errors/fatal_errors_screen.tsx rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.tsx index b46fdf134d0bd..6fbf6ab80aebb 100644 --- a/src/core/public/fatal_errors/fatal_errors_screen.tsx +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_screen.tsx @@ -17,17 +17,16 @@ import { EuiPageContent, } from '@elastic/eui'; import React from 'react'; -import * as Rx from 'rxjs'; -import { tap } from 'rxjs/operators'; +import { Observable, Subscription, merge, tap, fromEvent } from 'rxjs'; import { FormattedMessage } from '@kbn/i18n-react'; -import { FatalErrorInfo } from './get_error_info'; +import { FatalErrorInfo } from '@kbn/core-fatal-errors-browser'; interface Props { kibanaVersion: string; buildNumber: number; - errorInfo$: Rx.Observable; + errorInfo$: Observable; } interface State { @@ -39,12 +38,12 @@ export class FatalErrorsScreen extends React.Component { errors: [], }; - private subscription?: Rx.Subscription; + private subscription?: Subscription; public componentDidMount() { - this.subscription = Rx.merge( + this.subscription = merge( // reload the page if hash-based navigation is attempted - Rx.fromEvent(window, 'hashchange').pipe( + fromEvent(window, 'hashchange').pipe( tap(() => { window.location.reload(); }) diff --git a/src/core/public/fatal_errors/fatal_errors_service.test.mocks.ts b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_service.test.mocks.ts similarity index 100% rename from src/core/public/fatal_errors/fatal_errors_service.test.mocks.ts rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_service.test.mocks.ts diff --git a/src/core/public/fatal_errors/fatal_errors_service.test.ts b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_service.test.ts similarity index 97% rename from src/core/public/fatal_errors/fatal_errors_service.test.ts rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_service.test.ts index fe3e623b00f91..cc7da2e0eb353 100644 --- a/src/core/public/fatal_errors/fatal_errors_service.test.ts +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_service.test.ts @@ -6,10 +6,10 @@ * Side Public License, v 1. */ -import * as Rx from 'rxjs'; +import { Observable } from 'rxjs'; expect.addSnapshotSerializer({ - test: (val) => val instanceof Rx.Observable, + test: (val) => val instanceof Observable, print: () => `Rx.Observable`, }); diff --git a/src/core/public/fatal_errors/fatal_errors_service.tsx b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_service.tsx similarity index 71% rename from src/core/public/fatal_errors/fatal_errors_service.tsx rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_service.tsx index 952740c414163..cefa6e7c0ecb2 100644 --- a/src/core/public/fatal_errors/fatal_errors_service.tsx +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/fatal_errors_service.tsx @@ -8,55 +8,26 @@ import React from 'react'; import { render } from 'react-dom'; -import * as Rx from 'rxjs'; -import { first, tap } from 'rxjs/operators'; +import { ReplaySubject, first, tap } from 'rxjs'; import type { InternalInjectedMetadataSetup } from '@kbn/core-injected-metadata-browser-internal'; import type { ThemeServiceSetup } from '@kbn/core-theme-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; -import { CoreContextProvider } from '../utils'; +import type { FatalErrorInfo, FatalErrorsSetup } from '@kbn/core-fatal-errors-browser'; +import { CoreContextProvider } from '@kbn/core-theme-browser-internal'; import { FatalErrorsScreen } from './fatal_errors_screen'; -import { FatalErrorInfo, getErrorInfo } from './get_error_info'; +import { getErrorInfo } from './get_error_info'; -export interface Deps { +/** @internal */ +export interface FatalErrorsServiceSetupDeps { i18n: I18nStart; theme: ThemeServiceSetup; injectedMetadata: InternalInjectedMetadataSetup; } -/** - * FatalErrors stop the Kibana Public Core and displays a fatal error screen - * with details about the Kibana build and the error. - * - * @public - */ -export interface FatalErrorsSetup { - /** - * Add a new fatal error. This will stop the Kibana Public Core and display - * a fatal error screen with details about the Kibana build and the error. - * - * @param error - The error to display - * @param source - Adds a prefix of the form `${source}: ` to the error message - */ - add: (error: string | Error, source?: string) => never; - - /** - * An Observable that will emit whenever a fatal error is added with `add()` - */ - get$: () => Rx.Observable; -} - -/** - * FatalErrors stop the Kibana Public Core and displays a fatal error screen - * with details about the Kibana build and the error. - * - * @public - */ -export type FatalErrorsStart = FatalErrorsSetup; - /** @internal */ export class FatalErrorsService { - private readonly errorInfo$ = new Rx.ReplaySubject(); + private readonly errorInfo$ = new ReplaySubject(); private fatalErrors?: FatalErrorsSetup; /** @@ -67,7 +38,7 @@ export class FatalErrorsService { */ constructor(private rootDomElement: HTMLElement, private onFirstErrorCb: () => void) {} - public setup(deps: Deps) { + public setup(deps: FatalErrorsServiceSetupDeps) { this.errorInfo$ .pipe( first(), @@ -115,7 +86,7 @@ export class FatalErrorsService { return fatalErrors; } - private renderError({ i18n, theme, injectedMetadata }: Deps) { + private renderError({ i18n, theme, injectedMetadata }: FatalErrorsServiceSetupDeps) { // delete all content in the rootDomElement this.rootDomElement.textContent = ''; diff --git a/src/core/public/fatal_errors/get_error_info.test.ts b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/get_error_info.test.ts similarity index 100% rename from src/core/public/fatal_errors/get_error_info.test.ts rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/get_error_info.test.ts diff --git a/src/core/public/fatal_errors/get_error_info.ts b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/get_error_info.ts similarity index 92% rename from src/core/public/fatal_errors/get_error_info.ts rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/get_error_info.ts index 89ecb3f4a918f..186011b778eda 100644 --- a/src/core/public/fatal_errors/get_error_info.ts +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/get_error_info.ts @@ -7,7 +7,7 @@ */ import { inspect } from 'util'; - +import type { FatalErrorInfo } from '@kbn/core-fatal-errors-browser'; /** * Produce a string version of an error, */ @@ -63,13 +63,3 @@ export function getErrorInfo(error: any, source?: string): FatalErrorInfo { stack: formatStack(error), }; } - -/** - * Represents the `message` and `stack` of a fatal Error - * - * @public - * */ -export interface FatalErrorInfo { - message: string; - stack: string | undefined; -} diff --git a/src/core/public/fatal_errors/index.ts b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/index.ts similarity index 75% rename from src/core/public/fatal_errors/index.ts rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/src/index.ts index bb6590c691296..20bd9db4936d4 100644 --- a/src/core/public/fatal_errors/index.ts +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/src/index.ts @@ -7,5 +7,4 @@ */ export { FatalErrorsService } from './fatal_errors_service'; -export type { FatalErrorsSetup, FatalErrorsStart } from './fatal_errors_service'; -export type { FatalErrorInfo } from './get_error_info'; +export type { FatalErrorsServiceSetupDeps } from './fatal_errors_service'; diff --git a/packages/kbn-aiops-utils/tsconfig.json b/packages/core/fatal-errors/core-fatal-errors-browser-internal/tsconfig.json similarity index 84% rename from packages/kbn-aiops-utils/tsconfig.json rename to packages/core/fatal-errors/core-fatal-errors-browser-internal/tsconfig.json index e4dca2b15c9c0..dc20b641b1989 100644 --- a/packages/kbn-aiops-utils/tsconfig.json +++ b/packages/core/fatal-errors/core-fatal-errors-browser-internal/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.bazel.json", + "extends": "../../../../tsconfig.bazel.json", "compilerOptions": { "declaration": true, "emitDeclarationOnly": true, diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-mocks/BUILD.bazel b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/BUILD.bazel new file mode 100644 index 0000000000000..647682e9f5b98 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/BUILD.bazel @@ -0,0 +1,109 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-fatal-errors-browser-mocks" +PKG_REQUIRE_NAME = "@kbn/core-fatal-errors-browser-mocks" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + ], + exclude = [ + "**/*.test.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ + "@npm//react", + "//packages/core/fatal-errors/core-fatal-errors-browser-internal", +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/react", + "//packages/core/fatal-errors/core-fatal-errors-browser:npm_module_types", + "//packages/core/fatal-errors/core-fatal-errors-browser-internal:npm_module_types", + "//packages/kbn-utility-types:npm_module_types" +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + web = True, +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node", ":target_web"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-mocks/README.md b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/README.md new file mode 100644 index 0000000000000..9f532282c5535 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/README.md @@ -0,0 +1,3 @@ +# @kbn/core-fatal-errors-browser-mocks + +This package contains the mocks for Core's fatalErrors service. diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-mocks/jest.config.js b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/jest.config.js new file mode 100644 index 0000000000000..2aebfcfd4f993 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/jest.config.js @@ -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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test', + rootDir: '../../../..', + roots: ['/packages/core/fatal-errors/core-fatal-errors-browser-mocks'], +}; diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-mocks/package.json b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/package.json new file mode 100644 index 0000000000000..208ee92ee8367 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/package.json @@ -0,0 +1,8 @@ +{ + "name": "@kbn/core-fatal-errors-browser-mocks", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "browser": "./target_web/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/src/core/public/fatal_errors/fatal_errors_service.mock.ts b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/fatal_errors_service.mock.ts similarity index 88% rename from src/core/public/fatal_errors/fatal_errors_service.mock.ts rename to packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/fatal_errors_service.mock.ts index 151164000bfb3..222fb29ebc811 100644 --- a/src/core/public/fatal_errors/fatal_errors_service.mock.ts +++ b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/fatal_errors_service.mock.ts @@ -7,7 +7,8 @@ */ import type { PublicMethodsOf } from '@kbn/utility-types'; -import { FatalErrorsService, FatalErrorsSetup } from './fatal_errors_service'; +import type { FatalErrorsSetup } from '@kbn/core-fatal-errors-browser'; +import { FatalErrorsService } from '@kbn/core-fatal-errors-browser-internal'; const createSetupContractMock = () => { const setupContract: jest.Mocked = { diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/index.ts b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/index.ts new file mode 100644 index 0000000000000..a31ac652c885d --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/src/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { fatalErrorsServiceMock } from './fatal_errors_service.mock'; diff --git a/packages/core/fatal-errors/core-fatal-errors-browser-mocks/tsconfig.json b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/tsconfig.json new file mode 100644 index 0000000000000..dc20b641b1989 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser-mocks/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/core/fatal-errors/core-fatal-errors-browser/BUILD.bazel b/packages/core/fatal-errors/core-fatal-errors-browser/BUILD.bazel new file mode 100644 index 0000000000000..5cd525836c328 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser/BUILD.bazel @@ -0,0 +1,106 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "core-fatal-errors-browser" +PKG_REQUIRE_NAME = "@kbn/core-fatal-errors-browser" + +SOURCE_FILES = glob( + [ + "src/**/*.ts", + "src/**/*.tsx", + ], + exclude = [ + "**/*.test.*", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +RUNTIME_DEPS = [ + "@npm//react" +] + +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//@types/react", + "@npm//rxjs", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +jsts_transpiler( + name = "target_web", + srcs = SRCS, + build_pkg_name = package_name(), + web = True, +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + emit_declaration_only = True, + out_dir = "target_types", + root_dir = "src", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node", ":target_web"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/core/fatal-errors/core-fatal-errors-browser/README.md b/packages/core/fatal-errors/core-fatal-errors-browser/README.md new file mode 100644 index 0000000000000..a0d4ead4c4837 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser/README.md @@ -0,0 +1,3 @@ +# @kbn/core-fatal-errors-browser + +This package contains the browser public types for the fatalErrors core service. diff --git a/packages/kbn-aiops-utils/jest.config.js b/packages/core/fatal-errors/core-fatal-errors-browser/jest.config.js similarity index 79% rename from packages/kbn-aiops-utils/jest.config.js rename to packages/core/fatal-errors/core-fatal-errors-browser/jest.config.js index f3941d7831732..aef7abddb0e6e 100644 --- a/packages/kbn-aiops-utils/jest.config.js +++ b/packages/core/fatal-errors/core-fatal-errors-browser/jest.config.js @@ -8,6 +8,6 @@ module.exports = { preset: '@kbn/test', - rootDir: '../..', - roots: ['/packages/kbn-aiops-utils'], + rootDir: '../../../..', + roots: ['/packages/core/fatal-errors/core-fatal-errors-browser'], }; diff --git a/packages/kbn-aiops-utils/package.json b/packages/core/fatal-errors/core-fatal-errors-browser/package.json similarity index 79% rename from packages/kbn-aiops-utils/package.json rename to packages/core/fatal-errors/core-fatal-errors-browser/package.json index eb6ec7e802f5b..d45515d4d9f92 100644 --- a/packages/kbn-aiops-utils/package.json +++ b/packages/core/fatal-errors/core-fatal-errors-browser/package.json @@ -1,5 +1,5 @@ { - "name": "@kbn/aiops-utils", + "name": "@kbn/core-fatal-errors-browser", "private": true, "version": "1.0.0", "main": "./target_node/index.js", diff --git a/packages/core/fatal-errors/core-fatal-errors-browser/src/contract.ts b/packages/core/fatal-errors/core-fatal-errors-browser/src/contract.ts new file mode 100644 index 0000000000000..2b6bc8ee0abad --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser/src/contract.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import type { Observable } from 'rxjs'; +import type { FatalErrorInfo } from './get_error_info'; +/** + * FatalErrors stop the Kibana Public Core and displays a fatal error screen + * with details about the Kibana build and the error. + * + * @public + */ +export interface FatalErrorsSetup { + /** + * Add a new fatal error. This will stop the Kibana Public Core and display + * a fatal error screen with details about the Kibana build and the error. + * + * @param error - The error to display + * @param source - Adds a prefix of the form `${source}: ` to the error message + */ + add: (error: string | Error, source?: string) => never; + + /** + * An Observable that will emit whenever a fatal error is added with `add()` + */ + get$: () => Observable; +} + +/** + * FatalErrors stop the Kibana Public Core and displays a fatal error screen + * with details about the Kibana build and the error. + * + * @public + */ +export type FatalErrorsStart = FatalErrorsSetup; diff --git a/packages/core/fatal-errors/core-fatal-errors-browser/src/get_error_info.ts b/packages/core/fatal-errors/core-fatal-errors-browser/src/get_error_info.ts new file mode 100644 index 0000000000000..a0e0b67b24d29 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser/src/get_error_info.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * Represents the `message` and `stack` of a fatal Error + * + * @public + * */ +export interface FatalErrorInfo { + message: string; + stack: string | undefined; +} diff --git a/packages/core/fatal-errors/core-fatal-errors-browser/src/index.ts b/packages/core/fatal-errors/core-fatal-errors-browser/src/index.ts new file mode 100644 index 0000000000000..365e8ab268df8 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser/src/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export type { FatalErrorsSetup, FatalErrorsStart } from './contract'; +export type { FatalErrorInfo } from './get_error_info'; diff --git a/packages/core/fatal-errors/core-fatal-errors-browser/tsconfig.json b/packages/core/fatal-errors/core-fatal-errors-browser/tsconfig.json new file mode 100644 index 0000000000000..dc20b641b1989 --- /dev/null +++ b/packages/core/fatal-errors/core-fatal-errors-browser/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/core/theme/core-theme-browser-internal/BUILD.bazel b/packages/core/theme/core-theme-browser-internal/BUILD.bazel index e4e56b6ef38f3..4dc740ef5804d 100644 --- a/packages/core/theme/core-theme-browser-internal/BUILD.bazel +++ b/packages/core/theme/core-theme-browser-internal/BUILD.bazel @@ -46,6 +46,7 @@ TYPES_DEPS = [ "//packages/core/base/core-base-common:npm_module_types", "//packages/core/injected-metadata/core-injected-metadata-browser-internal:npm_module_types", "//packages/core/theme/core-theme-browser:npm_module_types", + "//packages/core/i18n/core-i18n-browser:npm_module_types", ] jsts_transpiler( diff --git a/src/core/public/utils/core_context_provider.tsx b/packages/core/theme/core-theme-browser-internal/src/core_context_provider.tsx similarity index 95% rename from src/core/public/utils/core_context_provider.tsx rename to packages/core/theme/core-theme-browser-internal/src/core_context_provider.tsx index a400f8eae9916..0c1f8aca9e2cc 100644 --- a/src/core/public/utils/core_context_provider.tsx +++ b/packages/core/theme/core-theme-browser-internal/src/core_context_provider.tsx @@ -8,8 +8,8 @@ import React, { FC } from 'react'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; -import { CoreThemeProvider } from '@kbn/core-theme-browser-internal'; import type { I18nStart } from '@kbn/core-i18n-browser'; +import { CoreThemeProvider } from './core_theme_provider'; interface CoreContextProviderProps { theme: ThemeServiceStart; diff --git a/packages/core/theme/core-theme-browser-internal/src/index.ts b/packages/core/theme/core-theme-browser-internal/src/index.ts index 8e698a6bc226e..48cbb5c6848d6 100644 --- a/packages/core/theme/core-theme-browser-internal/src/index.ts +++ b/packages/core/theme/core-theme-browser-internal/src/index.ts @@ -9,3 +9,4 @@ export { ThemeService } from './theme_service'; export { CoreThemeProvider } from './core_theme_provider'; export type { ThemeServiceSetupDeps } from './theme_service'; +export { CoreContextProvider } from './core_context_provider'; diff --git a/packages/kbn-aiops-utils/README.md b/packages/kbn-aiops-utils/README.md deleted file mode 100644 index 0dd5984d456ad..0000000000000 --- a/packages/kbn-aiops-utils/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# @kbn/aiops-utils - -The `aiops-utils` package contains static utilities maintained by the ML team for AIOps related efforts. diff --git a/packages/kbn-ambient-storybook-types/package.json b/packages/kbn-ambient-storybook-types/package.json index 9a29b8f60ccd1..301d28d5e585c 100644 --- a/packages/kbn-ambient-storybook-types/package.json +++ b/packages/kbn-ambient-storybook-types/package.json @@ -2,5 +2,8 @@ "name": "@kbn/ambient-storybook-types", "private": true, "version": "1.0.0", - "license": "SSPL-1.0 OR Elastic License 2.0" + "license": "SSPL-1.0 OR Elastic License 2.0", + "kibana": { + "devOnly": true + } } diff --git a/packages/kbn-ambient-ui-types/package.json b/packages/kbn-ambient-ui-types/package.json index 9ff278bf1dbe2..ddeb5082cb41f 100644 --- a/packages/kbn-ambient-ui-types/package.json +++ b/packages/kbn-ambient-ui-types/package.json @@ -2,5 +2,8 @@ "name": "@kbn/ambient-ui-types", "private": true, "version": "1.0.0", - "license": "SSPL-1.0 OR Elastic License 2.0" + "license": "SSPL-1.0 OR Elastic License 2.0", + "kibana": { + "devOnly": true + } } \ No newline at end of file diff --git a/packages/kbn-ci-stats-performance-metrics/package.json b/packages/kbn-ci-stats-performance-metrics/package.json index 0801174ab4a02..e8da3dcde3dca 100644 --- a/packages/kbn-ci-stats-performance-metrics/package.json +++ b/packages/kbn-ci-stats-performance-metrics/package.json @@ -3,5 +3,8 @@ "private": true, "version": "1.0.0", "main": "./target_node/index.js", - "license": "SSPL-1.0 OR Elastic License 2.0" + "license": "SSPL-1.0 OR Elastic License 2.0", + "kibana": { + "devOnly": true + } } diff --git a/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts b/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts index 460a695f83fca..de9e14ed650fd 100644 --- a/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts +++ b/packages/kbn-docs-utils/src/api_docs/build_api_docs_cli.ts @@ -294,6 +294,7 @@ function getTsProject(repoPath: string) { skipAddingFilesFromTsConfig: true, }); project.addSourceFilesAtPaths([`${repoPath}/x-pack/plugins/**/*.ts`, '!**/*.d.ts']); + project.addSourceFilesAtPaths([`${repoPath}/x-pack/packages/**/*.ts`, '!**/*.d.ts']); project.addSourceFilesAtPaths([`${repoPath}/src/plugins/**/*.ts`, '!**/*.d.ts']); project.addSourceFilesAtPaths([`${repoPath}/packages/**/*.ts`, '!**/*.d.ts']); project.resolveSourceFileDependencies(); diff --git a/packages/kbn-docs-utils/src/api_docs/find_plugins.ts b/packages/kbn-docs-utils/src/api_docs/find_plugins.ts index 5740d094a6894..6ba699d1466d0 100644 --- a/packages/kbn-docs-utils/src/api_docs/find_plugins.ts +++ b/packages/kbn-docs-utils/src/api_docs/find_plugins.ts @@ -35,7 +35,7 @@ export function findPlugins(): PluginOrPackage[] { */ export function findPackages(): PluginOrPackage[] { const packagePaths = globby - .sync(Path.resolve(REPO_ROOT, 'packages/**/package.json'), { absolute: true }) + .sync(Path.resolve(REPO_ROOT, '{x-pack/,}packages/**/package.json'), { absolute: true }) .map((path) => // absolute paths returned from globby are using normalize or // something so the path separators are `/` even on windows, @@ -59,6 +59,14 @@ export function findPackages(): PluginOrPackage[] { scope = ApiScope.CLIENT; } + let ownerName = '[Owner missing]'; + // Some of these author fields have "" in the name which mdx chokes on. Removing the < and > seems to work. + if (Array.isArray(manifest.author)) { + ownerName = manifest.author.map((d) => d.replace(/[<>]/gi, '')).join(', '); + } else if (typeof manifest.author === 'string') { + ownerName = manifest.author.replace(/[<>]/gi, ''); + } + acc.push({ directory: Path.dirname(path), manifestPath: path, @@ -66,8 +74,7 @@ export function findPackages(): PluginOrPackage[] { ...manifest, id: manifest.name, serviceFolders: [], - // Some of these author fields have "" in the name which mdx chokes on. Removing the < and > seems to work. - owner: { name: manifest.author?.replace(/[<>]/gi, '') || '[Owner missing]' }, + owner: { name: ownerName }, }, isPlugin: false, scope, diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index 29a396e371b9d..484f21d3eaac7 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -27,7 +27,7 @@ pageLoadAssetSize: indexLifecycleManagement: 107090 indexManagement: 140608 infra: 184320 - fleet: 100000 + fleet: 126917 ingestPipelines: 58003 inputControlVis: 172675 inspector: 148711 diff --git a/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts b/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts index a0d9c8f63595a..d115b2f3bbabd 100644 --- a/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts +++ b/packages/kbn-performance-testing-dataset-extractor/src/es_client.ts @@ -114,6 +114,7 @@ export function initClient(options: ClientOptions) { { field: 'processor.event', value: 'transaction' }, { field: 'labels.testBuildId', value: buildId }, { field: 'labels.journeyName', value: journeyName }, + { field: 'labels.performancePhase', value: 'TEST' }, ]; const queryFilters = filters.map((filter) => addBooleanFilter(filter)); return await this.getTransactions(queryFilters); @@ -125,7 +126,7 @@ export function initClient(options: ClientOptions) { sort: [ { '@timestamp': { - order: 'desc', + order: 'asc', unmapped_type: 'boolean', }, }, diff --git a/src/core/public/core_system.test.mocks.ts b/src/core/public/core_system.test.mocks.ts index 25bbe39ddcc25..9899e6c345ab8 100644 --- a/src/core/public/core_system.test.mocks.ts +++ b/src/core/public/core_system.test.mocks.ts @@ -12,7 +12,7 @@ import { themeServiceMock } from '@kbn/core-theme-browser-mocks'; import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; import { applicationServiceMock } from './application/application_service.mock'; import { chromeServiceMock } from './chrome/chrome_service.mock'; -import { fatalErrorsServiceMock } from './fatal_errors/fatal_errors_service.mock'; +import { fatalErrorsServiceMock } from '@kbn/core-fatal-errors-browser-mocks'; import { httpServiceMock } from './http/http_service.mock'; import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; import { notificationServiceMock } from './notifications/notifications_service.mock'; @@ -48,7 +48,7 @@ export const MockFatalErrorsService = fatalErrorsServiceMock.create(); export const FatalErrorsServiceConstructor = jest .fn() .mockImplementation(() => MockFatalErrorsService); -jest.doMock('./fatal_errors', () => ({ +jest.doMock('@kbn/core-fatal-errors-browser-internal', () => ({ FatalErrorsService: FatalErrorsServiceConstructor, })); diff --git a/src/core/public/core_system.ts b/src/core/public/core_system.ts index bdf94d953b659..1dbb16b274ff4 100644 --- a/src/core/public/core_system.ts +++ b/src/core/public/core_system.ts @@ -18,9 +18,10 @@ import { ThemeService } from '@kbn/core-theme-browser-internal'; import type { AnalyticsServiceSetup, AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import { AnalyticsService } from '@kbn/core-analytics-browser-internal'; import { I18nService } from '@kbn/core-i18n-browser-internal'; +import type { FatalErrorsSetup } from '@kbn/core-fatal-errors-browser'; +import { FatalErrorsService } from '@kbn/core-fatal-errors-browser-internal'; import { CoreSetup, CoreStart } from '.'; import { ChromeService } from './chrome'; -import { FatalErrorsService, FatalErrorsSetup } from './fatal_errors'; import { HttpService } from './http'; import { NotificationsService } from './notifications'; import { OverlayService } from './overlays'; diff --git a/src/core/public/http/http_service.test.ts b/src/core/public/http/http_service.test.ts index af6e2343d5f8a..0a844dfe2f4be 100644 --- a/src/core/public/http/http_service.test.ts +++ b/src/core/public/http/http_service.test.ts @@ -10,7 +10,7 @@ import fetchMock from 'fetch-mock/es5/client'; import { loadingServiceMock } from './http_service.test.mocks'; -import { fatalErrorsServiceMock } from '../fatal_errors/fatal_errors_service.mock'; +import { fatalErrorsServiceMock } from '@kbn/core-fatal-errors-browser-mocks'; import { injectedMetadataServiceMock } from '@kbn/core-injected-metadata-browser-mocks'; import { HttpService } from './http_service'; import { Observable } from 'rxjs'; diff --git a/src/core/public/http/http_service.ts b/src/core/public/http/http_service.ts index 4507b808e5a4a..57e5bc7ef2d75 100644 --- a/src/core/public/http/http_service.ts +++ b/src/core/public/http/http_service.ts @@ -8,8 +8,8 @@ import type { CoreService } from '@kbn/core-base-browser-internal'; import type { InternalInjectedMetadataSetup } from '@kbn/core-injected-metadata-browser-internal'; +import type { FatalErrorsSetup } from '@kbn/core-fatal-errors-browser'; import { HttpSetup, HttpStart } from './types'; -import { FatalErrorsSetup } from '../fatal_errors'; import { BasePath } from './base_path'; import { AnonymousPathsService } from './anonymous_paths_service'; import { LoadingCountService } from './loading_count_service'; diff --git a/src/core/public/http/loading_count_service.test.ts b/src/core/public/http/loading_count_service.test.ts index e933e93b4bde2..041af203c8b37 100644 --- a/src/core/public/http/loading_count_service.test.ts +++ b/src/core/public/http/loading_count_service.test.ts @@ -9,7 +9,7 @@ import { Observable, throwError, of, Subject } from 'rxjs'; import { toArray } from 'rxjs/operators'; -import { fatalErrorsServiceMock } from '../fatal_errors/fatal_errors_service.mock'; +import { fatalErrorsServiceMock } from '@kbn/core-fatal-errors-browser-mocks'; import { LoadingCountService } from './loading_count_service'; describe('LoadingCountService', () => { diff --git a/src/core/public/http/loading_count_service.ts b/src/core/public/http/loading_count_service.ts index c2ae7433b82c4..4df60e53f9c66 100644 --- a/src/core/public/http/loading_count_service.ts +++ b/src/core/public/http/loading_count_service.ts @@ -17,7 +17,7 @@ import { tap, } from 'rxjs/operators'; import type { CoreService } from '@kbn/core-base-browser-internal'; -import { FatalErrorsSetup } from '../fatal_errors'; +import type { FatalErrorsSetup } from '@kbn/core-fatal-errors-browser'; /** @public */ export interface LoadingCountSetup { diff --git a/src/core/public/index.ts b/src/core/public/index.ts index 5162cdac1024d..e16aa3ec174c1 100644 --- a/src/core/public/index.ts +++ b/src/core/public/index.ts @@ -35,6 +35,11 @@ import type { ThemeServiceSetup, ThemeServiceStart } from '@kbn/core-theme-brows import type { AnalyticsServiceSetup, AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; +import type { + FatalErrorsSetup, + FatalErrorsStart, + FatalErrorInfo, +} from '@kbn/core-fatal-errors-browser'; import { ChromeBadge, ChromeBreadcrumb, @@ -57,7 +62,6 @@ import { NavType, ChromeHelpMenuActions, } from './chrome'; -import { FatalErrorsSetup, FatalErrorsStart, FatalErrorInfo } from './fatal_errors'; import { HttpSetup, HttpStart } from './http'; import { NotificationsSetup, NotificationsStart } from './notifications'; import { OverlayStart } from './overlays'; diff --git a/src/core/public/kbn_bootstrap.test.mocks.ts b/src/core/public/kbn_bootstrap.test.mocks.ts index b1b48b1a21ab8..0e3a9ca95d35a 100644 --- a/src/core/public/kbn_bootstrap.test.mocks.ts +++ b/src/core/public/kbn_bootstrap.test.mocks.ts @@ -7,7 +7,7 @@ */ import { applicationServiceMock } from './application/application_service.mock'; -import { fatalErrorsServiceMock } from './fatal_errors/fatal_errors_service.mock'; +import { fatalErrorsServiceMock } from '@kbn/core-fatal-errors-browser-mocks'; export const fatalErrorMock = fatalErrorsServiceMock.createSetupContract(); export const coreSystemMock = { setup: jest.fn().mockResolvedValue({ diff --git a/src/core/public/mocks.ts b/src/core/public/mocks.ts index 3a1f03f5ea782..c905526fc257f 100644 --- a/src/core/public/mocks.ts +++ b/src/core/public/mocks.ts @@ -15,12 +15,12 @@ import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; // Only import types from '.' to avoid triggering default Jest mocks. import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; +import { fatalErrorsServiceMock } from '@kbn/core-fatal-errors-browser-mocks'; import { PluginInitializerContext, AppMountParameters } from '.'; // Import values from their individual modules instead. import { ScopedHistory } from './application'; import { applicationServiceMock } from './application/application_service.mock'; import { chromeServiceMock } from './chrome/chrome_service.mock'; -import { fatalErrorsServiceMock } from './fatal_errors/fatal_errors_service.mock'; import { httpServiceMock } from './http/http_service.mock'; import { notificationServiceMock } from './notifications/notifications_service.mock'; import { overlayServiceMock } from './overlays/overlay_service.mock'; @@ -35,7 +35,7 @@ export { themeServiceMock } from '@kbn/core-theme-browser-mocks'; export { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; export { chromeServiceMock } from './chrome/chrome_service.mock'; export { executionContextServiceMock } from './execution_context/execution_context_service.mock'; -export { fatalErrorsServiceMock } from './fatal_errors/fatal_errors_service.mock'; +export { fatalErrorsServiceMock } from '@kbn/core-fatal-errors-browser-mocks'; export { httpServiceMock } from './http/http_service.mock'; export { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; export { notificationServiceMock } from './notifications/notifications_service.mock'; diff --git a/src/core/public/notifications/toasts/toasts_service.tsx b/src/core/public/notifications/toasts/toasts_service.tsx index 045da1fc24d02..63edd56085797 100644 --- a/src/core/public/notifications/toasts/toasts_service.tsx +++ b/src/core/public/notifications/toasts/toasts_service.tsx @@ -11,11 +11,11 @@ import { render, unmountComponentAtNode } from 'react-dom'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; +import { CoreContextProvider } from '@kbn/core-theme-browser-internal'; import { IUiSettingsClient } from '../../ui_settings'; import { GlobalToastList } from './global_toast_list'; import { ToastsApi, IToasts } from './toasts_api'; import { OverlayStart } from '../../overlays'; -import { CoreContextProvider } from '../../utils'; interface SetupDeps { uiSettings: IUiSettingsClient; diff --git a/src/core/public/overlays/flyout/flyout_service.tsx b/src/core/public/overlays/flyout/flyout_service.tsx index 701915113bb5a..186517890412d 100644 --- a/src/core/public/overlays/flyout/flyout_service.tsx +++ b/src/core/public/overlays/flyout/flyout_service.tsx @@ -14,9 +14,10 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { Subject } from 'rxjs'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; +import { CoreContextProvider } from '@kbn/core-theme-browser-internal'; import { MountPoint } from '../../types'; import { OverlayRef } from '../types'; -import { MountWrapper, CoreContextProvider } from '../../utils'; +import { MountWrapper } from '../../utils'; /** * A FlyoutRef is a reference to an opened flyout panel. It offers methods to diff --git a/src/core/public/overlays/modal/modal_service.tsx b/src/core/public/overlays/modal/modal_service.tsx index 0195fb2b5bf1f..5645ed5c2b8a1 100644 --- a/src/core/public/overlays/modal/modal_service.tsx +++ b/src/core/public/overlays/modal/modal_service.tsx @@ -15,9 +15,10 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { Subject } from 'rxjs'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; +import { CoreContextProvider } from '@kbn/core-theme-browser-internal'; import { MountPoint } from '../../types'; import { OverlayRef } from '../types'; -import { MountWrapper, CoreContextProvider } from '../../utils'; +import { MountWrapper } from '../../utils'; /** * A ModalRef is a reference to an opened modal. It offers methods to diff --git a/src/core/public/plugins/plugins_service.test.ts b/src/core/public/plugins/plugins_service.test.ts index b3d0ab8f295a5..98320dda7a3ae 100644 --- a/src/core/public/plugins/plugins_service.test.ts +++ b/src/core/public/plugins/plugins_service.test.ts @@ -30,7 +30,7 @@ import { applicationServiceMock } from '../application/application_service.mock' import { i18nServiceMock } from '@kbn/core-i18n-browser-mocks'; import { overlayServiceMock } from '../overlays/overlay_service.mock'; import { chromeServiceMock } from '../chrome/chrome_service.mock'; -import { fatalErrorsServiceMock } from '../fatal_errors/fatal_errors_service.mock'; +import { fatalErrorsServiceMock } from '@kbn/core-fatal-errors-browser-mocks'; import { uiSettingsServiceMock } from '../ui_settings/ui_settings_service.mock'; import { injectedMetadataServiceMock } from '@kbn/core-injected-metadata-browser-mocks'; import { httpServiceMock } from '../http/http_service.mock'; diff --git a/src/core/public/rendering/rendering_service.tsx b/src/core/public/rendering/rendering_service.tsx index 48031db64897a..1a656877d924a 100644 --- a/src/core/public/rendering/rendering_service.tsx +++ b/src/core/public/rendering/rendering_service.tsx @@ -12,10 +12,10 @@ import { pairwise, startWith } from 'rxjs/operators'; import type { ThemeServiceStart } from '@kbn/core-theme-browser'; import type { I18nStart } from '@kbn/core-i18n-browser'; +import { CoreContextProvider } from '@kbn/core-theme-browser-internal'; import type { InternalChromeStart } from '../chrome'; import type { InternalApplicationStart } from '../application'; import type { OverlayStart } from '../overlays'; -import { CoreContextProvider } from '../utils'; import { AppWrapper } from './app_containers'; export interface StartDeps { diff --git a/src/core/public/utils/index.ts b/src/core/public/utils/index.ts index 4fb9c50f715c6..812862c499dab 100644 --- a/src/core/public/utils/index.ts +++ b/src/core/public/utils/index.ts @@ -8,5 +8,4 @@ export { Sha256 } from './crypto'; export { MountWrapper, mountReactNode } from './mount'; -export { CoreContextProvider } from './core_context_provider'; export { KBN_LOAD_MARKS } from './consts'; diff --git a/src/core/server/saved_objects/migrations/integration_tests/type_registrations.test.ts b/src/core/server/saved_objects/migrations/integration_tests/type_registrations.test.ts index c50d29ba521e7..d24da636b7dd3 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/type_registrations.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/type_registrations.test.ts @@ -59,6 +59,7 @@ const previouslyRegisteredTypes = [ 'infrastructure-monitoring-log-view', 'infrastructure-ui-source', 'ingest-agent-policies', + 'ingest-download-sources', 'ingest-outputs', 'ingest-package-policies', 'ingest_manager_settings', diff --git a/src/core/test_helpers/http_test_setup.ts b/src/core/test_helpers/http_test_setup.ts index 2a7d6451319cb..6adc0be8b744d 100644 --- a/src/core/test_helpers/http_test_setup.ts +++ b/src/core/test_helpers/http_test_setup.ts @@ -7,8 +7,8 @@ */ import { injectedMetadataServiceMock } from '@kbn/core-injected-metadata-browser-mocks'; +import { fatalErrorsServiceMock } from '@kbn/core-fatal-errors-browser-mocks'; import { HttpService } from '../public/http'; -import { fatalErrorsServiceMock } from '../public/fatal_errors/fatal_errors_service.mock'; import { executionContextServiceMock } from '../public/execution_context/execution_context_service.mock'; export type SetupTap = ( diff --git a/src/plugins/console/public/application/models/legacy_core_editor/legacy_core_editor.ts b/src/plugins/console/public/application/models/legacy_core_editor/legacy_core_editor.ts index f13597e933bb2..8ee5781bf852f 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/legacy_core_editor.ts +++ b/src/plugins/console/public/application/models/legacy_core_editor/legacy_core_editor.ts @@ -414,4 +414,48 @@ export class LegacyCoreEditor implements CoreEditor { destroy() { this.editor.destroy(); } + + /** + * Formats body of the request in the editor by removing the extra whitespaces at the beginning of lines, + * And adds the correct indentation for each line + * @param reqRange request range to indent + */ + autoIndent(reqRange: Range) { + const session = this.editor.getSession(); + const mode = session.getMode(); + const startRow = reqRange.start.lineNumber; + const endRow = reqRange.end.lineNumber; + const tab = session.getTabString(); + + for (let row = startRow; row <= endRow; row++) { + let prevLineState = ''; + let prevLineIndent = ''; + if (row > 0) { + prevLineState = session.getState(row - 1); + const prevLine = session.getLine(row - 1); + prevLineIndent = mode.getNextLineIndent(prevLineState, prevLine, tab); + } + + const line = session.getLine(row); + // @ts-ignore + // Brace does not expose type definition for mode.$getIndent, though we have access to this method provided by the underlying Ace editor. + // See https://github.com/ajaxorg/ace/blob/87ce087ed1cf20eeabe56fb0894e048d9bc9c481/lib/ace/mode/text.js#L259 + const currLineIndent = mode.$getIndent(line); + if (prevLineIndent !== currLineIndent) { + if (currLineIndent.length > 0) { + // If current line has indentation, remove it. + // Next we will add the correct indentation by looking at the previous line + const range = new _AceRange(row, 0, row, currLineIndent.length); + session.remove(range); + } + if (prevLineIndent.length > 0) { + // If previous line has indentation, add indentation at the current line + session.insert({ row, column: 0 }, prevLineIndent); + } + } + + // Lastly outdent any closing braces + mode.autoOutdent(prevLineState, session, row); + } + } } diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/input_highlight_rules.js b/src/plugins/console/public/application/models/legacy_core_editor/mode/input_highlight_rules.js index ffbfa264a77b8..6c188eca0f0cc 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/input_highlight_rules.js +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/input_highlight_rules.js @@ -39,7 +39,7 @@ export function InputHighlightRules() { start: mergeTokens( [ { token: 'warning', regex: '#!.*$' }, - { token: 'comment', regex: /^#.*$/ }, + { include: 'comments' }, { token: 'paren.lparen', regex: '{', next: 'json', push: true }, ], addEOL(['method'], /([a-zA-Z]+)/, 'start', 'method_sep'), @@ -88,9 +88,46 @@ export function InputHighlightRules() { addEOL(['url.param'], /([^&=]+)/, 'start-sql'), addEOL(['url.amp'], /(&)/, 'start-sql') ), + /** + * Each key in this.$rules considered to be a state in state machine. Regular expressions define the tokens for the current state, as well as the transitions into another state. + * See for more details https://cloud9-sdk.readme.io/docs/highlighting-rules#section-defining-states + * * + * Define a state for comments, these comment rules then can be included in other states. E.g. in 'start' and 'json' states by including { include: 'comments' } + * This will avoid duplicating the same rules in other states + */ + comments: [ + { + // Capture a line comment, indicated by # + token: ['comment.punctuation', 'comment.line'], + regex: /(#)(.*$)/, + }, + { + // Begin capturing a block comment, indicated by /* + token: 'comment.punctuation', + regex: /\/\*/, + push: [ + { + // Finish capturing a block comment, indicated by */ + token: 'comment.punctuation', + regex: /\*\//, + next: 'pop', + }, + { + defaultToken: 'comment.block', + }, + ], + }, + { + // Capture a line comment, indicated by // + token: ['comment.punctuation', 'comment.line'], + regex: /(\/\/)(.*$)/, + }, + ], }; addXJsonToRules(this); + // Add comment rules to json rule set + this.$rules.json.unshift({ include: 'comments' }); if (this.constructor === InputHighlightRules) { this.normalizeRules(); diff --git a/src/plugins/console/public/application/models/legacy_core_editor/mode/worker/worker.js b/src/plugins/console/public/application/models/legacy_core_editor/mode/worker/worker.js index efd7dbd088581..a570f97ced0a3 100644 --- a/src/plugins/console/public/application/models/legacy_core_editor/mode/worker/worker.js +++ b/src/plugins/console/public/application/models/legacy_core_editor/mode/worker/worker.js @@ -1901,8 +1901,8 @@ ace.define( reset(i + upTo.length); return text.substring(currentAt, i); }, - peek = function (c) { - return text.substr(at, c.length) === c; // nocommit - double check + peek = function (offset) { + return text.charAt(at + offset); }, number = function () { let number, @@ -1948,7 +1948,8 @@ ace.define( uffff; if (ch === '"') { - if (peek('""')) { + let c = '""'; + if (text.substring(at, c.length) === c) { // literal next('"'); next('"'); @@ -1984,8 +1985,31 @@ ace.define( error('Bad string'); }, white = function () { - while (ch && ch <= ' ') { - next(); + while (ch) { + // Skip whitespace. + while (ch && ch <= ' ') { + next(); + } + // if the current char in iteration is '#' or the char and the next char is equal to '//' + // we are on the single line comment + if (ch === '#' || ch === '/' && peek(0) === '/') { + // Until we are on the new line, skip to the next char + while (ch && ch !== '\n') { + next(); + } + } else if (ch === '/' && peek(0) === '*') { + // If the chars starts with '/*', we are on the multiline comment + next(); + next(); + while (ch && !(ch === '*' && peek(0) === '/')) { + // Until we have closing tags '*/', skip to the next char + next(); + } + if (ch) { + next(); + next(); + } + } else break; } }, strictWhite = function () { diff --git a/src/plugins/console/public/application/models/sense_editor/sense_editor.ts b/src/plugins/console/public/application/models/sense_editor/sense_editor.ts index ac65afce2c18a..37c3799c05119 100644 --- a/src/plugins/console/public/application/models/sense_editor/sense_editor.ts +++ b/src/plugins/console/public/application/models/sense_editor/sense_editor.ts @@ -96,6 +96,15 @@ export class SenseEditor { return; } + if (parsedReq.data.some((doc) => utils.hasComments(doc))) { + /** + * Comments require different approach for indentation and do not have condensed format + * We need to delegate indentation logic to coreEditor since it has access to session and other methods used for formatting and indenting the comments + */ + this.coreEditor.autoIndent(parsedReq.range); + return; + } + if (parsedReq.data && parsedReq.data.length > 0) { let indent = parsedReq.data.length === 1; // unindent multi docs by default let formattedData = utils.formatRequestBodyDoc(parsedReq.data, indent); diff --git a/src/plugins/console/public/lib/autocomplete/autocomplete.ts b/src/plugins/console/public/lib/autocomplete/autocomplete.ts index 3e59c4e6bb023..21c1acf73bfd5 100644 --- a/src/plugins/console/public/lib/autocomplete/autocomplete.ts +++ b/src/plugins/console/public/lib/autocomplete/autocomplete.ts @@ -1104,6 +1104,9 @@ export default function ({ case 'paren.rparen': case 'punctuation.colon': case 'punctuation.comma': + case 'comment.line': + case 'comment.punctuation': + case 'comment.block': case 'UNKNOWN': return; } diff --git a/src/plugins/console/public/lib/row_parser.ts b/src/plugins/console/public/lib/row_parser.ts index e18bf6ac6446b..5faca5ffc4a7d 100644 --- a/src/plugins/console/public/lib/row_parser.ts +++ b/src/plugins/console/public/lib/row_parser.ts @@ -40,7 +40,7 @@ export default class RowParser { return MODE.IN_REQUEST; } let line = (this.editor.getLineValue(lineNumber) || '').trim(); - if (!line || line[0] === '#') { + if (!line || line.startsWith('#') || line.startsWith('//') || line.startsWith('/*')) { return MODE.BETWEEN_REQUESTS; } // empty line or a comment waiting for a new req to start diff --git a/src/plugins/console/public/lib/utils/index.ts b/src/plugins/console/public/lib/utils/index.ts index 3e6eb4a93f1f5..02d4023282cb2 100644 --- a/src/plugins/console/public/lib/utils/index.ts +++ b/src/plugins/console/public/lib/utils/index.ts @@ -48,6 +48,12 @@ export function formatRequestBodyDoc(data: string[], indent: boolean) { }; } +export function hasComments(data: string) { + // matches single line and multiline comments + const re = /(\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\/)|(\/\/.*)|(#.*)/; + return re.test(data); +} + export function extractWarningMessages(warnings: string) { // pattern for valid warning header const re = diff --git a/src/plugins/console/public/lib/utils/utils.test.js b/src/plugins/console/public/lib/utils/utils.test.js index d7fc690e1bc24..738aa5b9bf5c3 100644 --- a/src/plugins/console/public/lib/utils/utils.test.js +++ b/src/plugins/console/public/lib/utils/utils.test.js @@ -82,4 +82,95 @@ describe('Utils class', () => { 'e", f"', ]); }); + + describe('formatRequestBodyDoc', function () { + const tests = [ + { + source: ['{\n "test": {}\n}'], + indent: false, + assert: ['{"test":{}}'], + }, + { + source: ['{"test":{}}'], + indent: true, + assert: ['{\n "test": {}\n}'], + }, + { + source: ['{\n "test": """a\n b"""\n}'], + indent: false, + assert: ['{"test":"a\\n b"}'], + }, + { + source: ['{"test":"a\\n b"}'], + indent: true, + assert: ['{\n "test": """a\n b"""\n}'], + }, + ]; + + tests.forEach(({ source, indent, assert }, id) => { + test(`Test ${id}`, () => { + const formattedData = utils.formatRequestBodyDoc(source, indent); + expect(formattedData.data).toEqual(assert); + }); + }); + }); + + describe('hasComments', function () { + const runCommentTests = (tests) => { + tests.forEach(({ source, assert }) => { + test(`\n${source}`, () => { + const hasComments = utils.hasComments(source); + expect(hasComments).toEqual(assert); + }); + }); + }; + + describe('match single line comments', () => { + runCommentTests([ + { source: '{\n "test": {\n // "f": {}\n "a": "b"\n }\n}', assert: true }, + { + source: '{\n "test": {\n "a": "b",\n "f": {\n # "b": {}\n }\n }\n}', + assert: true, + }, + ]); + }); + + describe('match multiline comments', () => { + runCommentTests([ + { source: '{\n /* "test": {\n "a": "b"\n } */\n}', assert: true }, + { + source: + '{\n "test": {\n "a": "b",\n /* "f": {\n "b": {}\n } */\n "c": 1\n }\n}', + assert: true, + }, + ]); + }); + + describe('ignore non-comment tokens', () => { + runCommentTests([ + { source: '{"test":{"a":"b","f":{"b":{"c":{}}}}}', assert: false }, + { + source: '{\n "test": {\n "a": "b",\n "f": {\n "b": {}\n }\n }\n}', + assert: false, + }, + { source: '{\n "test": {\n "f": {}\n }\n}', assert: false }, + ]); + }); + + describe.skip('ignore comment tokens as values', () => { + runCommentTests([ + { source: '{\n "test": {\n "f": "//"\n }\n}', assert: false }, + { source: '{\n "test": {\n "f": "/* */"\n }\n}', assert: false }, + { source: '{\n "test": {\n "f": "#"\n }\n}', assert: false }, + ]); + }); + + describe.skip('ignore comment tokens as field names', () => { + runCommentTests([ + { source: '{\n "#": {\n "f": {}\n }\n}', assert: false }, + { source: '{\n "//": {\n "f": {}\n }\n}', assert: false }, + { source: '{\n "/* */": {\n "f": {}\n }\n}', assert: false }, + ]); + }); + }); }); diff --git a/src/plugins/console/public/types/core_editor.ts b/src/plugins/console/public/types/core_editor.ts index db8010afe762b..700b805aaecc0 100644 --- a/src/plugins/console/public/types/core_editor.ts +++ b/src/plugins/console/public/types/core_editor.ts @@ -272,4 +272,9 @@ export interface CoreEditor { * Release any resources in use by the editor. */ destroy(): void; + + /** + * Indent document within request range + */ + autoIndent(reqRange: Range): void; } diff --git a/src/plugins/data_views/common/data_views/data_view.ts b/src/plugins/data_views/common/data_views/data_view.ts index 91ae12c2b3c1c..d6af0850c8f59 100644 --- a/src/plugins/data_views/common/data_views/data_view.ts +++ b/src/plugins/data_views/common/data_views/data_view.ts @@ -265,6 +265,10 @@ export class DataView implements DataViewBase { }; } + isPersisted() { + return typeof this.version === 'string'; + } + /** * Creates static representation of the data view. */ diff --git a/src/plugins/data_views/common/data_views/data_views.test.ts b/src/plugins/data_views/common/data_views/data_views.test.ts index 9e419e0903606..d374253347b55 100644 --- a/src/plugins/data_views/common/data_views/data_views.test.ts +++ b/src/plugins/data_views/common/data_views/data_views.test.ts @@ -103,6 +103,7 @@ describe('IndexPatterns', () => { onError: () => {}, onRedirectNoIndexPattern: () => {}, getCanSave: () => Promise.resolve(true), + getCanSaveAdvancedSettings: () => Promise.resolve(true), }); indexPatternsNoAccess = new DataViewsService({ @@ -114,6 +115,7 @@ describe('IndexPatterns', () => { onError: () => {}, onRedirectNoIndexPattern: () => {}, getCanSave: () => Promise.resolve(false), + getCanSaveAdvancedSettings: () => Promise.resolve(false), }); }); @@ -235,6 +237,31 @@ describe('IndexPatterns', () => { await indexPatterns.create({ title }); expect(indexPatterns.refreshFields).toBeCalled(); + expect(indexPattern.id).toBeDefined(); + expect(indexPattern.isPersisted()).toBe(false); + }); + + test('createSavedObject', async () => { + const title = 'kibana-*'; + const version = '8.4.0'; + const dataView = await indexPatterns.create({ title }, true); + + savedObjectsClient.find = jest.fn().mockResolvedValue([]); + savedObjectsClient.create = jest.fn().mockResolvedValue({ + ...savedObject, + id: dataView.id, + version, + attributes: { + ...savedObject.attributes, + title: dataView.title, + }, + }); + + const indexPattern = await indexPatterns.createSavedObject(dataView); + expect(indexPattern).toBeInstanceOf(DataView); + expect(indexPattern.id).toBe(dataView.id); + expect(indexPattern.title).toBe(title); + expect(indexPattern.isPersisted()).toBe(true); }); test('find', async () => { @@ -413,5 +440,30 @@ describe('IndexPatterns', () => { expect(uiSettings.remove).toBeCalledTimes(0); expect(uiSettings.set).toBeCalledTimes(1); }); + test('dont set defaultIndex without capability allowing advancedSettings save', async () => { + savedObjectsClient.find = jest.fn().mockResolvedValue([ + { + id: 'id1', + version: 'a', + attributes: { title: '1' }, + }, + { + id: 'id2', + version: 'a', + attributes: { title: '2' }, + }, + ]); + + savedObjectsClient.get = jest + .fn() + .mockImplementation((type: string, id: string) => + Promise.resolve({ id, version: 'a', attributes: { title: '1' } }) + ); + + const defaultDataViewResult = await indexPatternsNoAccess.getDefaultDataView(); + expect(defaultDataViewResult).toBeInstanceOf(DataView); + expect(defaultDataViewResult?.id).toBe('id1'); + expect(uiSettings.set).toBeCalledTimes(0); + }); }); }); diff --git a/src/plugins/data_views/common/data_views/data_views.ts b/src/plugins/data_views/common/data_views/data_views.ts index 021b457c890ed..3ffb326cd4611 100644 --- a/src/plugins/data_views/common/data_views/data_views.ts +++ b/src/plugins/data_views/common/data_views/data_views.ts @@ -11,6 +11,7 @@ import { PublicMethodsOf } from '@kbn/utility-types'; import { castEsToKbnFieldTypeName } from '@kbn/field-types'; import { FieldFormatsStartCommon, FORMATS_UI_SETTINGS } from '@kbn/field-formats-plugin/common'; import { SavedObjectNotFound } from '@kbn/kibana-utils-plugin/common'; +import uuid from 'uuid'; import { DATA_VIEW_SAVED_OBJECT_TYPE, DEFAULT_ASSETS_TO_IGNORE } from '..'; import { SavedObjectsClientCommon } from '../types'; @@ -52,7 +53,7 @@ export type IndexPatternListSavedObjectAttrs = Pick< */ export interface DataViewListItem { /** - * Saved object id + * Saved object id (or generated id if in-memory only) */ id: string; /** @@ -95,7 +96,7 @@ export interface DataViewsServiceDeps { */ fieldFormats: FieldFormatsStartCommon; /** - * Hander for service notifications + * Handler for service notifications */ onNotification: OnNotification; /** @@ -110,6 +111,10 @@ export interface DataViewsServiceDeps { * Determines whether the user can save data views */ getCanSave: () => Promise; + /** + * Determines whether the user can save advancedSettings (used for defaultIndex) + */ + getCanSaveAdvancedSettings: () => Promise; } /** @@ -274,11 +279,14 @@ export class DataViewsService { */ private onError: OnError; private dataViewCache: ReturnType; + /** + * Can the user save advanced settings? + */ + private getCanSaveAdvancedSettings: () => Promise; /** * Can the user save data views? */ public getCanSave: () => Promise; - /** * DataViewsService constructor * @param deps Service dependencies @@ -292,6 +300,7 @@ export class DataViewsService { onNotification, onError, getCanSave = () => Promise.resolve(false), + getCanSaveAdvancedSettings, } = deps; this.apiClient = apiClient; this.config = uiSettings; @@ -300,6 +309,7 @@ export class DataViewsService { this.onNotification = onNotification; this.onError = onError; this.getCanSave = getCanSave; + this.getCanSaveAdvancedSettings = getCanSaveAdvancedSettings; this.dataViewCache = createDataViewCache(); } @@ -762,10 +772,15 @@ export class DataViewsService { * @param skipFetchFields if true, will not fetch fields * @returns DataView */ - async create(spec: DataViewSpec, skipFetchFields = false): Promise { + async create({ id, ...restOfSpec }: DataViewSpec, skipFetchFields = false): Promise { const shortDotsEnable = await this.config.get(FORMATS_UI_SETTINGS.SHORT_DOTS_ENABLE); const metaFields = await this.config.get(META_FIELDS); + const spec = { + id: id ?? uuid.v4(), + ...restOfSpec, + }; + const indexPattern = new DataView({ spec, fieldFormats: this.fieldFormats, @@ -831,9 +846,10 @@ export class DataViewsService { } /** - * Save existing dat aview. Will attempt to merge differences if there are conflicts. + * Save existing data view. Will attempt to merge differences if there are conflicts. * @param indexPattern * @param saveAttempts + * @param ignoreErrors */ async updateSavedObject( @@ -953,7 +969,10 @@ export class DataViewsService { const exists = defaultId ? patterns.some((pattern) => pattern.id === defaultId) : false; if (defaultId && !exists) { - await this.config.remove('defaultIndex'); + if (await this.getCanSaveAdvancedSettings()) { + await this.config.remove('defaultIndex'); + } + defaultId = undefined; } @@ -967,7 +986,9 @@ export class DataViewsService { ); defaultId = userDataViews[0]?.id ?? patterns[0].id; - await this.config.set('defaultIndex', defaultId); + if (await this.getCanSaveAdvancedSettings()) { + await this.config.set('defaultIndex', defaultId); + } } if (defaultId) { diff --git a/src/plugins/data_views/common/types.ts b/src/plugins/data_views/common/types.ts index 81f5551fab1bb..11b0982446bfe 100644 --- a/src/plugins/data_views/common/types.ts +++ b/src/plugins/data_views/common/types.ts @@ -429,7 +429,7 @@ export type DataViewFieldMap = Record; // eslint-disable-next-line @typescript-eslint/consistent-type-definitions export type DataViewSpec = { /** - * Saved object id + * Saved object id (or generated id if in-memory only) */ id?: string; /** diff --git a/src/plugins/data_views/public/plugin.ts b/src/plugins/data_views/public/plugin.ts index 1de31618172b6..df379ab18964e 100644 --- a/src/plugins/data_views/public/plugin.ts +++ b/src/plugins/data_views/public/plugin.ts @@ -74,6 +74,8 @@ export class DataViewsPublicPlugin }, getCanSave: () => Promise.resolve(application.capabilities.indexPatterns.save === true), getCanSaveSync: () => application.capabilities.indexPatterns.save === true, + getCanSaveAdvancedSettings: () => + Promise.resolve(application.capabilities.advancedSettings.save === true), }); } diff --git a/src/plugins/data_views/server/data_views_service_factory.ts b/src/plugins/data_views/server/data_views_service_factory.ts index f1501b19ca438..bc910b3822dba 100644 --- a/src/plugins/data_views/server/data_views_service_factory.ts +++ b/src/plugins/data_views/server/data_views_service_factory.ts @@ -59,5 +59,11 @@ export const dataViewsServiceFactory = (deps: DataViewsServiceFactoryDeps) => : request ? (await capabilities.resolveCapabilities(request)).indexPatterns.save === true : false, + getCanSaveAdvancedSettings: async () => + byPassCapabilities + ? true + : request + ? (await capabilities.resolveCapabilities(request)).advancedSettings.save === true + : false, }); }; diff --git a/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.tsx b/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.tsx index ee35e10b6631a..07841c33ee57a 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/get_top_nav_links.tsx @@ -103,7 +103,17 @@ export const getTopNavLinks = ({ testId: 'discoverSaveButton', iconType: 'save', emphasize: true, - run: () => onSaveSearch({ savedSearch, services, indexPattern, navigateTo, state }), + run: (anchorElement: HTMLElement) => + onSaveSearch({ + savedSearch, + services, + indexPattern, + navigateTo, + state, + onClose: () => { + anchorElement?.focus(); + }, + }), }; const openSearch = { @@ -161,6 +171,9 @@ export const getTopNavLinks = ({ }, isDirty: !savedSearch.id || state.isAppStateDirty(), showPublicUrlSwitch, + onClose: () => { + anchorElement?.focus(); + }, }); }, }; diff --git a/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx index 88be94742dfd5..6263df7814e2b 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/on_save_search.tsx @@ -88,12 +88,14 @@ export async function onSaveSearch({ savedSearch, services, state, + onClose, }: { indexPattern: DataView; navigateTo: (path: string) => void; savedSearch: SavedSearch; services: DiscoverServices; state: GetStateReturn; + onClose?: () => void; }) { const onSave = async ({ newTitle, @@ -136,7 +138,7 @@ export async function onSaveSearch({ const saveModal = ( {}} + onClose={onClose ?? (() => {})} title={savedSearch.title ?? ''} showCopyOnSave={!!savedSearch.id} description={savedSearch.description} diff --git a/src/plugins/discover/public/application/main/components/top_nav/open_alerts_popover.tsx b/src/plugins/discover/public/application/main/components/top_nav/open_alerts_popover.tsx index bfc1b28ed6eec..db97ac10096cb 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/open_alerts_popover.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/open_alerts_popover.tsx @@ -33,12 +33,16 @@ export function AlertsPopover({ searchSource, anchorElement, savedQueryId, - onClose, + onClose: originalOnClose, }: AlertsPopoverProps) { const dataView = searchSource.getField('index')!; const services = useDiscoverServices(); const { triggersActionsUi } = services; const [alertFlyoutVisible, setAlertFlyoutVisibility] = useState(false); + const onClose = useCallback(() => { + originalOnClose(); + anchorElement?.focus(); + }, [anchorElement, originalOnClose]); /** * Provides the default parameters used to initialize the new rule diff --git a/src/plugins/discover/public/application/main/components/top_nav/open_options_popover.tsx b/src/plugins/discover/public/application/main/components/top_nav/open_options_popover.tsx index 9a0e17b97c19b..09056ae24b31d 100644 --- a/src/plugins/discover/public/application/main/components/top_nav/open_options_popover.tsx +++ b/src/plugins/discover/public/application/main/components/top_nav/open_options_popover.tsx @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { useCallback } from 'react'; import ReactDOM from 'react-dom'; import { CoreTheme, I18nStart } from '@kbn/core/public'; import { i18n } from '@kbn/i18n'; @@ -51,8 +51,14 @@ export function OptionsPopover(props: OptionsPopoverProps) { defaultMessage: 'Document Explorer', }); + const { anchorElement, onClose: originalOnClose } = props; + const closePopover = useCallback(() => { + originalOnClose(); + anchorElement?.focus(); + }, [anchorElement, originalOnClose]); + return ( - +

diff --git a/src/plugins/discover/public/application/main/services/discover_state.ts b/src/plugins/discover/public/application/main/services/discover_state.ts index bc33b2f1ff09d..86d279ec09c20 100644 --- a/src/plugins/discover/public/application/main/services/discover_state.ts +++ b/src/plugins/discover/public/application/main/services/discover_state.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { isEqual, cloneDeep } from 'lodash'; +import { cloneDeep, isEqual } from 'lodash'; import { i18n } from '@kbn/i18n'; import { History } from 'history'; import { NotificationsStart, IUiSettingsClient } from '@kbn/core/public'; @@ -34,12 +34,12 @@ import { syncQueryStateWithUrl, } from '@kbn/data-plugin/public'; import { DataView } from '@kbn/data-views-plugin/public'; -import { migrateLegacyQuery } from '../../../utils/migrate_legacy_query'; import { DiscoverGridSettings } from '../../../components/discover_grid/types'; import { SavedSearch } from '../../../services/saved_searches'; import { handleSourceColumnState } from '../../../utils/state_helpers'; import { DISCOVER_APP_LOCATOR, DiscoverAppLocatorParams } from '../../../locator'; import { VIEW_MODE } from '../../../components/view_mode_toggle'; +import { cleanupUrlState } from '../utils/cleanup_url_state'; export interface AppState { /** @@ -92,6 +92,13 @@ export interface AppState { rowHeight?: number; } +export interface AppStateUrl extends Omit { + /** + * Necessary to take care of legacy links [fieldName,direction] + */ + sort?: string[][] | [string, string]; +} + interface GetStateParams { /** * Default state used for merging with with URL state to get the initial state @@ -193,17 +200,7 @@ export function getState({ ...(toasts && withNotifyOnErrors(toasts)), }); - const appStateFromUrl = stateStorage.get(APP_STATE_URL_KEY) as AppState; - - if (appStateFromUrl && appStateFromUrl.query && !appStateFromUrl.query.language) { - appStateFromUrl.query = migrateLegacyQuery(appStateFromUrl.query); - } - - if (appStateFromUrl?.sort && !appStateFromUrl.sort.length) { - // If there's an empty array given in the URL, the sort prop should be removed - // This allows the sort prop to be overwritten with the default sorting - delete appStateFromUrl.sort; - } + const appStateFromUrl = cleanupUrlState(stateStorage.get(APP_STATE_URL_KEY) as AppStateUrl); let initialAppState = handleSourceColumnState( { diff --git a/src/plugins/discover/public/application/main/utils/cleanup_url_state.test.ts b/src/plugins/discover/public/application/main/utils/cleanup_url_state.test.ts new file mode 100644 index 0000000000000..e76e40a45a316 --- /dev/null +++ b/src/plugins/discover/public/application/main/utils/cleanup_url_state.test.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { cleanupUrlState } from './cleanup_url_state'; +import { AppStateUrl } from '../services/discover_state'; + +describe('cleanupUrlState', () => { + test('cleaning up legacy sort', async () => { + const state = { sort: ['batman', 'desc'] } as AppStateUrl; + expect(cleanupUrlState(state)).toMatchInlineSnapshot(` + Object { + "sort": Array [ + Array [ + "batman", + "desc", + ], + ], + } + `); + }); + test('not cleaning up broken legacy sort', async () => { + const state = { sort: ['batman'] } as unknown as AppStateUrl; + expect(cleanupUrlState(state)).toMatchInlineSnapshot(`Object {}`); + }); + test('not cleaning up regular sort', async () => { + const state = { + sort: [ + ['batman', 'desc'], + ['robin', 'asc'], + ], + } as AppStateUrl; + expect(cleanupUrlState(state)).toMatchInlineSnapshot(` + Object { + "sort": Array [ + Array [ + "batman", + "desc", + ], + Array [ + "robin", + "asc", + ], + ], + } + `); + }); + test('removing empty sort', async () => { + const state = { + sort: [], + } as AppStateUrl; + expect(cleanupUrlState(state)).toMatchInlineSnapshot(`Object {}`); + }); +}); diff --git a/src/plugins/discover/public/application/main/utils/cleanup_url_state.ts b/src/plugins/discover/public/application/main/utils/cleanup_url_state.ts new file mode 100644 index 0000000000000..0148931f73c58 --- /dev/null +++ b/src/plugins/discover/public/application/main/utils/cleanup_url_state.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ +import { migrateLegacyQuery } from '../../../utils/migrate_legacy_query'; +import { AppState, AppStateUrl } from '../services/discover_state'; + +/** + * Takes care of the given url state, migrates legacy props and cleans up empty props + * @param appStateFromUrl + */ +export function cleanupUrlState(appStateFromUrl: AppStateUrl): AppState { + if (appStateFromUrl && appStateFromUrl.query && !appStateFromUrl.query.language) { + appStateFromUrl.query = migrateLegacyQuery(appStateFromUrl.query); + } + + if (typeof appStateFromUrl?.sort?.[0] === 'string') { + if (appStateFromUrl?.sort?.[1] === 'asc' || appStateFromUrl.sort[1] === 'desc') { + // handling sort props like this[fieldName,direction] + appStateFromUrl.sort = [[appStateFromUrl.sort[0], appStateFromUrl.sort[1]]]; + } else { + delete appStateFromUrl.sort; + } + } + + if (appStateFromUrl?.sort && !appStateFromUrl.sort.length) { + // If there's an empty array given in the URL, the sort prop should be removed + // This allows the sort prop to be overwritten with the default sorting + delete appStateFromUrl.sort; + } + return appStateFromUrl as AppState; +} diff --git a/src/plugins/embeddable/public/lib/attribute_service/attribute_service.tsx b/src/plugins/embeddable/public/lib/attribute_service/attribute_service.tsx index aa31c6afcf51a..cb93ef13b918d 100644 --- a/src/plugins/embeddable/public/lib/attribute_service/attribute_service.tsx +++ b/src/plugins/embeddable/public/lib/attribute_service/attribute_service.tsx @@ -181,7 +181,7 @@ export class AttributeService< this.showSaveModal( reject()} + onClose={() => {}} title={get( saveOptions, 'saveModalTitle', diff --git a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx index 7903faeb509c0..615724ae5f237 100644 --- a/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx +++ b/src/plugins/saved_objects/public/save_modal/show_saved_object_save_modal.tsx @@ -38,6 +38,7 @@ export function showSaveModal( const closeModal = () => { ReactDOM.unmountComponentAtNode(container); document.body.removeChild(container); + saveModal.props.onClose?.(); }; const onSave = saveModal.props.onSave; diff --git a/src/plugins/share/public/services/share_menu_manager.tsx b/src/plugins/share/public/services/share_menu_manager.tsx index a6be0c4811cab..6f27fc8030969 100644 --- a/src/plugins/share/public/services/share_menu_manager.tsx +++ b/src/plugins/share/public/services/share_menu_manager.tsx @@ -37,10 +37,15 @@ export class ShareMenuManager { * @param options */ toggleShareContextMenu: (options: ShowShareMenuOptions) => { - const menuItems = shareRegistry.getShareMenuItems({ ...options, onClose: this.onClose }); + const onClose = () => { + this.onClose(); + options.onClose?.(); + }; + const menuItems = shareRegistry.getShareMenuItems({ ...options, onClose }); const anonymousAccess = anonymousAccessServiceProvider?.(); this.toggleShareContextMenu({ ...options, + onClose, menuItems, urlService, anonymousAccess, @@ -69,14 +74,16 @@ export class ShareMenuManager { showPublicUrlSwitch, urlService, anonymousAccess, + onClose, }: ShowShareMenuOptions & { menuItems: ShareMenuItem[]; urlService: BrowserUrlService; anonymousAccess: AnonymousAccessServiceContract | undefined; theme: ThemeServiceStart; + onClose: () => void; }) { if (this.isOpen) { - this.onClose(); + onClose(); return; } @@ -90,7 +97,7 @@ export class ShareMenuManager { id="sharePopover" button={anchorElement} isOpen={true} - closePopover={this.onClose} + closePopover={onClose} panelPaddingSize="none" anchorPosition="downLeft" > @@ -102,7 +109,7 @@ export class ShareMenuManager { shareMenuItems={menuItems} sharingData={sharingData} shareableUrl={shareableUrl} - onClose={this.onClose} + onClose={onClose} embedUrlParamExtensions={embedUrlParamExtensions} anonymousAccess={anonymousAccess} showPublicUrlSwitch={showPublicUrlSwitch} diff --git a/src/plugins/share/public/types.ts b/src/plugins/share/public/types.ts index 15634e31011e2..355b890c9028c 100644 --- a/src/plugins/share/public/types.ts +++ b/src/plugins/share/public/types.ts @@ -97,4 +97,5 @@ export interface ShowShareMenuOptions extends Omit { allowEmbed: boolean; allowShortUrl: boolean; embedUrlParamExtensions?: UrlParamExtension[]; + onClose?: () => void; } diff --git a/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts b/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts index 08319e8e9a11b..8dc7481300bc0 100644 --- a/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts +++ b/src/plugins/vis_types/xy/public/expression_functions/xy_vis_fn.ts @@ -19,13 +19,13 @@ import { DEFAULT_LEGEND_SIZE, LegendSize, } from '@kbn/visualizations-plugin/public'; -import type { ChartType } from '../../common'; import type { VisParams, XYVisConfig } from '../types'; +import type { XyVisType } from '../../common'; export const visName = 'xy_vis'; export interface RenderValue { visData: Datatable; - visType: ChartType; + visType: XyVisType; visConfig: VisParams; syncColors: boolean; syncTooltips: boolean; @@ -262,7 +262,7 @@ export const visTypeXyVisFn = (): VisTypeXyExpressionFunctionDefinition => ({ }, }, fn(context, args, handlers) { - const visType = args.chartType; + const visType = args.type; const visConfig = { ariaLabel: args.ariaLabel ?? diff --git a/test/functional/apps/console/_comments.ts b/test/functional/apps/console/_comments.ts new file mode 100644 index 0000000000000..fe0fd882c607f --- /dev/null +++ b/test/functional/apps/console/_comments.ts @@ -0,0 +1,155 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import expect from '@kbn/expect'; +import { asyncForEach } from '@kbn/std'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const log = getService('log'); + const retry = getService('retry'); + const PageObjects = getPageObjects(['common', 'console', 'header']); + + describe('console app', function testComments() { + this.tags('includeFirefox'); + before(async () => { + log.debug('navigateTo console'); + await PageObjects.common.navigateToApp('console'); + // blocks the close help button for several seconds so just retry until we can click it. + await retry.try(async () => { + await PageObjects.console.collapseHelp(); + }); + }); + + describe('with comments', async () => { + const enterRequest = async (url: string, body: string) => { + await PageObjects.console.clearTextArea(); + await PageObjects.console.enterRequest(url); + await PageObjects.console.pressEnter(); + await PageObjects.console.enterText(body); + }; + + async function runTests( + tests: Array<{ description: string; url?: string; body: string }>, + fn: () => Promise + ) { + await asyncForEach(tests, async ({ description, url, body }) => { + it(description, async () => { + await enterRequest(url ?? '\nGET search', body); + await fn(); + }); + }); + } + + describe('with single line comments', async () => { + await runTests( + [ + { + url: '\n// GET _search', + body: '', + description: 'should allow in request url, using //', + }, + { + body: '{\n\t\t"query": {\n\t\t\t// "match_all": {}', + description: 'should allow in request body, using //', + }, + { + url: '\n # GET _search', + body: '', + description: 'should allow in request url, using #', + }, + { + body: '{\n\t\t"query": {\n\t\t\t# "match_all": {}', + description: 'should allow in request body, using #', + }, + { + description: 'should accept as field names, using //', + body: '{\n "//": {}', + }, + { + description: 'should accept as field values, using //', + body: '{\n "f": "//"', + }, + { + description: 'should accept as field names, using #', + body: '{\n "#": {}', + }, + { + description: 'should accept as field values, using #', + body: '{\n "f": "#"', + }, + ], + async () => { + expect(await PageObjects.console.hasInvalidSyntax()).to.be(false); + expect(await PageObjects.console.hasErrorMarker()).to.be(false); + } + ); + }); + + describe('with multiline comments', async () => { + await runTests( + [ + { + url: '\n /* \nGET _search \n*/', + body: '', + description: 'should allow in request url, using /* */', + }, + { + body: '{\n\t\t"query": {\n\t\t\t/* "match_all": {} */', + description: 'should allow in request body, using /* */', + }, + { + description: 'should accept as field names, using /*', + body: '{\n "/*": {} \n\t\t /* "f": 1 */', + }, + { + description: 'should accept as field values, using */', + body: '{\n /* "f": 1 */ \n"f": "*/"', + }, + ], + async () => { + expect(await PageObjects.console.hasInvalidSyntax()).to.be(false); + expect(await PageObjects.console.hasErrorMarker()).to.be(false); + } + ); + }); + + describe('with invalid syntax in request body', async () => { + await runTests( + [ + { + description: 'should highlight invalid syntax', + body: '{\n "query": \'\'', // E.g. using single quotes + }, + ], + async () => { + expect(await PageObjects.console.hasInvalidSyntax()).to.be(true); + } + ); + }); + + describe('with invalid request', async () => { + await runTests( + [ + { + description: 'with invalid character should display error marker', + body: '{\n $ "query": {}', + }, + { + description: 'with missing field name', + body: '{\n "query": {},\n {}', + }, + ], + async () => { + expect(await PageObjects.console.hasErrorMarker()).to.be(true); + } + ); + }); + }); + }); +} diff --git a/test/functional/apps/console/index.js b/test/functional/apps/console/index.js index 4f0c362268b6f..f827a043176a8 100644 --- a/test/functional/apps/console/index.js +++ b/test/functional/apps/console/index.js @@ -20,6 +20,7 @@ export default function ({ getService, loadTestFile }) { loadTestFile(require.resolve('./_console')); loadTestFile(require.resolve('./_autocomplete')); loadTestFile(require.resolve('./_vector_tile')); + loadTestFile(require.resolve('./_comments')); } }); } diff --git a/test/functional/apps/discover/_discover_accessibility.ts b/test/functional/apps/discover/_discover_accessibility.ts index 599891aac7a42..deb5cbf61fcaf 100644 --- a/test/functional/apps/discover/_discover_accessibility.ts +++ b/test/functional/apps/discover/_discover_accessibility.ts @@ -8,6 +8,7 @@ import expect from '@kbn/expect'; +import { WebElementWrapper } from '../../services/lib/web_element_wrapper'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { @@ -17,12 +18,19 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const find = getService('find'); const testSubjects = getService('testSubjects'); + const retry = getService('retry'); const PageObjects = getPageObjects(['common', 'discover', 'header', 'timePicker']); const defaultSettings = { defaultIndex: 'logstash-*', }; + const hasFocus = async (testSubject: string) => { + const targetElement = await testSubjects.find(testSubject); + const activeElement = await find.activeElement(); + return (await targetElement._webElement.getId()) === (await activeElement._webElement.getId()); + }; + describe('discover accessibility', () => { before(async () => { log.debug('load kibana index with default index pattern'); @@ -38,20 +46,71 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should give focus to the saved search title h1 on navigate', async () => { - const titleElement = await testSubjects.find('discoverSavedSearchTitle'); - const activeElement = await find.activeElement(); - expect(await titleElement.getAttribute('data-test-subj')).to.eql( - await activeElement.getAttribute('data-test-subj') - ); + expect(await hasFocus('discoverSavedSearchTitle')).to.be(true); }); it('should give focus to the data view switch link when Tab is pressed', async () => { await browser.pressKeys(browser.keys.TAB); - const dataViewSwitchLink = await testSubjects.find('discover-dataView-switch-link'); - const activeElement = await find.activeElement(); - expect(await dataViewSwitchLink.getAttribute('data-test-subj')).to.eql( - await activeElement.getAttribute('data-test-subj') - ); + expect(await hasFocus('discover-dataView-switch-link')).to.be(true); + }); + + describe('top nav menu buttons', () => { + const focusAndPressButton = async (buttonTestSubject: string | WebElementWrapper) => { + const button = + typeof buttonTestSubject === 'string' + ? await testSubjects.find(buttonTestSubject) + : buttonTestSubject; + await button.focus(); + await browser.pressKeys(browser.keys.ENTER); + }; + + const expectButtonToLoseAndRegainFocusWhenOverlayIsOpenedAndClosed = async ( + menuButtonTestSubject: string + ) => { + await focusAndPressButton(menuButtonTestSubject); + expect(await hasFocus(menuButtonTestSubject)).to.be(false); + await browser.pressKeys(browser.keys.ESCAPE); + expect(await hasFocus(menuButtonTestSubject)).to.be(true); + }; + + it('should return focus to the options button when dismissing the options popover', () => + expectButtonToLoseAndRegainFocusWhenOverlayIsOpenedAndClosed('discoverOptionsButton')); + + it('should return focus to the open button when dismissing the open search flyout', () => + expectButtonToLoseAndRegainFocusWhenOverlayIsOpenedAndClosed('discoverOpenButton')); + + it('should return focus to the alerts button when dismissing the alerts popover', () => + expectButtonToLoseAndRegainFocusWhenOverlayIsOpenedAndClosed('discoverAlertsButton')); + + it('should return focus to the alerts button when dismissing the create rule flyout', async () => { + await focusAndPressButton('discoverAlertsButton'); + expect(await hasFocus('discoverAlertsButton')).to.be(false); + await focusAndPressButton('discoverCreateAlertButton'); + expect(await hasFocus('discoverCreateAlertButton')).to.be(false); + await retry.try(async () => { + await browser.pressKeys(browser.keys.ESCAPE); + // A bug exists with the create rule flyout where sometimes the confirm modal + // shows even though the form hasn't been touched, so this works around it + if (await testSubjects.exists('confirmRuleCloseModal', { timeout: 0 })) { + await focusAndPressButton( + await testSubjects.findDescendant( + 'confirmModalConfirmButton', + await testSubjects.find('confirmRuleCloseModal') + ) + ); + } + expect(await hasFocus('discoverAlertsButton')).to.be(true); + }); + }); + + it('should return focus to the share button when dismissing the share popover', () => + expectButtonToLoseAndRegainFocusWhenOverlayIsOpenedAndClosed('shareTopNavButton')); + + it('should return focus to the inspect button when dismissing the inspector flyout', () => + expectButtonToLoseAndRegainFocusWhenOverlayIsOpenedAndClosed('openInspectorButton')); + + it('should return focus to the save button when dismissing the save modal', () => + expectButtonToLoseAndRegainFocusWhenOverlayIsOpenedAndClosed('discoverSaveButton')); }); }); } diff --git a/test/functional/apps/kibana_overview/_analytics.ts b/test/functional/apps/kibana_overview/_analytics.ts index 296256d924b24..fe43514c7e394 100644 --- a/test/functional/apps/kibana_overview/_analytics.ts +++ b/test/functional/apps/kibana_overview/_analytics.ts @@ -16,7 +16,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const PageObjects = getPageObjects(['common', 'header']); - describe('overview page - Analytics apps', function describeIndexTests() { + // FLAKY https://github.com/elastic/kibana/issues/135089 + describe.skip('overview page - Analytics apps', function describeIndexTests() { before(async () => { await esArchiver.load('test/functional/fixtures/es_archiver/logstash_functional'); await kibanaServer.importExport.load( diff --git a/test/functional/page_objects/console_page.ts b/test/functional/page_objects/console_page.ts index e8467ce714ff8..8f8308b4eef5a 100644 --- a/test/functional/page_objects/console_page.ts +++ b/test/functional/page_objects/console_page.ts @@ -14,6 +14,7 @@ export class ConsolePageObject extends FtrService { private readonly testSubjects = this.ctx.getService('testSubjects'); private readonly retry = this.ctx.getService('retry'); private readonly find = this.ctx.getService('find'); + log = this.ctx.getService('log'); public async getVisibleTextFromAceEditor(editor: WebElementWrapper) { const lines = await editor.findAllByClassName('ace_line_group'); @@ -187,4 +188,22 @@ export class ConsolePageObject extends FtrService { return false; } } + + public async hasInvalidSyntax() { + try { + const requestEditor = await this.getRequestEditor(); + return Boolean(await requestEditor.findByCssSelector('.ace_invalid')); + } catch (e) { + return false; + } + } + + public async hasErrorMarker() { + try { + const requestEditor = await this.getRequestEditor(); + return Boolean(await requestEditor.findByCssSelector('.ace_error')); + } catch (e) { + return false; + } + } } diff --git a/x-pack/packages/ml/agg_utils/README.md b/x-pack/packages/ml/agg_utils/README.md index 63a30e1f1cbef..9325aa0478797 100644 --- a/x-pack/packages/ml/agg_utils/README.md +++ b/x-pack/packages/ml/agg_utils/README.md @@ -1,32 +1,5 @@ # @kbn/ml-agg-utils -This package includes utility functions provided by the ML team to be used in Kibana plugins related to data manipulation and verification. +This package includes utility functions related to creating elasticsearch aggregation queries, data manipulation and verification. - - -### `buildSamplerAggregation` (function) - -Wraps the supplied aggregations in a sampler aggregation. -A supplied samplerShardSize (the shard_size parameter of the sampler aggregation) -of less than 1 indicates no sampling, and the aggs are returned as-is. - -**Parameters:** - -- aggs (`any`) -- samplerShardSize (`number`) - -**returns:** Record - -### `getSamplerAggregationsResponsePath` (function) - -**Parameters:** - -- samplerShardSize (`number`) - -**returns:** string[] - -### `getAggIntervals` (function) - -Returns aggregation intervals for the supplied document fields. - - +https://docs.elastic.dev/kibana-dev-docs/api/kbn-ml-agg-utils diff --git a/x-pack/packages/ml/agg_utils/package.json b/x-pack/packages/ml/agg_utils/package.json index 11f2fe9d4d450..c7e49c11207b2 100644 --- a/x-pack/packages/ml/agg_utils/package.json +++ b/x-pack/packages/ml/agg_utils/package.json @@ -1,13 +1,10 @@ { "name": "@kbn/ml-agg-utils", + "description": "This package includes utility functions related to creating elasticsearch aggregation queries, data manipulation and verification.", + "author": "Machine Learning UI", + "homepage": "https://docs.elastic.dev/kibana-dev-docs/api/kbn-ml-agg-utils", "private": true, "version": "1.0.0", "main": "./target_node/index.js", - "license": "SSPL-1.0 OR Elastic License 2.0", - "devDependencies": { - "ts-readme": "^1.1.3" - }, - "scripts": { - "generate-docs": "ts-readme src/index.ts" - } + "license": "SSPL-1.0 OR Elastic License 2.0" } diff --git a/x-pack/packages/ml/agg_utils/yarn.lock b/x-pack/packages/ml/agg_utils/yarn.lock deleted file mode 100644 index e826cf14c9da2..0000000000000 --- a/x-pack/packages/ml/agg_utils/yarn.lock +++ /dev/null @@ -1,300 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@types/command-line-args@^5.0.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@types/command-line-args/-/command-line-args-5.2.0.tgz#adbb77980a1cc376bb208e3f4142e907410430f6" - integrity sha512-UuKzKpJJ/Ief6ufIaIzr3A/0XnluX7RvFgwkV89Yzvm77wCh1kFaFmqN8XEnGcN62EuHdedQjEMb8mYxFLGPyA== - -"@types/command-line-usage@^5.0.1": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@types/command-line-usage/-/command-line-usage-5.0.2.tgz#ba5e3f6ae5a2009d466679cc431b50635bf1a064" - integrity sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -array-back@^3.0.1, array-back@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" - integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== - -array-back@^4.0.1, array-back@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" - integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -command-line-application@^0.9.6: - version "0.9.6" - resolved "https://registry.yarnpkg.com/command-line-application/-/command-line-application-0.9.6.tgz#03da3db29a0dbee1af601f03198a2f2425d67803" - integrity sha512-7wc7YX7s/hqZWKp4r37IBlW/Bhh92HWeQW2VV++Mt9x35AKFntz9f7A94Zz+AsImHZmRGHd8iNW5m0jUd4GQpg== - dependencies: - "@types/command-line-args" "^5.0.0" - "@types/command-line-usage" "^5.0.1" - chalk "^2.4.1" - command-line-args "^5.1.1" - command-line-usage "^6.0.0" - meant "^1.0.1" - remove-markdown "^0.3.0" - tslib "1.10.0" - -command-line-args@^5.1.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" - integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== - dependencies: - array-back "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - -command-line-usage@^6.0.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" - integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== - dependencies: - array-back "^4.0.2" - chalk "^2.4.2" - table-layout "^1.0.2" - typical "^5.2.0" - -deep-extend@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -fast-glob@^3.1.1: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-replace@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" - integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== - dependencies: - array-back "^3.0.1" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - -meant@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.3.tgz#67769af9de1d158773e928ae82c456114903554c" - integrity sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw== - -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -prettier@1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -reduce-flatten@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" - integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== - -remove-markdown@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/remove-markdown/-/remove-markdown-0.3.0.tgz#5e4b667493a93579728f3d52ecc1db9ca505dc98" - integrity sha512-5392eIuy1mhjM74739VunOlsOYKjsH82rQcTBlJ1bkICVC3dQ3ksQzTHh4jGHQFnM+1xzLzcFOMH+BofqXhroQ== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -table-layout@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" - integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== - dependencies: - array-back "^4.0.1" - deep-extend "~0.6.0" - typical "^5.2.0" - wordwrapjs "^4.0.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -ts-readme@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/ts-readme/-/ts-readme-1.1.3.tgz#18a73d21f3bb50ee8e2df819bcbbe3a76385b15a" - integrity sha512-GvI+Vu3m/LGBlgrWwzSmvslnz8msJLNrZ7hQ3Ko2B6PMxeXidqsn6fi20IWgepFjOzhKGw/WlG8NmM7jl3DWeg== - dependencies: - command-line-application "^0.9.6" - fast-glob "^3.1.1" - prettier "1.19.1" - -tslib@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - -typical@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== - -typical@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" - integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== - -wordwrapjs@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" - integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== - dependencies: - reduce-flatten "^2.0.0" - typical "^5.2.0" diff --git a/packages/kbn-aiops-utils/BUILD.bazel b/x-pack/packages/ml/aiops_utils/BUILD.bazel similarity index 98% rename from packages/kbn-aiops-utils/BUILD.bazel rename to x-pack/packages/ml/aiops_utils/BUILD.bazel index cbbffd2703a87..149544b1a2b57 100644 --- a/packages/kbn-aiops-utils/BUILD.bazel +++ b/x-pack/packages/ml/aiops_utils/BUILD.bazel @@ -2,7 +2,7 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config") load("@build_bazel_rules_nodejs//:index.bzl", "js_library") load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") -PKG_DIRNAME = "kbn-aiops-utils" +PKG_DIRNAME = "aiops_utils" PKG_REQUIRE_NAME = "@kbn/aiops-utils" SOURCE_FILES = glob( diff --git a/x-pack/packages/ml/aiops_utils/README.md b/x-pack/packages/ml/aiops_utils/README.md new file mode 100644 index 0000000000000..4e7eb7101e090 --- /dev/null +++ b/x-pack/packages/ml/aiops_utils/README.md @@ -0,0 +1,5 @@ +# @kbn/aiops-utils + +Static utilities for AIOps related efforts. + +https://docs.elastic.dev/kibana-dev-docs/api/kbn-aiops-utils diff --git a/x-pack/packages/ml/aiops_utils/jest.config.js b/x-pack/packages/ml/aiops_utils/jest.config.js new file mode 100644 index 0000000000000..1adc1d58be699 --- /dev/null +++ b/x-pack/packages/ml/aiops_utils/jest.config.js @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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/jest_node', + rootDir: '../../../..', + roots: ['/x-pack/packages/ml/aiops_utils'], +}; diff --git a/x-pack/packages/ml/aiops_utils/package.json b/x-pack/packages/ml/aiops_utils/package.json new file mode 100644 index 0000000000000..395e8e4b8a168 --- /dev/null +++ b/x-pack/packages/ml/aiops_utils/package.json @@ -0,0 +1,11 @@ +{ + "name": "@kbn/aiops-utils", + "description": "Static utilities for AIOps related efforts.", + "author": "Machine Learning UI", + "homepage": "https://docs.elastic.dev/kibana-dev-docs/api/kbn-aiops-utils", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "browser": "./target_web/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/kbn-aiops-utils/src/index.ts b/x-pack/packages/ml/aiops_utils/src/index.ts similarity index 67% rename from packages/kbn-aiops-utils/src/index.ts rename to x-pack/packages/ml/aiops_utils/src/index.ts index 7fe98de70eb7b..9b5c34d9011b6 100644 --- a/packages/kbn-aiops-utils/src/index.ts +++ b/x-pack/packages/ml/aiops_utils/src/index.ts @@ -1,9 +1,8 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ export { streamFactory } from './lib/stream_factory'; diff --git a/packages/kbn-aiops-utils/src/lib/accept_compression.test.ts b/x-pack/packages/ml/aiops_utils/src/lib/accept_compression.test.ts similarity index 90% rename from packages/kbn-aiops-utils/src/lib/accept_compression.test.ts rename to x-pack/packages/ml/aiops_utils/src/lib/accept_compression.test.ts index cf64dfb95232a..f1c51f75cbe0c 100644 --- a/packages/kbn-aiops-utils/src/lib/accept_compression.test.ts +++ b/x-pack/packages/ml/aiops_utils/src/lib/accept_compression.test.ts @@ -1,9 +1,8 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import { acceptCompression } from './accept_compression'; diff --git a/packages/kbn-aiops-utils/src/lib/accept_compression.ts b/x-pack/packages/ml/aiops_utils/src/lib/accept_compression.ts similarity index 77% rename from packages/kbn-aiops-utils/src/lib/accept_compression.ts rename to x-pack/packages/ml/aiops_utils/src/lib/accept_compression.ts index f8be882b3ff92..5585641acbe66 100644 --- a/packages/kbn-aiops-utils/src/lib/accept_compression.ts +++ b/x-pack/packages/ml/aiops_utils/src/lib/accept_compression.ts @@ -1,9 +1,8 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ // TODO: Replace these with kbn packaged versions once we have those available to us. @@ -11,6 +10,13 @@ // import type { Headers } from '@kbn/core/server'; type Headers = Record; +function containsGzip(s: string) { + return s + .split(',') + .map((d) => d.trim()) + .includes('gzip'); +} + /** * Returns whether request headers accept a response using gzip compression. * @@ -24,13 +30,6 @@ export function acceptCompression(headers: Headers) { if (key.toLocaleLowerCase() === 'accept-encoding') { const acceptEncoding = headers[key]; - function containsGzip(s: string) { - return s - .split(',') - .map((d) => d.trim()) - .includes('gzip'); - } - if (typeof acceptEncoding === 'string') { compressed = containsGzip(acceptEncoding); } else if (Array.isArray(acceptEncoding)) { diff --git a/packages/kbn-aiops-utils/src/lib/fetch_stream.ts b/x-pack/packages/ml/aiops_utils/src/lib/fetch_stream.ts similarity index 96% rename from packages/kbn-aiops-utils/src/lib/fetch_stream.ts rename to x-pack/packages/ml/aiops_utils/src/lib/fetch_stream.ts index 1977276adc92b..4a1ed282c3ee7 100644 --- a/packages/kbn-aiops-utils/src/lib/fetch_stream.ts +++ b/x-pack/packages/ml/aiops_utils/src/lib/fetch_stream.ts @@ -1,9 +1,8 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import type { ReducerAction } from 'react'; diff --git a/packages/kbn-aiops-utils/src/lib/stream_factory.test.ts b/x-pack/packages/ml/aiops_utils/src/lib/stream_factory.test.ts similarity index 96% rename from packages/kbn-aiops-utils/src/lib/stream_factory.test.ts rename to x-pack/packages/ml/aiops_utils/src/lib/stream_factory.test.ts index a5628f8d8313c..53cd5f332f805 100644 --- a/packages/kbn-aiops-utils/src/lib/stream_factory.test.ts +++ b/x-pack/packages/ml/aiops_utils/src/lib/stream_factory.test.ts @@ -1,12 +1,11 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ -import zlib from 'zlib'; +import * as zlib from 'zlib'; import { streamFactory } from './stream_factory'; diff --git a/packages/kbn-aiops-utils/src/lib/stream_factory.ts b/x-pack/packages/ml/aiops_utils/src/lib/stream_factory.ts similarity index 94% rename from packages/kbn-aiops-utils/src/lib/stream_factory.ts rename to x-pack/packages/ml/aiops_utils/src/lib/stream_factory.ts index f017f5190a695..3900056cd3a79 100644 --- a/packages/kbn-aiops-utils/src/lib/stream_factory.ts +++ b/x-pack/packages/ml/aiops_utils/src/lib/stream_factory.ts @@ -1,13 +1,12 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import { Stream } from 'stream'; -import zlib from 'zlib'; +import * as zlib from 'zlib'; // TODO: Replace these with kbn packaged versions once we have those available to us. // At the moment imports from runtime plugins into packages are not supported. diff --git a/packages/kbn-aiops-utils/src/lib/string_reducer.ts b/x-pack/packages/ml/aiops_utils/src/lib/string_reducer.ts similarity index 88% rename from packages/kbn-aiops-utils/src/lib/string_reducer.ts rename to x-pack/packages/ml/aiops_utils/src/lib/string_reducer.ts index 352b8f8ddd3e5..281fe9c8495b1 100644 --- a/packages/kbn-aiops-utils/src/lib/string_reducer.ts +++ b/x-pack/packages/ml/aiops_utils/src/lib/string_reducer.ts @@ -1,9 +1,8 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import { Reducer, ReducerAction, ReducerState } from 'react'; diff --git a/packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts b/x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts similarity index 95% rename from packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts rename to x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts index d3ab97e4cd2b1..13436efc6d471 100644 --- a/packages/kbn-aiops-utils/src/lib/use_fetch_stream.ts +++ b/x-pack/packages/ml/aiops_utils/src/lib/use_fetch_stream.ts @@ -1,9 +1,8 @@ /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. */ import { diff --git a/x-pack/packages/ml/aiops_utils/tsconfig.json b/x-pack/packages/ml/aiops_utils/tsconfig.json new file mode 100644 index 0000000000000..dc20b641b1989 --- /dev/null +++ b/x-pack/packages/ml/aiops_utils/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "rootDir": "src", + "stripInternal": false, + "types": [ + "jest", + "node", + "react" + ] + }, + "include": [ + "src/**/*" + ] +} diff --git a/x-pack/packages/ml/is_populated_object/README.md b/x-pack/packages/ml/is_populated_object/README.md index 8d2d47329a3fa..c30942078e952 100644 --- a/x-pack/packages/ml/is_populated_object/README.md +++ b/x-pack/packages/ml/is_populated_object/README.md @@ -1,24 +1,5 @@ # @kbn/ml-is-populated-object - - -### `isPopulatedObject` (function) - A type guard to check record like object structures. -Examples: - -- `isPopulatedObject({...})` - Limits type to Record - -- `isPopulatedObject({...}, ['attribute'])` - Limits type to Record<'attribute', unknown> - -- `isPopulatedObject({...})` - Limits type to a record with keys of the given interface. - Note that you might want to add keys from the interface to the - array of requiredAttributes to satisfy runtime requirements. - Otherwise you'd just satisfy TS requirements but might still - run into runtime issues. - - +https://docs.elastic.dev/kibana-dev-docs/api/kbn-ml-is-populated-object diff --git a/x-pack/packages/ml/is_populated_object/package.json b/x-pack/packages/ml/is_populated_object/package.json index 3ca3e0fcffb01..ec81756845881 100644 --- a/x-pack/packages/ml/is_populated_object/package.json +++ b/x-pack/packages/ml/is_populated_object/package.json @@ -1,13 +1,10 @@ { "name": "@kbn/ml-is-populated-object", + "description": "A type guard to check record like object structures.", + "author": "Machine Learning UI", + "homepage": "https://docs.elastic.dev/kibana-dev-docs/api/kbn-ml-is-populated-object", "private": true, "version": "1.0.0", "main": "./target_node/index.js", - "license": "SSPL-1.0 OR Elastic License 2.0", - "devDependencies": { - "ts-readme": "^1.1.3" - }, - "scripts": { - "generate-docs": "ts-readme src/index.ts" - } + "license": "SSPL-1.0 OR Elastic License 2.0" } diff --git a/x-pack/packages/ml/is_populated_object/yarn.lock b/x-pack/packages/ml/is_populated_object/yarn.lock deleted file mode 100644 index e826cf14c9da2..0000000000000 --- a/x-pack/packages/ml/is_populated_object/yarn.lock +++ /dev/null @@ -1,300 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@types/command-line-args@^5.0.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@types/command-line-args/-/command-line-args-5.2.0.tgz#adbb77980a1cc376bb208e3f4142e907410430f6" - integrity sha512-UuKzKpJJ/Ief6ufIaIzr3A/0XnluX7RvFgwkV89Yzvm77wCh1kFaFmqN8XEnGcN62EuHdedQjEMb8mYxFLGPyA== - -"@types/command-line-usage@^5.0.1": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@types/command-line-usage/-/command-line-usage-5.0.2.tgz#ba5e3f6ae5a2009d466679cc431b50635bf1a064" - integrity sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -array-back@^3.0.1, array-back@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" - integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== - -array-back@^4.0.1, array-back@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" - integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -command-line-application@^0.9.6: - version "0.9.6" - resolved "https://registry.yarnpkg.com/command-line-application/-/command-line-application-0.9.6.tgz#03da3db29a0dbee1af601f03198a2f2425d67803" - integrity sha512-7wc7YX7s/hqZWKp4r37IBlW/Bhh92HWeQW2VV++Mt9x35AKFntz9f7A94Zz+AsImHZmRGHd8iNW5m0jUd4GQpg== - dependencies: - "@types/command-line-args" "^5.0.0" - "@types/command-line-usage" "^5.0.1" - chalk "^2.4.1" - command-line-args "^5.1.1" - command-line-usage "^6.0.0" - meant "^1.0.1" - remove-markdown "^0.3.0" - tslib "1.10.0" - -command-line-args@^5.1.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" - integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== - dependencies: - array-back "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - -command-line-usage@^6.0.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" - integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== - dependencies: - array-back "^4.0.2" - chalk "^2.4.2" - table-layout "^1.0.2" - typical "^5.2.0" - -deep-extend@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -fast-glob@^3.1.1: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-replace@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" - integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== - dependencies: - array-back "^3.0.1" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - -meant@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.3.tgz#67769af9de1d158773e928ae82c456114903554c" - integrity sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw== - -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -prettier@1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -reduce-flatten@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" - integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== - -remove-markdown@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/remove-markdown/-/remove-markdown-0.3.0.tgz#5e4b667493a93579728f3d52ecc1db9ca505dc98" - integrity sha512-5392eIuy1mhjM74739VunOlsOYKjsH82rQcTBlJ1bkICVC3dQ3ksQzTHh4jGHQFnM+1xzLzcFOMH+BofqXhroQ== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -table-layout@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" - integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== - dependencies: - array-back "^4.0.1" - deep-extend "~0.6.0" - typical "^5.2.0" - wordwrapjs "^4.0.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -ts-readme@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/ts-readme/-/ts-readme-1.1.3.tgz#18a73d21f3bb50ee8e2df819bcbbe3a76385b15a" - integrity sha512-GvI+Vu3m/LGBlgrWwzSmvslnz8msJLNrZ7hQ3Ko2B6PMxeXidqsn6fi20IWgepFjOzhKGw/WlG8NmM7jl3DWeg== - dependencies: - command-line-application "^0.9.6" - fast-glob "^3.1.1" - prettier "1.19.1" - -tslib@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - -typical@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== - -typical@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" - integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== - -wordwrapjs@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" - integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== - dependencies: - reduce-flatten "^2.0.0" - typical "^5.2.0" diff --git a/x-pack/packages/ml/string_hash/README.md b/x-pack/packages/ml/string_hash/README.md index 32ea547e20f37..4e6d1f099edf8 100644 --- a/x-pack/packages/ml/string_hash/README.md +++ b/x-pack/packages/ml/string_hash/README.md @@ -1,15 +1,5 @@ # @kbn/ml-string-hash - - -### `stringHash` (function) - Creates a deterministic number based hash out of a string. -**Parameters:** - -- str (`string`) - -**returns:** number - - +https://docs.elastic.dev/kibana-dev-docs/api/kbn-ml-string-hash diff --git a/x-pack/packages/ml/string_hash/package.json b/x-pack/packages/ml/string_hash/package.json index 81a0bf1c743f5..9456893b31658 100644 --- a/x-pack/packages/ml/string_hash/package.json +++ b/x-pack/packages/ml/string_hash/package.json @@ -1,13 +1,10 @@ { "name": "@kbn/ml-string-hash", + "description": "Creates a deterministic number based hash out of a string.", + "author": "Machine Learning UI", + "homepage": "https://docs.elastic.dev/kibana-dev-docs/api/kbn-ml-string-hash", "private": true, "version": "1.0.0", "main": "./target_node/index.js", - "license": "SSPL-1.0 OR Elastic License 2.0", - "devDependencies": { - "ts-readme": "^1.1.3" - }, - "scripts": { - "generate-docs": "ts-readme src/index.ts" - } + "license": "SSPL-1.0 OR Elastic License 2.0" } diff --git a/x-pack/packages/ml/string_hash/yarn.lock b/x-pack/packages/ml/string_hash/yarn.lock deleted file mode 100644 index e826cf14c9da2..0000000000000 --- a/x-pack/packages/ml/string_hash/yarn.lock +++ /dev/null @@ -1,300 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@types/command-line-args@^5.0.0": - version "5.2.0" - resolved "https://registry.yarnpkg.com/@types/command-line-args/-/command-line-args-5.2.0.tgz#adbb77980a1cc376bb208e3f4142e907410430f6" - integrity sha512-UuKzKpJJ/Ief6ufIaIzr3A/0XnluX7RvFgwkV89Yzvm77wCh1kFaFmqN8XEnGcN62EuHdedQjEMb8mYxFLGPyA== - -"@types/command-line-usage@^5.0.1": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@types/command-line-usage/-/command-line-usage-5.0.2.tgz#ba5e3f6ae5a2009d466679cc431b50635bf1a064" - integrity sha512-n7RlEEJ+4x4TS7ZQddTmNSxP+zziEG0TNsMfiRIxcIVXt71ENJ9ojeXmGO3wPoTdn7pJcU2xc3CJYMktNT6DPg== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -array-back@^3.0.1, array-back@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" - integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== - -array-back@^4.0.1, array-back@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" - integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== - -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -command-line-application@^0.9.6: - version "0.9.6" - resolved "https://registry.yarnpkg.com/command-line-application/-/command-line-application-0.9.6.tgz#03da3db29a0dbee1af601f03198a2f2425d67803" - integrity sha512-7wc7YX7s/hqZWKp4r37IBlW/Bhh92HWeQW2VV++Mt9x35AKFntz9f7A94Zz+AsImHZmRGHd8iNW5m0jUd4GQpg== - dependencies: - "@types/command-line-args" "^5.0.0" - "@types/command-line-usage" "^5.0.1" - chalk "^2.4.1" - command-line-args "^5.1.1" - command-line-usage "^6.0.0" - meant "^1.0.1" - remove-markdown "^0.3.0" - tslib "1.10.0" - -command-line-args@^5.1.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" - integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== - dependencies: - array-back "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - -command-line-usage@^6.0.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" - integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== - dependencies: - array-back "^4.0.2" - chalk "^2.4.2" - table-layout "^1.0.2" - typical "^5.2.0" - -deep-extend@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -fast-glob@^3.1.1: - version "3.2.11" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" - integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fastq@^1.6.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" - integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== - dependencies: - reusify "^1.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-replace@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" - integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== - dependencies: - array-back "^3.0.1" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - -meant@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.3.tgz#67769af9de1d158773e928ae82c456114903554c" - integrity sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw== - -merge2@^1.3.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -prettier@1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -reduce-flatten@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" - integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== - -remove-markdown@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/remove-markdown/-/remove-markdown-0.3.0.tgz#5e4b667493a93579728f3d52ecc1db9ca505dc98" - integrity sha512-5392eIuy1mhjM74739VunOlsOYKjsH82rQcTBlJ1bkICVC3dQ3ksQzTHh4jGHQFnM+1xzLzcFOMH+BofqXhroQ== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -table-layout@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" - integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== - dependencies: - array-back "^4.0.1" - deep-extend "~0.6.0" - typical "^5.2.0" - wordwrapjs "^4.0.0" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -ts-readme@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/ts-readme/-/ts-readme-1.1.3.tgz#18a73d21f3bb50ee8e2df819bcbbe3a76385b15a" - integrity sha512-GvI+Vu3m/LGBlgrWwzSmvslnz8msJLNrZ7hQ3Ko2B6PMxeXidqsn6fi20IWgepFjOzhKGw/WlG8NmM7jl3DWeg== - dependencies: - command-line-application "^0.9.6" - fast-glob "^3.1.1" - prettier "1.19.1" - -tslib@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" - integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== - -typical@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== - -typical@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" - integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== - -wordwrapjs@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" - integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== - dependencies: - reduce-flatten "^2.0.0" - typical "^5.2.0" diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts index d394c0b34dafb..b000a3a8c2f3f 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts @@ -8,7 +8,7 @@ import url from 'url'; import { synthtrace } from '../../../../synthtrace'; import { checkA11y } from '../../../support/commands'; -import { generateData } from './generate_data'; +import { generateData, generateErrors } from './generate_data'; const start = '2021-10-10T00:00:00.000Z'; const end = '2021-10-10T00:15:00.000Z'; @@ -110,3 +110,67 @@ describe('Errors page', () => { }); }); }); + +describe('Check detailed statistics API with multiple errors', () => { + before(async () => { + cy.loginAsViewerUser(); + await synthtrace.index( + generateErrors({ + from: new Date(start).getTime(), + to: new Date(end).getTime(), + errorCount: 50, + }) + ); + }); + + after(async () => { + await synthtrace.clean(); + }); + + it('calls detailed API with visible items only', () => { + cy.intercept( + 'GET', + '/internal/apm/services/opbeans-java/errors/groups/main_statistics?*' + ).as('errorsMainStatistics'); + cy.intercept( + 'POST', + '/internal/apm/services/opbeans-java/errors/groups/detailed_statistics?*' + ).as('errorsDetailedStatistics'); + cy.visit(`${javaServiceErrorsPageHref}&pageSize=10`); + cy.wait('@errorsMainStatistics'); + cy.get('.euiPagination__list').children().should('have.length', 5); + cy.wait('@errorsDetailedStatistics').then((payload) => { + expect(payload.request.body.groupIds).eql( + JSON.stringify([ + '0000000000000000000000000Error 0', + '0000000000000000000000000Error 1', + '0000000000000000000000000Error 2', + '0000000000000000000000000Error 3', + '0000000000000000000000000Error 4', + '0000000000000000000000000Error 5', + '0000000000000000000000000Error 6', + '0000000000000000000000000Error 7', + '0000000000000000000000000Error 8', + '0000000000000000000000000Error 9', + ]) + ); + }); + cy.get('[data-test-subj="pagination-button-1"]').click(); + cy.wait('@errorsDetailedStatistics').then((payload) => { + expect(payload.request.body.groupIds).eql( + JSON.stringify([ + '000000000000000000000000Error 10', + '000000000000000000000000Error 11', + '000000000000000000000000Error 12', + '000000000000000000000000Error 13', + '000000000000000000000000Error 14', + '000000000000000000000000Error 15', + '000000000000000000000000Error 16', + '000000000000000000000000Error 17', + '000000000000000000000000Error 18', + '000000000000000000000000Error 19', + ]) + ); + }); + }); +}); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts index a65e4e08d198f..66a70428b2275 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/generate_data.ts @@ -39,3 +39,40 @@ export function generateData({ from, to }: { from: number; to: number }) { .success(), ]); } + +export function generateErrors({ + from, + to, + errorCount, +}: { + from: number; + to: number; + errorCount: number; +}) { + const range = timerange(from, to); + + const opbeansJava = apm + .service('opbeans-java', 'production', 'java') + .instance('opbeans-java-prod-1') + .podId('opbeans-java-prod-1-pod'); + + return range + .interval('2m') + .rate(1) + .generator((timestamp, index) => [ + opbeansJava + .transaction('GET /apple 🍎 ') + .timestamp(timestamp) + .duration(1000) + .success() + .errors( + ...Array(errorCount) + .fill(0) + .map((_, idx) => { + return opbeansJava + .error(`Error ${idx}`, `exception ${idx}`) + .timestamp(timestamp); + }) + ), + ]); +} diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/generate_data.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/generate_data.ts new file mode 100644 index 0000000000000..4fc94d2305b57 --- /dev/null +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/generate_data.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { apm, timerange } from '@elastic/apm-synthtrace'; + +export function generateMultipleServicesData({ + from, + to, +}: { + from: number; + to: number; +}) { + const range = timerange(from, to); + + const services = Array(50) + .fill(0) + .map((_, idx) => + apm + .service(`${idx}`, 'production', 'nodejs') + .instance('opbeans-node-prod-1') + ); + + return range + .interval('2m') + .rate(1) + .generator((timestamp, index) => + services.map((service) => + service + .transaction('GET /foo') + .timestamp(timestamp) + .duration(500) + .success() + ) + ); +} diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts index 54920596733b5..f2be1d7067b0c 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_inventory/service_inventory.spec.ts @@ -9,6 +9,7 @@ import url from 'url'; import { synthtrace } from '../../../../synthtrace'; import { opbeans } from '../../../fixtures/synthtrace/opbeans'; import { checkA11y } from '../../../support/commands'; +import { generateMultipleServicesData } from './generate_data'; const timeRange = { rangeFrom: '2021-10-10T00:00:00.000Z', @@ -132,3 +133,68 @@ describe('When navigating to the service inventory', () => { }); }); }); + +describe('Check detailed statistics API with multiple services', () => { + before(async () => { + cy.loginAsViewerUser(); + const { rangeFrom, rangeTo } = timeRange; + + await synthtrace.index( + generateMultipleServicesData({ + from: new Date(rangeFrom).getTime(), + to: new Date(rangeTo).getTime(), + }) + ); + }); + + after(async () => { + await synthtrace.clean(); + }); + + it('calls detailed API with visible items only', () => { + cy.intercept('POST', '/internal/apm/services/detailed_statistics?*').as( + 'detailedStatisticsRequest' + ); + cy.intercept('GET', '/internal/apm/services?*').as('mainStatisticsRequest'); + + cy.visit( + `${serviceInventoryHref}&pageSize=10&sortField=serviceName&sortDirection=asc` + ); + cy.wait('@mainStatisticsRequest'); + cy.contains('Services'); + cy.get('.euiPagination__list').children().should('have.length', 5); + cy.wait('@detailedStatisticsRequest').then((payload) => { + expect(payload.request.body.serviceNames).eql( + JSON.stringify([ + '0', + '1', + '10', + '11', + '12', + '13', + '14', + '15', + '16', + '17', + ]) + ); + }); + cy.get('[data-test-subj="pagination-button-1"]').click(); + cy.wait('@detailedStatisticsRequest').then((payload) => { + expect(payload.request.body.serviceNames).eql( + JSON.stringify([ + '18', + '19', + '2', + '20', + '21', + '22', + '23', + '24', + '25', + '26', + ]) + ); + }); + }); +}); diff --git a/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx b/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx index 67b8a2c28001d..1ce254ea91941 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx @@ -55,13 +55,15 @@ const Culprit = euiStyled.div` type ErrorGroupItem = APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>['errorGroups'][0]; type ErrorGroupDetailedStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; + APIReturnType<'POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; interface Props { mainStatistics: ErrorGroupItem[]; serviceName: string; detailedStatisticsLoading: boolean; detailedStatistics: ErrorGroupDetailedStatistics; + initialSortField: string; + initialSortDirection: 'asc' | 'desc'; comparisonEnabled?: boolean; } @@ -71,6 +73,8 @@ function ErrorGroupList({ detailedStatisticsLoading, detailedStatistics, comparisonEnabled, + initialSortField, + initialSortDirection, }: Props) { const { query } = useApmParams('/services/{serviceName}/errors'); const { offset } = query; @@ -251,8 +255,8 @@ function ErrorGroupList({ })} items={mainStatistics} columns={columns} - initialSortField="occurrences" - initialSortDirection="desc" + initialSortField={initialSortField} + initialSortDirection={initialSortDirection} sortItems={false} /> ); diff --git a/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx b/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx index c7e74ff5ec3cd..d198d1712772c 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx @@ -15,6 +15,7 @@ import { import { i18n } from '@kbn/i18n'; import React from 'react'; import uuid from 'uuid'; +import { orderBy } from 'lodash'; import { isTimeComparison } from '../../shared/time_comparison/get_comparison_options'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; import { ChartPointerEventContextProvider } from '../../../context/chart_pointer_event/chart_pointer_event_context'; @@ -26,18 +27,21 @@ import { APIReturnType } from '../../../services/rest/create_call_apm_api'; import { FailedTransactionRateChart } from '../../shared/charts/failed_transaction_rate_chart'; import { ErrorDistribution } from '../error_group_details/distribution'; import { ErrorGroupList } from './error_group_list'; +import { INITIAL_PAGE_SIZE } from '../../shared/managed_table'; type ErrorGroupMainStatistics = APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>; type ErrorGroupDetailedStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; + APIReturnType<'POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; const INITIAL_STATE_MAIN_STATISTICS: { errorGroupMainStatistics: ErrorGroupMainStatistics['errorGroups']; requestId?: string; + currentPageGroupIds: ErrorGroupMainStatistics['errorGroups']; } = { errorGroupMainStatistics: [], requestId: undefined, + currentPageGroupIds: [], }; const INITIAL_STATE_DETAILED_STATISTICS: ErrorGroupDetailedStatistics = { @@ -52,12 +56,14 @@ export function ErrorGroupOverview() { query: { environment, kuery, - sortField, - sortDirection, + sortField = 'occurrences', + sortDirection = 'desc', rangeFrom, rangeTo, offset, comparisonEnabled, + page = 0, + pageSize = INITIAL_PAGE_SIZE, }, } = useApmParams('/services/{serviceName}/errors'); @@ -94,27 +100,48 @@ export function ErrorGroupOverview() { }, } ).then((response) => { + const currentPageGroupIds = orderBy( + response.errorGroups, + sortField, + sortDirection + ) + .slice(page * pageSize, (page + 1) * pageSize) + .map(({ groupId }) => groupId) + .sort(); + return { // Everytime the main statistics is refetched, updates the requestId making the comparison API to be refetched. requestId: uuid(), errorGroupMainStatistics: response.errorGroups, + currentPageGroupIds, }; }); } }, - [environment, kuery, serviceName, start, end, sortField, sortDirection] + [ + environment, + kuery, + serviceName, + start, + end, + sortField, + sortDirection, + page, + pageSize, + ] ); - const { requestId, errorGroupMainStatistics } = errorGroupListData; + const { requestId, errorGroupMainStatistics, currentPageGroupIds } = + errorGroupListData; const { data: errorGroupDetailedStatistics = INITIAL_STATE_DETAILED_STATISTICS, status: errorGroupDetailedStatisticsStatus, } = useFetcher( (callApmApi) => { - if (requestId && errorGroupMainStatistics.length && start && end) { + if (requestId && currentPageGroupIds.length && start && end) { return callApmApi( - 'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics', + 'POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics', { params: { path: { serviceName }, @@ -124,14 +151,14 @@ export function ErrorGroupOverview() { start, end, numBuckets: 20, - groupIds: JSON.stringify( - errorGroupMainStatistics.map(({ groupId }) => groupId).sort() - ), offset: comparisonEnabled && isTimeComparison(offset) ? offset : undefined, }, + body: { + groupIds: JSON.stringify(currentPageGroupIds), + }, }, } ); @@ -192,6 +219,8 @@ export function ErrorGroupOverview() { } detailedStatistics={errorGroupDetailedStatistics} comparisonEnabled={comparisonEnabled} + initialSortField={sortField} + initialSortDirection={sortDirection} /> diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx index 34de2e3fbf2fa..fc9228bf486e2 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/index.tsx @@ -24,6 +24,7 @@ import { useProgressiveFetcher } from '../../../hooks/use_progressive_fetcher'; import { joinByKey } from '../../../../common/utils/join_by_key'; import { ServiceInventoryFieldName } from '../../../../common/service_inventory'; import { orderServiceItems } from './service_list/order_service_items'; +import { INITIAL_PAGE_SIZE } from '../../shared/managed_table'; const initialData = { requestId: '', @@ -32,7 +33,7 @@ const initialData = { hasLegacyData: false, }; -function useServicesFetcher() { +function useServicesMainStatisticsFetcher() { const { query: { rangeFrom, @@ -40,8 +41,10 @@ function useServicesFetcher() { environment, kuery, serviceGroup, - offset, - comparisonEnabled, + page = 0, + pageSize = INITIAL_PAGE_SIZE, + sortDirection, + sortField, }, } = useApmParams('/services'); @@ -85,36 +88,93 @@ function useServicesFetcher() { }); } }, - [environment, kuery, start, end, serviceGroup] + // eslint-disable-next-line react-hooks/exhaustive-deps + [ + environment, + kuery, + start, + end, + serviceGroup, + // not used, but needed to update the requestId to call the details statistics API when table is options are updated + page, + pageSize, + sortField, + sortDirection, + ] ); + return { + sortedAndFilteredServicesFetch, + mainStatisticsFetch, + }; +} + +function useServicesDetailedStatisticsFetcher({ + mainStatisticsFetch, + initialSortField, + initialSortDirection, + tiebreakerField, +}: { + mainStatisticsFetch: ReturnType< + typeof useServicesMainStatisticsFetcher + >['mainStatisticsFetch']; + initialSortField: ServiceInventoryFieldName; + initialSortDirection: 'asc' | 'desc'; + tiebreakerField: ServiceInventoryFieldName; +}) { + const { + query: { + rangeFrom, + rangeTo, + environment, + kuery, + offset, + comparisonEnabled, + page = 0, + pageSize = INITIAL_PAGE_SIZE, + sortDirection = initialSortDirection, + sortField = initialSortField, + }, + } = useApmParams('/services'); + + const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const { data: mainStatisticsData = initialData } = mainStatisticsFetch; + const currentPageItems = orderServiceItems({ + items: mainStatisticsData.items, + primarySortField: sortField as ServiceInventoryFieldName, + sortDirection, + tiebreakerField, + }).slice(page * pageSize, (page + 1) * pageSize); + const comparisonFetch = useProgressiveFetcher( (callApmApi) => { if ( start && end && - mainStatisticsData.items.length && + currentPageItems.length && mainStatisticsFetch.status === FETCH_STATUS.SUCCESS ) { - return callApmApi('GET /internal/apm/services/detailed_statistics', { + return callApmApi('POST /internal/apm/services/detailed_statistics', { params: { query: { environment, kuery, start, end, + offset: + comparisonEnabled && isTimeComparison(offset) + ? offset + : undefined, + }, + body: { serviceNames: JSON.stringify( - mainStatisticsData.items + currentPageItems .map(({ serviceName }) => serviceName) // Service name is sorted to guarantee the same order every time this API is called so the result can be cached. .sort() ), - offset: - comparisonEnabled && isTimeComparison(offset) - ? offset - : undefined, }, }, }); @@ -126,19 +186,43 @@ function useServicesFetcher() { { preservePreviousData: false } ); - return { - sortedAndFilteredServicesFetch, - mainStatisticsFetch, - comparisonFetch, - }; + return { comparisonFetch }; } export function ServiceInventory() { - const { - sortedAndFilteredServicesFetch, + const { sortedAndFilteredServicesFetch, mainStatisticsFetch } = + useServicesMainStatisticsFetcher(); + + const mainStatisticsItems = mainStatisticsFetch.data?.items ?? []; + const preloadedServices = sortedAndFilteredServicesFetch.data?.services || []; + + const displayHealthStatus = [ + ...mainStatisticsItems, + ...preloadedServices, + ].some((item) => 'healthStatus' in item); + + const useOptimizedSorting = + useKibana().services.uiSettings?.get( + apmServiceInventoryOptimizedSorting + ) || false; + + const tiebreakerField = useOptimizedSorting + ? ServiceInventoryFieldName.ServiceName + : ServiceInventoryFieldName.Throughput; + + const initialSortField = displayHealthStatus + ? ServiceInventoryFieldName.HealthStatus + : tiebreakerField; + + const initialSortDirection = + initialSortField === ServiceInventoryFieldName.ServiceName ? 'asc' : 'desc'; + + const { comparisonFetch } = useServicesDetailedStatisticsFetcher({ mainStatisticsFetch, - comparisonFetch, - } = useServicesFetcher(); + initialSortField, + initialSortDirection, + tiebreakerField, + }); const { anomalyDetectionSetupState } = useAnomalyDetectionJobsContext(); @@ -151,11 +235,6 @@ export function ServiceInventory() { !userHasDismissedCallout && shouldDisplayMlCallout(anomalyDetectionSetupState); - const useOptimizedSorting = - useKibana().services.uiSettings?.get( - apmServiceInventoryOptimizedSorting - ) || false; - let isLoading: boolean; if (useOptimizedSorting) { @@ -183,25 +262,6 @@ export function ServiceInventory() { /> ); - const mainStatisticsItems = mainStatisticsFetch.data?.items ?? []; - const preloadedServices = sortedAndFilteredServicesFetch.data?.services || []; - - const displayHealthStatus = [ - ...mainStatisticsItems, - ...preloadedServices, - ].some((item) => 'healthStatus' in item); - - const tiebreakerField = useOptimizedSorting - ? ServiceInventoryFieldName.ServiceName - : ServiceInventoryFieldName.Throughput; - - const initialSortField = displayHealthStatus - ? ServiceInventoryFieldName.HealthStatus - : tiebreakerField; - - const initialSortDirection = - initialSortField === ServiceInventoryFieldName.ServiceName ? 'asc' : 'desc'; - const items = joinByKey( [ // only use preloaded services if tiebreaker field is service.name, diff --git a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx index 7bf340bed12a9..1d087748bd8ce 100644 --- a/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_inventory/service_list/index.tsx @@ -50,7 +50,7 @@ import { } from '../../../../../common/service_inventory'; type ServicesDetailedStatisticsAPIResponse = - APIReturnType<'GET /internal/apm/services/detailed_statistics'>; + APIReturnType<'POST /internal/apm/services/detailed_statistics'>; function formatString(value?: string | null) { return value || NOT_AVAILABLE_LABEL; @@ -271,7 +271,16 @@ export function ServiceList({ transactionType !== TRANSACTION_PAGE_LOAD ); - const { query } = useApmParams('/services'); + const { + // removes pagination and sort instructions from the query so it won't be passed down to next route + query: { + page, + pageSize, + sortDirection: direction, + sortField: field, + ...query + }, + } = useApmParams('/services'); const { kuery } = query; const { fallbackToTransactions } = useFallbackToTransactionsFetcher({ diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx index 294c224bdfd28..0af05ead4fb24 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx @@ -32,7 +32,7 @@ const ErrorLink = euiStyled(ErrorOverviewLink)` type ErrorGroupMainStatistics = APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>; type ErrorGroupDetailedStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; + APIReturnType<'POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; export function getColumns({ serviceName, diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx index 3078058c8c8df..602bfaa811c3c 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx @@ -30,7 +30,7 @@ interface Props { type ErrorGroupMainStatistics = APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>; type ErrorGroupDetailedStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; + APIReturnType<'POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; type SortDirection = 'asc' | 'desc'; type SortField = 'name' | 'lastSeen' | 'occurrences'; @@ -137,7 +137,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { (callApmApi) => { if (requestId && items.length && start && end) { return callApmApi( - 'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics', + 'POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics', { params: { path: { serviceName }, @@ -147,14 +147,16 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { start, end, numBuckets: 20, - groupIds: JSON.stringify( - items.map(({ groupId: groupId }) => groupId).sort() - ), offset: comparisonEnabled && isTimeComparison(offset) ? offset : undefined, }, + body: { + groupIds: JSON.stringify( + items.map(({ groupId: groupId }) => groupId).sort() + ), + }, }, } ); diff --git a/x-pack/plugins/apm/public/components/routing/home/index.tsx b/x-pack/plugins/apm/public/components/routing/home/index.tsx index 3bbd3098788c3..8642561fd19e8 100644 --- a/x-pack/plugins/apm/public/components/routing/home/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/home/index.tsx @@ -169,6 +169,10 @@ export const home = { t.partial({ refreshPaused: t.union([t.literal('true'), t.literal('false')]), refreshInterval: t.string, + page: toNumberRt, + pageSize: toNumberRt, + sortField: t.string, + sortDirection: t.union([t.literal('asc'), t.literal('desc')]), }), offsetRt, ]), diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx index 777d7bcb67a96..55b486f5ae366 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_main_template.tsx @@ -71,15 +71,17 @@ export function ApmMainTemplate({ [shouldBypassNoDataScreen, data?.hasData] ); + const isLoading = + status === FETCH_STATUS.LOADING || + fleetApmPoliciesStatus === FETCH_STATUS.LOADING; + const noDataConfig = getNoDataConfig({ basePath, docsLink: docLinks!.links.observability.guide, hasApmData: data?.hasData, hasApmIntegrations: fleetApmPoliciesData?.hasApmPolicies, shouldBypassNoDataScreen, - loading: - status === FETCH_STATUS.LOADING || - fleetApmPoliciesStatus === FETCH_STATUS.LOADING, + loading: isLoading, }); const { @@ -96,6 +98,7 @@ export function ApmMainTemplate({ const pageTemplate = ( { } const PAGE_SIZE_OPTIONS = [10, 25, 50]; -const INITIAL_PAGE_SIZE = 25; +export const INITIAL_PAGE_SIZE = 25; function defaultSortFn( items: T[], diff --git a/x-pack/plugins/apm/server/routes/errors/route.ts b/x-pack/plugins/apm/server/routes/errors/route.ts index 1d9f46d886f3b..f49ab9aaca8e0 100644 --- a/x-pack/plugins/apm/server/routes/errors/route.ts +++ b/x-pack/plugins/apm/server/routes/errors/route.ts @@ -70,7 +70,7 @@ const errorsMainStatisticsRoute = createApmServerRoute({ const errorsDetailedStatisticsRoute = createApmServerRoute({ endpoint: - 'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics', + 'POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics', params: t.type({ path: t.type({ serviceName: t.string, @@ -82,9 +82,9 @@ const errorsDetailedStatisticsRoute = createApmServerRoute({ offsetRt, t.type({ numBuckets: toNumberRt, - groupIds: jsonRt.pipe(t.array(t.string)), }), ]), + body: t.type({ groupIds: jsonRt.pipe(t.array(t.string)) }), }), options: { tags: ['access:apm'] }, handler: async ( @@ -107,7 +107,8 @@ const errorsDetailedStatisticsRoute = createApmServerRoute({ const { path: { serviceName }, - query: { environment, kuery, numBuckets, groupIds, start, end, offset }, + query: { environment, kuery, numBuckets, start, end, offset }, + body: { groupIds }, } = params; return getErrorGroupPeriods({ diff --git a/x-pack/plugins/apm/server/routes/rum_client/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/routes/rum_client/__snapshots__/queries.test.ts.snap index 52c4c4b1d0333..e56aca85de3c4 100644 --- a/x-pack/plugins/apm/server/routes/rum_client/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/routes/rum_client/__snapshots__/queries.test.ts.snap @@ -1,79 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`rum client dashboard queries fetches long task metrics 1`] = ` -Object { - "apm": Object { - "events": Array [ - "transaction", - ], - }, - "body": Object { - "aggs": Object { - "longTaskCount": Object { - "percentiles": Object { - "field": "transaction.experience.longtask.count", - "hdr": Object { - "number_of_significant_value_digits": 3, - }, - "percents": Array [ - 50, - ], - }, - }, - "longTaskMax": Object { - "percentiles": Object { - "field": "transaction.experience.longtask.max", - "hdr": Object { - "number_of_significant_value_digits": 3, - }, - "percents": Array [ - 50, - ], - }, - }, - "longTaskSum": Object { - "percentiles": Object { - "field": "transaction.experience.longtask.sum", - "hdr": Object { - "number_of_significant_value_digits": 3, - }, - "percents": Array [ - 50, - ], - }, - }, - }, - "query": Object { - "bool": Object { - "filter": Array [ - Object { - "range": Object { - "@timestamp": Object { - "format": "epoch_millis", - "gte": 0, - "lte": 50000, - }, - }, - }, - Object { - "term": Object { - "transaction.type": "page-load", - }, - }, - Object { - "exists": Object { - "field": "transaction.marks.navigationTiming.fetchStart", - }, - }, - ], - "must_not": Array [], - }, - }, - "size": 0, - }, -} -`; - exports[`rum client dashboard queries fetches page load distribution 1`] = ` Object { "apm": Object { diff --git a/x-pack/plugins/apm/server/routes/rum_client/queries.test.ts b/x-pack/plugins/apm/server/routes/rum_client/queries.test.ts index a3725b0500c5f..eb2bb60ac0a25 100644 --- a/x-pack/plugins/apm/server/routes/rum_client/queries.test.ts +++ b/x-pack/plugins/apm/server/routes/rum_client/queries.test.ts @@ -11,7 +11,6 @@ import { } from '../../utils/test_helpers'; import { getPageViewTrends } from './get_page_view_trends'; import { getPageLoadDistribution } from './get_page_load_distribution'; -import { getLongTaskMetrics } from './get_long_task_metrics'; describe('rum client dashboard queries', () => { let mock: SearchParamsMock; @@ -48,15 +47,4 @@ describe('rum client dashboard queries', () => { ); expect(mock.params).toMatchSnapshot(); }); - - it('fetches long task metrics', async () => { - mock = await inspectSearchParams((setup) => - getLongTaskMetrics({ - setup, - start: 0, - end: 50000, - }) - ); - expect(mock.params).toMatchSnapshot(); - }); }); diff --git a/x-pack/plugins/apm/server/routes/rum_client/route.ts b/x-pack/plugins/apm/server/routes/rum_client/route.ts index d7911ef4a0206..c75f7545978d2 100644 --- a/x-pack/plugins/apm/server/routes/rum_client/route.ts +++ b/x-pack/plugins/apm/server/routes/rum_client/route.ts @@ -7,7 +7,6 @@ import * as t from 'io-ts'; import { Logger } from '@kbn/core/server'; import { setupRequest, Setup } from '../../lib/helpers/setup_request'; -import { getLongTaskMetrics } from './get_long_task_metrics'; import { getPageLoadDistribution } from './get_page_load_distribution'; import { getPageViewTrends } from './get_page_view_trends'; import { getPageLoadDistBreakdown } from './get_pl_dist_breakdown'; @@ -180,35 +179,6 @@ const rumVisitorsBreakdownRoute = createApmServerRoute({ }, }); -const rumLongTaskMetrics = createApmServerRoute({ - endpoint: 'GET /internal/apm/ux/long-task-metrics', - params: t.type({ - query: uxQueryRt, - }), - options: { tags: ['access:apm'] }, - handler: async ( - resources - ): Promise<{ - noOfLongTasks: number; - sumOfLongTasks: number; - longestLongTask: number; - }> => { - const setup = await setupUXRequest(resources); - - const { - query: { urlQuery, percentile, start, end }, - } = resources.params; - - return getLongTaskMetrics({ - setup, - urlQuery, - percentile: percentile ? Number(percentile) : undefined, - start, - end, - }); - }, -}); - function decodeUiFilters( logger: Logger, uiFiltersEncoded?: string @@ -243,5 +213,4 @@ export const rumRouteRepository = { ...rumPageLoadDistBreakdownRoute, ...rumPageViewsTrendRoute, ...rumVisitorsBreakdownRoute, - ...rumLongTaskMetrics, }; diff --git a/x-pack/plugins/apm/server/routes/services/route.ts b/x-pack/plugins/apm/server/routes/services/route.ts index ff388df333559..bc224b1315f8c 100644 --- a/x-pack/plugins/apm/server/routes/services/route.ts +++ b/x-pack/plugins/apm/server/routes/services/route.ts @@ -152,19 +152,16 @@ const servicesRoute = createApmServerRoute({ }); const servicesDetailedStatisticsRoute = createApmServerRoute({ - endpoint: 'GET /internal/apm/services/detailed_statistics', + endpoint: 'POST /internal/apm/services/detailed_statistics', params: t.type({ query: t.intersection([ - // t.intersection seemingly only supports 5 arguments so let's wrap them in another intersection - t.intersection([ - environmentRt, - kueryRt, - rangeRt, - offsetRt, - probabilityRt, - ]), - t.type({ serviceNames: jsonRt.pipe(t.array(t.string)) }), + environmentRt, + kueryRt, + rangeRt, + offsetRt, + probabilityRt, ]), + body: t.type({ serviceNames: jsonRt.pipe(t.array(t.string)) }), }), options: { tags: ['access:apm'] }, handler: async ( @@ -207,15 +204,10 @@ const servicesDetailedStatisticsRoute = createApmServerRoute({ plugins: { security }, } = resources; - const { - environment, - kuery, - offset, - serviceNames, - start, - end, - probability, - } = params.query; + const { environment, kuery, offset, start, end, probability } = + params.query; + + const { serviceNames } = params.body; const [setup, randomSampler] = await Promise.all([ setupRequest(resources), diff --git a/x-pack/plugins/cloud_security_posture/common/constants.ts b/x-pack/plugins/cloud_security_posture/common/constants.ts index 872b5353d31a1..6ffd8cc01709e 100644 --- a/x-pack/plugins/cloud_security_posture/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/common/constants.ts @@ -36,4 +36,5 @@ export const INTERNAL_FEATURE_FLAGS = { showFindingsGroupBy: true, } as const; -export const cspRuleAssetSavedObjectType = 'csp_rule'; +export const CSP_RULE_SAVED_OBJECT_TYPE = 'csp_rule'; +export const CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE = 'csp-rule-template'; diff --git a/x-pack/plugins/cloud_security_posture/common/schemas/csp_configuration.ts b/x-pack/plugins/cloud_security_posture/common/schemas/csp_configuration.ts index 2a3a1f1152540..0f5a1fbb7582f 100644 --- a/x-pack/plugins/cloud_security_posture/common/schemas/csp_configuration.ts +++ b/x-pack/plugins/cloud_security_posture/common/schemas/csp_configuration.ts @@ -6,7 +6,7 @@ */ import { schema as rt, TypeOf } from '@kbn/config-schema'; -// cspRulesConfigSchema have to be correspond to DataYaml struct in https://github.com/elastic/cloudbeat/blob/main/config/config.go#L44-L50 +// cspRulesConfigSchema has to match the 'DataYaml' struct in https://github.com/elastic/cloudbeat/blob/main/config/config.go#L45-L51 export const cspRulesConfigSchema = rt.object({ data_yaml: rt.object({ activated_rules: rt.object({ diff --git a/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule.ts b/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule.ts index 8ad7e07339936..1ed129b442f88 100644 --- a/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule.ts +++ b/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule.ts @@ -5,27 +5,38 @@ * 2.0. */ import { schema as rt, TypeOf } from '@kbn/config-schema'; +import { cspRuleMetadataSchema } from './csp_rule_metadata'; -// TODO: needs to be shared with cloudbeat -export const cspRuleSchema = rt.object({ +export const cspRuleSchemaV830 = rt.object({ + audit: rt.string(), + benchmark: rt.object({ name: rt.string(), version: rt.string() }), + default_value: rt.nullable(rt.string()), + description: rt.string(), + enabled: rt.boolean(), id: rt.string(), + impact: rt.nullable(rt.string()), + muted: rt.boolean(), name: rt.string(), - description: rt.string(), + package_policy_id: rt.string(), + policy_id: rt.string(), + profile_applicability: rt.string(), rationale: rt.string(), - impact: rt.string(), - default_value: rt.string(), - remediation: rt.string(), - benchmark: rt.object({ name: rt.string(), version: rt.string() }), + references: rt.nullable(rt.string()), rego_rule_id: rt.string(), + remediation: rt.string(), + section: rt.string(), tags: rt.arrayOf(rt.string()), + version: rt.string(), +}); + +export const cspRuleSchemaV840 = rt.object({ enabled: rt.boolean(), + metadata: cspRuleMetadataSchema, muted: rt.boolean(), package_policy_id: rt.string(), policy_id: rt.string(), - section: rt.string(), - audit: rt.string(), - references: rt.string(), - profile_applicability: rt.string(), }); -export type CspRuleSchema = TypeOf; +export type CspRuleTypeV830 = TypeOf; +export type CspRuleTypeV840 = TypeOf; +export type CspRuleType = CspRuleTypeV840; diff --git a/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule_metadata.ts b/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule_metadata.ts new file mode 100644 index 0000000000000..41fbd9df5869a --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule_metadata.ts @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { schema as rt, TypeOf } from '@kbn/config-schema'; + +export const cspRuleMetadataSchema = rt.object({ + audit: rt.string(), + benchmark: rt.object({ name: rt.string(), version: rt.string() }), + default_value: rt.maybe(rt.string()), + description: rt.string(), + id: rt.string(), + impact: rt.maybe(rt.string()), + name: rt.string(), + profile_applicability: rt.string(), + rationale: rt.string(), + references: rt.maybe(rt.string()), + rego_rule_id: rt.string(), + remediation: rt.string(), + section: rt.string(), + tags: rt.arrayOf(rt.string()), + version: rt.string(), +}); + +export type CspRuleMetadataType = TypeOf; diff --git a/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule_template.ts b/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule_template.ts index 04666bf1a9a90..09a1321ff4e3e 100644 --- a/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule_template.ts +++ b/x-pack/plugins/cloud_security_posture/common/schemas/csp_rule_template.ts @@ -5,24 +5,34 @@ * 2.0. */ import { schema as rt, TypeOf } from '@kbn/config-schema'; +import { cspRuleMetadataSchema } from './csp_rule_metadata'; -const cspRuleTemplateSchema = rt.object({ +export const cspRuleTemplateSchemaV830 = rt.object({ + audit: rt.string(), + benchmark: rt.object({ name: rt.string(), version: rt.string() }), + default_value: rt.maybe(rt.string()), + description: rt.string(), + enabled: rt.boolean(), id: rt.string(), + impact: rt.maybe(rt.string()), + muted: rt.boolean(), name: rt.string(), - tags: rt.arrayOf(rt.string()), - description: rt.string(), + profile_applicability: rt.string(), rationale: rt.string(), - default_value: rt.string(), - impact: rt.string(), - remediation: rt.string(), - benchmark: rt.object({ name: rt.string(), version: rt.string() }), + references: rt.maybe(rt.string()), rego_rule_id: rt.string(), + remediation: rt.string(), + section: rt.string(), + tags: rt.arrayOf(rt.string()), + version: rt.string(), +}); + +export const cspRuleTemplateSchemaV840 = rt.object({ enabled: rt.boolean(), + metadata: cspRuleMetadataSchema, muted: rt.boolean(), - section: rt.string(), - audit: rt.string(), - references: rt.string(), - profile_applicability: rt.string(), }); -export const cloudSecurityPostureRuleTemplateSavedObjectType = 'csp-rule-template'; -export type CloudSecurityPostureRuleTemplateSchema = TypeOf; + +export type CspRuleTemplateTypeV830 = TypeOf; +export type CspRuleTemplateTypeV840 = TypeOf; +export type CspRuleTemplateType = CspRuleTemplateTypeV840; diff --git a/x-pack/plugins/cloud_security_posture/common/schemas/index.ts b/x-pack/plugins/cloud_security_posture/common/schemas/index.ts new file mode 100644 index 0000000000000..de70e10237d62 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/common/schemas/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './csp_rule'; +export * from './csp_rule_metadata'; +export * from './csp_rule_template'; +export * from './csp_configuration'; diff --git a/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts b/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts index 745b59724dcb2..43856c4e5b1ba 100644 --- a/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts +++ b/x-pack/plugins/cloud_security_posture/common/utils/helpers.ts @@ -5,6 +5,8 @@ * 2.0. */ +import { CSP_RULE_SAVED_OBJECT_TYPE } from '../constants'; + /** * @example * declare const foo: Array @@ -19,3 +21,14 @@ export const extractErrorMessage = (e: unknown, defaultMessage = 'Unknown Error' return defaultMessage; // TODO: i18n }; + +export const createCspRuleSearchFilterByPackagePolicy = ({ + packagePolicyId, + policyId, +}: { + packagePolicyId: string; + policyId?: string; +}): string => + `${CSP_RULE_SAVED_OBJECT_TYPE}.attributes.package_policy_id: "${packagePolicyId}"${ + policyId ? ` AND ${CSP_RULE_SAVED_OBJECT_TYPE}.attributes.policy_id: "${policyId}"` : '' + }`; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/cases_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/cases_table.tsx index 30107d6689752..f978f19bc9a29 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/cases_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/cases_table.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { EuiFlexGroup, EuiFlexItem, EuiText } from '@elastic/eui'; import { EuiIcon } from '@elastic/eui'; -import * as TEXT from '../translations'; +import { FormattedMessage } from '@kbn/i18n-react'; export const CasesTable = () => { return ( @@ -17,7 +17,12 @@ export const CasesTable = () => { - {TEXT.COMING_SOON} + + + ); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/risks_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/risks_table.tsx index 16abf969f3062..b911688dc0cf1 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/risks_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_charts/risks_table.tsx @@ -15,9 +15,10 @@ import { EuiLink, EuiText, } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; import { ComplianceDashboardData, GroupedFindingsEvaluation } from '../../../../common/types'; import { CompactFormattedNumber } from '../../../components/compact_formatted_number'; -import * as TEXT from '../translations'; export interface RisksTableProps { data: ComplianceDashboardData['groupedFindingsEvaluation']; @@ -47,7 +48,9 @@ export const RisksTable = ({ { field: 'name', truncateText: true, - name: TEXT.CIS_SECTION, + name: i18n.translate('xpack.csp.dashboard.risksTable.cisSectionColumnLabel', { + defaultMessage: 'CIS Section', + }), render: (name: GroupedFindingsEvaluation['name']) => ( onCellClick(name)} className="eui-textTruncate"> {name} @@ -56,7 +59,9 @@ export const RisksTable = ({ }, { field: 'totalFailed', - name: TEXT.FINDINGS, + name: i18n.translate('xpack.csp.dashboard.risksTable.findingsColumnLabel', { + defaultMessage: 'Findings', + }), render: ( totalFailed: GroupedFindingsEvaluation['totalFailed'], resource: GroupedFindingsEvaluation @@ -91,7 +96,10 @@ export const RisksTable = ({ - {TEXT.VIEW_ALL_FAILED_FINDINGS} + diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx index 14d8c60c583ec..4b25fe3c8b175 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx @@ -11,10 +11,9 @@ import { render, screen } from '@testing-library/react'; import { TestProvider } from '../../test/test_provider'; import { ComplianceDashboard } from '..'; import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; -import { NO_DATA_CONFIG_TEXT } from './translations'; import { useCisKubernetesIntegration } from '../../common/api/use_cis_kubernetes_integration'; -import * as TEXT from './translations'; import { useComplianceDashboardDataApi } from '../../common/api/use_compliance_dashboard_data_api'; +import { DASHBOARD_PAGE_HEADER, MISSING_FINDINGS_NO_DATA_CONFIG } from './test_subjects'; jest.mock('../../common/api/use_setup_status_api'); jest.mock('../../common/api/use_cis_kubernetes_integration'); @@ -206,10 +205,8 @@ describe('', () => { renderComplianceDashboardPage(); - Object.values(NO_DATA_CONFIG_TEXT).forEach((text) => - expect(screen.getAllByText(text)[0]).toBeInTheDocument() - ); - expect(screen.queryByText(TEXT.CLOUD_POSTURE_SCORE)).not.toBeInTheDocument(); + expect(screen.queryByTestId(MISSING_FINDINGS_NO_DATA_CONFIG)).toBeInTheDocument(); + expect(screen.queryByTestId(DASHBOARD_PAGE_HEADER)).not.toBeInTheDocument(); }); it('shows dashboard when latestFindingsIndexStatus is applicable', () => { @@ -227,9 +224,7 @@ describe('', () => { renderComplianceDashboardPage(); - [NO_DATA_CONFIG_TEXT.BUTTON_TITLE, NO_DATA_CONFIG_TEXT.DESCRIPTION].forEach((text) => - expect(screen.queryByText(text)).not.toBeInTheDocument() - ); - expect(screen.getByText(TEXT.CLOUD_POSTURE_SCORE)).toBeInTheDocument(); + expect(screen.queryByTestId(MISSING_FINDINGS_NO_DATA_CONFIG)).not.toBeInTheDocument(); + expect(screen.getByTestId(DASHBOARD_PAGE_HEADER)).toBeInTheDocument(); }); }); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx index 978307d59c5ec..e0ba90441ea74 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx @@ -9,18 +9,24 @@ import React from 'react'; import { EuiSpacer, EuiIcon } from '@elastic/eui'; import { type KibanaPageTemplateProps } from '@kbn/kibana-react-plugin/public'; import { UseQueryResult } from 'react-query'; +import { i18n } from '@kbn/i18n'; +import { DASHBOARD_PAGE_HEADER, MISSING_FINDINGS_NO_DATA_CONFIG } from './test_subjects'; import { allNavigationItems } from '../../common/navigation/constants'; import { useCspBreadcrumbs } from '../../common/navigation/use_csp_breadcrumbs'; import { SummarySection } from './dashboard_sections/summary_section'; import { BenchmarksSection } from './dashboard_sections/benchmarks_section'; import { useComplianceDashboardDataApi } from '../../common/api'; import { CspPageTemplate } from '../../components/csp_page_template'; -import { CLOUD_POSTURE, NO_DATA_CONFIG_TEXT } from './translations'; import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; const getNoDataConfig = (onClick: () => void): KibanaPageTemplateProps['noDataConfig'] => ({ - pageTitle: NO_DATA_CONFIG_TEXT.PAGE_TITLE, - solution: NO_DATA_CONFIG_TEXT.SOLUTION, + 'data-test-subj': MISSING_FINDINGS_NO_DATA_CONFIG, + pageTitle: i18n.translate('xpack.csp.dashboard.noDataConfig.pageTitle', { + defaultMessage: 'Cloud Posture Dashboard', + }), + solution: i18n.translate('xpack.csp.dashboard.noDataConfig.solutionNameTitle', { + defaultMessage: 'Cloud Security Posture', + }), // TODO: Add real docs link once we have it docsLink: 'https://www.elastic.co/guide/index.html', logo: 'logoSecurity', @@ -28,8 +34,13 @@ const getNoDataConfig = (onClick: () => void): KibanaPageTemplateProps['noDataCo dashboardNoDataCard: { icon: , onClick, - title: NO_DATA_CONFIG_TEXT.BUTTON_TITLE, - description: NO_DATA_CONFIG_TEXT.DESCRIPTION, + title: i18n.translate('xpack.csp.dashboard.noDataConfig.actionTitle', { + defaultMessage: 'Try Again', + }), + description: i18n.translate('xpack.csp.dashboard.noDataConfig.actionDescription', { + defaultMessage: + "The cloud posture dashboard can't be presented since there are no findings. This can happen due to the agent not being installed yet, or since data is still being processed.", + }), }, }, }); @@ -46,7 +57,12 @@ export const ComplianceDashboard = () => { return ( - + - + - + - + - + diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/test_subjects.ts b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/test_subjects.ts new file mode 100644 index 0000000000000..04cf7a1398114 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/test_subjects.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const MISSING_FINDINGS_NO_DATA_CONFIG = 'missing-findings-no-data-config'; +export const DASHBOARD_PAGE_HEADER = 'dashboard-page-header'; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/translations.ts b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/translations.ts deleted file mode 100644 index 1154d0e55de08..0000000000000 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/translations.ts +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; - -export const CLOUD_POSTURE = i18n.translate('xpack.csp.cloud_posture', { - defaultMessage: 'Cloud Posture', -}); - -export const CLOUD_POSTURE_SCORE = i18n.translate('xpack.csp.cloud_posture_score', { - defaultMessage: 'Cloud Posture Score', -}); - -export const RISKS = i18n.translate('xpack.csp.complianceDashboard.failedFindingsChartLabel', { - defaultMessage: 'Failed Findings', -}); - -export const OPEN_CASES = i18n.translate('xpack.csp.open_cases', { - defaultMessage: 'Open Cases', -}); - -export const COMING_SOON = i18n.translate('xpack.csp.coming_soon', { - defaultMessage: 'Coming soon', -}); - -export const COMPLIANCE_SCORE = i18n.translate('xpack.csp.compliance_score', { - defaultMessage: 'Compliance Score', -}); - -export const COMPLIANCE_TREND = i18n.translate('xpack.csp.compliance_trend', { - defaultMessage: 'Compliance Trend', -}); - -export const POSTURE_SCORE = i18n.translate('xpack.csp.posture_score', { - defaultMessage: 'Posture Score', -}); - -export const STATUS = i18n.translate('xpack.csp.status', { - defaultMessage: 'STATUS', -}); - -export const TOTAL_FAILURES = i18n.translate('xpack.csp.total_failures', { - defaultMessage: 'Total Failures', -}); - -export const ERROR = i18n.translate('xpack.csp.error', { - defaultMessage: 'Error', -}); - -export const POSTURE_SCORE_TREND = i18n.translate('xpack.csp.posture_score_trend', { - defaultMessage: 'Posture Score Trend', -}); - -export const ACTIVE_FRAMEWORKS = i18n.translate('xpack.csp.active_frameworks', { - defaultMessage: 'Active Frameworks', -}); - -export const TOTAL_RESOURCES = i18n.translate('xpack.csp.total_resources', { - defaultMessage: 'Total Resources', -}); - -export const PASSED = i18n.translate('xpack.csp.passed', { - defaultMessage: 'Passed', -}); - -export const FAILED = i18n.translate('xpack.csp.failed', { - defaultMessage: 'Failed', -}); - -export const VIEW_ALL_FAILED_FINDINGS = i18n.translate('xpack.csp.view_all_failed_findings', { - defaultMessage: 'View all failed findings', -}); - -export const CIS_SECTION = i18n.translate('xpack.csp.dashboard.risksTable.cisSectionColumnLabel', { - defaultMessage: 'CIS Section', -}); - -export const FINDINGS = i18n.translate('xpack.csp.findings', { - defaultMessage: 'Findings', -}); - -export const NO_DATA_CONFIG_TEXT = { - PAGE_TITLE: i18n.translate('xpack.csp.complianceDashboard.noDataConfig.pageTitle', { - defaultMessage: 'Cloud Posture Dashboard', - }), - SOLUTION: i18n.translate('xpack.csp.complianceDashboard.noDataConfig.solutionNameLabel', { - defaultMessage: 'Cloud Security Posture', - }), - BUTTON_TITLE: i18n.translate('xpack.csp.complianceDashboard.noDataConfig.actionTitle', { - defaultMessage: 'Try Again', - }), - DESCRIPTION: i18n.translate('xpack.csp.complianceDashboard.noDataConfig.actionDescription', { - defaultMessage: - "The cloud posture dashboard can't be presented since there are no findings. This can happen due to the agent not being installed yet, or since data is still being processed.", - }), -}; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/overview_tab.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/overview_tab.tsx index 1c2606d42111d..31e7795670f7c 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/overview_tab.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/overview_tab.tsx @@ -44,14 +44,22 @@ export const getRemediationList = (rule: CspFinding['rule']) => [ title: '', description: {rule.remediation}, }, - { - title: TEXT.IMPACT, - description: {rule.impact}, - }, - { - title: TEXT.DEFAULT_VALUE, - description: {rule.default_value}, - }, + ...(rule.impact + ? [ + { + title: TEXT.IMPACT, + description: {rule.impact}, + }, + ] + : []), + ...(rule.default_value + ? [ + { + title: TEXT.DEFAULT_VALUE, + description: {rule.default_value}, + }, + ] + : []), { title: TEXT.RATIONALE, description: {rule.rationale}, diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/rule_tab.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/rule_tab.tsx index 1196bd586b0f0..36ee5d405159a 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/rule_tab.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/findings_flyout/rule_tab.tsx @@ -36,15 +36,18 @@ export const getRuleList = (rule: CspFinding['rule']) => [ title: TEXT.BENCHMARK, description: rule.benchmark.name, }, - { title: TEXT.AUDIT, description: {rule.audit}, }, - { - title: TEXT.REFERENCES, - description: {rule.references}, - }, + ...(rule.references + ? [ + { + title: TEXT.REFERENCES, + description: {rule.references}, + }, + ] + : []), ]; export const RuleTab = ({ data }: { data: CspFinding }) => ( diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.test.tsx index a64e1bc30f851..431296623a060 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/latest_findings/latest_findings_table.test.tsx @@ -27,21 +27,24 @@ const getFakeFindings = (name: string): CspFinding & { id: string } => ({ }, }, rule: { - name, - description: chance.paragraph(), - impact: chance.word(), - remediation: chance.word(), + audit: chance.paragraph(), benchmark: { name: 'CIS Kubernetes', version: '1.6.0', }, - section: chance.sentence(), - audit: chance.paragraph(), - references: chance.paragraph(), + default_value: chance.sentence(), + description: chance.paragraph(), + id: chance.guid(), + impact: chance.word(), + name, profile_applicability: chance.sentence(), rationale: chance.paragraph(), - default_value: chance.sentence(), + references: chance.paragraph(), + rego_rule_id: 'cis_X_X_X', + remediation: chance.word(), + section: chance.sentence(), tags: [], + version: '1.0', }, agent: { id: chance.string(), diff --git a/x-pack/plugins/cloud_security_posture/public/pages/findings/types.ts b/x-pack/plugins/cloud_security_posture/public/pages/findings/types.ts index 4f984c5a1f1e3..b5f05a02bcc51 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/findings/types.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/findings/types.ts @@ -6,6 +6,7 @@ */ import type { DataView } from '@kbn/data-views-plugin/common'; import type { BoolQuery, Filter, Query } from '@kbn/es-query'; +import type { CspRuleMetadataType } from '../../../common/schemas'; export type FindingsGroupByKind = 'default' | 'resource'; @@ -30,7 +31,7 @@ export interface CspFinding { cycle_id: string; result: CspFindingResult; resource: CspFindingResource; - rule: CspRule; + rule: CspRuleMetadataType; host: CspFindingHost; agent: CspFindingAgent; ecs: { @@ -38,21 +39,6 @@ export interface CspFinding { }; } -interface CspRule { - benchmark: { name: string; version: string }; - section: string; - audit: string; - references: string; - profile_applicability: string; - description: string; - impact: string; - default_value: string; - rationale: string; - name: string; - remediation: string; - tags: string[]; -} - interface CspFindingResult { evaluation: 'passed' | 'failed'; expected?: Record; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx index e81fcd489180e..6925d0d9d7ead 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.test.tsx @@ -50,20 +50,35 @@ const getRuleMock = ({ savedObjectId?: string; id?: string; enabled: boolean; -}) => +}): RuleSavedObject => ({ id: savedObjectId, updatedAt: chance.date().toISOString(), attributes: { - id, - name: chance.sentence(), + metadata: { + audit: chance.sentence(), + benchmark: { + name: chance.word(), + version: chance.sentence(), + }, + default_value: chance.sentence(), + description: chance.sentence(), + id, + impact: chance.sentence(), + name: chance.sentence(), + profile_applicability: chance.sentence(), + rationale: chance.sentence(), + references: chance.sentence(), + rego_rule_id: chance.word(), + remediation: chance.sentence(), + section: chance.sentence(), + tags: [chance.word(), chance.word()], + version: chance.sentence(), + }, package_policy_id: packagePolicyId, policy_id: policyId, enabled, - benchmark: { - name: chance.word(), - version: chance.sentence(), - }, + muted: false, }, } as RuleSavedObject); @@ -115,7 +130,7 @@ describe('', () => { ); expect(await screen.findByTestId(TEST_SUBJECTS.CSP_RULES_CONTAINER)).toBeInTheDocument(); - expect(await screen.findByText(rule1.attributes.name)).toBeInTheDocument(); + expect(await screen.findByText(rule1.attributes.metadata.name)).toBeInTheDocument(); expect( screen .getByTestId(TEST_SUBJECTS.getCspRulesTableItemSwitchTestId(rule1.id)) diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx index 797f8c0796568..26460e63a8086 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_container.tsx @@ -7,8 +7,11 @@ import React, { useEffect, useState, useMemo, useCallback, useRef } from 'react'; import { type EuiBasicTable, EuiPanel, EuiSpacer, EuiCallOut } from '@elastic/eui'; import { useParams } from 'react-router-dom'; -import { cspRuleAssetSavedObjectType } from '../../../common/constants'; -import { extractErrorMessage, isNonNullable } from '../../../common/utils/helpers'; +import { + extractErrorMessage, + createCspRuleSearchFilterByPackagePolicy, + isNonNullable, +} from '../../../common/utils/helpers'; import { RulesTable } from './rules_table'; import { RulesBottomBar } from './rules_bottom_bar'; import { RulesTableHeader } from './rules_table_header'; @@ -35,9 +38,6 @@ interface RulesPageData { export type RulesState = RulesPageData & RulesQuery; -const getSimpleQueryString = (searchValue?: string): string => - searchValue ? `${searchValue}*` : ''; - const getChangedRules = ( baseRules: ReadonlyMap, currentChangedRules: ReadonlyMap, @@ -100,7 +100,10 @@ export const RulesContainer = () => { const [isAllSelected, setIsAllSelected] = useState(false); const [visibleSelectedRulesIds, setVisibleSelectedRulesIds] = useState([]); const [rulesQuery, setRulesQuery] = useState({ - filter: `${cspRuleAssetSavedObjectType}.attributes.policy_id: "${params.policyId}" and ${cspRuleAssetSavedObjectType}.attributes.package_policy_id: "${params.packagePolicyId}"`, + filter: createCspRuleSearchFilterByPackagePolicy({ + packagePolicyId: params.packagePolicyId, + policyId: params.policyId, + }), search: '', page: 0, perPage: 10, @@ -108,7 +111,7 @@ export const RulesContainer = () => { const { data, status, error, refetch } = useFindCspRules({ filter: rulesQuery.filter, - search: getSimpleQueryString(rulesQuery.search), + search: rulesQuery.search, page: 1, perPage: MAX_ITEMS_PER_PAGE, }); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx index 517aace52cc90..c175089caf67a 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_flyout.tsx @@ -48,7 +48,7 @@ export const RuleFlyout = ({ onClose, rule, toggleRule }: RuleFlyoutProps) => { > -

{rule.attributes.name}

+

{rule.attributes.metadata.name}

@@ -67,7 +67,10 @@ export const RuleFlyout = ({ onClose, rule, toggleRule }: RuleFlyoutProps) => { {tab === 'overview' && toggleRule(rule)} />} {tab === 'remediation' && ( - + )} @@ -87,7 +90,7 @@ const RuleOverviewTab = ({ rule, toggleRule }: { rule: RuleSavedObject; toggleRu - + ); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_table.tsx b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_table.tsx index ed8c27d7fa2b8..2a47e0dd399c8 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_table.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/rules_table.tsx @@ -108,7 +108,7 @@ const getColumns = ({ setSelectedRuleId, }: GetColumnProps): Array> => [ { - field: 'attributes.name', + field: 'attributes.metadata.name', name: TEXT.RULE_NAME, width: '60%', truncateText: true, @@ -127,7 +127,7 @@ const getColumns = ({ ), }, { - field: 'attributes.section', + field: 'attributes.metadata.section', name: TEXT.CIS_SECTION, width: '15%', }, diff --git a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts index bd6df3116680f..17f112df10803 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts +++ b/x-pack/plugins/cloud_security_posture/public/pages/rules/use_csp_rules.ts @@ -9,16 +9,13 @@ import { FunctionKeys } from 'utility-types'; import type { SavedObjectsFindOptions, SimpleSavedObject } from '@kbn/core/public'; import { UPDATE_RULES_CONFIG_ROUTE_PATH, - cspRuleAssetSavedObjectType, + CSP_RULE_SAVED_OBJECT_TYPE, } from '../../../common/constants'; -import type { CspRuleSchema } from '../../../common/schemas/csp_rule'; +import type { CspRuleType } from '../../../common/schemas'; import { useKibana } from '../../common/hooks/use_kibana'; import { UPDATE_FAILED } from './translations'; -export type RuleSavedObject = Omit< - SimpleSavedObject, - FunctionKeys ->; +export type RuleSavedObject = Omit, FunctionKeys>; export type RulesQuery = Required< Pick @@ -28,14 +25,13 @@ export type RulesQueryResult = ReturnType; export const useFindCspRules = ({ search, page, perPage, filter }: RulesQuery) => { const { savedObjects } = useKibana().services; - return useQuery([cspRuleAssetSavedObjectType, { search, page, perPage }], () => - savedObjects.client.find({ - type: cspRuleAssetSavedObjectType, - search, - searchFields: ['name'], + return useQuery([CSP_RULE_SAVED_OBJECT_TYPE, { search, page, perPage }], () => + savedObjects.client.find({ + type: CSP_RULE_SAVED_OBJECT_TYPE, + search: search ? `"${search}"*` : '', + searchFields: ['metadata.name.text'], page: 1, - // NOTE: 'name.raw' is a field mapping we defined on 'name' - sortField: 'name.raw', + sortField: 'metadata.name', perPage, filter, }) @@ -52,11 +48,11 @@ export const useBulkUpdateCspRules = () => { packagePolicyId, }: { savedObjectRules: RuleSavedObject[]; - packagePolicyId: CspRuleSchema['package_policy_id']; + packagePolicyId: CspRuleType['package_policy_id']; }) => { await savedObjects.client.bulkUpdate( savedObjectRules.map((savedObjectRule) => ({ - type: cspRuleAssetSavedObjectType, + type: CSP_RULE_SAVED_OBJECT_TYPE, id: savedObjectRule.id, attributes: savedObjectRule.attributes, })) @@ -75,7 +71,7 @@ export const useBulkUpdateCspRules = () => { onSettled: () => // Invalidate all queries for simplicity queryClient.invalidateQueries({ - queryKey: cspRuleAssetSavedObjectType, + queryKey: CSP_RULE_SAVED_OBJECT_TYPE, exact: false, }), } diff --git a/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts b/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts index 16bebd252ee49..50dac15250e04 100644 --- a/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts +++ b/x-pack/plugins/cloud_security_posture/server/fleet_integration/fleet_integration.ts @@ -13,12 +13,12 @@ import type { Logger, } from '@kbn/core/server'; import { PackagePolicy, DeletePackagePoliciesResponse } from '@kbn/fleet-plugin/common'; +import { createCspRuleSearchFilterByPackagePolicy } from '../../common/utils/helpers'; import { - cloudSecurityPostureRuleTemplateSavedObjectType, - CloudSecurityPostureRuleTemplateSchema, -} from '../../common/schemas/csp_rule_template'; -import { cspRuleAssetSavedObjectType } from '../../common/constants'; -import { CspRuleSchema } from '../../common/schemas/csp_rule'; + CSP_RULE_SAVED_OBJECT_TYPE, + CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE, +} from '../../common/constants'; +import type { CspRuleType, CspRuleTemplateType } from '../../common/schemas'; type ArrayElement = ArrayType extends ReadonlyArray< infer ElementType @@ -35,9 +35,9 @@ export const onPackagePolicyPostCreateCallback = async ( savedObjectsClient: SavedObjectsClientContract ): Promise => { // Create csp-rules from the generic asset - const existingRuleTemplates: SavedObjectsFindResponse = + const existingRuleTemplates: SavedObjectsFindResponse = await savedObjectsClient.find({ - type: cloudSecurityPostureRuleTemplateSavedObjectType, + type: CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE, perPage: 10000, }); @@ -69,15 +69,15 @@ export const removeCspRulesInstancesCallback = async ( logger: Logger ): Promise => { try { - const { saved_objects: cspRules }: SavedObjectsFindResponse = - await soClient.find({ - type: cspRuleAssetSavedObjectType, - filter: `${cspRuleAssetSavedObjectType}.attributes.package_policy_id: ${deletedPackagePolicy.id} AND ${cspRuleAssetSavedObjectType}.attributes.policy_id: ${deletedPackagePolicy.policy_id}`, - perPage: 10000, - }); - await Promise.all( - cspRules.map((rule) => soClient.delete(cspRuleAssetSavedObjectType, rule.id)) - ); + const { saved_objects: cspRules }: SavedObjectsFindResponse = await soClient.find({ + type: CSP_RULE_SAVED_OBJECT_TYPE, + filter: createCspRuleSearchFilterByPackagePolicy({ + packagePolicyId: deletedPackagePolicy.id, + policyId: deletedPackagePolicy.policy_id, + }), + perPage: 10000, + }); + await Promise.all(cspRules.map((rule) => soClient.delete(CSP_RULE_SAVED_OBJECT_TYPE, rule.id))); } catch (e) { logger.error(`Failed to delete CSP rules after delete package ${deletedPackagePolicy.id}`); logger.error(e); @@ -90,9 +90,9 @@ export const isCspPackageInstalled = async ( ): Promise => { // TODO: check if CSP package installed via the Fleet API try { - const { saved_objects: postDeleteRules }: SavedObjectsFindResponse = + const { saved_objects: postDeleteRules }: SavedObjectsFindResponse = await soClient.find({ - type: cspRuleAssetSavedObjectType, + type: CSP_RULE_SAVED_OBJECT_TYPE, }); if (!postDeleteRules.length) { @@ -108,10 +108,10 @@ export const isCspPackageInstalled = async ( const generateRulesFromTemplates = ( packagePolicyId: string, policyId: string, - cspRuleTemplates: Array> -): Array> => + cspRuleTemplates: Array> +): Array> => cspRuleTemplates.map((template) => ({ - type: cspRuleAssetSavedObjectType, + type: CSP_RULE_SAVED_OBJECT_TYPE, attributes: { ...template.attributes, package_policy_id: packagePolicyId, diff --git a/x-pack/plugins/cloud_security_posture/server/index.ts b/x-pack/plugins/cloud_security_posture/server/index.ts index 16fc2a2434bf9..1462eccda6cca 100755 --- a/x-pack/plugins/cloud_security_posture/server/index.ts +++ b/x-pack/plugins/cloud_security_posture/server/index.ts @@ -8,7 +8,6 @@ import type { PluginInitializerContext } from '@kbn/core/server'; import { CspPlugin } from './plugin'; export type { CspServerPluginSetup, CspServerPluginStart } from './types'; -export type { cspRuleTemplateAssetType } from './saved_objects/csp_rule_template'; export const plugin = (initializerContext: PluginInitializerContext) => new CspPlugin(initializerContext); diff --git a/x-pack/plugins/cloud_security_posture/server/plugin.ts b/x-pack/plugins/cloud_security_posture/server/plugin.ts index 127c9ccbd0b0d..4666c110b015d 100755 --- a/x-pack/plugins/cloud_security_posture/server/plugin.ts +++ b/x-pack/plugins/cloud_security_posture/server/plugin.ts @@ -31,8 +31,7 @@ import type { CspServerPluginStartServices, } from './types'; import { defineRoutes } from './routes'; -import { cspRuleTemplateAssetType } from './saved_objects/csp_rule_template'; -import { cspRuleAssetType } from './saved_objects/csp_rule_type'; +import { setupSavedObjects } from './saved_objects'; import { initializeCspIndices } from './create_indices/create_indices'; import { initializeCspTransforms } from './create_transforms/create_transforms'; import { @@ -82,8 +81,7 @@ export class CspPlugin security: plugins.security, }; - core.savedObjects.registerType(cspRuleAssetType); - core.savedObjects.registerType(cspRuleTemplateAssetType); + setupSavedObjects(core.savedObjects); const router = core.http.createRouter(); diff --git a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts index d19a86d5b5c27..8246d1f1eee5c 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/benchmarks/benchmarks.ts @@ -19,11 +19,10 @@ import type { AgentPolicy, ListResult, } from '@kbn/fleet-plugin/common'; -import { CspRuleSchema } from '../../../common/schemas/csp_rule'; import { BENCHMARKS_ROUTE_PATH, CLOUD_SECURITY_POSTURE_PACKAGE_NAME, - cspRuleAssetSavedObjectType, + CSP_RULE_SAVED_OBJECT_TYPE, } from '../../../common/constants'; import { BENCHMARK_PACKAGE_POLICY_PREFIX, @@ -32,7 +31,11 @@ import { } from '../../../common/schemas/benchmark'; import { CspAppContext } from '../../plugin'; import type { Benchmark, CspRulesStatus } from '../../../common/types'; -import { isNonNullable } from '../../../common/utils/helpers'; +import type { CspRuleType } from '../../../common/schemas'; +import { + createCspRuleSearchFilterByPackagePolicy, + isNonNullable, +} from '../../../common/utils/helpers'; import { CspRouter } from '../../types'; export const PACKAGE_POLICY_SAVED_OBJECT_TYPE = 'ingest-package-policies'; @@ -104,15 +107,18 @@ export interface RulesStatusAggregation { export const getCspRulesStatus = ( soClient: SavedObjectsClientContract, packagePolicy: PackagePolicy -): Promise> => { - const cspRules = soClient.find({ - type: cspRuleAssetSavedObjectType, - filter: `${cspRuleAssetSavedObjectType}.attributes.package_policy_id: ${packagePolicy.id} AND ${cspRuleAssetSavedObjectType}.attributes.policy_id: ${packagePolicy.policy_id}`, +): Promise> => { + const cspRules = soClient.find({ + type: CSP_RULE_SAVED_OBJECT_TYPE, + filter: createCspRuleSearchFilterByPackagePolicy({ + packagePolicyId: packagePolicy.id, + policyId: packagePolicy.policy_id, + }), aggs: { enabled_status: { filter: { term: { - [`${cspRuleAssetSavedObjectType}.attributes.enabled`]: true, + [`${CSP_RULE_SAVED_OBJECT_TYPE}.attributes.enabled`]: true, }, }, }, diff --git a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.test.ts b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.test.ts index 9c8a96cab06cb..f24dcc5cbbca6 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.test.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.test.ts @@ -25,8 +25,8 @@ import { CspAppContext } from '../../plugin'; import { createPackagePolicyMock } from '@kbn/fleet-plugin/common/mocks'; import { createPackagePolicyServiceMock } from '@kbn/fleet-plugin/server/mocks'; -import { cspRuleAssetSavedObjectType } from '../../../common/constants'; -import { CspRuleSchema } from '../../../common/schemas/csp_rule'; +import { CSP_RULE_SAVED_OBJECT_TYPE } from '../../../common/constants'; +import type { CspRuleType } from '../../../common/schemas'; import { ElasticsearchClient, @@ -38,6 +38,7 @@ import { Chance } from 'chance'; import { PackagePolicy, UpdatePackagePolicy } from '@kbn/fleet-plugin/common'; import { securityMock } from '@kbn/security-plugin/server/mocks'; import { mockAuthenticatedUser } from '@kbn/security-plugin/common/model/authenticated_user.mock'; +import { DeepPartial } from 'utility-types'; describe('Update rules configuration API', () => { let logger: ReturnType; @@ -123,59 +124,87 @@ describe('Update rules configuration API', () => { await getCspRules(mockSoClient, packagePolicy); expect(mockSoClient.find).toBeCalledTimes(1); expect(mockSoClient.find).toHaveBeenCalledWith( - expect.objectContaining({ type: cspRuleAssetSavedObjectType }) + expect.objectContaining({ type: CSP_RULE_SAVED_OBJECT_TYPE }) ); }); it('create csp rules config based on activated csp rules', async () => { - const cspRules = { + const cspRules: DeepPartial> = { page: 1, per_page: 1000, total: 2, saved_objects: [ { type: 'csp_rule', - rego_rule_id: '1.1.1', - attributes: { enabled: true, rego_rule_id: 'cis_1_1_1' }, + attributes: { + enabled: true, + metadata: { + rego_rule_id: 'cis_1_1_1', + }, + }, }, { type: 'csp_rule', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_2' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_2', + }, + }, }, { type: 'csp_rule', - attributes: { enabled: true, rego_rule_id: 'cis_1_1_3' }, + attributes: { + enabled: true, + metadata: { + rego_rule_id: 'cis_1_1_3', + }, + }, }, ], - } as unknown as SavedObjectsFindResponse; - const cspConfig = await createRulesConfig(cspRules); + }; + const cspConfig = await createRulesConfig(cspRules as SavedObjectsFindResponse); expect(cspConfig).toMatchObject({ data_yaml: { activated_rules: { cis_k8s: ['cis_1_1_1', 'cis_1_1_3'] } }, }); }); it('create empty csp rules config when all rules are disabled', async () => { - const cspRules = { + const cspRules: DeepPartial> = { page: 1, per_page: 1000, total: 2, saved_objects: [ { type: 'csp_rule', - rego_rule_id: '1.1.1', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_1' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_1', + }, + }, }, { type: 'csp_rule', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_2' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_2', + }, + }, }, { type: 'csp_rule', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_3' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_3', + }, + }, }, ], - } as unknown as SavedObjectsFindResponse; - const cspConfig = await createRulesConfig(cspRules); + }; + const cspConfig = await createRulesConfig(cspRules as SavedObjectsFindResponse); expect(cspConfig).toMatchObject({ data_yaml: { activated_rules: { cis_k8s: [] } } }); }); @@ -213,26 +242,41 @@ describe('Update rules configuration API', () => { } ); - mockSoClient.find.mockResolvedValueOnce({ + const cspRules: DeepPartial> = { page: 1, per_page: 1000, total: 2, saved_objects: [ { type: 'csp_rule', - rego_rule_id: '1.1.1', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_1' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_1', + }, + }, }, { type: 'csp_rule', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_2' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_2', + }, + }, }, { type: 'csp_rule', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_3' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_3', + }, + }, }, ], - } as unknown as SavedObjectsFindResponse); + }; + mockSoClient.find.mockResolvedValueOnce(cspRules as SavedObjectsFindResponse); const mockPackagePolicy = createPackagePolicyMock(); mockPackagePolicy.vars = { dataYaml: { type: 'foo' } }; @@ -260,26 +304,41 @@ describe('Update rules configuration API', () => { mockSoClient = savedObjectsClientMock.create(); const mockPackagePolicyService = createPackagePolicyServiceMock(); - mockSoClient.find.mockResolvedValueOnce({ + const cspRules: DeepPartial> = { page: 1, per_page: 1000, total: 2, saved_objects: [ { type: 'csp_rule', - rego_rule_id: '1.1.1', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_1' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_1', + }, + }, }, { type: 'csp_rule', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_2' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_2', + }, + }, }, { type: 'csp_rule', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_3' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_3', + }, + }, }, ], - } as unknown as SavedObjectsFindResponse); + }; + mockSoClient.find.mockResolvedValueOnce(cspRules as SavedObjectsFindResponse); const mockPackagePolicy = createPackagePolicyMock(); const packagePolicyId1 = chance.guid(); @@ -319,18 +378,23 @@ describe('Update rules configuration API', () => { const mockPackagePolicy = createPackagePolicyMock(); const user = mockAuthenticatedUser(); - mockSoClient.find.mockResolvedValueOnce({ + const cspRules: DeepPartial> = { page: 1, per_page: 1000, total: 2, saved_objects: [ { type: 'csp_rule', - rego_rule_id: '1.1.1', - attributes: { enabled: false, rego_rule_id: 'cis_1_1_1' }, + attributes: { + enabled: false, + metadata: { + rego_rule_id: 'cis_1_1_1', + }, + }, }, ], - } as unknown as SavedObjectsFindResponse); + }; + mockSoClient.find.mockResolvedValueOnce(cspRules as SavedObjectsFindResponse); mockPackagePolicy.vars = { dataYaml: { type: 'yaml' } }; diff --git a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts index 63d7b605ff08d..78e7c6fce0e5b 100644 --- a/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts +++ b/x-pack/plugins/cloud_security_posture/server/routes/configuration/update_rules_configuration.ts @@ -19,13 +19,13 @@ import yaml from 'js-yaml'; import { PackagePolicy, PackagePolicyConfigRecord } from '@kbn/fleet-plugin/common'; import { PackagePolicyServiceInterface } from '@kbn/fleet-plugin/server'; import { AuthenticatedUser } from '@kbn/security-plugin/common'; +import { createCspRuleSearchFilterByPackagePolicy } from '../../../common/utils/helpers'; import { CspAppContext } from '../../plugin'; -import { CspRulesConfigSchema } from '../../../common/schemas/csp_configuration'; -import { CspRuleSchema } from '../../../common/schemas/csp_rule'; +import type { CspRuleType, CspRulesConfigSchema } from '../../../common/schemas'; import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME, UPDATE_RULES_CONFIG_ROUTE_PATH, - cspRuleAssetSavedObjectType, + CSP_RULE_SAVED_OBJECT_TYPE, } from '../../../common/constants'; import { CspRouter } from '../../types'; @@ -52,10 +52,13 @@ export const getPackagePolicy = async ( export const getCspRules = ( soClient: SavedObjectsClientContract, packagePolicy: PackagePolicy -): Promise> => { - return soClient.find({ - type: cspRuleAssetSavedObjectType, - filter: `${cspRuleAssetSavedObjectType}.attributes.package_policy_id: ${packagePolicy.id} AND ${cspRuleAssetSavedObjectType}.attributes.policy_id: ${packagePolicy.policy_id}`, +): Promise> => { + return soClient.find({ + type: CSP_RULE_SAVED_OBJECT_TYPE, + filter: createCspRuleSearchFilterByPackagePolicy({ + packagePolicyId: packagePolicy.id, + policyId: packagePolicy.policy_id, + }), searchFields: ['name'], // TODO: research how to get all rules perPage: 10000, @@ -63,13 +66,15 @@ export const getCspRules = ( }; export const createRulesConfig = ( - cspRules: SavedObjectsFindResponse + cspRules: SavedObjectsFindResponse ): CspRulesConfigSchema => { const activatedRules = cspRules.saved_objects.filter((cspRule) => cspRule.attributes.enabled); const config = { data_yaml: { activated_rules: { - cis_k8s: activatedRules.map((activatedRule) => activatedRule.attributes.rego_rule_id), + cis_k8s: activatedRules.map( + (activatedRule) => activatedRule.attributes.metadata.rego_rule_id + ), }, }, }; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts deleted file mode 100644 index a75386728ce8b..0000000000000 --- a/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_template.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { SavedObjectsType } from '@kbn/core/server'; -import { - type CloudSecurityPostureRuleTemplateSchema, - cloudSecurityPostureRuleTemplateSavedObjectType, -} from '../../common/schemas/csp_rule_template'; - -const ruleTemplateAssetSavedObjectMappings: SavedObjectsType['mappings'] = - { - dynamic: false, - properties: {}, - }; - -export const cspRuleTemplateAssetType: SavedObjectsType = { - name: cloudSecurityPostureRuleTemplateSavedObjectType, - hidden: false, - management: { - importableAndExportable: true, - visibleInManagement: true, - }, - namespaceType: 'agnostic', - mappings: ruleTemplateAssetSavedObjectMappings, -}; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_type.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_type.ts deleted file mode 100644 index 3afa68fdea228..0000000000000 --- a/x-pack/plugins/cloud_security_posture/server/saved_objects/csp_rule_type.ts +++ /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 { i18n } from '@kbn/i18n'; -import type { SavedObjectsType, SavedObjectsValidationMap } from '@kbn/core/server'; -import { cspRuleAssetSavedObjectType } from '../../common/constants'; -import { type CspRuleSchema, cspRuleSchema } from '../../common/schemas/csp_rule'; - -const validationMap: SavedObjectsValidationMap = { - '1.0.0': cspRuleSchema, -}; - -export const ruleAssetSavedObjectMappings: SavedObjectsType['mappings'] = { - dynamic: false, - properties: { - name: { - type: 'text', // search - fields: { - // TODO: how is fields mapping shared with UI ? - raw: { - type: 'keyword', // sort - }, - }, - }, - package_policy_id: { - type: 'keyword', - }, - policy_id: { - type: 'keyword', - }, - description: { - type: 'text', - }, - enabled: { - type: 'boolean', - fields: { - keyword: { - type: 'keyword', // sort - }, - }, - }, - }, -}; - -export const cspRuleAssetType: SavedObjectsType = { - name: cspRuleAssetSavedObjectType, - hidden: false, - namespaceType: 'agnostic', - mappings: ruleAssetSavedObjectMappings, - schemas: validationMap, - // migrations: {} - management: { - importableAndExportable: true, - visibleInManagement: true, - getTitle: (savedObject) => - `${i18n.translate('xpack.csp.cspSettings.rules', { - defaultMessage: `CSP Security Rules - `, - })} ${savedObject.attributes.benchmark.name} ${savedObject.attributes.benchmark.version} ${ - savedObject.attributes.name - }`, - }, -}; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/index.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/index.ts new file mode 100644 index 0000000000000..7217fd8606ed9 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/saved_objects/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { setupSavedObjects } from './saved_objects'; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/mappings.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/mappings.ts new file mode 100644 index 0000000000000..80f7ae069d459 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/saved_objects/mappings.ts @@ -0,0 +1,46 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { SavedObjectsTypeMappingDefinition } from '@kbn/core/server'; + +export const cspRuleSavedObjectMapping: SavedObjectsTypeMappingDefinition = { + dynamic: false, + properties: { + metadata: { + type: 'object', + properties: { + name: { + type: 'keyword', + fields: { + text: { + type: 'text', + }, + }, + }, + }, + }, + package_policy_id: { + type: 'keyword', + }, + policy_id: { + type: 'keyword', + }, + enabled: { + type: 'boolean', + fields: { + keyword: { + type: 'keyword', + }, + }, + }, + }, +}; + +export const cspRuleTemplateSavedObjectMapping: SavedObjectsTypeMappingDefinition = { + dynamic: false, + properties: {}, +}; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_rule.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_rule.ts new file mode 100644 index 0000000000000..7bade4dc1ff3d --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_rule.ts @@ -0,0 +1,41 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + SavedObjectMigrationMap, + SavedObjectUnsanitizedDoc, + SavedObjectMigrationContext, +} from '@kbn/core/server'; +import { CspRuleTypeV830, CspRuleTypeV840 } from '../../../common/schemas/csp_rule'; + +function migrateCspRuleMetadata( + doc: SavedObjectUnsanitizedDoc, + context: SavedObjectMigrationContext +): SavedObjectUnsanitizedDoc { + // eslint-disable-next-line @typescript-eslint/naming-convention + const { enabled, muted, package_policy_id, policy_id, ...metadata } = doc.attributes; + + return { + ...doc, + attributes: { + enabled, + muted, + package_policy_id, + policy_id, + metadata: { + ...metadata, + impact: metadata.impact || undefined, + default_value: metadata.default_value || undefined, + references: metadata.references || undefined, + }, + }, + }; +} + +export const cspRuleMigrations: SavedObjectMigrationMap = { + '8.4.0': migrateCspRuleMetadata, +}; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_rule_template.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_rule_template.ts new file mode 100644 index 0000000000000..c1c668bb76364 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/csp_rule_template.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + SavedObjectMigrationMap, + SavedObjectUnsanitizedDoc, + SavedObjectMigrationContext, +} from '@kbn/core/server'; +import { + CspRuleTemplateTypeV830, + CspRuleTemplateTypeV840, +} from '../../../common/schemas/csp_rule_template'; + +function migrateCspRuleMetadata( + doc: SavedObjectUnsanitizedDoc, + context: SavedObjectMigrationContext +): SavedObjectUnsanitizedDoc { + const { enabled, muted, ...metadata } = doc.attributes; + return { + ...doc, + attributes: { + enabled, + muted, + metadata: { + ...metadata, + impact: metadata.impact || undefined, + default_value: metadata.default_value || undefined, + references: metadata.references || undefined, + }, + }, + }; +} + +export const cspRuleTemplateMigrations: SavedObjectMigrationMap = { + '8.4.0': migrateCspRuleMetadata, +}; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/index.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/index.ts new file mode 100644 index 0000000000000..01120e57d4efb --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/saved_objects/migrations/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './csp_rule'; +export * from './csp_rule_template'; diff --git a/x-pack/plugins/cloud_security_posture/server/saved_objects/saved_objects.ts b/x-pack/plugins/cloud_security_posture/server/saved_objects/saved_objects.ts new file mode 100644 index 0000000000000..ebc53043fa1b8 --- /dev/null +++ b/x-pack/plugins/cloud_security_posture/server/saved_objects/saved_objects.ts @@ -0,0 +1,63 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { SavedObjectsServiceSetup } from '@kbn/core/server'; +import { cspRuleSavedObjectMapping, cspRuleTemplateSavedObjectMapping } from './mappings'; +import { cspRuleMigrations, cspRuleTemplateMigrations } from './migrations'; +import { + cspRuleSchemaV830, + cspRuleSchemaV840, + cspRuleTemplateSchemaV830, + cspRuleTemplateSchemaV840, + CspRuleTemplateType, + CspRuleType, +} from '../../common/schemas'; + +import { + CSP_RULE_SAVED_OBJECT_TYPE, + CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE, +} from '../../common/constants'; + +export function setupSavedObjects(savedObjects: SavedObjectsServiceSetup) { + savedObjects.registerType({ + name: CSP_RULE_SAVED_OBJECT_TYPE, + hidden: false, + namespaceType: 'agnostic', + management: { + importableAndExportable: true, + visibleInManagement: true, + getTitle: (savedObject) => + `${i18n.translate('xpack.csp.cspSettings.rules', { + defaultMessage: `CSP Security Rules - `, + })} ${savedObject.attributes.metadata.benchmark.name} ${ + savedObject.attributes.metadata.benchmark.version + } ${savedObject.attributes.metadata.name}`, + }, + schemas: { + '8.3.0': cspRuleSchemaV830, + '8.4.0': cspRuleSchemaV840, + }, + migrations: cspRuleMigrations, + mappings: cspRuleSavedObjectMapping, + }); + savedObjects.registerType({ + name: CSP_RULE_TEMPLATE_SAVED_OBJECT_TYPE, + hidden: false, + namespaceType: 'agnostic', + management: { + importableAndExportable: true, + visibleInManagement: true, + }, + schemas: { + '8.3.0': cspRuleTemplateSchemaV830, + '8.4.0': cspRuleTemplateSchemaV840, + }, + migrations: cspRuleTemplateMigrations, + mappings: cspRuleTemplateSavedObjectMapping, + }); +} diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_api.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_api.test.tsx index f47be4269edcc..93b92271cbd28 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_api.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_api.test.tsx @@ -9,10 +9,12 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { EuiSteps } from '@elastic/eui'; + import { MethodApi } from './method_api'; import { NewSearchIndexTemplate } from './new_search_index_template'; -describe('API ingestion method', () => { +describe('MethodApi', () => { beforeEach(() => { jest.clearAllMocks(); }); @@ -22,5 +24,6 @@ describe('API ingestion method', () => { const template = wrapper.find(NewSearchIndexTemplate); expect(template.prop('type')).toEqual('api'); + expect(template.find(EuiSteps)).toHaveLength(1); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_api.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_api.tsx index bfe9c6293da03..a5b2cfdb74a3b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_api.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_api.tsx @@ -12,7 +12,8 @@ import React from 'react'; -import { EuiText } from '@elastic/eui'; +import { EuiSteps, EuiText } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { NewSearchIndexTemplate } from './new_search_index_template'; @@ -37,6 +38,81 @@ export const MethodApi: React.FC = () => { docsUrl="#" type="api" onSubmit={() => null} - /> + > + +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.createIndex.content', + { + defaultMessage: + 'Provide a unique name for your index and select an optional language analyzer.', + } + )} +

+
+ ), + status: 'incomplete', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.configureIngestion.title', + { + defaultMessage: 'Configure ingestion settings', + } + ), + titleSize: 'xs', + children: ( + +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.methodApi.steps.configureIngestion.content', + { + defaultMessage: + 'Generate an API key and view the documentation for posting documents to the Elasticsearch API endpoint. Language clients are available for streamlined integration.', + } + )} +

+
+ ), + status: 'incomplete', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.buildSearchExperience.title', + { + defaultMessage: 'Build a search experience', + } + ), + titleSize: 'xs', + children: ( + +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.buildSearchExperience.content', + { + defaultMessage: + 'Connect your newly created Elasticsearch index to an App Search engine to build a cusomtizable search experience.', + } + )} +

+
+ ), + status: 'incomplete', + }, + ]} + /> + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector.test.tsx new file mode 100644 index 0000000000000..e5aee84132c6c --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector.test.tsx @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic'; + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { EuiSteps } from '@elastic/eui'; + +import { Status } from '../../../../../common/types/api'; + +import { MethodConnector } from './method_connector'; +import { NewSearchIndexTemplate } from './new_search_index_template'; + +describe('MethodConnector', () => { + beforeEach(() => { + jest.clearAllMocks(); + setMockValues({ status: Status.IDLE }); + setMockActions({ makeRequest: jest.fn() }); + }); + + it('renders connector ingestion method tab', () => { + const wrapper = shallow(); + const template = wrapper.find(NewSearchIndexTemplate); + + expect(template.prop('type')).toEqual('connector'); + expect(template.find(EuiSteps)).toHaveLength(1); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector.tsx index 0a79bb1600d35..f8890f898ae32 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_connector.tsx @@ -15,6 +15,7 @@ import React from 'react'; import { useActions, useValues } from 'kea'; +import { EuiSteps, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { Status } from '../../../../../common/types/api'; @@ -40,6 +41,81 @@ export const MethodConnector: React.FC = () => { onSubmit={(name) => makeRequest({ indexName: name })} formDisabled={status === Status.LOADING} buttonLoading={status === Status.LOADING} - /> + > + +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.createIndex.content', + { + defaultMessage: + 'Provide a unique name for your index and select an optional language analyzer.', + } + )} +

+ + ), + status: 'incomplete', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.configureIngestion.title', + { + defaultMessage: 'Configure ingestion settings', + } + ), + titleSize: 'xs', + children: ( + +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.methodConnector.steps.configureIngestion.content', + { + defaultMessage: + 'Clone the connector package repository on GitHub and build a custom connector that suits your needs.', + } + )} +

+
+ ), + status: 'incomplete', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.buildSearchExperience.title', + { + defaultMessage: 'Build a search experience', + } + ), + titleSize: 'xs', + children: ( + +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.buildSearchExperience.content', + { + defaultMessage: + 'Connect your newly created Elasticsearch index to an App Search engine to build a cusomtizable search experience.', + } + )} +

+
+ ), + status: 'incomplete', + }, + ]} + /> + ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_crawler.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_crawler.test.tsx new file mode 100644 index 0000000000000..aa81e661332a1 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_crawler.test.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { EuiSteps } from '@elastic/eui'; + +import { MethodCrawler } from './method_crawler'; +import { NewSearchIndexTemplate } from './new_search_index_template'; + +describe('MethodApi', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders API ingestion method tab', () => { + const wrapper = shallow(); + const template = wrapper.find(NewSearchIndexTemplate); + + expect(template.prop('type')).toEqual('crawler'); + expect(template.find(EuiSteps)).toHaveLength(1); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_crawler.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_crawler.tsx index 8f46e5e0dc0e9..7dfa4456e8054 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_crawler.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/method_crawler.tsx @@ -13,7 +13,7 @@ import React from 'react'; -import { EuiPanel, EuiTitle } from '@elastic/eui'; +import { EuiSteps, EuiText } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { NewSearchIndexTemplate } from './new_search_index_template'; @@ -33,19 +33,80 @@ export const MethodCrawler: React.FC = () => { type="crawler" onSubmit={() => null} > - - -

Place the crawler domain validation here...

-
-
+ +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.createIndex.content', + { + defaultMessage: + 'Provide a unique name for your index and select an optional language analyzer.', + } + )} +

+ + ), + status: 'incomplete', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.configureIngestion.title', + { + defaultMessage: 'Configure ingestion settings', + } + ), + titleSize: 'xs', + children: ( + +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.methodCrawler.steps.configureIngestion.content', + { + defaultMessage: + 'Enter the domains you’d like to crawl, configure crawl rules and entry points, set up a crawl schedule and let Enterprise Search do the rest.', + } + )} +

+
+ ), + status: 'incomplete', + }, + { + title: i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.buildSearchExperience.title', + { + defaultMessage: 'Build a search experience', + } + ), + titleSize: 'xs', + children: ( + +

+ {i18n.translate( + 'xpack.enterpriseSearch.content.newIndex.steps.buildSearchExperience.content', + { + defaultMessage: + 'Connect your newly created Elasticsearch index to an App Search engine to build a cusomtizable search experience.', + } + )} +

+
+ ), + status: 'incomplete', + }, + ]} + /> ); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.test.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.test.tsx new file mode 100644 index 0000000000000..8d7a41312a642 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.test.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { setMockValues, setMockActions } from '../../../__mocks__/kea_logic'; + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { + NewSearchIndexTemplate, + Props as NewSearchIndexTemplateProps, +} from './new_search_index_template'; + +describe('NewSearchIndexTemplate', () => { + const mockProps: NewSearchIndexTemplateProps = { + title: 'Index using the API', + description: 'Provide a name and optionally select a language analyzer.', + docsUrl: 'http://www.elastic.co/guide', + onSubmit: jest.fn(), + type: 'api', + }; + + beforeEach(() => { + jest.clearAllMocks(); + setMockValues({ name: 'my-name', rawName: 'MY$_RAW_$NAME', language: 'Universal' }); + setMockActions({ makeRequest: jest.fn() }); + }); + + it('renders children', () => { + const wrapper = shallow( + +
+ + ); + + expect(wrapper.find('[data-test-subj="ChildComponent"]')).toHaveLength(1); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.tsx index 6252b28a54b38..9524b1c83bd1c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/new_index/new_search_index_template.tsx @@ -22,11 +22,11 @@ import { EuiFlexItem, EuiForm, EuiFormRow, + EuiHorizontalRule, EuiLink, EuiPanel, EuiSelect, EuiSpacer, - EuiSteps, EuiText, EuiTitle, } from '@elastic/eui'; @@ -35,7 +35,7 @@ import { i18n } from '@kbn/i18n'; import { SUPPORTED_LANGUAGES } from './constants'; import { NewSearchIndexLogic } from './new_search_index_logic'; -interface SearchIndex { +export interface Props { title: React.ReactNode; description: React.ReactNode; docsUrl: string; @@ -46,7 +46,7 @@ interface SearchIndex { formDisabled?: boolean; } -export const NewSearchIndexTemplate: React.FC = ({ +export const NewSearchIndexTemplate: React.FC = ({ children, title, description, @@ -98,7 +98,6 @@ export const NewSearchIndexTemplate: React.FC = ({

- @@ -159,7 +158,6 @@ export const NewSearchIndexTemplate: React.FC = ({ - {children} @@ -190,82 +188,8 @@ export const NewSearchIndexTemplate: React.FC = ({ - - - -

- {i18n.translate( - 'xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.steps.createIndex.content', - { - defaultMessage: - 'Provide a unique name for your index and select an optional language analyzer.', - } - )} -

- - ), - status: 'incomplete', - }, - { - title: i18n.translate( - 'xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.steps.configureIngestion.title', - { - defaultMessage: 'Configure ingestion settings', - } - ), - titleSize: 'xs', - children: ( - -

- {i18n.translate( - 'xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.steps.configureIngestion.content', - { - defaultMessage: - 'Generate an API key and view the documentation for posting documents to the Elasticsearch API endpoint. Language clients are available for streamlined integration.', - } - )} -

-
- ), - status: 'incomplete', - }, - { - title: i18n.translate( - 'xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.steps.buildSearchExperience.title', - { - defaultMessage: 'Build a search experience', - } - ), - titleSize: 'xs', - children: ( - -

- {i18n.translate( - 'xpack.enterpriseSearch.content.newIndex.newSearchIndexTemplate.steps.buildSearchExperience.content', - { - defaultMessage: - 'Connect your newly created Elasticsearch index to an App Search engine to build a cusomtizable search experience.', - } - )} -

-
- ), - status: 'incomplete', - }, - ]} - /> + + {children} ); }; diff --git a/x-pack/plugins/fleet/common/constants/download_source.ts b/x-pack/plugins/fleet/common/constants/download_source.ts new file mode 100644 index 0000000000000..1b74c627e93f7 --- /dev/null +++ b/x-pack/plugins/fleet/common/constants/download_source.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 DEFAULT_DOWNLOAD_SOURCE = 'artifactory.elastic.co'; + +export const DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE = 'ingest-download-sources'; + +export const DEFAULT_DOWNLOAD_SOURCE_ID = 'fleet-default-download-source'; diff --git a/x-pack/plugins/fleet/common/constants/epm.ts b/x-pack/plugins/fleet/common/constants/epm.ts index 07f6fa048dc42..776691a895c17 100644 --- a/x-pack/plugins/fleet/common/constants/epm.ts +++ b/x-pack/plugins/fleet/common/constants/epm.ts @@ -18,6 +18,9 @@ export const FLEET_SYNTHETICS_PACKAGE = 'synthetics'; export const FLEET_KUBERNETES_PACKAGE = 'kubernetes'; export const FLEET_CLOUD_SECURITY_POSTURE_PACKAGE = 'cloud_security_posture'; +export const PACKAGE_TEMPLATE_SUFFIX = '@package'; +export const USER_SETTINGS_TEMPLATE_SUFFIX = '@custom'; + export const FLEET_ELASTIC_AGENT_DETAILS_DASHBOARD_ID = 'elastic_agent-f47f18cc-9c7d-4278-b2ea-a6dee816d395'; /* diff --git a/x-pack/plugins/fleet/common/constants/index.ts b/x-pack/plugins/fleet/common/constants/index.ts index ef8cb63f132b4..31bcd317a8052 100644 --- a/x-pack/plugins/fleet/common/constants/index.ts +++ b/x-pack/plugins/fleet/common/constants/index.ts @@ -16,6 +16,7 @@ export * from './output'; export * from './enrollment_api_key'; export * from './settings'; export * from './preconfiguration'; +export * from './download_source'; // TODO: This is the default `index.max_result_window` ES setting, which dictates // the maximum amount of results allowed to be returned from a search. It's possible diff --git a/x-pack/plugins/fleet/common/constants/routes.ts b/x-pack/plugins/fleet/common/constants/routes.ts index 33bf1b6f6b5b7..f9c36b986969e 100644 --- a/x-pack/plugins/fleet/common/constants/routes.ts +++ b/x-pack/plugins/fleet/common/constants/routes.ts @@ -15,6 +15,7 @@ export const DATA_STREAM_API_ROOT = `${API_ROOT}/data_streams`; export const PACKAGE_POLICY_API_ROOT = `${API_ROOT}/package_policies`; export const AGENT_POLICY_API_ROOT = `${API_ROOT}/agent_policies`; export const K8S_API_ROOT = `${API_ROOT}/kubernetes`; +export const DOWNLOAD_SOURCE_API_ROOT = `${API_ROOT}/agent_download_sources`; export const LIMITED_CONCURRENCY_ROUTE_TAG = 'ingest:limited-concurrency'; @@ -151,3 +152,12 @@ export const PRECONFIGURATION_API_ROUTES = { RESET_PATTERN: `${INTERNAL_ROOT}/reset_preconfigured_agent_policies`, RESET_ONE_PATTERN: `${INTERNAL_ROOT}/reset_preconfigured_agent_policies/{agentPolicyId}`, }; + +// Agent download source routes +export const DOWNLOAD_SOURCE_API_ROUTES = { + LIST_PATTERN: `${API_ROOT}/agent_download_sources`, + INFO_PATTERN: `${API_ROOT}/agent_download_sources/{sourceId}`, + CREATE_PATTERN: `${API_ROOT}/agent_download_sources`, + UPDATE_PATTERN: `${API_ROOT}/agent_download_sources/{sourceId}`, + DELETE_PATTERN: `${API_ROOT}/agent_download_sources/{sourceId}`, +}; diff --git a/x-pack/plugins/fleet/common/openapi/bundled.json b/x-pack/plugins/fleet/common/openapi/bundled.json index eb6f7626ea35f..5e4138a5b51c5 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.json +++ b/x-pack/plugins/fleet/common/openapi/bundled.json @@ -3042,6 +3042,213 @@ ] } }, + "/agent_download_sources": { + "get": { + "summary": "Agent Download Sources", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "items": { + "type": "array", + "items": { + "$ref": "#/components/schemas/download_sources" + } + }, + "total": { + "type": "integer" + }, + "page": { + "type": "integer" + }, + "perPage": { + "type": "integer" + } + } + } + } + } + } + }, + "operationId": "get-download-sources" + }, + "post": { + "summary": "Agent Download Sources", + "description": "Create a new agent download source", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "item": { + "$ref": "#/components/schemas/download_sources" + } + } + } + } + } + } + }, + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "is_default": { + "type": "boolean" + }, + "host": { + "type": "string" + } + }, + "required": [ + "name", + "host", + "is_default" + ] + } + } + } + }, + "operationId": "post-download-sources" + } + }, + "/agent_download_sources/{sourceId}": { + "get": { + "summary": "Agent Download Sources - Info", + "tags": [], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "item": { + "$ref": "#/components/schemas/download_sources" + } + }, + "required": [ + "item" + ] + } + } + } + } + }, + "operationId": "get-one-download-source" + }, + "parameters": [ + { + "schema": { + "type": "string" + }, + "name": "sourceId", + "in": "path", + "required": true + } + ], + "delete": { + "summary": "Agent Download Sources - Delete", + "operationId": "delete-download-source", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ] + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + } + ] + }, + "put": { + "summary": "Agent Download Sources - Update", + "operationId": "update-download-source", + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "is_default": { + "type": "boolean" + }, + "host": { + "type": "string" + } + }, + "required": [ + "name", + "is_default", + "host" + ] + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "item": { + "$ref": "#/components/schemas/download_sources" + } + }, + "required": [ + "item" + ] + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/kbn_xsrf" + } + ] + } + }, "/logstash_api_keys": { "post": { "summary": "Generate Logstash API key", @@ -4572,6 +4779,30 @@ "name", "type" ] + }, + "download_sources": { + "title": "Download Source", + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "is_default": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "host": { + "type": "string" + } + }, + "required": [ + "id", + "is_default", + "name", + "host" + ] } } }, diff --git a/x-pack/plugins/fleet/common/openapi/bundled.yaml b/x-pack/plugins/fleet/common/openapi/bundled.yaml index 3793dfe7982dc..77218a60236dc 100644 --- a/x-pack/plugins/fleet/common/openapi/bundled.yaml +++ b/x-pack/plugins/fleet/common/openapi/bundled.yaml @@ -1872,6 +1872,135 @@ paths: - item parameters: - $ref: '#/components/parameters/kbn_xsrf' + /agent_download_sources: + get: + summary: Agent Download Sources + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/download_sources' + total: + type: integer + page: + type: integer + perPage: + type: integer + operationId: get-download-sources + post: + summary: Agent Download Sources + description: Create a new agent download source + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + item: + $ref: '#/components/schemas/download_sources' + requestBody: + content: + application/json: + schema: + type: object + properties: + id: + type: string + name: + type: string + is_default: + type: boolean + host: + type: string + required: + - name + - host + - is_default + operationId: post-download-sources + /agent_download_sources/{sourceId}: + get: + summary: Agent Download Sources - Info + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + item: + $ref: '#/components/schemas/download_sources' + required: + - item + operationId: get-one-download-source + parameters: + - schema: + type: string + name: sourceId + in: path + required: true + delete: + summary: Agent Download Sources - Delete + operationId: delete-download-source + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + id: + type: string + required: + - id + parameters: + - $ref: '#/components/parameters/kbn_xsrf' + put: + summary: Agent Download Sources - Update + operationId: update-download-source + requestBody: + content: + application/json: + schema: + type: object + properties: + name: + type: string + is_default: + type: boolean + host: + type: string + required: + - name + - is_default + - host + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + item: + $ref: '#/components/schemas/download_sources' + required: + - item + parameters: + - $ref: '#/components/parameters/kbn_xsrf' /logstash_api_keys: post: summary: Generate Logstash API key @@ -2894,5 +3023,22 @@ components: - is_default - name - type + download_sources: + title: Download Source + type: object + properties: + id: + type: string + is_default: + type: boolean + name: + type: string + host: + type: string + required: + - id + - is_default + - name + - host security: - basicAuth: [] diff --git a/x-pack/plugins/fleet/common/openapi/components/schemas/download_sources.yaml b/x-pack/plugins/fleet/common/openapi/components/schemas/download_sources.yaml new file mode 100644 index 0000000000000..d963e82089303 --- /dev/null +++ b/x-pack/plugins/fleet/common/openapi/components/schemas/download_sources.yaml @@ -0,0 +1,16 @@ +title: Download Source +type: object +properties: + id: + type: string + is_default: + type: boolean + name: + type: string + host: + type: string +required: + - id + - is_default + - name + - host diff --git a/x-pack/plugins/fleet/common/openapi/entrypoint.yaml b/x-pack/plugins/fleet/common/openapi/entrypoint.yaml index 275deb8e8b843..da5e4a00f58f4 100644 --- a/x-pack/plugins/fleet/common/openapi/entrypoint.yaml +++ b/x-pack/plugins/fleet/common/openapi/entrypoint.yaml @@ -108,6 +108,10 @@ paths: $ref: paths/outputs.yaml /outputs/{outputId}: $ref: paths/outputs@{output_id}.yaml + /agent_download_sources: + $ref: paths/agent_download_sources.yaml + /agent_download_sources/{sourceId}: + $ref: paths/agent_download_sources@{source_id}.yaml /logstash_api_keys: $ref: paths/logstash_api_keys.yaml components: diff --git a/x-pack/plugins/fleet/common/openapi/paths/agent_download_sources.yaml b/x-pack/plugins/fleet/common/openapi/paths/agent_download_sources.yaml new file mode 100644 index 0000000000000..a76eef05cae73 --- /dev/null +++ b/x-pack/plugins/fleet/common/openapi/paths/agent_download_sources.yaml @@ -0,0 +1,55 @@ +get: + summary: Agent Download Sources + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + items: + type: array + items: + $ref: ../components/schemas/download_sources.yaml + total: + type: integer + page: + type: integer + perPage: + type: integer + operationId: get-download-sources +post: + summary: Agent Download Sources + description: 'Create a new agent download source' + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + item: + $ref: ../components/schemas/download_sources.yaml + requestBody: + content: + application/json: + schema: + type: object + properties: + id: + type: string + name: + type: string + is_default: + type: boolean + host: + type: string + required: + - name + - host + - is_default + operationId: post-download-sources diff --git a/x-pack/plugins/fleet/common/openapi/paths/agent_download_sources@{source_id}.yaml b/x-pack/plugins/fleet/common/openapi/paths/agent_download_sources@{source_id}.yaml new file mode 100644 index 0000000000000..c9b97018aa523 --- /dev/null +++ b/x-pack/plugins/fleet/common/openapi/paths/agent_download_sources@{source_id}.yaml @@ -0,0 +1,72 @@ +get: + summary: Agent Download Sources - Info + tags: [] + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + item: + $ref: ../components/schemas/download_sources.yaml + required: + - item + operationId: get-one-download-source +parameters: + - schema: + type: string + name: sourceId + in: path + required: true +delete: + summary: Agent Download Sources - Delete + operationId: delete-download-source + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + id: + type: string + required: + - id + parameters: + - $ref: ../components/headers/kbn_xsrf.yaml +put: + summary: Agent Download Sources - Update + operationId: update-download-source + requestBody: + content: + application/json: + schema: + type: object + properties: + name: + type: string + is_default: + type: boolean + host: + type: string + required: + - name + - is_default + - host + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + properties: + item: + $ref: ../components/schemas/download_sources.yaml + required: + - item + parameters: + - $ref: ../components/headers/kbn_xsrf.yaml diff --git a/x-pack/plugins/fleet/common/services/agent_status.ts b/x-pack/plugins/fleet/common/services/agent_status.ts index d2a217a06e5bf..59ec2b9babd70 100644 --- a/x-pack/plugins/fleet/common/services/agent_status.ts +++ b/x-pack/plugins/fleet/common/services/agent_status.ts @@ -8,6 +8,8 @@ import { AGENT_POLLING_THRESHOLD_MS } from '../constants'; import type { Agent, AgentStatus } from '../types'; +const offlineTimeoutIntervalCount = 10; // 30s*10 = 5m timeout + export function getAgentStatus(agent: Agent): AgentStatus { const { last_checkin: lastCheckIn } = agent; @@ -34,7 +36,7 @@ export function getAgentStatus(agent: Agent): AgentStatus { if (agent.upgrade_started_at && !agent.upgraded_at) { return 'updating'; } - if (intervalsSinceLastCheckIn >= 10) { + if (intervalsSinceLastCheckIn >= offlineTimeoutIntervalCount) { return 'offline'; } @@ -63,7 +65,7 @@ export function buildKueryForErrorAgents(path: string = '') { export function buildKueryForOfflineAgents(path: string = '') { return `${path}last_checkin < now-${ - (4 * AGENT_POLLING_THRESHOLD_MS) / 1000 + (offlineTimeoutIntervalCount * AGENT_POLLING_THRESHOLD_MS) / 1000 }s AND not (${buildKueryForErrorAgents(path)}) AND not ( ${buildKueryForUpdatingAgents(path)} )`; } diff --git a/x-pack/plugins/fleet/common/services/datastream_es_name.test.ts b/x-pack/plugins/fleet/common/services/datastream_es_name.test.ts new file mode 100644 index 0000000000000..8e1eb3b1b9f12 --- /dev/null +++ b/x-pack/plugins/fleet/common/services/datastream_es_name.test.ts @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + getCustomPipelineNameForDatastream, + getRegistryDataStreamAssetBaseName, +} from './datastream_es_name'; + +describe('getCustomPipelineNameForDatastream', () => { + it('return the correct custom pipeline for datastream', () => { + const res = getCustomPipelineNameForDatastream({ + type: 'logs', + dataset: 'test', + } as any); + + expect(res).toBe('logs-test@custom'); + }); +}); + +describe('getRegistryDataStreamAssetBaseName', () => { + it('return the asset name', () => { + const dataStream = { + dataset: 'nginx.access', + title: 'Nginx Acess Logs', + release: 'beta', + type: 'logs', + ingest_pipeline: 'default', + package: 'nginx', + path: 'access', + }; + const name = getRegistryDataStreamAssetBaseName(dataStream); + expect(name).toStrictEqual('logs-nginx.access'); + }); + + it('return the asset name for hidden index', () => { + const dataStream = { + dataset: 'nginx.access', + title: 'Nginx Acess Logs', + release: 'beta', + type: 'logs', + ingest_pipeline: 'default', + package: 'nginx', + path: 'access', + hidden: true, + }; + const name = getRegistryDataStreamAssetBaseName(dataStream); + expect(name).toStrictEqual('.logs-nginx.access'); + }); +}); diff --git a/x-pack/plugins/fleet/common/services/datastream_es_name.ts b/x-pack/plugins/fleet/common/services/datastream_es_name.ts new file mode 100644 index 0000000000000..077f1f5f0dc7f --- /dev/null +++ b/x-pack/plugins/fleet/common/services/datastream_es_name.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { USER_SETTINGS_TEMPLATE_SUFFIX, PACKAGE_TEMPLATE_SUFFIX } from '../constants'; + +/** + * Creates the base name for Elasticsearch assets in the form of + * {type}-{dataset} + */ +export function getRegistryDataStreamAssetBaseName(dataStream: { + dataset: string; + type: string; + hidden?: boolean; +}): string { + const baseName = `${dataStream.type}-${dataStream.dataset}`; + return dataStream.hidden ? `.${baseName}` : baseName; +} + +/** + * Return the name for a component template + */ +export function getComponentTemplateNameForDatastream( + dataStream: { + dataset: string; + type: string; + hidden?: boolean; + }, + suffix?: typeof PACKAGE_TEMPLATE_SUFFIX | typeof USER_SETTINGS_TEMPLATE_SUFFIX +): string { + return `${getRegistryDataStreamAssetBaseName(dataStream)}${suffix ?? ''}`; +} + +/** + * Return the ingest pipeline name for a datastream + */ +export const getPipelineNameForDatastream = ({ + dataStream, + packageVersion, +}: { + dataStream: { dataset: string; type: string }; + packageVersion: string; +}): string => { + return `${dataStream.type}-${dataStream.dataset}-${packageVersion}`; +}; + +/** + * Return the custom user ingest pipeline name for a datastream + */ +export const getCustomPipelineNameForDatastream = (dataStream: { + dataset: string; + type: string; +}): string => { + return `${dataStream.type}-${dataStream.dataset}@custom`; +}; diff --git a/x-pack/plugins/fleet/common/services/index.ts b/x-pack/plugins/fleet/common/services/index.ts index d8a7ed080ac63..3774abb1cc4b3 100644 --- a/x-pack/plugins/fleet/common/services/index.ts +++ b/x-pack/plugins/fleet/common/services/index.ts @@ -36,3 +36,9 @@ export { normalizeHostsForAgents } from './hosts_utils'; export { splitPkgKey } from './split_pkg_key'; export { getMaxPackageName } from './max_package_name'; export { getMinVersion, getMaxVersion } from './get_min_max_version'; +export { + getPipelineNameForDatastream, + getCustomPipelineNameForDatastream, + getRegistryDataStreamAssetBaseName, + getComponentTemplateNameForDatastream, +} from './datastream_es_name'; diff --git a/x-pack/plugins/fleet/common/types/models/agent.ts b/x-pack/plugins/fleet/common/types/models/agent.ts index f6c72ae9d2680..65c719947e52a 100644 --- a/x-pack/plugins/fleet/common/types/models/agent.ts +++ b/x-pack/plugins/fleet/common/types/models/agent.ts @@ -87,6 +87,7 @@ export interface Agent extends AgentBase { access_api_key?: string; status?: AgentStatus; packages: string[]; + sort?: Array; } export interface AgentSOAttributes extends AgentBase { diff --git a/x-pack/plugins/fleet/common/types/models/agent_policy.ts b/x-pack/plugins/fleet/common/types/models/agent_policy.ts index c289ebf32fd16..269a0d606b0c8 100644 --- a/x-pack/plugins/fleet/common/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/common/types/models/agent_policy.ts @@ -28,6 +28,7 @@ export interface NewAgentPolicy { // Nullable to allow user to reset to default outputs data_output_id?: string | null; monitoring_output_id?: string | null; + download_source_id?: string | null; } export interface AgentPolicy extends Omit { diff --git a/x-pack/plugins/fleet/common/types/models/download_sources.ts b/x-pack/plugins/fleet/common/types/models/download_sources.ts new file mode 100644 index 0000000000000..1595965be7d1d --- /dev/null +++ b/x-pack/plugins/fleet/common/types/models/download_sources.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface DownloadSourceBase { + name: string; + host: string; + is_default: boolean; +} + +export type DownloadSource = DownloadSourceBase & { + id: string; +}; +export type DownloadSourceAttributes = DownloadSourceBase & { + source_id?: string; +}; diff --git a/x-pack/plugins/fleet/common/types/models/index.ts b/x-pack/plugins/fleet/common/types/models/index.ts index ded6b3d9ee59d..07becab0af3f3 100644 --- a/x-pack/plugins/fleet/common/types/models/index.ts +++ b/x-pack/plugins/fleet/common/types/models/index.ts @@ -15,3 +15,4 @@ export * from './package_spec'; export * from './enrollment_api_key'; export * from './settings'; export * from './preconfiguration'; +export * from './download_sources'; diff --git a/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts b/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts new file mode 100644 index 0000000000000..13af84f372c2f --- /dev/null +++ b/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DownloadSourceBase } from '../models'; + +import type { ListResult } from './common'; + +export interface GetOneDownloadSourceResponse { + item: DownloadSourceBase; +} + +export interface DeleteDownloadSourceResponse { + id: string; +} + +export interface GetOneDownloadSourceRequest { + params: { + outputId: string; + }; +} + +export interface PutDownloadSourceRequest { + params: { + outputId: string; + }; + body: { + id: string; + name: string; + hosts: string; + is_default?: boolean; + }; +} + +export interface PostDownloadSourceRequest { + body: { + id: string; + name: string; + hosts: string; + is_default?: boolean; + }; +} + +export interface PutDownloadSourceResponse { + item: DownloadSourceBase; +} + +export type GetDownloadSourceResponse = ListResult; diff --git a/x-pack/plugins/fleet/common/types/rest_spec/index.ts b/x-pack/plugins/fleet/common/types/rest_spec/index.ts index 3ad6df3a97303..78b9f09f7f9f8 100644 --- a/x-pack/plugins/fleet/common/types/rest_spec/index.ts +++ b/x-pack/plugins/fleet/common/types/rest_spec/index.ts @@ -16,3 +16,4 @@ export * from './enrollment_api_key'; export * from './output'; export * from './settings'; export * from './app'; +export * from './download_sources'; diff --git a/x-pack/plugins/fleet/kibana.json b/x-pack/plugins/fleet/kibana.json index 4bfc6e95f0157..409e9f2a896ae 100644 --- a/x-pack/plugins/fleet/kibana.json +++ b/x-pack/plugins/fleet/kibana.json @@ -9,7 +9,7 @@ "ui": true, "configPath": ["xpack", "fleet"], "requiredPlugins": ["licensing", "data", "encryptedSavedObjects", "navigation", "customIntegrations", "share", "spaces", "security", "unifiedSearch"], - "optionalPlugins": ["features", "cloud", "usageCollection", "home", "globalSearch", "telemetry", "discover"], + "optionalPlugins": ["features", "cloud", "usageCollection", "home", "globalSearch", "telemetry", "discover", "ingestPipelines"], "extraPublicDirs": ["common"], "requiredBundles": ["kibanaReact", "cloud", "esUiShared", "infra", "kibanaUtils", "usageCollection", "unifiedSearch"] } diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_hooks.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_hooks.tsx new file mode 100644 index 0000000000000..b8fd2fdcdc81d --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_hooks.tsx @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useRouteMatch } from 'react-router-dom'; + +import { useLink } from '../../../../hooks'; + +export function usePackagePolicyEditorPageUrl() { + const { + params: { packagePolicyId, policyId }, + } = useRouteMatch<{ policyId: string; packagePolicyId: string }>(); + const { getHref } = useLink(); + + return packagePolicyId && policyId + ? getHref('edit_integration', { + policyId, + packagePolicyId, + }) + : getHref('integration_policy_edit', { + packagePolicyId, + }); +} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings.tsx new file mode 100644 index 0000000000000..8a2f056233041 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings.tsx @@ -0,0 +1,133 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { EuiBasicTable, EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle, EuiLink } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; + +import type { PackageInfo } from '../../../../types'; +import { getComponentTemplateNameForDatastream } from '../../../../../../../common'; +import { useStartServices } from '../../../../hooks'; + +import { usePackagePolicyEditorPageUrl } from './datastream_hooks'; + +export interface PackagePolicyEditorDatastreamMappingsProps { + packageInfo: PackageInfo; + dataStream: { dataset: string; type: string }; +} + +function useComponentTemplates(dataStream: { dataset: string; type: string }) { + return [ + { + templateName: getComponentTemplateNameForDatastream(dataStream, '@package'), + }, + { + templateName: getComponentTemplateNameForDatastream(dataStream, '@custom'), + canEdit: true, + }, + ]; +} + +export const PackagePolicyEditorDatastreamMappings: React.FunctionComponent< + PackagePolicyEditorDatastreamMappingsProps +> = ({ dataStream, packageInfo }) => { + const pageUrl = usePackagePolicyEditorPageUrl(); + + const { application, docLinks } = useStartServices(); + const componentTemplateItems = useComponentTemplates(dataStream); + + return ( + + + +
+ +
+
+
+ + + + + + ), + }} + /> + + + + { + const url = application.getUrlForApp('management', { + path: `/data/index_management/edit_component_template/${el.templateName}`, + }); + + application.navigateToUrl(`${url}?redirect_path=${pageUrl}`); + }, + available: ({ canEdit }) => !!canEdit, + }, + { + icon: 'inspect', + type: 'icon', + description: i18n.translate( + 'xpack.fleet.packagePolicyEditor.datastreamMappings.inspectBtn', + { + defaultMessage: 'Inspect mappings', + } + ), + name: 'inspect', + 'data-test-subj': 'datastreamInspectMappingsBtn', + isPrimary: true, + onClick: async (el) => { + const url = application.getUrlForApp('management', { + path: `/data/index_management/component_templates/${el.templateName}`, + }); + + application.navigateToUrl(`${url}?redirect_path=${pageUrl}`); + }, + }, + ], + }, + ]} + /> + +
+ ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.test.tsx new file mode 100644 index 0000000000000..a68facb62c3b4 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.test.tsx @@ -0,0 +1,78 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { createFleetTestRendererMock } from '../../../../../../mock'; +import { useGetPipeline } from '../../../../hooks'; + +import { PackagePolicyEditorDatastreamPipelines } from './datastream_pipelines'; + +const mockedUseGetPipeline = useGetPipeline as jest.MockedFunction; + +jest.mock('../../../../hooks', () => { + return { + ...jest.requireActual('../../../../hooks'), + FleetStatusProvider: (props: any) => { + return props.children; + }, + useFleetStatus: jest.fn().mockReturnValue({ isReady: true } as any), + useGetPipeline: jest.fn(), + }; +}); + +describe('DatastreamPipelines', () => { + it('should render with a add button if there is no custom pipeline', () => { + const renderer = createFleetTestRendererMock(); + mockedUseGetPipeline.mockReturnValue({ + isLoading: false, + error: { + statusCode: 404, + }, + } as any); + + const result = renderer.render( + + ); + + expect(result.queryByTestId('datastreamAddCustomIngestPipelineBtn')).not.toBeNull(); + expect(result.queryAllByTestId('datastreamInspectPipelineBtn')).toHaveLength(1); + expect(result.queryAllByTestId('datastreamEditPipelineBtn')).toHaveLength(0); + }); + + it('should render without a add button if there is a pipeline', () => { + const renderer = createFleetTestRendererMock(); + mockedUseGetPipeline.mockReturnValue({ + isLoading: false, + data: { + name: 'test', + }, + } as any); + + const result = renderer.render( + + ); + + expect(result.queryByTestId('datastreamAddCustomIngestPipelineBtn')).toBeNull(); + expect(result.queryAllByTestId('datastreamInspectPipelineBtn')).toHaveLength(2); + expect(result.queryAllByTestId('datastreamEditPipelineBtn')).toHaveLength(1); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.tsx new file mode 100644 index 0000000000000..33c1be4703121 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines.tsx @@ -0,0 +1,227 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useEffect, useMemo, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { + EuiBasicTable, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiText, + EuiTitle, + EuiSpacer, + EuiLink, +} from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; + +import type { PackageInfo } from '../../../../types'; +import { useStartServices, useGetPipeline } from '../../../../hooks'; +import { + getPipelineNameForDatastream, + getCustomPipelineNameForDatastream, +} from '../../../../../../../common'; + +import { usePackagePolicyEditorPageUrl } from './datastream_hooks'; + +export interface PackagePolicyEditorDatastreamPipelinesProps { + packageInfo: PackageInfo; + dataStream: { dataset: string; type: string }; +} + +interface PipelineItem { + pipelineName: string; + canEdit: boolean; +} + +function toPipelineItem(pipelineName: string, canEdit = false): PipelineItem { + return { pipelineName, canEdit }; +} + +function useDatastreamIngestPipelines( + packageInfo: PackageInfo, + dataStream: { dataset: string; type: string }, + pageUrl: string | null +) { + const [addPipelineUrl, setAddPipelineUrl] = useState(''); + + const { share } = useStartServices(); + const ingestPipelineLocator = share.url.locators.get('INGEST_PIPELINES_APP_LOCATOR'); + + const defaultPipelineName = getPipelineNameForDatastream({ + dataStream, + packageVersion: packageInfo.version, + }); + + const customPipelineName = getCustomPipelineNameForDatastream(dataStream); + + const res = useGetPipeline(customPipelineName); + + const pipelines: PipelineItem[] = useMemo(() => { + if (res.data) { + return [toPipelineItem(defaultPipelineName), toPipelineItem(customPipelineName, true)]; + } + return [toPipelineItem(defaultPipelineName)]; + }, [defaultPipelineName, customPipelineName, res.data]); + + useEffect(() => { + async function getUrl() { + if (!ingestPipelineLocator) { + return; + } + const createUrl = await ingestPipelineLocator.getUrl({ + page: 'pipeline_create', + }); + setAddPipelineUrl(`${createUrl}?name=${customPipelineName}&redirect_path=${pageUrl}`); + } + + getUrl(); + }, [customPipelineName, pageUrl, ingestPipelineLocator]); + + return { + isLoading: res.isLoading, + hasCustom: !res.isLoading && res.error?.statusCode !== 404, + pipelines, + addPipelineUrl, + }; +} + +export const PackagePolicyEditorDatastreamPipelines: React.FunctionComponent< + PackagePolicyEditorDatastreamPipelinesProps +> = ({ dataStream, packageInfo }) => { + const { application, share, docLinks } = useStartServices(); + const ingestPipelineLocator = share.url.locators.get('INGEST_PIPELINES_APP_LOCATOR'); + + const pageUrl = usePackagePolicyEditorPageUrl(); + + const { pipelines, addPipelineUrl, hasCustom, isLoading } = useDatastreamIngestPipelines( + packageInfo, + dataStream, + pageUrl + ); + + if (!dataStream) { + return null; + } + + return ( + + + +
+ +
+
+
+ + + + + + ), + }} + /> + + + + { + if (!ingestPipelineLocator) { + return; + } + const url = await ingestPipelineLocator.getUrl({ + page: 'pipeline_edit', + pipelineId: el.pipelineName, + }); + + application.navigateToUrl(`${url}?redirect_path=${pageUrl}`); + }, + available: ({ canEdit }) => canEdit, + }, + { + icon: 'inspect', + type: 'icon', + description: i18n.translate( + 'xpack.fleet.packagePolicyEditor.datastreamIngestPipelines.inspectBtn', + { + defaultMessage: 'Inspect pipeline', + } + ), + name: 'inspect', + 'data-test-subj': 'datastreamInspectPipelineBtn', + isPrimary: true, + onClick: async (el) => { + if (!ingestPipelineLocator) { + return; + } + const url = await ingestPipelineLocator.getUrl({ + page: 'pipeline_list', + }); + + application.navigateToUrl( + `${url}?pipeline=${el.pipelineName}&redirect_path=${pageUrl}` + ); + }, + }, + ], + }, + ]} + /> + + {!isLoading && !hasCustom && ( + + + + + + + )} +
+ ); +}; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/index.ts b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/index.ts index 08099f4078a08..b81947f49e65b 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/index.ts +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/index.ts @@ -7,3 +7,7 @@ export { IntegrationBreadcrumb } from './integration_breadcrumb'; export * from './steps'; +export { PackagePolicyEditorDatastreamPipelines } from './datastream_pipelines'; +export type { PackagePolicyEditorDatastreamPipelinesProps } from './datastream_pipelines'; +export { PackagePolicyEditorDatastreamMappings } from './datastream_mappings'; +export type { PackagePolicyEditorDatastreamMappingsProps } from './datastream_mappings'; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_panel.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_panel.tsx index 47056b1c2dabf..cc641812235ce 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_panel.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/components/package_policy_input_panel.tsx @@ -20,7 +20,9 @@ import { } from '@elastic/eui'; import type { + NewPackagePolicy, NewPackagePolicyInput, + PackageInfo, PackagePolicyInputStream, RegistryInput, RegistryStream, @@ -40,7 +42,7 @@ const ShortenedHorizontalRule = styled(EuiHorizontalRule)` const shouldShowStreamsByDefault = ( packageInput: RegistryInput, - packageInputStreams: Array, + packageInputStreams: Array, packagePolicyInput: NewPackagePolicyInput ): boolean => { return ( @@ -63,7 +65,9 @@ const shouldShowStreamsByDefault = ( export const PackagePolicyInputPanel: React.FunctionComponent<{ packageInput: RegistryInput; - packageInputStreams: Array; + packageInfo: PackageInfo; + packagePolicy: NewPackagePolicy; + packageInputStreams: Array; packagePolicyInput: NewPackagePolicyInput; updatePackagePolicyInput: (updatedInput: Partial) => void; inputValidationResults: PackagePolicyInputValidationResults; @@ -71,8 +75,10 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{ }> = memo( ({ packageInput, + packageInfo, packageInputStreams, packagePolicyInput, + packagePolicy, updatePackagePolicyInput, inputValidationResults, forceShowErrors, @@ -214,6 +220,8 @@ export const PackagePolicyInputPanel: React.FunctionComponent<{ {inputStreams.map(({ packageInputStream, packagePolicyInputStream }, index) => ( ) => void; inputStreamValidationResults: PackagePolicyConfigValidationResults; forceShowErrors?: boolean; }> = memo( ({ + packagePolicy, packageInputStream, + packageInfo, packagePolicyInputStream, updatePackagePolicyInputStream, inputStreamValidationResults, forceShowErrors, }) => { + const { + params: { packagePolicyId }, + } = useRouteMatch<{ packagePolicyId?: string }>(); + + const isPackagePolicyEdit = !!packagePolicyId; + // Showing advanced options toggle state const [isShowingAdvanced, setIsShowingAdvanced] = useState(); // Errors state const hasErrors = forceShowErrors && validationHasErrors(inputStreamValidationResults); - const requiredVars: RegistryVarsEntry[] = []; - // eslint-disable-next-line react-hooks/exhaustive-deps - const advancedVars: RegistryVarsEntry[] = []; + const [requiredVars, advancedVars] = useMemo(() => { + const _requiredVars: RegistryVarsEntry[] = []; + const _advancedVars: RegistryVarsEntry[] = []; - if (packageInputStream.vars && packageInputStream.vars.length) { - packageInputStream.vars.forEach((varDef) => { - if (isAdvancedVar(varDef)) { - advancedVars.push(varDef); - } else { - requiredVars.push(varDef); - } - }); - } + if (packageInputStream.vars && packageInputStream.vars.length) { + packageInputStream.vars.forEach((varDef) => { + if (isAdvancedVar(varDef)) { + _advancedVars.push(varDef); + } else { + _requiredVars.push(varDef); + } + }); + } + + return [_requiredVars, _advancedVars]; + }, [packageInputStream.vars]); const advancedVarsWithErrorsCount: number = useMemo( () => @@ -135,7 +153,8 @@ export const PackagePolicyInputStreamConfig: React.FunctionComponent<{ ); })} - {advancedVars.length ? ( + {/* Advanced section */} + {(isPackagePolicyEdit || advancedVars.length) && ( @@ -165,8 +184,9 @@ export const PackagePolicyInputStreamConfig: React.FunctionComponent<{ ) : null} - {isShowingAdvanced - ? advancedVars.map((varDef) => { + {isShowingAdvanced ? ( + <> + {advancedVars.map((varDef) => { if (!packagePolicyInputStream.vars) return null; const { name: varName, type: varType } = varDef; const value = packagePolicyInputStream.vars?.[varName]?.value; @@ -192,10 +212,28 @@ export const PackagePolicyInputStreamConfig: React.FunctionComponent<{ /> ); - }) - : null} + })} + {/* Only show datastream pipelines and mappings on edit */} + {isPackagePolicyEdit && ( + <> + + + + + + + + )} + + ) : null} - ) : null} + )} diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_configure_package.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_configure_package.tsx index db70c4b480b02..57b5376c9fbb7 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_configure_package.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/components/steps/step_configure_package.tsx @@ -72,6 +72,8 @@ export const StepConfigurePackagePolicy: React.FunctionComponent<{ ) => { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx new file mode 100644 index 0000000000000..4ae3a88ba7d66 --- /dev/null +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.test.tsx @@ -0,0 +1,159 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import type { RenderResult } from '@testing-library/react'; +import { act, fireEvent, waitFor } from '@testing-library/react'; + +import { createFleetTestRendererMock } from '../../../../../mock'; + +import { sendGetAgents } from '../../../hooks'; + +import { AgentListPage } from '.'; + +jest.mock('../../../hooks', () => ({ + ...jest.requireActual('../../../hooks'), + sendGetAgents: jest.fn(), + useGetAgentPolicies: jest.fn().mockReturnValue({ + data: { items: [{ id: 'policy1' }] }, + isLoading: false, + resendRequest: jest.fn(), + }), + FleetStatusProvider: (props: any) => { + return props.children; + }, + useFleetStatus: jest.fn().mockReturnValue({}), + sendGetAgentStatus: jest.fn().mockResolvedValue({ + data: { + results: { + online: 6, + error: 0, + offline: 0, + updating: 0, + }, + totalInactive: 0, + }, + }), + useAuthz: jest.fn().mockReturnValue({ fleet: { all: true } }), + useStartServices: jest.fn().mockReturnValue({ + notifications: { + toasts: { + addError: jest.fn(), + }, + }, + cloud: {}, + data: { dataViews: { getFieldsForWildcard: jest.fn() } }, + }), + useBreadcrumbs: jest.fn(), + useLink: jest.fn().mockReturnValue({ getHref: jest.fn() }), + useUrlParams: jest.fn().mockReturnValue({ urlParams: { kuery: '' } }), + useKibanaVersion: jest.fn().mockReturnValue('8.3.0'), + usePagination: jest.fn().mockReturnValue({ + pagination: { + currentPage: 1, + pageSize: 5, + }, + pageSizeOptions: [5, 20, 50], + setPagination: jest.fn(), + }), + useFleetServerUnhealthy: jest.fn().mockReturnValue({ + isUnhealthy: false, + isLoading: false, + }), +})); + +jest.mock('./components/search_and_filter_bar', () => { + return { + SearchAndFilterBar: () => <>SearchAndFilterBar, + }; +}); + +const mockedSendGetAgents = sendGetAgents as jest.Mock; + +function renderAgentList() { + const renderer = createFleetTestRendererMock(); + + const utils = renderer.render(); + + return { utils }; +} + +describe('agent_list_page', () => { + const mapAgents = (ids: string[]) => + ids.map((agent) => ({ + id: agent, + active: true, + policy_id: 'policy1', + local_metadata: { host: { hostname: agent } }, + })); + + let utils: RenderResult; + + beforeEach(async () => { + mockedSendGetAgents + .mockResolvedValueOnce({ + data: { + items: mapAgents(['agent1', 'agent2', 'agent3', 'agent4', 'agent5']), + total: 6, + totalInactive: 0, + }, + }) + .mockResolvedValueOnce({ + data: { + items: mapAgents(['agent1', 'agent2', 'agent3', 'agent4', 'agent6']), + total: 6, + totalInactive: 0, + }, + }); + jest.useFakeTimers(); + + ({ utils } = renderAgentList()); + + await waitFor(() => { + expect(utils.getByText('Showing 6 agents')).toBeInTheDocument(); + }); + + act(() => { + const selectAll = utils.container.querySelector('[data-test-subj="checkboxSelectAll"]'); + fireEvent.click(selectAll!); + }); + + await waitFor(() => { + utils.getByText('5 agents selected'); + }); + + act(() => { + fireEvent.click(utils.getByText('Select everything on all pages')); + }); + utils.getByText('All agents selected'); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it('should not set selection mode when agent selection changed automatically', async () => { + act(() => { + jest.runOnlyPendingTimers(); + }); + + await waitFor(() => { + expect(utils.getByText('agent6')).toBeInTheDocument(); + }); + + utils.getByText('All agents selected'); + }); + + it('should set selection mode when agent selection changed manually', async () => { + act(() => { + fireEvent.click(utils.getAllByRole('checkbox')[3]); + }); + + utils.getByText('4 agents selected'); + }); +}); diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx index bc55e477b9993..436f79c4b9345 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/index.tsx @@ -6,6 +6,7 @@ */ import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react'; +import { differenceBy } from 'lodash'; import { EuiBasicTable, EuiFlexGroup, @@ -319,6 +320,18 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { return !isHosted; }; + const onSelectionChange = (newAgents: Agent[]) => { + setSelectedAgents(newAgents); + if (selectionMode === 'query' && newAgents.length < selectedAgents.length) { + // differentiating between selection changed by agents dropping from current page or user action + const areSelectedAgentsStillVisible = + selectedAgents.length > 0 && differenceBy(selectedAgents, agents, 'id').length === 0; + if (areSelectedAgentsStillVisible) { + setSelectionMode('manual'); + } + } + }; + const agentToUnenrollHasFleetServer = useMemo(() => { if (!agentToUnenroll || !agentToUnenroll.policy_id) { return false; @@ -631,10 +644,7 @@ export const AgentListPage: React.FunctionComponent<{}> = () => { }} isSelectable={true} selection={{ - onSelectionChange: (newAgents: Agent[]) => { - setSelectedAgents(newAgents); - setSelectionMode('manual'); - }, + onSelectionChange, selectable: isAgentSelectable, selectableMessage: (selectable, agent) => { if (selectable) return ''; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx index f6255902f7ccf..6136bd413e6e9 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/components/agent_reassign_policy_modal/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState, useEffect, useMemo } from 'react'; +import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiConfirmModal, @@ -39,29 +39,18 @@ export const AgentReassignAgentPolicyModal: React.FunctionComponent = ({ const { notifications } = useStartServices(); const isSingleAgent = Array.isArray(agents) && agents.length === 1; - const [selectedAgentPolicyId, setSelectedAgentPolicyId] = useState( - isSingleAgent ? (agents[0] as Agent).policy_id : undefined - ); const agentPoliciesRequest = useGetAgentPolicies({ page: 1, perPage: SO_SEARCH_LIMIT, }); - // eslint-disable-next-line react-hooks/exhaustive-deps - const agentPolicies = agentPoliciesRequest.data ? agentPoliciesRequest.data.items : []; - useEffect(() => { - if (!selectedAgentPolicyId && agentPolicies[0]) { - setSelectedAgentPolicyId(agentPolicies[0].id); - } - }, [agentPolicies, selectedAgentPolicyId]); - const policySelectOptions = useMemo(() => { - return agentPolicies - .filter((policy) => policy && !policy.is_managed) - .map((agentPolicy) => ({ - value: agentPolicy.id, - text: agentPolicy.name, - })); - }, [agentPolicies]); + const agentPolicies = agentPoliciesRequest.data + ? agentPoliciesRequest.data.items.filter((policy) => policy && !policy.is_managed) + : []; + + const [selectedAgentPolicyId, setSelectedAgentPolicyId] = useState( + isSingleAgent ? (agents[0] as Agent).policy_id : agentPolicies[0]?.id ?? undefined + ); const [isSubmitting, setIsSubmitting] = useState(false); async function onSubmit() { @@ -146,7 +135,10 @@ export const AgentReassignAgentPolicyModal: React.FunctionComponent = ({ ({ + value: agentPolicy.id, + text: agentPolicy.name, + }))} value={selectedAgentPolicyId} onChange={(e) => setSelectedAgentPolicyId(e.target.value)} /> diff --git a/x-pack/plugins/fleet/public/hooks/use_request/index.ts b/x-pack/plugins/fleet/public/hooks/use_request/index.ts index 2973d2dcd3fc8..2f700052acd7b 100644 --- a/x-pack/plugins/fleet/public/hooks/use_request/index.ts +++ b/x-pack/plugins/fleet/public/hooks/use_request/index.ts @@ -16,3 +16,4 @@ export * from './outputs'; export * from './settings'; export * from './setup'; export * from './app'; +export * from './ingest_pipelines'; diff --git a/x-pack/plugins/fleet/public/hooks/use_request/ingest_pipelines.ts b/x-pack/plugins/fleet/public/hooks/use_request/ingest_pipelines.ts new file mode 100644 index 0000000000000..c5bd3fed7d7fe --- /dev/null +++ b/x-pack/plugins/fleet/public/hooks/use_request/ingest_pipelines.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { GetDataStreamsResponse } from '../../types'; + +import { useRequest } from './use_request'; + +export const useGetPipeline = (pipelineId: string) => { + return useRequest({ + path: `/api/ingest_pipelines/${pipelineId}`, + method: 'get', + }); +}; diff --git a/x-pack/plugins/fleet/public/index.ts b/x-pack/plugins/fleet/public/index.ts index 25714ead50a30..5f97cfa4d2740 100644 --- a/x-pack/plugins/fleet/public/index.ts +++ b/x-pack/plugins/fleet/public/index.ts @@ -26,3 +26,8 @@ export { pagePathGetters } from './constants'; export { pkgKeyFromPackageInfo } from './services'; export type { CustomAssetsAccordionProps } from './components/custom_assets_accordion'; export { CustomAssetsAccordion } from './components/custom_assets_accordion'; +// Export Package editor components for custom editors +export { PackagePolicyEditorDatastreamPipelines } from './applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines'; +export type { PackagePolicyEditorDatastreamPipelinesProps } from './applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_pipelines'; +export { PackagePolicyEditorDatastreamMappings } from './applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings'; +export type { PackagePolicyEditorDatastreamMappingsProps } from './applications/fleet/sections/agent_policy/create_package_policy_page/components/datastream_mappings'; diff --git a/x-pack/plugins/fleet/server/constants/fleet_es_assets.ts b/x-pack/plugins/fleet/server/constants/fleet_es_assets.ts index 56aaf450d46e9..ded329ba79bab 100644 --- a/x-pack/plugins/fleet/server/constants/fleet_es_assets.ts +++ b/x-pack/plugins/fleet/server/constants/fleet_es_assets.ts @@ -9,10 +9,6 @@ import { getESAssetMetadata } from '../services/epm/elasticsearch/meta'; const meta = getESAssetMetadata(); -export const PACKAGE_TEMPLATE_SUFFIX = '@package'; - -export const USER_SETTINGS_TEMPLATE_SUFFIX = '@custom'; - export const FLEET_FINAL_PIPELINE_ID = '.fleet_final_pipeline-1'; export const FLEET_GLOBALS_COMPONENT_TEMPLATE_NAME = '.fleet_globals-1'; diff --git a/x-pack/plugins/fleet/server/constants/index.ts b/x-pack/plugins/fleet/server/constants/index.ts index 813f381ecc4fc..11f44ab07896c 100644 --- a/x-pack/plugins/fleet/server/constants/index.ts +++ b/x-pack/plugins/fleet/server/constants/index.ts @@ -33,6 +33,8 @@ export { SETTINGS_API_ROUTES, APP_API_ROUTES, PRECONFIGURATION_API_ROUTES, + DOWNLOAD_SOURCE_API_ROOT, + DOWNLOAD_SOURCE_API_ROUTES, // Saved object types SO_SEARCH_LIMIT, AGENTS_PREFIX, @@ -55,6 +57,13 @@ export { PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE, PRECONFIGURATION_LATEST_KEYWORD, AUTO_UPDATE_PACKAGES, + // EPM + USER_SETTINGS_TEMPLATE_SUFFIX, + PACKAGE_TEMPLATE_SUFFIX, + // Download sources + DEFAULT_DOWNLOAD_SOURCE, + DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + DEFAULT_DOWNLOAD_SOURCE_ID, } from '../../common'; export { @@ -66,6 +75,4 @@ export { FLEET_FINAL_PIPELINE_ID, FLEET_FINAL_PIPELINE_CONTENT, FLEET_FINAL_PIPELINE_VERSION, - USER_SETTINGS_TEMPLATE_SUFFIX, - PACKAGE_TEMPLATE_SUFFIX, } from './fleet_es_assets'; diff --git a/x-pack/plugins/fleet/server/errors/index.ts b/x-pack/plugins/fleet/server/errors/index.ts index 1d1892f620e93..f617bcb55f341 100644 --- a/x-pack/plugins/fleet/server/errors/index.ts +++ b/x-pack/plugins/fleet/server/errors/index.ts @@ -60,6 +60,7 @@ export class FleetUnauthorizedError extends IngestManagerError {} export class OutputUnauthorizedError extends IngestManagerError {} export class OutputInvalidError extends IngestManagerError {} export class OutputLicenceError extends IngestManagerError {} +export class DownloadSourceError extends IngestManagerError {} export class ArtifactsClientError extends IngestManagerError {} export class ArtifactsClientAccessDeniedError extends IngestManagerError { diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts index ae4f6134e891f..961d318be2c59 100644 --- a/x-pack/plugins/fleet/server/plugin.ts +++ b/x-pack/plugins/fleet/server/plugin.ts @@ -67,6 +67,7 @@ import { registerSettingsRoutes, registerAppRoutes, registerPreconfigurationRoutes, + registerDownloadSourcesRoutes, registerHealthCheckRoutes, } from './routes'; @@ -367,6 +368,7 @@ export class FleetPlugin registerSettingsRoutes(fleetAuthzRouter); registerDataStreamRoutes(fleetAuthzRouter); registerPreconfigurationRoutes(fleetAuthzRouter); + registerDownloadSourcesRoutes(fleetAuthzRouter); registerHealthCheckRoutes(fleetAuthzRouter); // Conditional config routes diff --git a/x-pack/plugins/fleet/server/routes/agent/handlers.ts b/x-pack/plugins/fleet/server/routes/agent/handlers.ts index fd0a2ae4ab4bb..8fd4c2db6c929 100644 --- a/x-pack/plugins/fleet/server/routes/agent/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/agent/handlers.ts @@ -195,7 +195,7 @@ export const postBulkAgentsReassignHandler: RequestHandler< const results = await AgentService.reassignAgents( soClient, esClient, - agentOptions, + { ...agentOptions, batchSize: request.body.batchSize }, request.body.policy_id ); diff --git a/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts b/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts index f9d27ff71ed9d..257112dc6872d 100644 --- a/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/unenroll_handler.ts @@ -65,6 +65,7 @@ export const postBulkAgentsUnenrollHandler: RequestHandler< ...agentOptions, revoke: request.body?.revoke, force: request.body?.force, + batchSize: request.body?.batchSize, }); const body = results.items.reduce((acc, so) => { acc[so.id] = { diff --git a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts index 17ac6772ee623..a389f749c9b11 100644 --- a/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts +++ b/x-pack/plugins/fleet/server/routes/agent/upgrade_handler.ts @@ -97,6 +97,7 @@ export const postBulkAgentsUpgradeHandler: RequestHandler< force, rollout_duration_seconds: upgradeDurationSeconds, start_time: startTime, + batchSize, } = request.body; const kibanaVersion = appContextService.getKibanaVersion(); try { @@ -122,6 +123,7 @@ export const postBulkAgentsUpgradeHandler: RequestHandler< force, upgradeDurationSeconds, startTime, + batchSize, }; const results = await AgentService.sendUpgradeAgentsActions(soClient, esClient, upgradeOptions); const body = results.items.reduce((acc, so) => { diff --git a/x-pack/plugins/fleet/server/routes/download_source/handler.ts b/x-pack/plugins/fleet/server/routes/download_source/handler.ts new file mode 100644 index 0000000000000..878f19e655ed2 --- /dev/null +++ b/x-pack/plugins/fleet/server/routes/download_source/handler.ts @@ -0,0 +1,151 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { RequestHandler } from '@kbn/core/server'; +import type { TypeOf } from '@kbn/config-schema'; + +import type { + GetOneDownloadSourcesRequestSchema, + PutDownloadSourcesRequestSchema, + PostDownloadSourcesRequestSchema, + DeleteDownloadSourcesRequestSchema, +} from '../../types'; +import type { + GetOneDownloadSourceResponse, + DeleteDownloadSourceResponse, + PutDownloadSourceResponse, + GetDownloadSourceResponse, +} from '../../../common'; +import { downloadSourceService } from '../../services/download_source'; +import { defaultIngestErrorHandler } from '../../errors'; +import { agentPolicyService } from '../../services'; + +export const getDownloadSourcesHandler: RequestHandler = async (context, request, response) => { + const soClient = (await context.core).savedObjects.client; + try { + const downloadSources = await downloadSourceService.list(soClient); + + const body: GetDownloadSourceResponse = { + items: downloadSources.items, + page: downloadSources.page, + perPage: downloadSources.perPage, + total: downloadSources.total, + }; + + return response.ok({ body }); + } catch (error) { + return defaultIngestErrorHandler({ error, response }); + } +}; + +export const getOneDownloadSourcesHandler: RequestHandler< + TypeOf +> = async (context, request, response) => { + const soClient = (await context.core).savedObjects.client; + try { + const downloadSource = await downloadSourceService.get(soClient, request.params.sourceId); + + const body: GetOneDownloadSourceResponse = { + item: downloadSource, + }; + + return response.ok({ body }); + } catch (error) { + if (error.isBoom && error.output.statusCode === 404) { + return response.notFound({ + body: { message: `Download source ${request.params.sourceId} not found` }, + }); + } + + return defaultIngestErrorHandler({ error, response }); + } +}; + +export const putDownloadSourcesHandler: RequestHandler< + TypeOf, + undefined, + TypeOf +> = async (context, request, response) => { + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; + try { + await downloadSourceService.update(soClient, request.params.sourceId, request.body); + const downloadSource = await downloadSourceService.get(soClient, request.params.sourceId); + if (downloadSource.is_default) { + await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + } else { + await agentPolicyService.bumpAllAgentPoliciesForDownloadSource( + soClient, + esClient, + downloadSource.id + ); + } + + const body: PutDownloadSourceResponse = { + item: downloadSource, + }; + + return response.ok({ body }); + } catch (error) { + if (error.isBoom && error.output.statusCode === 404) { + return response.notFound({ + body: { message: `Download source ${request.params.sourceId} not found` }, + }); + } + + return defaultIngestErrorHandler({ error, response }); + } +}; + +export const postDownloadSourcesHandler: RequestHandler< + undefined, + undefined, + TypeOf +> = async (context, request, response) => { + const coreContext = await context.core; + const soClient = coreContext.savedObjects.client; + const esClient = coreContext.elasticsearch.client.asInternalUser; + try { + const { id, ...data } = request.body; + const downloadSource = await downloadSourceService.create(soClient, data, { id }); + if (downloadSource.is_default) { + await agentPolicyService.bumpAllAgentPolicies(soClient, esClient); + } + + const body: GetOneDownloadSourceResponse = { + item: downloadSource, + }; + + return response.ok({ body }); + } catch (error) { + return defaultIngestErrorHandler({ error, response }); + } +}; + +export const deleteDownloadSourcesHandler: RequestHandler< + TypeOf +> = async (context, request, response) => { + const soClient = (await context.core).savedObjects.client; + try { + await downloadSourceService.delete(soClient, request.params.sourceId); + + const body: DeleteDownloadSourceResponse = { + id: request.params.sourceId, + }; + + return response.ok({ body }); + } catch (error) { + if (error.isBoom && error.output.statusCode === 404) { + return response.notFound({ + body: { message: `Donwload source ${request.params.sourceId} not found` }, + }); + } + + return defaultIngestErrorHandler({ error, response }); + } +}; diff --git a/x-pack/plugins/fleet/server/routes/download_source/index.tsx b/x-pack/plugins/fleet/server/routes/download_source/index.tsx new file mode 100644 index 0000000000000..1c670bdf2b018 --- /dev/null +++ b/x-pack/plugins/fleet/server/routes/download_source/index.tsx @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DOWNLOAD_SOURCE_API_ROUTES } from '../../constants'; +import { + getDownloadSourcesRequestSchema, + GetOneDownloadSourcesRequestSchema, + PutDownloadSourcesRequestSchema, + PostDownloadSourcesRequestSchema, + DeleteDownloadSourcesRequestSchema, +} from '../../types'; +import type { FleetAuthzRouter } from '../security'; + +import { + getDownloadSourcesHandler, + getOneDownloadSourcesHandler, + putDownloadSourcesHandler, + postDownloadSourcesHandler, + deleteDownloadSourcesHandler, +} from './handler'; + +export const registerRoutes = (router: FleetAuthzRouter) => { + router.get( + { + path: DOWNLOAD_SOURCE_API_ROUTES.LIST_PATTERN, + validate: getDownloadSourcesRequestSchema, + fleetAuthz: { + fleet: { all: true }, + }, + }, + getDownloadSourcesHandler + ); + router.get( + { + path: DOWNLOAD_SOURCE_API_ROUTES.INFO_PATTERN, + validate: GetOneDownloadSourcesRequestSchema, + fleetAuthz: { + fleet: { all: true }, + }, + }, + getOneDownloadSourcesHandler + ); + router.put( + { + path: DOWNLOAD_SOURCE_API_ROUTES.UPDATE_PATTERN, + validate: PutDownloadSourcesRequestSchema, + fleetAuthz: { + fleet: { all: true }, + }, + }, + putDownloadSourcesHandler + ); + + router.post( + { + path: DOWNLOAD_SOURCE_API_ROUTES.CREATE_PATTERN, + validate: PostDownloadSourcesRequestSchema, + fleetAuthz: { + fleet: { all: true }, + }, + }, + postDownloadSourcesHandler + ); + + router.delete( + { + path: DOWNLOAD_SOURCE_API_ROUTES.DELETE_PATTERN, + validate: DeleteDownloadSourcesRequestSchema, + fleetAuthz: { + fleet: { all: true }, + }, + }, + deleteDownloadSourcesHandler + ); +}; diff --git a/x-pack/plugins/fleet/server/routes/index.ts b/x-pack/plugins/fleet/server/routes/index.ts index b04e179a05dcf..24c0947a419f6 100644 --- a/x-pack/plugins/fleet/server/routes/index.ts +++ b/x-pack/plugins/fleet/server/routes/index.ts @@ -16,4 +16,5 @@ export { registerRoutes as registerOutputRoutes } from './output'; export { registerRoutes as registerSettingsRoutes } from './settings'; export { registerRoutes as registerAppRoutes } from './app'; export { registerRoutes as registerPreconfigurationRoutes } from './preconfiguration'; +export { registerRoutes as registerDownloadSourcesRoutes } from './download_source'; export { registerRoutes as registerHealthCheckRoutes } from './health_check'; diff --git a/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts b/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts index bd0ed690ec6fe..87cfe2c23fc9e 100644 --- a/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts +++ b/x-pack/plugins/fleet/server/routes/preconfiguration/handler.ts @@ -15,7 +15,11 @@ import type { PostResetOnePreconfiguredAgentPoliciesSchema, } from '../../types'; import { defaultIngestErrorHandler } from '../../errors'; -import { ensurePreconfiguredPackagesAndPolicies, outputService } from '../../services'; +import { + ensurePreconfiguredPackagesAndPolicies, + outputService, + downloadSourceService, +} from '../../services'; import { resetPreconfiguredAgentPolicies } from '../../services/preconfiguration/reset_agent_policies'; export const updatePreconfigurationHandler: FleetRequestHandler< @@ -28,6 +32,7 @@ export const updatePreconfigurationHandler: FleetRequestHandler< const soClient = coreContext.savedObjects.client; const esClient = coreContext.elasticsearch.client.asInternalUser; const defaultOutput = await outputService.ensureDefaultOutput(soClient); + const defaultDownloadSource = await downloadSourceService.ensureDefault(soClient); const spaceId = fleetContext.spaceId; const { agentPolicies, packages } = request.body; @@ -38,6 +43,7 @@ export const updatePreconfigurationHandler: FleetRequestHandler< (agentPolicies as PreconfiguredAgentPolicy[]) ?? [], packages ?? [], defaultOutput, + defaultDownloadSource, spaceId ); return response.ok({ body }); diff --git a/x-pack/plugins/fleet/server/saved_objects/index.ts b/x-pack/plugins/fleet/server/saved_objects/index.ts index 009cdef6aa771..6438c042bac7c 100644 --- a/x-pack/plugins/fleet/server/saved_objects/index.ts +++ b/x-pack/plugins/fleet/server/saved_objects/index.ts @@ -17,6 +17,7 @@ import { ASSETS_SAVED_OBJECT_TYPE, GLOBAL_SETTINGS_SAVED_OBJECT_TYPE, PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE, + DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, } from '../constants'; import { @@ -298,6 +299,22 @@ const getSavedObjectTypes = ( }, }, }, + [DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE]: { + name: DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + hidden: false, + namespaceType: 'agnostic', + management: { + importableAndExportable: false, + }, + mappings: { + properties: { + source_id: { type: 'keyword', index: false }, + name: { type: 'keyword' }, + is_default: { type: 'boolean' }, + host: { type: 'keyword' }, + }, + }, + }, }); export function registerSavedObjects( diff --git a/x-pack/plugins/fleet/server/services/agent_policy.test.ts b/x-pack/plugins/fleet/server/services/agent_policy.test.ts index a71180f235288..2d5bc0aa4f88a 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.test.ts @@ -25,6 +25,7 @@ import { getAgentsByKuery } from './agents'; import { packagePolicyService } from './package_policy'; import { appContextService } from './app_context'; import { outputService } from './output'; +import { downloadSourceService } from './download_source'; import { getFullAgentPolicy } from './agent_policies'; function getSavedObjectMock(agentPolicyAttributes: any) { @@ -60,6 +61,7 @@ function getSavedObjectMock(agentPolicyAttributes: any) { } jest.mock('./output'); +jest.mock('./download_source'); jest.mock('./agent_policy_update'); jest.mock('./agents'); jest.mock('./package_policy'); @@ -69,6 +71,9 @@ jest.mock('uuid/v5'); const mockedAppContextService = appContextService as jest.Mocked; const mockedOutputService = outputService as jest.Mocked; +const mockedDownloadSourceService = downloadSourceService as jest.Mocked< + typeof downloadSourceService +>; const mockedGetFullAgentPolicy = getFullAgentPolicy as jest.Mock< ReturnType >; @@ -257,6 +262,83 @@ describe('agent policy', () => { }); }); + describe('removeDefaultSourceFromAll', () => { + let mockedAgentPolicyServiceUpdate: jest.SpyInstance< + ReturnType + >; + beforeEach(() => { + mockedAgentPolicyServiceUpdate = jest + .spyOn(agentPolicyService, 'update') + .mockResolvedValue({} as any); + }); + + afterEach(() => { + mockedAgentPolicyServiceUpdate.mockRestore(); + }); + + it('should update policies using deleted download source host', async () => { + const soClient = savedObjectsClientMock.create(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + mockedDownloadSourceService.getDefaultDownloadSourceId.mockResolvedValue( + 'default-download-source-id' + ); + soClient.find.mockResolvedValue({ + saved_objects: [ + { + id: 'test-ds-1', + attributes: { + download_source_id: 'ds-id-1', + }, + }, + { + id: 'test-ds-2', + attributes: { + download_source_id: 'default-download-source-id', + }, + }, + ], + } as any); + + await agentPolicyService.removeDefaultSourceFromAll( + soClient, + esClient, + 'default-download-source-id' + ); + + expect(mockedAgentPolicyServiceUpdate).toHaveBeenCalledTimes(2); + expect(mockedAgentPolicyServiceUpdate).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + 'test-ds-1', + { download_source_id: 'ds-id-1' } + ); + expect(mockedAgentPolicyServiceUpdate).toHaveBeenCalledWith( + expect.anything(), + expect.anything(), + 'test-ds-2', + { download_source_id: null } + ); + }); + }); + + describe('bumpAllAgentPoliciesForDownloadSource', () => { + it('should call agentPolicyUpdateEventHandler with updated event once', async () => { + const soClient = getSavedObjectMock({ + revision: 1, + monitoring_enabled: ['metrics'], + }); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + + await agentPolicyService.bumpAllAgentPoliciesForDownloadSource( + soClient, + esClient, + 'test-id-1' + ); + + expect(agentPolicyUpdateEventHandler).toHaveBeenCalledTimes(1); + }); + }); + describe('update', () => { it('should update is_managed property, if given', async () => { // ignore unrelated unique name constraint diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index 1e86354513e26..af69cd8713cf0 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -842,6 +842,79 @@ class AgentPolicyService { ): Promise { return getFullAgentPolicy(soClient, id, options); } + + /** + * Remove a download source from all agent policies that are using it, and replace the output by the default ones. + * @param soClient + * @param esClient + * @param downloadSourceId + */ + public async removeDefaultSourceFromAll( + soClient: SavedObjectsClientContract, + esClient: ElasticsearchClient, + downloadSourceId: string + ) { + const agentPolicies = ( + await soClient.find({ + type: SAVED_OBJECT_TYPE, + fields: ['revision', 'download_source_id'], + searchFields: ['download_source_id'], + search: escapeSearchQueryPhrase(downloadSourceId), + perPage: SO_SEARCH_LIMIT, + }) + ).saved_objects.map((so) => ({ + id: so.id, + ...so.attributes, + })); + + if (agentPolicies.length > 0) { + await pMap( + agentPolicies, + (agentPolicy) => + this.update(soClient, esClient, agentPolicy.id, { + download_source_id: + agentPolicy.download_source_id === downloadSourceId + ? null + : agentPolicy.download_source_id, + }), + { + concurrency: 50, + } + ); + } + } + + public async bumpAllAgentPoliciesForDownloadSource( + soClient: SavedObjectsClientContract, + esClient: ElasticsearchClient, + downloadSourceId: string, + options?: { user?: AuthenticatedUser } + ): Promise> { + const currentPolicies = await soClient.find({ + type: SAVED_OBJECT_TYPE, + fields: ['revision', 'download_source_id'], + searchFields: ['download_source_id'], + search: escapeSearchQueryPhrase(downloadSourceId), + perPage: SO_SEARCH_LIMIT, + }); + const bumpedPolicies = currentPolicies.saved_objects.map((policy) => { + policy.attributes = { + ...policy.attributes, + revision: policy.attributes.revision + 1, + updated_at: new Date().toISOString(), + updated_by: options?.user ? options.user.username : 'system', + }; + return policy; + }); + const res = await soClient.bulkUpdate(bumpedPolicies); + await pMap( + currentPolicies.saved_objects, + (policy) => this.triggerAgentPolicyUpdatedEvent(soClient, esClient, 'updated', policy.id), + { concurrency: 50 } + ); + + return res; + } } export const agentPolicyService = new AgentPolicyService(); diff --git a/x-pack/plugins/fleet/server/services/agents/crud.test.ts b/x-pack/plugins/fleet/server/services/agents/crud.test.ts index 5a1b47a7b359a..db0c5d6e55b75 100644 --- a/x-pack/plugins/fleet/server/services/agents/crud.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/crud.test.ts @@ -9,7 +9,7 @@ import type { ElasticsearchClient } from '@kbn/core/server'; import type { Agent } from '../../types'; -import { getAgentsByKuery } from './crud'; +import { errorsToResults, getAgentsByKuery, processAgentsInBatches } from './crud'; jest.mock('../../../common', () => ({ ...jest.requireActual('../../../common'), @@ -19,26 +19,28 @@ jest.mock('../../../common', () => ({ describe('Agents CRUD test', () => { let esClientMock: ElasticsearchClient; let searchMock: jest.Mock; - describe('getAgentsByKuery', () => { - beforeEach(() => { - searchMock = jest.fn(); - esClientMock = { - search: searchMock, - } as unknown as ElasticsearchClient; - }); - function getEsResponse(ids: string[], total: number) { - return { - hits: { - total, - hits: ids.map((id: string) => ({ - _id: id, - _source: {}, - })), - }, - }; - } + beforeEach(() => { + searchMock = jest.fn(); + esClientMock = { + search: searchMock, + openPointInTime: jest.fn().mockResolvedValue({ id: '1' }), + closePointInTime: jest.fn(), + } as unknown as ElasticsearchClient; + }); + function getEsResponse(ids: string[], total: number) { + return { + hits: { + total, + hits: ids.map((id: string) => ({ + _id: id, + _source: {}, + })), + }, + }; + } + describe('getAgentsByKuery', () => { it('should return upgradeable on first page', async () => { searchMock .mockImplementationOnce(() => Promise.resolve(getEsResponse(['1', '2', '3', '4', '5'], 7))) @@ -192,4 +194,85 @@ describe('Agents CRUD test', () => { }); }); }); + + describe('processAgentsInBatches', () => { + const mockProcessAgents = (agents: Agent[]) => + Promise.resolve({ items: agents.map((agent) => ({ id: agent.id, success: true })) }); + it('should return results for multiple batches', async () => { + searchMock + .mockImplementationOnce(() => Promise.resolve(getEsResponse(['1', '2'], 3))) + .mockImplementationOnce(() => Promise.resolve(getEsResponse(['3'], 3))); + + const response = await processAgentsInBatches( + esClientMock, + { + kuery: 'active:true', + batchSize: 2, + showInactive: false, + }, + mockProcessAgents + ); + expect(response).toEqual({ + items: [ + { id: '1', success: true }, + { id: '2', success: true }, + { id: '3', success: true }, + ], + }); + }); + + it('should return results for one batch', async () => { + searchMock.mockImplementationOnce(() => Promise.resolve(getEsResponse(['1', '2', '3'], 3))); + + const response = await processAgentsInBatches( + esClientMock, + { + kuery: 'active:true', + showInactive: false, + }, + mockProcessAgents + ); + expect(response).toEqual({ + items: [ + { id: '1', success: true }, + { id: '2', success: true }, + { id: '3', success: true }, + ], + }); + }); + }); + + describe('errorsToResults', () => { + it('should transform errors to results', () => { + const results = errorsToResults([{ id: '1' } as Agent, { id: '2' } as Agent], { + '1': new Error('error'), + }); + expect(results).toEqual([ + { id: '1', success: false, error: new Error('error') }, + { id: '2', success: true }, + ]); + }); + + it('should transform errors to results with skip success', () => { + const results = errorsToResults( + [{ id: '1' } as Agent, { id: '2' } as Agent], + { '1': new Error('error') }, + undefined, + true + ); + expect(results).toEqual([{ id: '1', success: false, error: new Error('error') }]); + }); + + it('should transform errors to results preserve order', () => { + const results = errorsToResults( + [{ id: '1' } as Agent, { id: '2' } as Agent], + { '1': new Error('error') }, + ['2', '1'] + ); + expect(results).toEqual([ + { id: '2', success: true }, + { id: '1', success: false, error: new Error('error') }, + ]); + }); + }); }); diff --git a/x-pack/plugins/fleet/server/services/agents/crud.ts b/x-pack/plugins/fleet/server/services/agents/crud.ts index 258f0bf7d4898..2c62973e516e5 100644 --- a/x-pack/plugins/fleet/server/services/agents/crud.ts +++ b/x-pack/plugins/fleet/server/services/agents/crud.ts @@ -7,6 +7,7 @@ import Boom from '@hapi/boom'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import type { SortResults } from '@elastic/elasticsearch/lib/api/types'; import type { SavedObjectsClientContract, ElasticsearchClient } from '@kbn/core/server'; import type { KueryNode } from '@kbn/es-query'; @@ -68,6 +69,7 @@ export type GetAgentsOptions = | { kuery: string; showInactive?: boolean; + perPage?: number; }; export async function getAgents(esClient: ElasticsearchClient, options: GetAgentsOptions) { @@ -90,6 +92,113 @@ export async function getAgents(esClient: ElasticsearchClient, options: GetAgent return agents; } +export async function getAgentsByKueryPit( + esClient: ElasticsearchClient, + options: ListWithKuery & { + showInactive: boolean; + pitId: string; + searchAfter?: SortResults; + } +): Promise<{ + agents: Agent[]; + total: number; + page: number; + perPage: number; +}> { + const { + page = 1, + perPage = 20, + sortField = 'enrolled_at', + sortOrder = 'desc', + kuery, + showInactive = false, + showUpgradeable, + searchAfter, + } = options; + const { pitId } = options; + const filters = []; + + if (kuery && kuery !== '') { + filters.push(kuery); + } + + if (showInactive === false) { + filters.push(ACTIVE_AGENT_CONDITION); + } + + const kueryNode = _joinFilters(filters); + const body = kueryNode ? { query: toElasticsearchQuery(kueryNode) } : {}; + + const queryAgents = async (from: number, size: number) => { + return esClient.search({ + from, + size, + track_total_hits: true, + rest_total_hits_as_int: true, + body: { + ...body, + sort: [{ [sortField]: { order: sortOrder } }], + }, + pit: { + id: pitId, + keep_alive: '1m', + }, + ...(searchAfter ? { search_after: searchAfter, from: 0 } : {}), + }); + }; + + const res = await queryAgents((page - 1) * perPage, perPage); + + let agents = res.hits.hits.map(searchHitToAgent); + let total = res.hits.total as number; + + // filtering for a range on the version string will not work, + // nor does filtering on a flattened field (local_metadata), so filter here + if (showUpgradeable) { + // query all agents, then filter upgradeable, and return the requested page and correct total + // if there are more than SO_SEARCH_LIMIT agents, the logic falls back to same as before + if (total < SO_SEARCH_LIMIT) { + const response = await queryAgents(0, SO_SEARCH_LIMIT); + agents = response.hits.hits + .map(searchHitToAgent) + .filter((agent) => isAgentUpgradeable(agent, appContextService.getKibanaVersion())); + total = agents.length; + const start = (page - 1) * perPage; + agents = agents.slice(start, start + perPage); + } else { + agents = agents.filter((agent) => + isAgentUpgradeable(agent, appContextService.getKibanaVersion()) + ); + } + } + + return { + agents, + total, + page, + perPage, + }; +} + +export async function openAgentsPointInTime(esClient: ElasticsearchClient): Promise { + const pitKeepAlive = '10m'; + const pitRes = await esClient.openPointInTime({ + index: AGENTS_INDEX, + keep_alive: pitKeepAlive, + }); + return pitRes.id; +} + +export async function closeAgentsPointInTime(esClient: ElasticsearchClient, pitId: string) { + try { + await esClient.closePointInTime({ id: pitId }); + } catch (error) { + appContextService + .getLogger() + .warn(`Error closing point in time with id: ${pitId}. Error: ${error.message}`); + } +} + export async function getAgentsByKuery( esClient: ElasticsearchClient, options: ListWithKuery & { @@ -168,6 +277,83 @@ export async function getAgentsByKuery( }; } +export async function processAgentsInBatches( + esClient: ElasticsearchClient, + options: Omit & { + showInactive: boolean; + batchSize?: number; + }, + processAgents: ( + agents: Agent[], + includeSuccess: boolean + ) => Promise<{ items: BulkActionResult[] }> +): Promise<{ items: BulkActionResult[] }> { + const pitId = await openAgentsPointInTime(esClient); + + const perPage = options.batchSize ?? SO_SEARCH_LIMIT; + + const res = await getAgentsByKueryPit(esClient, { + ...options, + page: 1, + perPage, + pitId, + }); + + let currentAgents = res.agents; + // include successful agents if total agents does not exceed 10k + const skipSuccess = res.total > SO_SEARCH_LIMIT; + + let results = await processAgents(currentAgents, skipSuccess); + let allAgentsProcessed = currentAgents.length; + + while (allAgentsProcessed < res.total) { + const lastAgent = currentAgents[currentAgents.length - 1]; + const nextPage = await getAgentsByKueryPit(esClient, { + ...options, + page: 1, + perPage, + pitId, + searchAfter: lastAgent.sort!, + }); + currentAgents = nextPage.agents; + const currentResults = await processAgents(currentAgents, skipSuccess); + results = { items: results.items.concat(currentResults.items) }; + allAgentsProcessed += currentAgents.length; + } + + await closeAgentsPointInTime(esClient, pitId); + + return results; +} + +export function errorsToResults( + agents: Agent[], + errors: Record, + agentIds?: string[], + skipSuccess?: boolean +): BulkActionResult[] { + if (!skipSuccess) { + const givenOrder = agentIds ? agentIds : agents.map((agent) => agent.id); + return givenOrder.map((agentId) => { + const hasError = agentId in errors; + const result: BulkActionResult = { + id: agentId, + success: !hasError, + }; + if (hasError) { + result.error = errors[agentId]; + } + return result; + }); + } else { + return Object.entries(errors).map(([agentId, error]) => ({ + id: agentId, + success: false, + error, + })); + } +} + export async function getAllAgentsByKuery( esClient: ElasticsearchClient, options: Omit & { diff --git a/x-pack/plugins/fleet/server/services/agents/helpers.ts b/x-pack/plugins/fleet/server/services/agents/helpers.ts index 08c0c7ba964dc..127223629c263 100644 --- a/x-pack/plugins/fleet/server/services/agents/helpers.ts +++ b/x-pack/plugins/fleet/server/services/agents/helpers.ts @@ -6,7 +6,7 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; - +import type { SortResults } from '@elastic/elasticsearch/lib/api/types'; import type { SearchHit } from '@kbn/core/types/elasticsearch'; import type { Agent, AgentSOAttributes, FleetServerAgent } from '../../types'; @@ -17,7 +17,7 @@ type FleetServerAgentESResponse = | estypes.SearchResponse['hits']['hits'][0] | SearchHit; -export function searchHitToAgent(hit: FleetServerAgentESResponse): Agent { +export function searchHitToAgent(hit: FleetServerAgentESResponse & { sort?: SortResults }): Agent { // @ts-expect-error @elastic/elasticsearch MultiGetHit._source is optional const agent: Agent = { id: hit._id, @@ -26,6 +26,7 @@ export function searchHitToAgent(hit: FleetServerAgentESResponse): Agent { access_api_key: undefined, status: undefined, packages: hit._source?.packages ?? [], + sort: hit.sort, }; agent.status = getAgentStatus(agent); diff --git a/x-pack/plugins/fleet/server/services/agents/reassign.ts b/x-pack/plugins/fleet/server/services/agents/reassign.ts index e077e7e47294b..1746d324d626f 100644 --- a/x-pack/plugins/fleet/server/services/agents/reassign.ts +++ b/x-pack/plugins/fleet/server/services/agents/reassign.ts @@ -14,10 +14,11 @@ import { AgentReassignmentError, HostedAgentPolicyRestrictionRelatedError } from import { getAgentDocuments, - getAgents, getAgentPolicyForAgent, updateAgent, bulkUpdateAgents, + processAgentsInBatches, + errorsToResults, } from './crud'; import type { GetAgentsOptions } from '.'; import { createAgentAction } from './actions'; @@ -78,7 +79,7 @@ function isMgetDoc(doc?: estypes.MgetResponseItem): doc is estypes.GetG export async function reassignAgents( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, - options: ({ agents: Agent[] } | GetAgentsOptions) & { force?: boolean }, + options: ({ agents: Agent[] } | GetAgentsOptions) & { force?: boolean; batchSize?: number }, newAgentPolicyId: string ): Promise<{ items: BulkActionResult[] }> { const newAgentPolicy = await agentPolicyService.get(soClient, newAgentPolicyId); @@ -107,10 +108,46 @@ export async function reassignAgents( } } } else if ('kuery' in options) { - givenAgents = await getAgents(esClient, options); + return await processAgentsInBatches( + esClient, + { + kuery: options.kuery, + showInactive: options.showInactive ?? false, + batchSize: options.batchSize, + }, + async (agents: Agent[], skipSuccess: boolean) => + await reassignBatch( + soClient, + esClient, + newAgentPolicyId, + agents, + outgoingErrors, + undefined, + skipSuccess + ) + ); } - const givenOrder = - 'agentIds' in options ? options.agentIds : givenAgents.map((agent) => agent.id); + + return await reassignBatch( + soClient, + esClient, + newAgentPolicyId, + givenAgents, + outgoingErrors, + 'agentIds' in options ? options.agentIds : undefined + ); +} + +async function reassignBatch( + soClient: SavedObjectsClientContract, + esClient: ElasticsearchClient, + newAgentPolicyId: string, + givenAgents: Agent[], + outgoingErrors: Record, + agentIds?: string[], + skipSuccess?: boolean +): Promise<{ items: BulkActionResult[] }> { + const errors: Record = { ...outgoingErrors }; const hostedPolicies = await getHostedPolicies(soClient, givenAgents); @@ -137,7 +174,7 @@ export async function reassignAgents( agents.push(result.value); } else { const id = givenAgents[index].id; - outgoingErrors[id] = result.reason; + errors[id] = result.reason; } return agents; }, []); @@ -153,18 +190,6 @@ export async function reassignAgents( })) ); - const orderedOut = givenOrder.map((agentId) => { - const hasError = agentId in outgoingErrors; - const result: BulkActionResult = { - id: agentId, - success: !hasError, - }; - if (hasError) { - result.error = outgoingErrors[agentId]; - } - return result; - }); - const now = new Date().toISOString(); await createAgentAction(esClient, { agents: agentsToUpdate.map((agent) => agent.id), @@ -172,5 +197,5 @@ export async function reassignAgents( type: 'POLICY_REASSIGN', }); - return { items: orderedOut }; + return { items: errorsToResults(givenAgents, errors, agentIds, skipSuccess) }; } diff --git a/x-pack/plugins/fleet/server/services/agents/unenroll.ts b/x-pack/plugins/fleet/server/services/agents/unenroll.ts index 893fb5f20c76a..7d00f34377ed1 100644 --- a/x-pack/plugins/fleet/server/services/agents/unenroll.ts +++ b/x-pack/plugins/fleet/server/services/agents/unenroll.ts @@ -13,12 +13,14 @@ import { HostedAgentPolicyRestrictionRelatedError } from '../../errors'; import { createAgentAction } from './actions'; import type { GetAgentsOptions } from './crud'; +import { errorsToResults } from './crud'; import { getAgentById, getAgents, updateAgent, getAgentPolicyForAgent, bulkUpdateAgents, + processAgentsInBatches, } from './crud'; import { getHostedPolicies, isHostedAgent } from './hosted_agent'; @@ -69,11 +71,35 @@ export async function unenrollAgents( options: GetAgentsOptions & { force?: boolean; revoke?: boolean; + batchSize?: number; } ): Promise<{ items: BulkActionResult[] }> { - // start with all agents specified - const givenAgents = await getAgents(esClient, options); + if ('agentIds' in options) { + const givenAgents = await getAgents(esClient, options); + return await unenrollBatch(soClient, esClient, givenAgents, options); + } + return await processAgentsInBatches( + esClient, + { + kuery: options.kuery, + showInactive: options.showInactive ?? false, + batchSize: options.batchSize, + }, + async (agents: Agent[], skipSuccess?: boolean) => + await unenrollBatch(soClient, esClient, agents, options, skipSuccess) + ); +} +async function unenrollBatch( + soClient: SavedObjectsClientContract, + esClient: ElasticsearchClient, + givenAgents: Agent[], + options: { + force?: boolean; + revoke?: boolean; + }, + skipSuccess?: boolean +): Promise<{ items: BulkActionResult[] }> { // Filter to those not already unenrolled, or unenrolling const agentsEnrolled = givenAgents.filter((agent) => { if (options.revoke) { @@ -124,20 +150,8 @@ export async function unenrollAgents( agentsToUpdate.map(({ id }) => ({ agentId: id, data: updateData })) ); - const getResultForAgent = (agent: Agent) => { - const hasError = agent.id in outgoingErrors; - const result: BulkActionResult = { - id: agent.id, - success: !hasError, - }; - if (hasError) { - result.error = outgoingErrors[agent.id]; - } - return result; - }; - return { - items: givenAgents.map(getResultForAgent), + items: errorsToResults(givenAgents, outgoingErrors, undefined, skipSuccess), }; } diff --git a/x-pack/plugins/fleet/server/services/agents/upgrade.ts b/x-pack/plugins/fleet/server/services/agents/upgrade.ts index f5db132815fb7..5f9e6bc420b9a 100644 --- a/x-pack/plugins/fleet/server/services/agents/upgrade.ts +++ b/x-pack/plugins/fleet/server/services/agents/upgrade.ts @@ -21,13 +21,8 @@ import { AGENT_ACTIONS_INDEX, AGENT_ACTIONS_RESULTS_INDEX } from '../../../commo import { createAgentAction } from './actions'; import type { GetAgentsOptions } from './crud'; -import { - getAgentDocuments, - getAgents, - updateAgent, - bulkUpdateAgents, - getAgentPolicyForAgent, -} from './crud'; +import { errorsToResults, processAgentsInBatches } from './crud'; +import { getAgentDocuments, updateAgent, bulkUpdateAgents, getAgentPolicyForAgent } from './crud'; import { searchHitToAgent } from './helpers'; import { getHostedPolicies, isHostedAgent } from './hosted_agent'; @@ -85,6 +80,7 @@ export async function sendUpgradeAgentsActions( force?: boolean; upgradeDurationSeconds?: number; startTime?: string; + batchSize?: number; } ) { // Full set of agents @@ -104,9 +100,37 @@ export async function sendUpgradeAgentsActions( } } } else if ('kuery' in options) { - givenAgents = await getAgents(esClient, options); + return await processAgentsInBatches( + esClient, + { + kuery: options.kuery, + showInactive: options.showInactive ?? false, + batchSize: options.batchSize, + }, + async (agents: Agent[], skipSuccess: boolean) => + await upgradeBatch(soClient, esClient, agents, outgoingErrors, options, skipSuccess) + ); } + return await upgradeBatch(soClient, esClient, givenAgents, outgoingErrors, options); +} + +async function upgradeBatch( + soClient: SavedObjectsClientContract, + esClient: ElasticsearchClient, + givenAgents: Agent[], + outgoingErrors: Record, + options: ({ agents: Agent[] } | GetAgentsOptions) & { + version: string; + sourceUri?: string | undefined; + force?: boolean; + upgradeDurationSeconds?: number; + startTime?: string; + }, + skipSuccess?: boolean +): Promise<{ items: BulkActionResult[] }> { + const errors: Record = { ...outgoingErrors }; + const hostedPolicies = await getHostedPolicies(soClient, givenAgents); // results from getAgents with options.kuery '' (or even 'active:false') may include hosted agents @@ -141,7 +165,7 @@ export async function sendUpgradeAgentsActions( agents.push(result.value); } else { const id = givenAgents[index].id; - outgoingErrors[id] = result.reason; + errors[id] = result.reason; } return agents; }, []); @@ -183,22 +207,14 @@ export async function sendUpgradeAgentsActions( })) ); - const givenOrder = - 'agentIds' in options ? options.agentIds : agentsToCheckUpgradeable.map((agent) => agent.id); - - const orderedOut = givenOrder.map((agentId) => { - const hasError = agentId in outgoingErrors; - const result: BulkActionResult = { - id: agentId, - success: !hasError, - }; - if (hasError) { - result.error = outgoingErrors[agentId]; - } - return result; - }); - - return { items: orderedOut }; + return { + items: errorsToResults( + givenAgents, + errors, + 'agentIds' in options ? options.agentIds : undefined, + skipSuccess + ), + }; } /** diff --git a/x-pack/plugins/fleet/server/services/download_source.test.ts b/x-pack/plugins/fleet/server/services/download_source.test.ts new file mode 100644 index 0000000000000..07f450d2254e4 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/download_source.test.ts @@ -0,0 +1,259 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { savedObjectsClientMock } from '@kbn/core/server/mocks'; + +import type { DownloadSourceAttributes } from '../types'; + +import { DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE } from '../constants'; + +import { downloadSourceService } from './download_source'; +import { appContextService } from './app_context'; +import { agentPolicyService } from './agent_policy'; + +jest.mock('./app_context'); +jest.mock('./agent_policy'); + +const mockedAppContextService = appContextService as jest.Mocked; +const mockedAgentPolicyService = agentPolicyService as jest.Mocked; + +function mockDownloadSourceSO(id: string, attributes: any = {}) { + return { + id, + type: DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + references: [], + attributes: { + source_id: id, + ...attributes, + }, + }; +} + +function getMockedSoClient(options: { defaultDownloadSourceId?: string } = {}) { + const soClient = savedObjectsClientMock.create(); + + soClient.get.mockImplementation(async (type: string, id: string) => { + switch (id) { + case 'download-source-test': { + return mockDownloadSourceSO('download-source-test', { + is_default: false, + name: 'Test', + host: 'http://test.co', + }); + } + case 'existing-default-download-source': { + return mockDownloadSourceSO('existing-default-download-source', { + is_default: true, + name: 'Default host', + host: 'http://artifacts.co', + }); + } + default: + throw new Error('not found: ' + id); + } + }); + soClient.update.mockImplementation(async (type, id, data) => { + return { + id, + type, + attributes: {}, + references: [], + }; + }); + soClient.create.mockImplementation(async (type, data, createOptions) => { + return { + id: createOptions?.id || 'generated-id', + type, + attributes: {}, + references: [], + }; + }); + soClient.find.mockImplementation(async (findOptions) => { + if ( + options?.defaultDownloadSourceId && + findOptions.searchFields && + findOptions.searchFields.includes('is_default') && + findOptions.search === 'true' + ) { + return { + page: 1, + per_page: 10, + saved_objects: [ + { + score: 0, + ...(await soClient.get( + DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + options.defaultDownloadSourceId + )), + }, + ], + total: 1, + }; + } + + return { + page: 1, + per_page: 10, + saved_objects: [], + total: 0, + }; + }); + mockedAppContextService.getInternalUserSOClient.mockReturnValue(soClient); + + return soClient; +} + +describe('Download Service Service', () => { + beforeEach(() => { + mockedAgentPolicyService.list.mockClear(); + mockedAgentPolicyService.hasAPMIntegration.mockClear(); + mockedAgentPolicyService.removeDefaultSourceFromAll.mockReset(); + mockedAppContextService.getInternalUserSOClient.mockReset(); + }); + describe('create', () => { + it('work with a predefined id', async () => { + const soClient = getMockedSoClient(); + + await downloadSourceService.create( + soClient, + { + host: 'http://test.co', + is_default: false, + name: 'Test', + }, + { id: 'download-source-test' } + ); + + expect(soClient.create).toBeCalled(); + + // ID should always be the same for a predefined id + expect(soClient.create.mock.calls[0][2]?.id).toEqual('download-source-test'); + expect((soClient.create.mock.calls[0][1] as DownloadSourceAttributes).source_id).toEqual( + 'download-source-test' + ); + }); + + it('should create a new default value if none exists before', async () => { + const soClient = getMockedSoClient(); + + await downloadSourceService.create( + soClient, + { + is_default: true, + name: 'Test', + host: 'http://test.co', + }, + { id: 'download-source-test' } + ); + + expect(soClient.update).not.toBeCalled(); + }); + + it('should update existing default download source when creating a new default one', async () => { + const soClient = getMockedSoClient({ + defaultDownloadSourceId: 'existing-default-download-source', + }); + + await downloadSourceService.create(soClient, { + is_default: true, + name: 'New default host', + host: 'http://test.co', + }); + + expect(soClient.update).toBeCalledTimes(1); + expect(soClient.update).toBeCalledWith( + expect.anything(), + 'existing-default-download-source', + { is_default: false } + ); + }); + }); + + describe('update', () => { + it('should update existing default value when updating a download source to become the default one', async () => { + const soClient = getMockedSoClient({ + defaultDownloadSourceId: 'existing-default-download-source', + }); + + await downloadSourceService.update(soClient, 'download-source-test', { + is_default: true, + name: 'New default', + host: 'http://test.co', + }); + + expect(soClient.update).toBeCalledWith( + expect.anything(), + 'existing-default-download-source', + { + is_default: false, + } + ); + expect(soClient.update).toBeCalledWith(expect.anything(), 'download-source-test', { + is_default: true, + name: 'New default', + host: 'http://test.co', + }); + }); + + it('should not update existing default when the download source is already the default one', async () => { + const soClient = getMockedSoClient({ + defaultDownloadSourceId: 'existing-default-download-source', + }); + + await downloadSourceService.update(soClient, 'existing-default-download-source', { + is_default: true, + name: 'Test', + host: 'http://test.co', + }); + + expect(soClient.update).toBeCalledTimes(1); + expect(soClient.update).toBeCalledWith( + expect.anything(), + 'existing-default-download-source', + { + is_default: true, + name: 'Test', + host: 'http://test.co', + } + ); + }); + }); + + describe('delete', () => { + it('Call removeDefaultSourceFromAll before deleting the value', async () => { + const soClient = getMockedSoClient(); + await downloadSourceService.delete(soClient, 'download-source-test'); + expect(mockedAgentPolicyService.removeDefaultSourceFromAll).toBeCalled(); + expect(soClient.delete).toBeCalled(); + }); + }); + + describe('get', () => { + it('works with a predefined id', async () => { + const soClient = getMockedSoClient(); + const downloadSource = await downloadSourceService.get(soClient, 'download-source-test'); + + expect(soClient.get).toHaveBeenCalledWith( + DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + 'download-source-test' + ); + + expect(downloadSource.id).toEqual('download-source-test'); + }); + }); + + describe('getDefaultDownloadSourceId', () => { + it('works with a predefined id', async () => { + const soClient = getMockedSoClient({ + defaultDownloadSourceId: 'existing-default-download-source', + }); + const defaultId = await downloadSourceService.getDefaultDownloadSourceId(soClient); + + expect(defaultId).toEqual('existing-default-download-source'); + }); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/download_source.ts b/x-pack/plugins/fleet/server/services/download_source.ts new file mode 100644 index 0000000000000..c189ac1a23019 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/download_source.ts @@ -0,0 +1,176 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { SavedObjectsClientContract, SavedObject } from '@kbn/core/server'; + +import { + DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + DEFAULT_DOWNLOAD_SOURCE, + DEFAULT_DOWNLOAD_SOURCE_ID, +} from '../constants'; + +import type { DownloadSource, DownloadSourceAttributes, DownloadSourceBase } from '../types'; +import { DownloadSourceError } from '../errors'; +import { SO_SEARCH_LIMIT } from '../../common'; + +import { agentPolicyService } from './agent_policy'; +import { appContextService } from './app_context'; + +function savedObjectToDownloadSource(so: SavedObject) { + const { source_id: sourceId, ...attributes } = so.attributes; + + return { + id: sourceId ?? so.id, + ...attributes, + }; +} + +class DownloadSourceService { + public async get(soClient: SavedObjectsClientContract, id: string): Promise { + const soResponse = await soClient.get( + DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + id + ); + + if (soResponse.error) { + throw new Error(soResponse.error.message); + } + + return savedObjectToDownloadSource(soResponse); + } + + public async list(soClient: SavedObjectsClientContract) { + const downloadSources = await soClient.find({ + type: DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + page: 1, + perPage: SO_SEARCH_LIMIT, + sortField: 'is_default', + sortOrder: 'desc', + }); + + return { + items: downloadSources.saved_objects.map(savedObjectToDownloadSource), + total: downloadSources.total, + page: downloadSources.page, + perPage: downloadSources.per_page, + }; + } + + public async create( + soClient: SavedObjectsClientContract, + downloadSource: DownloadSourceBase, + options?: { id?: string } + ): Promise { + const data: DownloadSourceAttributes = downloadSource; + + // default should be only one + if (data.is_default) { + const defaultDownloadSourceId = await this.getDefaultDownloadSourceId(soClient); + + if (defaultDownloadSourceId) { + await this.update(soClient, defaultDownloadSourceId, { is_default: false }); + } + } + if (options?.id) { + data.source_id = options?.id; + } + + const newSo = await soClient.create( + DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + data, + { + id: options?.id, + } + ); + return savedObjectToDownloadSource(newSo); + } + + // default should be only one + public async update( + soClient: SavedObjectsClientContract, + id: string, + newData: Partial + ) { + const updateData: Partial = newData; + + if (updateData.is_default) { + const defaultDownloadSourceId = await this.getDefaultDownloadSourceId(soClient); + + if (defaultDownloadSourceId && defaultDownloadSourceId !== id) { + await this.update(soClient, defaultDownloadSourceId, { is_default: false }); + } + } + const soResponse = await soClient.update( + DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + id, + updateData + ); + if (soResponse.error) { + throw new Error(soResponse.error.message); + } + } + + public async delete( + soClient: SavedObjectsClientContract, + id: string, + { fromPreconfiguration = false }: { fromPreconfiguration?: boolean } = { + fromPreconfiguration: false, + } + ) { + const targetDS = await this.get(soClient, id); + + if (targetDS.is_default) { + throw new DownloadSourceError(`Default Download source ${id} cannot be deleted.`); + } + await agentPolicyService.removeDefaultSourceFromAll( + soClient, + appContextService.getInternalUserESClient(), + id + ); + + return soClient.delete(DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, id); + } + + public async getDefaultDownloadSourceId(soClient: SavedObjectsClientContract) { + const results = await this._getDefaultDownloadSourceSO(soClient); + + if (!results.saved_objects.length) { + return null; + } + + return savedObjectToDownloadSource(results.saved_objects[0]).id; + } + + public async ensureDefault(soClient: SavedObjectsClientContract) { + const downloadSources = await this.list(soClient); + + const defaultDS = downloadSources.items.find((o) => o.is_default); + + if (!defaultDS) { + const newDefaultDS: DownloadSourceBase = { + name: 'default', + is_default: true, + host: DEFAULT_DOWNLOAD_SOURCE, + }; + + return await this.create(soClient, newDefaultDS, { + id: DEFAULT_DOWNLOAD_SOURCE_ID, + }); + } + + return defaultDS; + } + + private async _getDefaultDownloadSourceSO(soClient: SavedObjectsClientContract) { + return await soClient.find({ + type: DOWNLOAD_SOURCE_SAVED_OBJECT_TYPE, + searchFields: ['is_default'], + search: 'true', + }); + } +} + +export const downloadSourceService = new DownloadSourceService(); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/index.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/index.test.ts deleted file mode 100644 index fb89c117ae16b..0000000000000 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/index.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { RegistryDataStream } from '../../../types'; - -import { getRegistryDataStreamAssetBaseName } from '.'; - -test('getBaseName', () => { - const dataStream: RegistryDataStream = { - dataset: 'nginx.access', - title: 'Nginx Acess Logs', - release: 'beta', - type: 'logs', - ingest_pipeline: 'default', - package: 'nginx', - path: 'access', - }; - const name = getRegistryDataStreamAssetBaseName(dataStream); - expect(name).toStrictEqual('logs-nginx.access'); -}); - -test('getBaseName for hidden index', () => { - const dataStream: RegistryDataStream = { - dataset: 'nginx.access', - title: 'Nginx Acess Logs', - release: 'beta', - type: 'logs', - ingest_pipeline: 'default', - package: 'nginx', - path: 'access', - hidden: true, - }; - const name = getRegistryDataStreamAssetBaseName(dataStream); - expect(name).toStrictEqual('.logs-nginx.access'); -}); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/index.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/index.ts deleted file mode 100644 index 81e05ef7d6314..0000000000000 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { RegistryDataStream } from '../../../types'; - -/** - * Creates the base name for Elasticsearch assets in the form of - * {type}-{dataset} - */ -export function getRegistryDataStreamAssetBaseName(dataStream: RegistryDataStream): string { - const baseName = `${dataStream.type}-${dataStream.dataset}`; - return dataStream.hidden ? `.${baseName}` : baseName; -} diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.test.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.test.ts index 3699db0531db6..fcd60ec51e69e 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.test.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.test.ts @@ -12,7 +12,6 @@ import type { RegistryDataStream } from '../../../../types'; import { addCustomPipelineProcessor, - getCustomPipelineNameForDatastream, getPipelineNameForInstallation, rewriteIngestPipeline, } from './helpers'; @@ -192,14 +191,3 @@ processors: ); }); }); - -describe('getCustomPipelineNameForDatastream', () => { - it('return the correct custom pipeline for datastream', () => { - const res = getCustomPipelineNameForDatastream({ - type: 'logs', - dataset: 'test', - } as any); - - expect(res).toBe('logs-test@custom'); - }); -}); diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.ts index b2022bfdb8aa3..dc6e72ffe1b3f 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/helpers.ts @@ -10,6 +10,8 @@ import { ElasticsearchAssetType } from '../../../../types'; import type { RegistryDataStream } from '../../../../types'; import { getPathParts } from '../../archive'; +import { getPipelineNameForDatastream } from '../../../../../common'; + import type { PipelineInstall, RewriteSubstitution } from './types'; export const isTopLevelPipeline = (path: string) => { @@ -38,20 +40,6 @@ export const getPipelineNameForInstallation = ({ return `${packageVersion}-${pipelineName}`; }; -export const getPipelineNameForDatastream = ({ - dataStream, - packageVersion, -}: { - dataStream: RegistryDataStream; - packageVersion: string; -}): string => { - return `${dataStream.type}-${dataStream.dataset}-${packageVersion}`; -}; - -export const getCustomPipelineNameForDatastream = (dataStream: RegistryDataStream): string => { - return `${dataStream.type}-${dataStream.dataset}@custom`; -}; - export function rewriteIngestPipeline( pipeline: string, substitutions: RewriteSubstitution[] diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/index.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/index.ts index a8f0065645b66..0a8414b4959bf 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/index.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/index.ts @@ -6,5 +6,5 @@ */ export { prepareToInstallPipelines } from './install'; -export { getPipelineNameForDatastream, isTopLevelPipeline } from './helpers'; +export { isTopLevelPipeline } from './helpers'; export { deletePreviousPipelines, deletePipeline } from './remove'; diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts index 481d551cb07ac..a1fad104d82ef 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/ingest_pipeline/install.ts @@ -17,13 +17,15 @@ import { FLEET_FINAL_PIPELINE_ID, FLEET_FINAL_PIPELINE_VERSION, } from '../../../../constants'; +import { + getCustomPipelineNameForDatastream, + getPipelineNameForDatastream, +} from '../../../../../common'; import { appendMetadataToIngestPipeline } from '../meta'; import { retryTransientEsErrors } from '../retry'; import { - getCustomPipelineNameForDatastream, - getPipelineNameForDatastream, getPipelineNameForInstallation, rewriteIngestPipeline, isTopLevelPipeline, diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts index 0393c8bf91a50..c0a185a0b270e 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/install.ts @@ -10,6 +10,7 @@ import Boom from '@hapi/boom'; import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import { ElasticsearchAssetType } from '../../../../types'; +import { getPipelineNameForDatastream } from '../../../../../common'; import type { RegistryDataStream, IndexTemplateEntry, @@ -22,9 +23,7 @@ import type { EsAssetReference, PackageInfo, } from '../../../../types'; - import { loadFieldsFromYaml, processFields } from '../../fields/field'; -import { getPipelineNameForDatastream } from '../ingest_pipeline'; import { getAsset, getPathParts } from '../../archive'; import { FLEET_COMPONENT_TEMPLATES, diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.ts index 44b9756edc448..b89f5f8a7355a 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/remove_legacy.ts @@ -12,7 +12,7 @@ import type { import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import type { InstallablePackage, RegistryDataStream } from '../../../../types'; -import { getRegistryDataStreamAssetBaseName } from '..'; +import { getRegistryDataStreamAssetBaseName } from '../../../../../common'; const LEGACY_TEMPLATE_SUFFIXES = ['@mappings', '@settings']; const getComponentTemplateWithSuffix = (dataStream: RegistryDataStream, suffix: string) => { diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts index c87df0921e745..02c5508321db9 100644 --- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts +++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts @@ -16,7 +16,7 @@ import type { IndexTemplateMappings, } from '../../../../types'; import { appContextService } from '../../..'; -import { getRegistryDataStreamAssetBaseName } from '..'; +import { getRegistryDataStreamAssetBaseName } from '../../../../../common'; import { FLEET_GLOBALS_COMPONENT_TEMPLATE_NAME, FLEET_AGENT_ID_VERIFY_COMPONENT_TEMPLATE_NAME, diff --git a/x-pack/plugins/fleet/server/services/index.ts b/x-pack/plugins/fleet/server/services/index.ts index 226d40cfd640a..a23a049bdc762 100644 --- a/x-pack/plugins/fleet/server/services/index.ts +++ b/x-pack/plugins/fleet/server/services/index.ts @@ -43,6 +43,7 @@ export type { AgentClient, AgentService } from './agents'; export { agentPolicyService } from './agent_policy'; export { packagePolicyService } from './package_policy'; export { outputService } from './output'; +export { downloadSourceService } from './download_source'; export { settingsService }; // Plugin services diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts index 1664215613cb3..c0b24f927d848 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts @@ -18,7 +18,7 @@ import type { PreconfiguredAgentPolicy, RegistrySearchResult, } from '../../common/types'; -import type { AgentPolicy, NewPackagePolicy, Output } from '../types'; +import type { AgentPolicy, NewPackagePolicy, Output, DownloadSource } from '../types'; import { AGENT_POLICY_SAVED_OBJECT_TYPE } from '../constants'; @@ -55,6 +55,12 @@ const mockDefaultOutput: Output = { type: 'elasticsearch', hosts: ['http://127.0.0.1:9201'], }; +const mockDefaultDownloadService: DownloadSource = { + id: 'ds-test-id', + is_default: true, + name: 'default download source host', + host: 'http://127.0.0.1:9201', +}; function getPutPreconfiguredPackagesMock() { const soClient = savedObjectsClientMock.create(); @@ -296,6 +302,7 @@ describe('policy preconfiguration', () => { [], [], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -314,6 +321,7 @@ describe('policy preconfiguration', () => { [], [{ name: 'test_package', version: '3.0.0' }], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -344,6 +352,7 @@ describe('policy preconfiguration', () => { ] as PreconfiguredAgentPolicy[], [{ name: 'test_package', version: '3.0.0' }], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -396,6 +405,7 @@ describe('policy preconfiguration', () => { ] as PreconfiguredAgentPolicy[], [{ name: 'test_package', version: '3.0.0' }], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -446,6 +456,7 @@ describe('policy preconfiguration', () => { ] as PreconfiguredAgentPolicy[], [{ name: 'test_package', version: '3.0.0' }], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -503,6 +514,7 @@ describe('policy preconfiguration', () => { ] as PreconfiguredAgentPolicy[], [{ name: 'test_package', version: '3.0.0' }], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -523,6 +535,7 @@ describe('policy preconfiguration', () => { { name: 'test_package', version: '2.0.0' }, ], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ) ).rejects.toThrow( @@ -555,6 +568,7 @@ describe('policy preconfiguration', () => { policies, [{ name: 'test_package', version: '3.0.0' }], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ) ).rejects.toThrow( @@ -587,6 +601,7 @@ describe('policy preconfiguration', () => { policies, [{ name: 'CANNOT_MATCH', version: 'x.y.z' }], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ) ).rejects.toThrow( @@ -612,6 +627,7 @@ describe('policy preconfiguration', () => { ] as PreconfiguredAgentPolicy[], [], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -638,6 +654,7 @@ describe('policy preconfiguration', () => { ] as PreconfiguredAgentPolicy[], [], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -678,6 +695,7 @@ describe('policy preconfiguration', () => { ] as PreconfiguredAgentPolicy[], [], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); expect(spyAgentPolicyServiceUpdate).toBeCalled(); @@ -718,6 +736,7 @@ describe('policy preconfiguration', () => { [policy], [], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); expect(spyAgentPolicyServiceUpdate).not.toBeCalled(); @@ -766,6 +785,7 @@ describe('policy preconfiguration', () => { }, ], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -803,6 +823,7 @@ describe('policy preconfiguration', () => { }, ], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); @@ -848,6 +869,7 @@ describe('policy preconfiguration', () => { }, ], mockDefaultOutput, + mockDefaultDownloadService, DEFAULT_SPACE_ID ); diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.ts b/x-pack/plugins/fleet/server/services/preconfiguration.ts index b425cc4ca4035..1be98d364e963 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.ts @@ -14,6 +14,7 @@ import type { AgentPolicy, Installation, Output, + DownloadSource, PreconfiguredAgentPolicy, PreconfiguredPackage, PreconfigurationError, @@ -45,6 +46,7 @@ export async function ensurePreconfiguredPackagesAndPolicies( policies: PreconfiguredAgentPolicy[] = [], packages: PreconfiguredPackage[] = [], defaultOutput: Output, + defaultDownloadSource: DownloadSource, spaceId: string ): Promise { const logger = appContextService.getLogger(); @@ -154,12 +156,17 @@ export async function ensurePreconfiguredPackagesAndPolicies( preconfiguredAgentPolicy, policy ); + + const newFields = { + defaultDownloadSourceId: defaultDownloadSource.id, + ...fields, + }; if (hasChanged) { const updatedPolicy = await agentPolicyService.update( soClient, esClient, String(preconfiguredAgentPolicy.id), - fields, + newFields, { force: true, } diff --git a/x-pack/plugins/fleet/server/services/setup.test.ts b/x-pack/plugins/fleet/server/services/setup.test.ts index c9dc4227ae48d..c7dd2b2657992 100644 --- a/x-pack/plugins/fleet/server/services/setup.test.ts +++ b/x-pack/plugins/fleet/server/services/setup.test.ts @@ -21,6 +21,7 @@ jest.mock('./preconfiguration'); jest.mock('./preconfiguration/outputs'); jest.mock('./settings'); jest.mock('./output'); +jest.mock('./download_source'); jest.mock('./epm/packages'); jest.mock('./managed_package_policies'); diff --git a/x-pack/plugins/fleet/server/services/setup.ts b/x-pack/plugins/fleet/server/services/setup.ts index 50819d7a2640d..ac8aa17603d92 100644 --- a/x-pack/plugins/fleet/server/services/setup.ts +++ b/x-pack/plugins/fleet/server/services/setup.ts @@ -26,6 +26,7 @@ import { agentPolicyService } from './agent_policy'; import { ensurePreconfiguredPackagesAndPolicies } from './preconfiguration'; import { ensurePreconfiguredOutputs } from './preconfiguration/outputs'; import { outputService } from './output'; +import { downloadSourceService } from './download_source'; import { generateEnrollmentAPIKey, hasEnrollementAPIKeysForPolicy } from './api_keys'; import { settingsService } from '.'; @@ -76,6 +77,8 @@ async function createSetupSideEffects( const defaultOutput = await outputService.ensureDefaultOutput(soClient); + const defaultDownloadSource = await downloadSourceService.ensureDefault(soClient); + if (appContextService.getConfig()?.agentIdVerificationEnabled) { logger.debug('Setting up Fleet Elasticsearch assets'); await ensureFleetGlobalEsAssets(soClient, esClient); @@ -109,6 +112,7 @@ async function createSetupSideEffects( policies, packages, defaultOutput, + defaultDownloadSource, DEFAULT_SPACE_ID ); diff --git a/x-pack/plugins/fleet/server/types/index.tsx b/x-pack/plugins/fleet/server/types/index.tsx index 10a00393f8075..1d83d4011115c 100644 --- a/x-pack/plugins/fleet/server/types/index.tsx +++ b/x-pack/plugins/fleet/server/types/index.tsx @@ -74,6 +74,9 @@ export type { FleetServerAgentAction, FleetServerPolicy, FullAgentPolicyInputStream, + DownloadSourceBase, + DownloadSource, + DownloadSourceAttributes, } from '../../common'; export { ElasticsearchAssetType, diff --git a/x-pack/plugins/fleet/server/types/models/download_sources.ts b/x-pack/plugins/fleet/server/types/models/download_sources.ts new file mode 100644 index 0000000000000..5d11419493660 --- /dev/null +++ b/x-pack/plugins/fleet/server/types/models/download_sources.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 { schema } from '@kbn/config-schema'; + +const DownloadSourceBaseSchema = { + id: schema.maybe(schema.string()), + name: schema.string(), + host: schema.uri({ scheme: ['http', 'https'] }), + is_default: schema.boolean({ defaultValue: false }), +}; + +export const DownloadSourceSchema = schema.object({ ...DownloadSourceBaseSchema }); diff --git a/x-pack/plugins/fleet/server/types/models/index.ts b/x-pack/plugins/fleet/server/types/models/index.ts index d71c6b2e0d748..0a58538616f77 100644 --- a/x-pack/plugins/fleet/server/types/models/index.ts +++ b/x-pack/plugins/fleet/server/types/models/index.ts @@ -11,3 +11,4 @@ export * from './package_policy'; export * from './output'; export * from './enrollment_api_key'; export * from './preconfiguration'; +export * from './download_sources'; diff --git a/x-pack/plugins/fleet/server/types/rest_spec/agent.ts b/x-pack/plugins/fleet/server/types/rest_spec/agent.ts index f008822437d64..405c71e9a42b3 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/agent.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/agent.ts @@ -59,6 +59,7 @@ export const PostBulkAgentUnenrollRequestSchema = { agents: schema.oneOf([schema.arrayOf(schema.string()), schema.string()]), force: schema.maybe(schema.boolean()), revoke: schema.maybe(schema.boolean()), + batchSize: schema.maybe(schema.number()), }), }; @@ -97,6 +98,7 @@ export const PostBulkAgentUpgradeRequestSchema = { }, }) ), + batchSize: schema.maybe(schema.number()), }), }; @@ -113,6 +115,7 @@ export const PostBulkAgentReassignRequestSchema = { body: schema.object({ policy_id: schema.string(), agents: schema.oneOf([schema.arrayOf(schema.string()), schema.string()]), + batchSize: schema.maybe(schema.number()), }), }; diff --git a/x-pack/plugins/fleet/server/types/rest_spec/download_sources.ts b/x-pack/plugins/fleet/server/types/rest_spec/download_sources.ts new file mode 100644 index 0000000000000..039afbdc55aad --- /dev/null +++ b/x-pack/plugins/fleet/server/types/rest_spec/download_sources.ts @@ -0,0 +1,35 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +import { DownloadSourceSchema } from '../models'; + +export const GetOneDownloadSourcesRequestSchema = { + params: schema.object({ + sourceId: schema.string(), + }), +}; + +export const getDownloadSourcesRequestSchema = {}; + +export const PostDownloadSourcesRequestSchema = { + body: DownloadSourceSchema, +}; + +export const PutDownloadSourcesRequestSchema = { + params: schema.object({ + sourceId: schema.string(), + }), + body: DownloadSourceSchema, +}; + +export const DeleteDownloadSourcesRequestSchema = { + params: schema.object({ + sourceId: schema.string(), + }), +}; diff --git a/x-pack/plugins/fleet/server/types/rest_spec/index.ts b/x-pack/plugins/fleet/server/types/rest_spec/index.ts index fe5dae4e39ed7..3bd19ddbeb921 100644 --- a/x-pack/plugins/fleet/server/types/rest_spec/index.ts +++ b/x-pack/plugins/fleet/server/types/rest_spec/index.ts @@ -16,3 +16,4 @@ export * from './preconfiguration'; export * from './settings'; export * from './setup'; export * from './check_permissions'; +export * from './download_sources'; diff --git a/x-pack/plugins/infra/public/pages/logs/page_template.tsx b/x-pack/plugins/infra/public/pages/logs/page_template.tsx index 8569a497b05fa..28cf9e5a60ab3 100644 --- a/x-pack/plugins/infra/public/pages/logs/page_template.tsx +++ b/x-pack/plugins/infra/public/pages/logs/page_template.tsx @@ -58,6 +58,7 @@ export const LogsPageTemplate: React.FC = ({ ); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.ts index 8069bf66053d0..8f431afa129e0 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/formula_public_api.ts @@ -30,6 +30,12 @@ export interface FormulaPublicApi { column: { formula: string; label?: string; + format?: { + id: string; + params?: { + decimals: number; + }; + }; }, layer: PersistedIndexPatternLayer, dataView: DataView @@ -51,7 +57,7 @@ export const createFormulaPublicApi = (): FormulaPublicApi => { }; return { - insertOrReplaceFormulaColumn: (id, { formula, label }, layer, dataView) => { + insertOrReplaceFormulaColumn: (id, { formula, label, format }, layer, dataView) => { const indexPattern = getCachedLensIndexPattern(dataView); return insertOrReplaceFormulaColumn( @@ -65,6 +71,7 @@ export const createFormulaPublicApi = (): FormulaPublicApi => { isBucketed: false, params: { formula, + format, }, }, { ...layer, indexPatternId: indexPattern.id }, diff --git a/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx b/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx index 4e713872c5a67..09bf2f065c60c 100644 --- a/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx +++ b/x-pack/plugins/lens/public/mocks/lens_plugin_mock.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { createFormulaPublicApi } from '../async_services'; import { LensPublicStart } from '..'; import { visualizationTypes } from '../xy_visualization/types'; @@ -27,9 +28,7 @@ export const lensPluginMock = { .mockReturnValue(new Promise((resolve) => resolve(visualizationTypes))), stateHelperApi: jest.fn().mockResolvedValue({ - formula: { - insertOrReplaceFormulaColumn: jest.fn(), - }, + formula: createFormulaPublicApi(), }), }; return startContract; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts index 3c0e84b6cafed..4de565e5a87e4 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.test.ts @@ -20,6 +20,8 @@ import { sampleAttributeKpi } from './test_data/sample_attribute_kpi'; import { RECORDS_FIELD, REPORT_METRIC_FIELD, PERCENTILE_RANKS, ReportTypes } from './constants'; import { obsvReportConfigMap } from '../obsv_exploratory_view'; import { sampleAttributeWithReferenceLines } from './test_data/sample_attribute_with_reference_lines'; +import { lensPluginMock } from '@kbn/lens-plugin/public/mocks'; +import { FormulaPublicApi } from '@kbn/lens-plugin/public'; describe('Lens Attribute', () => { mockAppDataView(); @@ -47,8 +49,13 @@ describe('Lens Attribute', () => { selectedMetricField: TRANSACTION_DURATION, }; - beforeEach(() => { - lnsAttr = new LensAttributes([layerConfig], reportViewConfig.reportType); + const lensPluginMockStart = lensPluginMock.createStartContract(); + + let formulaHelper: FormulaPublicApi; + + beforeEach(async () => { + formulaHelper = (await lensPluginMockStart.stateHelperApi()).formula; + lnsAttr = new LensAttributes([layerConfig], reportViewConfig.reportType, formulaHelper); }); it('should return expected json', function () { @@ -163,7 +170,6 @@ describe('Lens Attribute', () => { isFormulaBroken: false, }, references: ['y-axis-column-layer0X3'], - scale: 'ratio', }); }); @@ -218,7 +224,7 @@ describe('Lens Attribute', () => { selectedMetricField: TRANSACTION_DURATION, }; - lnsAttr = new LensAttributes([layerConfig1], reportViewConfig.reportType); + lnsAttr = new LensAttributes([layerConfig1], reportViewConfig.reportType, formulaHelper); expect(JSON.stringify(lnsAttr.getFieldMeta(REPORT_METRIC_FIELD, layerConfig1))).toEqual( JSON.stringify({ @@ -322,7 +328,8 @@ describe('Lens Attribute', () => { it('should hide y axis when there are multiple series', function () { const lensAttrWithMultiSeries = new LensAttributes( [layerConfig, layerConfig], - reportViewConfig.reportType + reportViewConfig.reportType, + formulaHelper ).getJSON() as any; expect(lensAttrWithMultiSeries.state.visualization.axisTitlesVisibilitySettings).toEqual({ x: true, @@ -334,7 +341,8 @@ describe('Lens Attribute', () => { it('should show y axis when there is a single series', function () { const lensAttrWithMultiSeries = new LensAttributes( [layerConfig], - reportViewConfig.reportType + reportViewConfig.reportType, + formulaHelper ).getJSON() as any; expect(lensAttrWithMultiSeries.state.visualization.axisTitlesVisibilitySettings).toEqual({ x: true, @@ -427,7 +435,8 @@ describe('Lens Attribute', () => { it('should not use global filters when there is more than one series', function () { const multiSeriesLensAttr = new LensAttributes( [layerConfig, layerConfig], - reportViewConfig.reportType + reportViewConfig.reportType, + formulaHelper ).getJSON(); expect(multiSeriesLensAttr.state.query.query).toEqual('transaction.duration.us < 60000000'); }); @@ -447,7 +456,7 @@ describe('Lens Attribute', () => { selectedMetricField: LCP_FIELD, }; - lnsAttr = new LensAttributes([layerConfig1], reportViewConfig.reportType); + lnsAttr = new LensAttributes([layerConfig1], reportViewConfig.reportType, formulaHelper); lnsAttr.getBreakdownColumn({ layerConfig: layerConfig1, @@ -540,7 +549,6 @@ describe('Lens Attribute', () => { isFormulaBroken: false, }, references: ['y-axis-column-layer0X3'], - scale: 'ratio', }, 'y-axis-column-layer0X0': { customLabel: true, @@ -551,8 +559,11 @@ describe('Lens Attribute', () => { 'transaction.type: page-load and processor.event: transaction and transaction.type : *', }, isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'count', + params: { + emptyAsNull: false, + }, scale: 'ratio', sourceField: RECORDS_FIELD, }, @@ -565,8 +576,11 @@ describe('Lens Attribute', () => { 'transaction.type: page-load and processor.event: transaction and transaction.type : *', }, isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'count', + params: { + emptyAsNull: false, + }, scale: 'ratio', sourceField: RECORDS_FIELD, }, @@ -574,7 +588,7 @@ describe('Lens Attribute', () => { customLabel: true, dataType: 'number', isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'overall_sum', references: ['y-axis-column-layer0X1'], scale: 'ratio', @@ -583,13 +597,13 @@ describe('Lens Attribute', () => { customLabel: true, dataType: 'number', isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'math', params: { tinymathAst: { args: ['y-axis-column-layer0X0', 'y-axis-column-layer0X2'], location: { - max: 30, + max: 212, min: 0, }, name: 'divide', @@ -645,7 +659,7 @@ describe('Lens Attribute', () => { selectedMetricField: TRANSACTION_DURATION, }; - lnsAttr = new LensAttributes([layerConfig1], reportViewConfig.reportType); + lnsAttr = new LensAttributes([layerConfig1], reportViewConfig.reportType, formulaHelper); const attributes = lnsAttr.getJSON(); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts index 740c45993ef04..7611801467b27 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_attributes.ts @@ -29,6 +29,7 @@ import { TypedLensByValueInput, XYCurveType, XYState, + FormulaPublicApi, YAxisMode, } from '@kbn/lens-plugin/public'; import type { DataView } from '@kbn/data-views-plugin/common'; @@ -139,11 +140,17 @@ export class LensAttributes { >; globalFilter?: { query: string; language: string }; reportType: string; + lensFormulaHelper?: FormulaPublicApi; - constructor(layerConfigs: LayerConfig[], reportType: string) { + constructor( + layerConfigs: LayerConfig[], + reportType: string, + lensFormulaHelper?: FormulaPublicApi + ) { this.layers = {}; this.seriesReferenceLines = {}; this.reportType = reportType; + this.lensFormulaHelper = lensFormulaHelper; layerConfigs.forEach(({ seriesConfig, operationType }) => { if (operationType && reportType !== ReportTypes.SINGLE_METRIC) { @@ -618,7 +625,13 @@ export class LensAttributes { layerConfig.seriesConfig.yAxisColumns[0]; if (sourceField === RECORDS_PERCENTAGE_FIELD) { - return getDistributionInPercentageColumn({ label, layerId, columnFilter }).main; + return getDistributionInPercentageColumn({ + label, + layerId, + columnFilter, + dataView: layerConfig.indexPattern, + lensFormulaHelper: this.lensFormulaHelper!, + }).main; } if (sourceField === RECORDS_FIELD || !sourceField) { @@ -647,8 +660,13 @@ export class LensAttributes { const { sourceField: mainSourceField, label: mainLabel } = yAxisColumns[0]; if (mainSourceField === RECORDS_PERCENTAGE_FIELD && layerId && !forAccessorsKeys) { - return getDistributionInPercentageColumn({ label: mainLabel, layerId, columnFilter }) - .supportingColumns; + return getDistributionInPercentageColumn({ + label: mainLabel, + layerId, + columnFilter, + dataView: layerConfig.indexPattern, + lensFormulaHelper: this.lensFormulaHelper!, + }).supportingColumns; } if (yAxisColumns.length === 1 && breakdown === PERCENTILE) { diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_columns/overall_column.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_columns/overall_column.ts index 66c246f36db18..b0cb9939dacc1 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_columns/overall_column.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/lens_columns/overall_column.ts @@ -4,24 +4,21 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { TinymathAST } from '@kbn/tinymath'; -import { - DataType, - CountIndexPatternColumn, - MathIndexPatternColumn, - FormulaIndexPatternColumn, - OverallSumIndexPatternColumn, -} from '@kbn/lens-plugin/public'; -import { RECORDS_FIELD } from '../constants'; +import { FormulaPublicApi } from '@kbn/lens-plugin/public'; +import type { DataView } from '@kbn/data-views-plugin/common'; export function getDistributionInPercentageColumn({ label, layerId, + dataView, columnFilter, + lensFormulaHelper, }: { label?: string; columnFilter?: string; layerId: string; + lensFormulaHelper: FormulaPublicApi; + dataView: DataView; }) { const yAxisColId = `y-axis-column-${layerId}`; @@ -31,70 +28,26 @@ export function getDistributionInPercentageColumn({ lensFormula = `count(kql='${columnFilter}') / overall_sum(count(kql='${columnFilter}'))`; } - const main: FormulaIndexPatternColumn = { - customLabel: true, - label: label || 'Percentage of records', - dataType: 'number' as DataType, - operationType: 'formula', - isBucketed: false, - scale: 'ratio', - params: { + const { columns } = lensFormulaHelper?.insertOrReplaceFormulaColumn( + yAxisColId, + { formula: lensFormula, - isFormulaBroken: false, - format: { id: 'percent', params: { decimals: 0 } }, + label, + format: { + id: 'percent', + params: { + decimals: 0, + }, + }, }, - references: [`${yAxisColId}X3`], - }; - - const countColumn: CountIndexPatternColumn = { - label: 'Part of count() / overall_sum(count())', - dataType: 'number', - operationType: 'count', - isBucketed: false, - scale: 'ratio', - sourceField: RECORDS_FIELD, - customLabel: true, - filter: { query: columnFilter ?? '', language: 'kuery' }, - }; - - const overAllSumColumn: OverallSumIndexPatternColumn = { - label: 'Part of count() / overall_sum(count())', - dataType: 'number', - operationType: 'overall_sum', - isBucketed: false, - scale: 'ratio', - references: [`${yAxisColId}X1`], - customLabel: true, - }; - - const tinyMathColumn: MathIndexPatternColumn = { - label: 'Part of count() / overall_sum(count())', - dataType: 'number', - operationType: 'math', - isBucketed: false, - scale: 'ratio', - params: { - tinymathAst: { - type: 'function', - name: 'divide', - args: [`${yAxisColId}X0`, `${yAxisColId}X2`], - location: { min: 0, max: 30 }, - text: lensFormula, - } as unknown as TinymathAST, + { + columns: {}, + columnOrder: [], }, - references: [`${yAxisColId}X0`, `${yAxisColId}X2`], - customLabel: true, - }; + dataView + ) ?? { columns: {} }; - const supportingColumns: Record< - string, - CountIndexPatternColumn | MathIndexPatternColumn | OverallSumIndexPatternColumn - > = { - [`${yAxisColId}X0`]: countColumn, - [`${yAxisColId}X1`]: countColumn, - [`${yAxisColId}X2`]: overAllSumColumn, - [`${yAxisColId}X3`]: tinyMathColumn, - }; + const { [yAxisColId]: main, ...supportingColumns } = columns; - return { main, supportingColumns }; + return { main: columns[yAxisColId], supportingColumns }; } diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts index 02ce7d5f0c966..e1940ea08def8 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute.ts @@ -81,7 +81,6 @@ export const sampleAttribute = { isFormulaBroken: false, }, references: ['y-axis-column-layer0X3'], - scale: 'ratio', }, 'y-axis-column-layer0X0': { customLabel: true, @@ -92,8 +91,11 @@ export const sampleAttribute = { 'transaction.type: page-load and processor.event: transaction and transaction.type : *', }, isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'count', + params: { + emptyAsNull: false, + }, scale: 'ratio', sourceField: RECORDS_FIELD, }, @@ -106,8 +108,11 @@ export const sampleAttribute = { 'transaction.type: page-load and processor.event: transaction and transaction.type : *', }, isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'count', + params: { + emptyAsNull: false, + }, scale: 'ratio', sourceField: RECORDS_FIELD, }, @@ -115,7 +120,7 @@ export const sampleAttribute = { customLabel: true, dataType: 'number', isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'overall_sum', references: ['y-axis-column-layer0X1'], scale: 'ratio', @@ -124,13 +129,13 @@ export const sampleAttribute = { customLabel: true, dataType: 'number', isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'math', params: { tinymathAst: { args: ['y-axis-column-layer0X0', 'y-axis-column-layer0X2'], location: { - max: 30, + max: 212, min: 0, }, name: 'divide', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_with_reference_lines.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_with_reference_lines.ts index 16ce665de0de4..6dcc241903849 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_with_reference_lines.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/configurations/test_data/sample_attribute_with_reference_lines.ts @@ -81,7 +81,6 @@ export const sampleAttributeWithReferenceLines = { isFormulaBroken: false, }, references: ['y-axis-column-layer0X3'], - scale: 'ratio', }, 'y-axis-column-layer0X0': { customLabel: true, @@ -92,8 +91,11 @@ export const sampleAttributeWithReferenceLines = { 'transaction.type: page-load and processor.event: transaction and transaction.type : * and service.name: (elastic or kibana)', }, isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'count', + params: { + emptyAsNull: false, + }, scale: 'ratio', sourceField: RECORDS_FIELD, }, @@ -106,8 +108,11 @@ export const sampleAttributeWithReferenceLines = { 'transaction.type: page-load and processor.event: transaction and transaction.type : * and service.name: (elastic or kibana)', }, isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'count', + params: { + emptyAsNull: false, + }, scale: 'ratio', sourceField: RECORDS_FIELD, }, @@ -115,7 +120,7 @@ export const sampleAttributeWithReferenceLines = { customLabel: true, dataType: 'number', isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'overall_sum', references: ['y-axis-column-layer0X1'], scale: 'ratio', @@ -124,13 +129,13 @@ export const sampleAttributeWithReferenceLines = { customLabel: true, dataType: 'number', isBucketed: false, - label: 'Part of count() / overall_sum(count())', + label: 'Part of Pages loaded', operationType: 'math', params: { tinymathAst: { args: ['y-axis-column-layer0X0', 'y-axis-column-layer0X2'], location: { - max: 30, + max: 288, min: 0, }, name: 'divide', diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.test.tsx index adbd899e099f0..623c5dd3e083b 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.test.tsx @@ -20,6 +20,9 @@ import * as theme from '../../../../hooks/use_theme'; import { dataTypes, obsvReportConfigMap, reportTypesList } from '../obsv_exploratory_view'; import { ExploratoryViewContextProvider } from '../contexts/exploratory_view_config'; import { themeServiceMock } from '@kbn/core/public/mocks'; +import * as lensHook from './use_lens_formula_helper'; +import { lensPluginMock } from '@kbn/lens-plugin/public/mocks'; +import { FormulaPublicApi } from '@kbn/lens-plugin/public'; const mockSingleSeries = [ { @@ -51,6 +54,16 @@ describe('useExpViewTimeRange', function () { euiColorVis1: '#111111', }, }); + + let formulaHelper: FormulaPublicApi; + + beforeAll(async () => { + const lensPluginMockStart = lensPluginMock.createStartContract(); + formulaHelper = (await lensPluginMockStart.stateHelperApi()).formula; + + jest.spyOn(lensHook, 'useLensFormulaHelper').mockReturnValue(formulaHelper); + }); + const lensAttributesSpy = jest.spyOn(lensAttributes, 'LensAttributes'); function Wrapper({ children }: { children: JSX.Element }) { @@ -82,7 +95,8 @@ describe('useExpViewTimeRange', function () { seriesConfig: expect.objectContaining({ reportType: ReportTypes.KPI }), }), ]), - 'kpi-over-time' + 'kpi-over-time', + formulaHelper ); }); }); diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts index 9e82c80802640..c846fbc93fbcd 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_attributes.ts @@ -9,6 +9,7 @@ import { useMemo } from 'react'; import { isEmpty } from 'lodash'; import { TypedLensByValueInput } from '@kbn/lens-plugin/public'; import { EuiTheme } from '@kbn/kibana-react-plugin/common'; +import { useLensFormulaHelper } from './use_lens_formula_helper'; import { ALL_VALUES_SELECTED } from '../configurations/constants/url_constants'; import { LayerConfig, LensAttributes } from '../configurations/lens_attributes'; import { @@ -101,12 +102,14 @@ export const useLensAttributes = (): TypedLensByValueInput['attributes'] | null const theme = useTheme(); + const lensFormulaHelper = useLensFormulaHelper(); + return useMemo(() => { // we only use the data from url to apply, since that gets updated to apply changes const allSeriesT: AllSeries = convertAllShortSeries(storage.get(allSeriesKey) ?? []); const reportTypeT: ReportViewType = storage.get(reportTypeKey) as ReportViewType; - if (isEmpty(dataViews) || isEmpty(allSeriesT) || !reportTypeT) { + if (isEmpty(dataViews) || isEmpty(allSeriesT) || !reportTypeT || !lensFormulaHelper) { return null; } const layerConfigs = getLayerConfigs( @@ -127,10 +130,10 @@ export const useLensAttributes = (): TypedLensByValueInput['attributes'] | null return lensAttributes.getJSON(lastRefresh); } - const lensAttributes = new LensAttributes(layerConfigs, reportTypeT); + const lensAttributes = new LensAttributes(layerConfigs, reportTypeT, lensFormulaHelper); return lensAttributes.getJSON(lastRefresh); // we also want to check the state on allSeries changes // eslint-disable-next-line react-hooks/exhaustive-deps - }, [dataViews, reportType, storage, theme, lastRefresh, allSeries]); + }, [dataViews, reportType, storage, theme, lastRefresh, allSeries, lensFormulaHelper]); }; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_formula_helper.ts b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_formula_helper.ts new file mode 100644 index 0000000000000..6e1bfe4a9eb83 --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/hooks/use_lens_formula_helper.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useMemo } from 'react'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; +import { ObservabilityPublicPluginsStart, useFetcher } from '../../../..'; + +export const useLensFormulaHelper = () => { + const { + services: { lens }, + } = useKibana(); + + const { data: lensHelper } = useFetcher(async () => { + return lens.stateHelperApi(); + }, [lens]); + + return useMemo(() => { + if (lensHelper) { + return lensHelper.formula; + } + }, [lensHelper]); +}; diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx index fe7fe29ee4637..9e649b06979ec 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/rtl_helpers.tsx @@ -29,6 +29,8 @@ import { createStubDataView } from '@kbn/data-views-plugin/common/stubs'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { casesPluginMock } from '@kbn/cases-plugin/public/mocks'; +import { DataViewSpec } from '@kbn/data-views-plugin/public'; +import { rumFieldFormats } from './configurations/rum/field_formats'; import { ObservabilityPublicPluginsStart } from '../../../plugin'; import * as useAppDataViewHook from './hooks/use_app_data_view'; import { DataViewContext, DataViewContextProvider } from './hooks/use_app_data_view'; @@ -365,12 +367,19 @@ export const mockHistory = { }, }; +const fieldFormatMap: DataViewSpec['fieldFormats'] = {}; + +rumFieldFormats.forEach(({ field, format }) => { + fieldFormatMap[field] = format; +}); + export const mockDataView = createStubDataView({ spec: { id: 'apm-*', title: 'apm-*', timeFieldName: '@timestamp', fields: JSON.parse(dataViewData.attributes.fields), + fieldFormats: fieldFormatMap, }, }); diff --git a/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx b/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx index 59c051f852ffe..949e83009019e 100644 --- a/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx +++ b/x-pack/plugins/observability/public/components/shared/page_template/page_template.tsx @@ -16,6 +16,7 @@ import { SharedUxServicesProvider } from '@kbn/shared-ux-services'; import type { SharedUXPluginStart } from '@kbn/shared-ux-plugin/public'; import { KibanaPageTemplate, KibanaPageTemplateProps } from '@kbn/shared-ux-components'; import type { NavigationSection } from '../../../services/navigation_registry'; +import { ObservabilityTour } from '../tour'; import { NavNameWithBadge, hideBadge } from './nav_name_with_badge'; export type WrappedPageTemplateProps = Pick< @@ -33,6 +34,7 @@ export type WrappedPageTemplateProps = Pick< | 'noDataConfig' > & { showSolutionNav?: boolean; + isPageDataLoaded?: boolean; }; export interface ObservabilityPageTemplateDependencies { @@ -54,6 +56,7 @@ export function ObservabilityPageTemplate({ navigationSections$, getSharedUXContext, showSolutionNav = true, + isPageDataLoaded = true, ...pageTemplateProps }: ObservabilityPageTemplateProps): React.ReactElement | null { const sections = useObservable(navigationSections$, []); @@ -90,6 +93,7 @@ export function ObservabilityPageTemplate({ ), href, isSelected, + 'data-nav-id': entry.label.toLowerCase().split(' ').join('_'), onClick: (event) => { if (entry.onClick) { entry.onClick(event); @@ -124,21 +128,34 @@ export function ObservabilityPageTemplate({ return ( - - {children} - + {({ isTourVisible }) => { + return ( + + {children} + + ); + }} + ); } diff --git a/x-pack/plugins/observability/public/components/shared/tour/index.ts b/x-pack/plugins/observability/public/components/shared/tour/index.ts new file mode 100644 index 0000000000000..a4f0e1e820180 --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/tour/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { ObservabilityTour } from './tour'; diff --git a/x-pack/plugins/observability/public/components/shared/tour/tour.scss b/x-pack/plugins/observability/public/components/shared/tour/tour.scss new file mode 100644 index 0000000000000..68d04250c5ec4 --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/tour/tour.scss @@ -0,0 +1,3 @@ +.euiOverlayMask.observabilityTour__overlayMask { + left: 248px; +} diff --git a/x-pack/plugins/observability/public/components/shared/tour/tour.tsx b/x-pack/plugins/observability/public/components/shared/tour/tour.tsx new file mode 100644 index 0000000000000..f90668ea14139 --- /dev/null +++ b/x-pack/plugins/observability/public/components/shared/tour/tour.tsx @@ -0,0 +1,308 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { ReactNode, useState, useCallback, useEffect } from 'react'; + +import { i18n } from '@kbn/i18n'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiTourStep, + EuiTourStepProps, + EuiText, + ElementTarget, + EuiOverlayMask, + useIsWithinBreakpoints, +} from '@elastic/eui'; +import { useLocation } from 'react-router-dom'; +import { ApplicationStart } from '@kbn/core/public'; +import { observabilityAppId } from '../../../../common'; + +import './tour.scss'; + +interface TourStep { + content: EuiTourStepProps['content']; + anchor: ElementTarget; + anchorPosition: EuiTourStepProps['anchorPosition']; + title: EuiTourStepProps['title']; + dataTestSubj: string; + showOverlay: boolean; +} + +const minWidth: EuiTourStepProps['minWidth'] = 360; +const maxWidth: EuiTourStepProps['maxWidth'] = 360; +const offset: EuiTourStepProps['offset'] = 30; +const repositionOnScroll: EuiTourStepProps['repositionOnScroll'] = false; + +const overviewPath = '/overview'; +const guidedSetupStep = 6; + +const observabilityTourStorageKey = 'xpack.observability.tourState'; + +const tourStepsConfig: TourStep[] = [ + { + title: i18n.translate('xpack.observability.tour.observabilityOverviewStep.tourTitle', { + defaultMessage: 'Welcome to Elastic Observability', + }), + content: ( + + {i18n.translate('xpack.observability.tour.observabilityOverviewStep.tourContent', { + defaultMessage: + 'Take a quick tour of the Observability solution to get a feel for how it works.', + })} + + ), + anchor: `[id^="KibanaPageTemplateSolutionNav"]`, + anchorPosition: 'rightUp', + dataTestSubj: 'overviewStep', + showOverlay: true, + }, + { + title: i18n.translate('xpack.observability.tour.streamStep.tourTitle', { + defaultMessage: 'View all your infrastructure logs in real time', + }), + content: ( + + {i18n.translate('xpack.observability.tour.streamStep.tourContent', { + defaultMessage: 'Verify your data is flowing correctly.', + })} + + ), + anchor: `[data-nav-id="stream"]`, + anchorPosition: 'rightUp', + dataTestSubj: 'streamStep', + showOverlay: true, + }, + { + title: i18n.translate('xpack.observability.tour.metricsExplorerStep.tourTitle', { + defaultMessage: 'Inspect your overall infrastructure performance', + }), + content: ( + + {i18n.translate('xpack.observability.tour.metricsExplorerStep.tourContent', { + defaultMessage: 'Check the health of your infrastructure.', + })} + + ), + anchor: `[data-nav-id="metrics_explorer"]`, + anchorPosition: 'rightUp', + dataTestSubj: 'metricsExplorerStep', + showOverlay: true, + }, + { + title: i18n.translate('xpack.observability.tour.tracesStep.tourTitle', { + defaultMessage: 'Understand the entire lifecycle of a request/action', + }), + content: ( + + {i18n.translate('xpack.observability.tour.tracesStep.tourContent', { + defaultMessage: 'Track down any issues affecting your infrastructure.', + })} + + ), + anchor: `[data-nav-id="traces"]`, + anchorPosition: 'rightUp', + dataTestSubj: 'tracesStep', + showOverlay: true, + }, + { + title: i18n.translate('xpack.observability.tour.alertsStep.tourTitle', { + defaultMessage: 'Get notified when something goes wrong', + }), + content: ( + + {i18n.translate('xpack.observability.tour.alertsStep.tourContent', { + defaultMessage: 'Configure how you want to be notified when a problem occurs.', + })} + + ), + anchor: `[data-nav-id="alerts"]`, + anchorPosition: 'rightUp', + dataTestSubj: 'alertStep', + showOverlay: true, + }, + { + title: i18n.translate('xpack.observability.tour.guidedSetupStep.tourTitle', { + defaultMessage: `You're ready!`, + }), + content: ( + + {i18n.translate('xpack.observability.tour.guidedSetupStep.tourContent', { + defaultMessage: 'View the guided setup to learn about next steps.', + })} + + ), + anchor: '#guidedSetupButton', + anchorPosition: 'rightUp', + dataTestSubj: 'guidedSetupStep', + showOverlay: false, + }, +]; + +const getSteps = ({ + activeStep, + incrementStep, + endTour, +}: { + activeStep: number; + incrementStep: () => void; + endTour: () => void; +}) => { + const footerAction = ( + + + endTour()} + size="xs" + color="text" + data-test-subj="skipButton" + > + {i18n.translate('xpack.observability.tour.skipButtonLabel', { + defaultMessage: 'Skip', + })} + + + + incrementStep()} + size="s" + color="success" + data-test-subj="nextButton" + > + {i18n.translate('xpack.observability.tour.nextButtonLabel', { + defaultMessage: 'Next', + })} + + + + ); + + const lastStepFooterAction = ( + endTour()} data-test-subj="endButton"> + {i18n.translate('xpack.observability.tour.endButtonLabel', { + defaultMessage: 'End tour', + })} + + ); + + return tourStepsConfig.map((stepConfig, index) => { + const step = index + 1; + const { dataTestSubj, showOverlay, ...tourStepProps } = stepConfig; + return ( + endTour()} + footerAction={activeStep === tourStepsConfig.length ? lastStepFooterAction : footerAction} + panelProps={{ + 'data-test-subj': dataTestSubj, + }} + /> + ); + }); +}; + +interface TourState { + activeStep: number; + isTourActive: boolean; +} + +const getInitialTourState = (prevTourState: string | null): TourState => { + if (prevTourState) { + try { + const parsedPrevTourState = JSON.parse(prevTourState); + return parsedPrevTourState as TourState; + } catch (e) { + // Fall back to default state + } + } + + return { + activeStep: 1, + isTourActive: false, + }; +}; + +export function ObservabilityTour({ + children, + navigateToApp, + isPageDataLoaded, + showTour, +}: { + children: ({ isTourVisible }: { isTourVisible: boolean }) => ReactNode; + navigateToApp: ApplicationStart['navigateToApp']; + isPageDataLoaded: boolean; + showTour: boolean; +}) { + const prevTourState = localStorage.getItem(observabilityTourStorageKey); + const { activeStep: initialActiveStep, isTourActive: initialIsTourActive } = + getInitialTourState(prevTourState); + + const [isTourActive, setIsTourActive] = useState(initialIsTourActive); + const [activeStep, setActiveStep] = useState(initialActiveStep); + + const { pathname: currentPath } = useLocation(); + + const isSmallBreakpoint = useIsWithinBreakpoints(['s']); + + const isOverviewPage = currentPath === overviewPath; + const { showOverlay } = tourStepsConfig[activeStep - 1]; + + const incrementStep = useCallback(() => { + setActiveStep((prevState) => prevState + 1); + }, []); + + const endTour = useCallback(() => setIsTourActive(false), []); + + /** + * The tour should only be visible if the following conditions are met: + * - Only pages with the side nav should show the tour (showTour === true) + * - Tour is set to active per localStorage setting (isTourActive === true) + * - Any page data must be loaded in order for the tour to render correctly + * - The tour should only render on medium-large screens + */ + const isTourVisible = showTour && isTourActive && isPageDataLoaded && isSmallBreakpoint === false; + + useEffect(() => { + localStorage.setItem(observabilityTourStorageKey, JSON.stringify({ isTourActive, activeStep })); + }, [isTourActive, activeStep]); + + useEffect(() => { + // The user must be on the overview page to view the guided setup step in the tour + if (isTourActive && isOverviewPage === false && activeStep === guidedSetupStep) { + navigateToApp(observabilityAppId, { + path: overviewPath, + }); + } + }, [activeStep, isOverviewPage, isTourActive, navigateToApp]); + + return ( + <> + {children({ isTourVisible })} + {isTourVisible && ( + <> + {getSteps({ activeStep, incrementStep, endTour })} + {showOverlay && ( + + )} + + )} + + ); +} diff --git a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx index a39e805941fe3..0ead6468ad0b0 100644 --- a/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/containers/alerts_page/alerts_page.tsx @@ -234,6 +234,7 @@ function AlertsPage() { return ( { return userPermissions == null || userPermissions?.read ? ( diff --git a/x-pack/plugins/observability/public/pages/overview/index.tsx b/x-pack/plugins/observability/public/pages/overview/index.tsx index 42f586a13d1e1..19f855b760cd4 100644 --- a/x-pack/plugins/observability/public/pages/overview/index.tsx +++ b/x-pack/plugins/observability/public/pages/overview/index.tsx @@ -160,6 +160,7 @@ export function OverviewPage({ routeParams }: Props) { return ( (false); - const tagsClicked = () => - setIsTagsPopoverOpen( - (oldStateIsTagsPopoverOpen) => rule.tags.length > 0 && !oldStateIsTagsPopoverOpen - ); - const closeTagsPopover = () => setIsTagsPopoverOpen(false); + return ( <> @@ -37,7 +32,7 @@ export function PageTitle({ rule }: PageHeaderProps) { - + {LAST_UPDATED_MESSAGE} {BY_WORD} {rule.updatedBy} {ON_WORD}  @@ -46,15 +41,14 @@ export function PageTitle({ rule }: PageHeaderProps) { {moment(rule.createdAt).format('ll')} - - {rule.tags.length > 0 && - triggersActionsUi.getRuleTagBadge({ - isOpen: isTagsPopoverOpen, - tags: rule.tags, - onClick: () => tagsClicked(), - onClose: () => closeTagsPopover(), - })} + + {rule.tags.length > 0 && + triggersActionsUi.getRuleTagBadge<'tagsOutPopover'>({ + tagsOutPopover: true, + tags: rule.tags, + })} + ); } diff --git a/x-pack/plugins/observability/public/pages/rules/index.tsx b/x-pack/plugins/observability/public/pages/rules/index.tsx index f4d6a3c10eeb0..43d98bb1b91b8 100644 --- a/x-pack/plugins/observability/public/pages/rules/index.tsx +++ b/x-pack/plugins/observability/public/pages/rules/index.tsx @@ -199,7 +199,7 @@ function RulesPage() { 'data-test-subj': 'rulesTableCell-tagsPopover', render: (ruleTags: string[], item: RuleTableItem) => { return ruleTags.length > 0 - ? triggersActionsUi.getRuleTagBadge({ + ? triggersActionsUi.getRuleTagBadge<'default'>({ isOpen: tagPopoverOpenIndex === item.index, tags: ruleTags, onClick: () => setTagPopoverOpenIndex(item.index), diff --git a/x-pack/plugins/rule_registry/README.md b/x-pack/plugins/rule_registry/README.md index 6643da6e5a52d..6ca34fc9ece18 100644 --- a/x-pack/plugins/rule_registry/README.md +++ b/x-pack/plugins/rule_registry/README.md @@ -99,7 +99,8 @@ const ruleDataClient = new RuleDataClient({ // to start writing data, call `getWriter().bulk()`. It supports a `namespace` // property as well, that for instance can be used to write data to a space-specific // index. -await ruleDataClient.getWriter().bulk({ +const writer = await ruleDataClient.getWriter(); +await writer.bulk({ body: eventsToIndex.flatMap((event) => [{ index: {} }, event]), }); diff --git a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.mock.ts b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.mock.ts index 3daf5cd722ce9..81521f9f27135 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.mock.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.mock.ts @@ -15,7 +15,9 @@ type MockInstances> = { type RuleDataClientMock = jest.Mocked> & { getReader: (...args: Parameters) => MockInstances; - getWriter: (...args: Parameters) => MockInstances; + getWriter: ( + ...args: Parameters + ) => Promise>; }; export const createRuleDataClientMock = ( @@ -37,8 +39,10 @@ export const createRuleDataClientMock = ( getDynamicIndexPattern, })), - getWriter: jest.fn(() => ({ - bulk, - })), + getWriter: jest.fn(() => + Promise.resolve({ + bulk, + }) + ), }; }; diff --git a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.test.ts b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.test.ts index 2fa05e0cf27ca..6a2841d868fb9 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.test.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.test.ts @@ -13,13 +13,14 @@ import { resourceInstallerMock } from '../rule_data_plugin_service/resource_inst import { loggingSystemMock, elasticsearchServiceMock } from '@kbn/core/server/mocks'; import { IndexPatternsFetcher } from '@kbn/data-plugin/server'; import { createNoMatchingIndicesError } from '@kbn/data-views-plugin/server/fetcher/lib/errors'; +import { ElasticsearchClient } from '@kbn/core/server'; const mockLogger = loggingSystemMock.create().get(); const scopedClusterClient = elasticsearchServiceMock.createScopedClusterClient().asInternalUser; const mockResourceInstaller = resourceInstallerMock.create(); // Be careful setting this delay too high. Jest tests can time out -const delay = (ms: number = 3000) => new Promise((resolve) => setTimeout(resolve, ms)); +const delay = (ms: number = 1500) => new Promise((resolve) => setTimeout(resolve, ms)); interface GetRuleDataClientOptionsOpts { isWriteEnabled?: boolean; @@ -184,132 +185,176 @@ describe('RuleDataClient', () => { jest.clearAllMocks(); }); - describe('bulk()', () => { - test('logs debug and returns undefined if writing is disabled', async () => { - const ruleDataClient = new RuleDataClient( - getRuleDataClientOptions({ isWriteEnabled: false }) - ); - const writer = ruleDataClient.getWriter(); - - // Previously, a delay between calling getWriter() and using a writer function - // would cause an Unhandled promise rejection if there were any errors getting a writer - // Adding this delay in the tests to ensure this does not pop up again. - await delay(); - - expect(await writer.bulk({})).toEqual(undefined); - expect(mockLogger.debug).toHaveBeenCalledWith( - `Writing is disabled, bulk() will not write any data.` - ); - }); + test('throws error if writing is disabled', async () => { + const ruleDataClient = new RuleDataClient( + getRuleDataClientOptions({ isWriteEnabled: false }) + ); - test('logs error, returns undefined and turns off writing if initialization error', async () => { - const ruleDataClient = new RuleDataClient( - getRuleDataClientOptions({ - waitUntilReadyForWriting: Promise.resolve( - left(new Error('could not get cluster client')) - ), - }) - ); - expect(ruleDataClient.isWriteEnabled()).toBe(true); - const writer = ruleDataClient.getWriter(); - - // Previously, a delay between calling getWriter() and using a writer function - // would cause an Unhandled promise rejection if there were any errors getting a writer - // Adding this delay in the tests to ensure this does not pop up again. - await delay(); - - expect(await writer.bulk({})).toEqual(undefined); - expect(mockLogger.error).toHaveBeenNthCalledWith( - 1, - new RuleDataWriterInitializationError( - 'index', - 'observability.apm', - new Error('could not get cluster client') - ) - ); - expect(mockLogger.error).toHaveBeenNthCalledWith( - 2, - `The writer for the Rule Data Client for the observability.apm registration context was not initialized properly, bulk() cannot continue, and writing will be disabled.` - ); - expect(ruleDataClient.isWriteEnabled()).toBe(false); - }); + await expect(() => ruleDataClient.getWriter()).rejects.toThrowErrorMatchingInlineSnapshot( + `"Rule registry writing is disabled. Make sure that \\"xpack.ruleRegistry.write.enabled\\" configuration is not set to false and \\"observability.apm\\" is not disabled in \\"xpack.ruleRegistry.write.disabledRegistrationContexts\\" within \\"kibana.yml\\"."` + ); + expect(mockLogger.debug).toHaveBeenCalledWith( + `Writing is disabled, bulk() will not write any data.` + ); + }); - test('logs error, returns undefined and turns off writing if resource installation error', async () => { - const error = new Error('bad resource installation'); - mockResourceInstaller.installAndUpdateNamespaceLevelResources.mockRejectedValueOnce(error); - const ruleDataClient = new RuleDataClient(getRuleDataClientOptions({})); - expect(ruleDataClient.isWriteEnabled()).toBe(true); - const writer = ruleDataClient.getWriter(); - - // Previously, a delay between calling getWriter() and using a writer function - // would cause an Unhandled promise rejection if there were any errors getting a writer - // Adding this delay in the tests to ensure this does not pop up again. - await delay(); - - expect(await writer.bulk({})).toEqual(undefined); - expect(mockLogger.error).toHaveBeenNthCalledWith( - 1, - new RuleDataWriterInitializationError('namespace', 'observability.apm', error) - ); - expect(mockLogger.error).toHaveBeenNthCalledWith( - 2, - `The writer for the Rule Data Client for the observability.apm registration context was not initialized properly, bulk() cannot continue, and writing will be disabled.` - ); - expect(ruleDataClient.isWriteEnabled()).toBe(false); - }); + test('throws error if initialization of writer fails due to index error', async () => { + const ruleDataClient = new RuleDataClient( + getRuleDataClientOptions({ + waitUntilReadyForWriting: Promise.resolve( + left(new Error('could not get cluster client')) + ), + }) + ); + expect(ruleDataClient.isWriteEnabled()).toBe(true); + await expect(() => ruleDataClient.getWriter()).rejects.toThrowErrorMatchingInlineSnapshot( + `"There has been a catastrophic error trying to install index level resources for the following registration context: observability.apm. This may have been due to a non-additive change to the mappings, removal and type changes are not permitted. Full error: Error: could not get cluster client"` + ); + expect(mockLogger.error).toHaveBeenNthCalledWith( + 1, + new RuleDataWriterInitializationError( + 'index', + 'observability.apm', + new Error('could not get cluster client') + ) + ); + expect(mockLogger.error).toHaveBeenNthCalledWith( + 2, + `The writer for the Rule Data Client for the observability.apm registration context was not initialized properly, bulk() cannot continue, and writing will be disabled.` + ); + expect(ruleDataClient.isWriteEnabled()).toBe(false); - test('logs error and returns undefined if bulk function throws error', async () => { - const error = new Error('something went wrong!'); - scopedClusterClient.bulk.mockRejectedValueOnce(error); - const ruleDataClient = new RuleDataClient(getRuleDataClientOptions({})); - expect(ruleDataClient.isWriteEnabled()).toBe(true); - const writer = ruleDataClient.getWriter(); - - // Previously, a delay between calling getWriter() and using a writer function - // would cause an Unhandled promise rejection if there were any errors getting a writer - // Adding this delay in the tests to ensure this does not pop up again. - await delay(); - - expect(await writer.bulk({})).toEqual(undefined); - expect(mockLogger.error).toHaveBeenNthCalledWith(1, error); - expect(ruleDataClient.isWriteEnabled()).toBe(true); - }); + // getting the writer again at this point should throw another error + await expect(() => ruleDataClient.getWriter()).rejects.toThrowErrorMatchingInlineSnapshot( + `"Rule registry writing is disabled due to an error during Rule Data Client initialization."` + ); + expect(mockLogger.debug).toHaveBeenCalledWith( + `Writing is disabled, bulk() will not write any data.` + ); + }); + + test('throws error if initialization of writer fails due to namespace error', async () => { + mockResourceInstaller.installAndUpdateNamespaceLevelResources.mockRejectedValueOnce( + new Error('bad resource installation') + ); + const ruleDataClient = new RuleDataClient(getRuleDataClientOptions({})); + expect(ruleDataClient.isWriteEnabled()).toBe(true); + await expect(() => ruleDataClient.getWriter()).rejects.toThrowErrorMatchingInlineSnapshot( + `"There has been a catastrophic error trying to install namespace level resources for the following registration context: observability.apm. This may have been due to a non-additive change to the mappings, removal and type changes are not permitted. Full error: Error: bad resource installation"` + ); + expect(mockLogger.error).toHaveBeenNthCalledWith( + 1, + new RuleDataWriterInitializationError( + 'namespace', + 'observability.apm', + new Error('bad resource installation') + ) + ); + expect(mockLogger.error).toHaveBeenNthCalledWith( + 2, + `The writer for the Rule Data Client for the observability.apm registration context was not initialized properly, bulk() cannot continue, and writing will be disabled.` + ); + expect(ruleDataClient.isWriteEnabled()).toBe(false); + + // getting the writer again at this point should throw another error + await expect(() => ruleDataClient.getWriter()).rejects.toThrowErrorMatchingInlineSnapshot( + `"Rule registry writing is disabled due to an error during Rule Data Client initialization."` + ); + expect(mockLogger.debug).toHaveBeenCalledWith( + `Writing is disabled, bulk() will not write any data.` + ); + }); + + test('uses cached cluster client when repeatedly initializing writer', async () => { + const ruleDataClient = new RuleDataClient(getRuleDataClientOptions({})); + + await ruleDataClient.getWriter(); + await ruleDataClient.getWriter(); + await ruleDataClient.getWriter(); + await ruleDataClient.getWriter(); + await ruleDataClient.getWriter(); + + expect(mockResourceInstaller.installAndUpdateNamespaceLevelResources).toHaveBeenCalledTimes( + 1 + ); + }); + }); + + describe('bulk()', () => { + test('logs debug and returns undefined if clusterClient is not defined', async () => { + const ruleDataClient = new RuleDataClient( + getRuleDataClientOptions({ + waitUntilReadyForWriting: new Promise((resolve) => + resolve(right(undefined as unknown as ElasticsearchClient)) + ), + }) + ); + const writer = await ruleDataClient.getWriter(); + + // Previously, a delay between calling getWriter() and using a writer function + // would cause an Unhandled promise rejection if there were any errors getting a writer + // Adding this delay in the tests to ensure this does not pop up again. + await delay(); + + expect(await writer.bulk({})).toEqual(undefined); + expect(mockLogger.debug).toHaveBeenCalledWith( + `Writing is disabled, bulk() will not write any data.` + ); + }); - test('waits until cluster client is ready before calling bulk', async () => { - const ruleDataClient = new RuleDataClient( - getRuleDataClientOptions({ - waitUntilReadyForWriting: new Promise((resolve) => - setTimeout(resolve, 3000, right(scopedClusterClient)) - ), - }) - ); - - const writer = ruleDataClient.getWriter(); - // Previously, a delay between calling getWriter() and using a writer function - // would cause an Unhandled promise rejection if there were any errors getting a writer - // Adding this delay in the tests to ensure this does not pop up again. - await delay(); - - const response = await writer.bulk({}); - - expect(response).toEqual({ - body: {}, - headers: { - 'x-elastic-product': 'Elasticsearch', - }, - meta: {}, - statusCode: 200, - warnings: [], - }); - - expect(scopedClusterClient.bulk).toHaveBeenCalledWith( - { - index: `.alerts-observability.apm.alerts-default`, - require_alias: true, - }, - { meta: true } - ); + test('throws and logs error if bulk function throws error', async () => { + const error = new Error('something went wrong!'); + scopedClusterClient.bulk.mockRejectedValueOnce(error); + const ruleDataClient = new RuleDataClient(getRuleDataClientOptions({})); + expect(ruleDataClient.isWriteEnabled()).toBe(true); + const writer = await ruleDataClient.getWriter(); + + // Previously, a delay between calling getWriter() and using a writer function + // would cause an Unhandled promise rejection if there were any errors getting a writer + // Adding this delay in the tests to ensure this does not pop up again. + await delay(); + + await expect(() => writer.bulk({})).rejects.toThrowErrorMatchingInlineSnapshot( + `"something went wrong!"` + ); + expect(mockLogger.error).toHaveBeenNthCalledWith(1, error); + expect(ruleDataClient.isWriteEnabled()).toBe(true); + }); + + test('waits until cluster client is ready before calling bulk', async () => { + const ruleDataClient = new RuleDataClient( + getRuleDataClientOptions({ + waitUntilReadyForWriting: new Promise((resolve) => + setTimeout(resolve, 3000, right(scopedClusterClient)) + ), + }) + ); + + const writer = await ruleDataClient.getWriter(); + // Previously, a delay between calling getWriter() and using a writer function + // would cause an Unhandled promise rejection if there were any errors getting a writer + // Adding this delay in the tests to ensure this does not pop up again. + await delay(); + + const response = await writer.bulk({}); + + expect(response).toEqual({ + body: {}, + headers: { + 'x-elastic-product': 'Elasticsearch', + }, + meta: {}, + statusCode: 200, + warnings: [], }); + + expect(scopedClusterClient.bulk).toHaveBeenCalledWith( + { + index: `.alerts-observability.apm.alerts-default`, + require_alias: true, + }, + { meta: true } + ); }); }); }); diff --git a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts index e8c57c7c4ee4a..cb78e6fb8ac23 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_client/rule_data_client.ts @@ -35,11 +35,14 @@ export type WaitResult = Either; export class RuleDataClient implements IRuleDataClient { private _isWriteEnabled: boolean = false; + private _isWriteInitializationFailed: boolean = false; private _isWriterCacheEnabled: boolean = true; // Writers cached by namespace private writerCache: Map; + private clusterClient: ElasticsearchClient | null = null; + constructor(private readonly options: RuleDataClientConstructorOptions) { this.writeEnabled = this.options.isWriteEnabled; this.writerCacheEnabled = this.options.isWriterCacheEnabled; @@ -66,6 +69,14 @@ export class RuleDataClient implements IRuleDataClient { this._isWriteEnabled = isEnabled; } + private get writeInitializationFailed(): boolean { + return this._isWriteInitializationFailed; + } + + private set writeInitializationFailed(isFailed: boolean) { + this._isWriteInitializationFailed = isFailed; + } + public isWriteEnabled(): boolean { return this.writeEnabled; } @@ -131,14 +142,14 @@ export class RuleDataClient implements IRuleDataClient { }; } - public getWriter(options: { namespace?: string } = {}): IRuleDataWriter { + public async getWriter(options: { namespace?: string } = {}): Promise { const namespace = options.namespace || 'default'; const cachedWriter = this.writerCache.get(namespace); const isWriterCacheEnabled = () => this.writerCacheEnabled; // There is no cached writer, so we'll install / update the namespace specific resources now. if (!isWriterCacheEnabled() || !cachedWriter) { - const writerForNamespace = this.initializeWriter(namespace); + const writerForNamespace = await this.initializeWriter(namespace); this.writerCache.set(namespace, writerForNamespace); return writerForNamespace; } else { @@ -146,19 +157,27 @@ export class RuleDataClient implements IRuleDataClient { } } - private initializeWriter(namespace: string): IRuleDataWriter { + private async initializeWriter(namespace: string): Promise { const isWriteEnabled = () => this.writeEnabled; - const turnOffWrite = () => (this.writeEnabled = false); + const isWriteInitializationError = () => this.writeInitializationFailed; + const turnOffWriteDueToInitializationError = () => { + this.writeEnabled = false; + this.writeInitializationFailed = true; + }; const { indexInfo, resourceInstaller } = this.options; const alias = indexInfo.getPrimaryAlias(namespace); // Wait until both index and namespace level resources have been installed / updated. - const prepareForWriting = async () => { - if (!isWriteEnabled()) { - throw new RuleDataWriteDisabledError(); - } + if (!isWriteEnabled()) { + this.options.logger.debug(`Writing is disabled, bulk() will not write any data.`); + throw new RuleDataWriteDisabledError({ + reason: isWriteInitializationError() ? 'error' : 'config', + registrationContext: indexInfo.indexOptions.registrationContext, + }); + } + try { const indexLevelResourcesResult = await this.options.waitUntilReadyForWriting; if (isLeft(indexLevelResourcesResult)) { @@ -170,7 +189,7 @@ export class RuleDataClient implements IRuleDataClient { } else { try { await resourceInstaller.installAndUpdateNamespaceLevelResources(indexInfo, namespace); - return indexLevelResourcesResult.right; + this.clusterClient = indexLevelResourcesResult.right; } catch (e) { throw new RuleDataWriterInitializationError( 'namespace', @@ -179,33 +198,31 @@ export class RuleDataClient implements IRuleDataClient { ); } } - }; - - const prepareForWritingResult = prepareForWriting().catch((error) => { + } catch (error) { if (error instanceof RuleDataWriterInitializationError) { this.options.logger.error(error); this.options.logger.error( `The writer for the Rule Data Client for the ${indexInfo.indexOptions.registrationContext} registration context was not initialized properly, bulk() cannot continue, and writing will be disabled.` ); - turnOffWrite(); - } else if (error instanceof RuleDataWriteDisabledError) { - this.options.logger.debug(`Writing is disabled, bulk() will not write any data.`); + turnOffWriteDueToInitializationError(); } - return undefined; - }); + + throw error; + } return { bulk: async (request: estypes.BulkRequest) => { try { - const clusterClient = await prepareForWritingResult; - if (clusterClient) { + if (this.clusterClient) { const requestWithDefaultParameters = { ...request, require_alias: true, index: alias, }; - const response = await clusterClient.bulk(requestWithDefaultParameters, { meta: true }); + const response = await this.clusterClient.bulk(requestWithDefaultParameters, { + meta: true, + }); if (response.body.errors) { const error = new errors.ResponseError(response); @@ -215,11 +232,9 @@ export class RuleDataClient implements IRuleDataClient { } else { this.options.logger.debug(`Writing is disabled, bulk() will not write any data.`); } - return undefined; } catch (error) { this.options.logger.error(error); - - return undefined; + throw error; } }, }; diff --git a/x-pack/plugins/rule_registry/server/rule_data_client/types.ts b/x-pack/plugins/rule_registry/server/rule_data_client/types.ts index 7b59a64047d04..24f435a94f902 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_client/types.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_client/types.ts @@ -19,7 +19,7 @@ export interface IRuleDataClient { kibanaVersion: string; isWriteEnabled(): boolean; getReader(options?: { namespace?: string }): IRuleDataReader; - getWriter(options?: { namespace?: string }): IRuleDataWriter; + getWriter(options?: { namespace?: string }): Promise; } export interface IRuleDataReader { diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts index fe8d3b3b18d9d..78a41c7ae4c99 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/errors.ts @@ -7,8 +7,28 @@ /* eslint-disable max-classes-per-file */ export class RuleDataWriteDisabledError extends Error { - constructor(message?: string) { - super(message); + constructor({ + reason, + registrationContext, + message, + }: { + reason: 'config' | 'error'; + registrationContext?: string; + message?: string; + }) { + let errMessage = message; + if (!errMessage) { + if (reason === 'config') { + if (registrationContext) { + errMessage = `Rule registry writing is disabled. Make sure that "xpack.ruleRegistry.write.enabled" configuration is not set to false and "${registrationContext}" is not disabled in "xpack.ruleRegistry.write.disabledRegistrationContexts" within "kibana.yml".`; + } else { + errMessage = `Rule registry writing is disabled. Make sure that "xpack.ruleRegistry.write.enabled" configuration is not set to false within "kibana.yml".`; + } + } else if (reason === 'error') { + errMessage = `Rule registry writing is disabled due to an error during Rule Data Client initialization.`; + } + } + super(errMessage); Object.setPrototypeOf(this, new.target.prototype); this.name = 'RuleDataWriteDisabledError'; } @@ -20,8 +40,9 @@ export class RuleDataWriterInitializationError extends Error { registrationContext: string, error: string | Error ) { - super(`There has been a catastrophic error trying to install ${resourceType} level resources for the following registration context: ${registrationContext}. - This may have been due to a non-additive change to the mappings, removal and type changes are not permitted. Full error: ${error.toString()}`); + super( + `There has been a catastrophic error trying to install ${resourceType} level resources for the following registration context: ${registrationContext}. This may have been due to a non-additive change to the mappings, removal and type changes are not permitted. Full error: ${error.toString()}` + ); Object.setPrototypeOf(this, new.target.prototype); this.name = 'RuleDataWriterInitializationError'; } diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.test.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.test.ts index 1768f0666fd51..2d49c09f007f7 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.test.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.test.ts @@ -86,7 +86,7 @@ describe('createLifecycleExecutor', () => { }) ); - expect(ruleDataClientMock.getWriter().bulk).toHaveBeenCalledWith( + expect((await ruleDataClientMock.getWriter()).bulk).toHaveBeenCalledWith( expect.objectContaining({ body: [ // alert documents @@ -107,7 +107,7 @@ describe('createLifecycleExecutor', () => { ], }) ); - expect(ruleDataClientMock.getWriter().bulk).not.toHaveBeenCalledWith( + expect((await ruleDataClientMock.getWriter()).bulk).not.toHaveBeenCalledWith( expect.objectContaining({ body: expect.arrayContaining([ // evaluation documents @@ -201,7 +201,7 @@ describe('createLifecycleExecutor', () => { }) ); - expect(ruleDataClientMock.getWriter().bulk).toHaveBeenCalledWith( + expect((await ruleDataClientMock.getWriter()).bulk).toHaveBeenCalledWith( expect.objectContaining({ body: [ // alert document @@ -227,7 +227,7 @@ describe('createLifecycleExecutor', () => { ], }) ); - expect(ruleDataClientMock.getWriter().bulk).not.toHaveBeenCalledWith( + expect((await ruleDataClientMock.getWriter()).bulk).not.toHaveBeenCalledWith( expect.objectContaining({ body: expect.arrayContaining([ // evaluation documents @@ -316,7 +316,7 @@ describe('createLifecycleExecutor', () => { }) ); - expect(ruleDataClientMock.getWriter().bulk).toHaveBeenCalledWith( + expect((await ruleDataClientMock.getWriter()).bulk).toHaveBeenCalledWith( expect.objectContaining({ body: expect.arrayContaining([ // alert document @@ -338,7 +338,7 @@ describe('createLifecycleExecutor', () => { ]), }) ); - expect(ruleDataClientMock.getWriter().bulk).not.toHaveBeenCalledWith( + expect((await ruleDataClientMock.getWriter()).bulk).not.toHaveBeenCalledWith( expect.objectContaining({ body: expect.arrayContaining([ // evaluation documents @@ -375,7 +375,35 @@ describe('createLifecycleExecutor', () => { }) ); - expect(ruleDataClientMock.getWriter).not.toHaveBeenCalled(); + expect((await ruleDataClientMock.getWriter()).bulk).not.toHaveBeenCalled(); + }); + + it('throws error when writer initialization fails', async () => { + const logger = loggerMock.create(); + const ruleDataClientMock = createRuleDataClientMock(); + ruleDataClientMock.getWriter = jest + .fn() + .mockRejectedValueOnce(new Error('error initializing!')); + const executor = createLifecycleExecutor( + logger, + ruleDataClientMock + )<{}, TestRuleState, never, never, never>(async (options) => { + const nextRuleState: TestRuleState = { + aRuleStateKey: 'NEXT_RULE_STATE_VALUE', + }; + + return nextRuleState; + }); + + await expect(() => + executor( + createDefaultAlertExecutorOptions({ + params: {}, + state: { wrapped: initialRuleState, trackedAlerts: {} }, + shouldWriteAlerts: false, + }) + ) + ).rejects.toThrowErrorMatchingInlineSnapshot(`"error initializing!"`); }); }); diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts index f38e73ca3a9a2..da68ef3c4c7b6 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_executor.ts @@ -145,6 +145,8 @@ export const createLifecycleExecutor = state: previousState, } = options; + const ruleDataClientWriter = await ruleDataClient.getWriter(); + const state = getOrElse( (): WrappedLifecycleRuleState => ({ wrapped: previousState as State, @@ -267,7 +269,7 @@ export const createLifecycleExecutor = if (allEventsToIndex.length > 0 && writeAlerts) { logger.debug(`[Rule Registry] Preparing to index ${allEventsToIndex.length} alerts.`); - await ruleDataClient.getWriter().bulk({ + await ruleDataClientWriter.bulk({ body: allEventsToIndex.flatMap(({ event, indexName }) => [ indexName ? { index: { _id: event[ALERT_UUID]!, _index: indexName, require_alias: false } } @@ -275,6 +277,10 @@ export const createLifecycleExecutor = event, ]), }); + } else { + logger.debug( + `[Rule Registry] Not indexing ${allEventsToIndex.length} alerts because writing has been disabled.` + ); } const nextTrackedAlerts = Object.fromEntries( diff --git a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts index 9387a9ce8c0ed..fefffd204c4a3 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_lifecycle_rule_type.test.ts @@ -158,7 +158,7 @@ describe('createLifecycleRuleTypeFactory', () => { }, ]); - expect(helpers.ruleDataClientMock.getWriter().bulk).toHaveBeenCalledTimes(0); + expect((await helpers.ruleDataClientMock.getWriter()).bulk).toHaveBeenCalledTimes(0); }); }); @@ -178,7 +178,7 @@ describe('createLifecycleRuleTypeFactory', () => { }, ]); - expect(helpers.ruleDataClientMock.getWriter().bulk).toHaveBeenCalledTimes(0); + expect((await helpers.ruleDataClientMock.getWriter()).bulk).toHaveBeenCalledTimes(0); }); }); @@ -200,10 +200,10 @@ describe('createLifecycleRuleTypeFactory', () => { ]); }); - it('writes the correct alerts', () => { - expect(helpers.ruleDataClientMock.getWriter().bulk).toHaveBeenCalledTimes(1); + it('writes the correct alerts', async () => { + expect((await helpers.ruleDataClientMock.getWriter()).bulk).toHaveBeenCalledTimes(1); - const body = helpers.ruleDataClientMock.getWriter().bulk.mock.calls[0][0].body!; + const body = (await helpers.ruleDataClientMock.getWriter()).bulk.mock.calls[0][0].body!; const documents = body.filter((op: any) => !('index' in op)) as any[]; @@ -302,9 +302,10 @@ describe('createLifecycleRuleTypeFactory', () => { ]); // TODO mock the resolved value before calling alertWithLifecycle again - const lastOpbeansNodeDoc = helpers.ruleDataClientMock - .getWriter() - .bulk.mock.calls[0][0].body?.concat() + const lastOpbeansNodeDoc = ( + await helpers.ruleDataClientMock.getWriter() + ).bulk.mock.calls[0][0].body + ?.concat() .reverse() .find( (doc: any) => !('index' in doc) && doc['service.name'] === 'opbeans-node' @@ -345,9 +346,9 @@ describe('createLifecycleRuleTypeFactory', () => { ]); }); - it('writes the correct alerts', () => { - expect(helpers.ruleDataClientMock.getWriter().bulk).toHaveBeenCalledTimes(2); - const body = helpers.ruleDataClientMock.getWriter().bulk.mock.calls[1][0].body!; + it('writes the correct alerts', async () => { + expect((await helpers.ruleDataClientMock.getWriter()).bulk).toHaveBeenCalledTimes(2); + const body = (await helpers.ruleDataClientMock.getWriter()).bulk.mock.calls[1][0].body!; const documents = body.filter((op: any) => !('index' in op)) as any[]; @@ -383,9 +384,10 @@ describe('createLifecycleRuleTypeFactory', () => { }, ]); - const lastOpbeansNodeDoc = helpers.ruleDataClientMock - .getWriter() - .bulk.mock.calls[0][0].body?.concat() + const lastOpbeansNodeDoc = ( + await helpers.ruleDataClientMock.getWriter() + ).bulk.mock.calls[0][0].body + ?.concat() .reverse() .find( (doc: any) => !('index' in doc) && doc['service.name'] === 'opbeans-node' @@ -418,10 +420,10 @@ describe('createLifecycleRuleTypeFactory', () => { ]); }); - it('writes the correct alerts', () => { - expect(helpers.ruleDataClientMock.getWriter().bulk).toHaveBeenCalledTimes(2); + it('writes the correct alerts', async () => { + expect((await helpers.ruleDataClientMock.getWriter()).bulk).toHaveBeenCalledTimes(2); - const body = helpers.ruleDataClientMock.getWriter().bulk.mock.calls[1][0].body!; + const body = (await helpers.ruleDataClientMock.getWriter()).bulk.mock.calls[1][0].body!; const documents = body.filter((op: any) => !('index' in op)) as any[]; diff --git a/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts b/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts index a23ae0d1b99c9..7d8c6921d9f1f 100644 --- a/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts +++ b/x-pack/plugins/rule_registry/server/utils/create_persistence_rule_type_wrapper.ts @@ -26,6 +26,10 @@ export const createPersistenceRuleTypeWrapper: CreatePersistenceRuleTypeWrapper const numAlerts = alerts.length; logger.debug(`Found ${numAlerts} alerts.`); + const ruleDataClientWriter = await ruleDataClient.getWriter({ + namespace: options.spaceId, + }); + // Only write alerts if: // - writing is enabled // AND @@ -92,15 +96,13 @@ export const createPersistenceRuleTypeWrapper: CreatePersistenceRuleTypeWrapper }; }); - const response = await ruleDataClient - .getWriter({ namespace: options.spaceId }) - .bulk({ - body: augmentedAlerts.flatMap((alert) => [ - { create: { _id: alert._id } }, - alert._source, - ]), - refresh, - }); + const response = await ruleDataClientWriter.bulk({ + body: augmentedAlerts.flatMap((alert) => [ + { create: { _id: alert._id } }, + alert._source, + ]), + refresh, + }); if (response == null) { return { createdAlerts: [], errors: {} }; diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 8b0d8a85c21df..cf73b5a3f4eee 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -121,6 +121,7 @@ export enum SecurityPageName { kubernetes = 'kubernetes', exploreLanding = 'explore', dashboardsLanding = 'dashboards', + noPage = '', } export const EXPLORE_PATH = '/explore' as const; diff --git a/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_action_generator.ts b/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_action_generator.ts index 745b2277b04c2..838f24548e8aa 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_action_generator.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_generators/endpoint_action_generator.ts @@ -16,13 +16,11 @@ import { EndpointActivityLogAction, EndpointActivityLogActionResponse, EndpointPendingActions, - ISOLATION_ACTIONS, LogsEndpointAction, LogsEndpointActionResponse, + RESPONSE_ACTION_COMMANDS, } from '../types'; -const ISOLATION_COMMANDS: ISOLATION_ACTIONS[] = ['isolate', 'unisolate']; - export class EndpointActionGenerator extends BaseDataGenerator { /** Generate a random endpoint Action request (isolate or unisolate) */ generate(overrides: DeepPartial = {}): LogsEndpointAction { @@ -42,8 +40,9 @@ export class EndpointActionGenerator extends BaseDataGenerator { type: 'INPUT_ACTION', input_type: 'endpoint', data: { - command: this.randomIsolateCommand(), + command: this.randomResponseActionCommand(), comment: this.randomString(15), + parameters: undefined, }, }, error: undefined, @@ -87,8 +86,9 @@ export class EndpointActionGenerator extends BaseDataGenerator { action_id: this.seededUUIDv4(), completed_at: timeStamp.toISOString(), data: { - command: this.randomIsolateCommand(), + command: this.randomResponseActionCommand(), comment: '', + parameters: undefined, }, started_at: this.randomPastDate(), }, @@ -116,67 +116,10 @@ export class EndpointActionGenerator extends BaseDataGenerator { isExpired: false, wasSuccessful: true, errors: undefined, - logEntries: [ - { - item: { - data: { - '@timestamp': '2022-04-27T16:08:47.449Z', - action_id: '123', - agents: ['agent-a'], - data: { - command: 'isolate', - comment: '5wb6pu6kh2xix5i', - }, - expiration: '2022-04-29T16:08:47.449Z', - input_type: 'endpoint', - type: 'INPUT_ACTION', - user_id: 'elastic', - }, - id: '44d8b915-c69c-4c48-8c86-b57d0bd631d0', - }, - type: 'fleetAction', - }, - { - item: { - data: { - '@timestamp': '2022-04-30T16:08:47.449Z', - action_data: { - command: 'unisolate', - comment: '', - }, - action_id: '123', - agent_id: 'agent-a', - completed_at: '2022-04-30T16:08:47.449Z', - error: '', - started_at: '2022-04-30T16:08:47.449Z', - }, - id: '54-65-65-98', - }, - type: 'fleetResponse', - }, - { - item: { - data: { - '@timestamp': '2022-04-30T16:08:47.449Z', - EndpointActions: { - action_id: '123', - completed_at: '2022-04-30T16:08:47.449Z', - data: { - command: 'unisolate', - comment: '', - }, - started_at: '2022-04-30T16:08:47.449Z', - }, - agent: { - id: 'agent-a', - }, - }, - id: '32-65-98', - }, - type: 'response', - }, - ], startedAt: '2022-04-27T16:08:47.449Z', + comment: 'thisisacomment', + createdBy: 'auserid', + parameters: undefined, }; return merge(details, overrides); @@ -235,7 +178,7 @@ export class EndpointActionGenerator extends BaseDataGenerator { return super.randomN(max); } - protected randomIsolateCommand() { - return this.randomChoice(ISOLATION_COMMANDS); + protected randomResponseActionCommand() { + return this.randomChoice(RESPONSE_ACTION_COMMANDS); } } diff --git a/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_action_generator.ts b/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_action_generator.ts index 1ca380989e09e..f6558453648d2 100644 --- a/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_action_generator.ts +++ b/x-pack/plugins/security_solution/common/endpoint/data_generators/fleet_action_generator.ts @@ -16,11 +16,9 @@ import { ActivityLogItemTypes, EndpointAction, EndpointActionResponse, - ISOLATION_ACTIONS, + RESPONSE_ACTION_COMMANDS, } from '../types'; -const ISOLATION_COMMANDS: ISOLATION_ACTIONS[] = ['isolate', 'unisolate']; - export class FleetActionGenerator extends BaseDataGenerator { /** Generate a random endpoint Action (isolate or unisolate) */ generate(overrides: DeepPartial = {}): EndpointAction { @@ -38,8 +36,9 @@ export class FleetActionGenerator extends BaseDataGenerator { agents: [this.seededUUIDv4()], user_id: 'elastic', data: { - command: this.randomIsolateCommand(), + command: this.randomResponseActionCommand(), comment: this.randomString(15), + parameter: undefined, }, }, overrides @@ -69,8 +68,9 @@ export class FleetActionGenerator extends BaseDataGenerator { return merge( { action_data: { - command: this.randomIsolateCommand(), + command: this.randomResponseActionCommand(), comment: '', + parameter: undefined, }, action_id: this.seededUUIDv4(), agent_id: this.seededUUIDv4(), @@ -135,7 +135,7 @@ export class FleetActionGenerator extends BaseDataGenerator { return super.randomN(max); } - protected randomIsolateCommand() { - return this.randomChoice(ISOLATION_COMMANDS); + protected randomResponseActionCommand() { + return this.randomChoice(RESPONSE_ACTION_COMMANDS); } } diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/actions.test.ts b/x-pack/plugins/security_solution/common/endpoint/schema/actions.test.ts index d3f47421d7d7c..a9ae8a91fe65b 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/actions.test.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/actions.test.ts @@ -213,7 +213,7 @@ describe('actions schemas', () => { KillOrSuspendProcessRequestSchema.body.validate({ endpoint_ids: ['ABC-XYZ-000'], parameters: { - entity_id: 5678, + entity_id: 'abc123', }, }); }).not.toThrow(); @@ -225,7 +225,7 @@ describe('actions schemas', () => { endpoint_ids: ['ABC-XYZ-000'], parameters: { pid: 1234, - entity_id: 5678, + entity_id: 'abc123', }, }); }).toThrow(); diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts b/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts index cf190e5c62ca2..600e69b83f6ef 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts @@ -27,7 +27,7 @@ export const KillOrSuspendProcessRequestSchema = { ...BaseActionRequestSchema, parameters: schema.oneOf([ schema.object({ pid: schema.number({ min: 1 }) }), - schema.object({ entity_id: schema.number({ min: 1 }) }), + schema.object({ entity_id: schema.string({ minLength: 1 }) }), ]), }), }; diff --git a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts index ee07e05bac2d3..e5386013cd458 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts @@ -14,11 +14,15 @@ import { export type ISOLATION_ACTIONS = 'isolate' | 'unisolate'; -export type ResponseActions = - | ISOLATION_ACTIONS - | 'kill-process' - | 'suspend-process' - | 'running-processes'; +export const RESPONSE_ACTION_COMMANDS = [ + 'isolate', + 'unisolate', + 'kill-process', + 'suspend-process', + 'running-processes', +] as const; + +export type ResponseActions = typeof RESPONSE_ACTION_COMMANDS[number]; export const ActivityLogItemTypes = { ACTION: 'action' as const, @@ -87,7 +91,7 @@ interface ResponseActionParametersWithPid { interface ResponseActionParametersWithEntityId { pid?: never; - entity_id: number; + entity_id: string; } export type ResponseActionParametersWithPidOrEntityId = @@ -232,7 +236,7 @@ export interface ActionDetails { * The Endpoint type of action (ex. `isolate`, `release`) that is being requested to be * performed on the endpoint */ - command: string; + command: ResponseActions; /** * Will be set to true only if action is not yet completed and elapsed time has exceeded * the request's expiration date @@ -248,10 +252,12 @@ export interface ActionDetails { startedAt: string; /** The date when the action was completed (a response by the endpoint (not fleet) was received) */ completedAt: string | undefined; - /** - * The list of action log items (actions and responses) received thus far for the action. - */ - logEntries: ActivityLogEntry[]; + /** user that created the action */ + createdBy: string; + /** comment submitted with action */ + comment?: string; + /** parameters submitted with action */ + parameters?: EndpointActionDataParameterTypes; } export interface ActionDetailsApiResponse { diff --git a/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts b/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts index 63dcbf872d626..c91af7e44cccb 100644 --- a/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/detection_rules/sorting.spec.ts @@ -110,7 +110,7 @@ describe('Alerts detection rules', () => { visit(DETECTIONS_RULE_MANAGEMENT_URL); - cy.clock(Date.now(), ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval', 'Date']); + cy.clock(Date.now(), ['setInterval', 'clearInterval', 'Date']); waitForRulesTableToBeLoaded(); diff --git a/x-pack/plugins/security_solution/cypress/integration/urls/state.spec.ts b/x-pack/plugins/security_solution/cypress/integration/urls/state.spec.ts index a5f814447ab59..230087c2310e7 100644 --- a/x-pack/plugins/security_solution/cypress/integration/urls/state.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/urls/state.spec.ts @@ -184,7 +184,7 @@ describe('url state', () => { cy.get(NETWORK).should( 'have.attr', 'href', - `/app/security/network?query=(language:kuery,query:'source.ip:%20%2210.142.0.9%22%20')&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2019-08-01T20:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2019-08-01T20:33:29.186Z')))` + `/app/security/network?query=(language:kuery,query:'source.ip:%20%2210.142.0.9%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2019-08-01T20:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2019-08-01T20:33:29.186Z')))&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))` ); }); @@ -197,12 +197,12 @@ describe('url state', () => { cy.get(HOSTS).should( 'have.attr', 'href', - `/app/security/hosts?query=(language:kuery,query:'host.name:%20%22siem-kibana%22%20')&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))` + `/app/security/hosts?query=(language:kuery,query:'host.name:%20%22siem-kibana%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))` ); cy.get(NETWORK).should( 'have.attr', 'href', - `/app/security/network?query=(language:kuery,query:'host.name:%20%22siem-kibana%22%20')&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))` + `/app/security/network?query=(language:kuery,query:'host.name:%20%22siem-kibana%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))` ); cy.get(HOSTS_NAMES).first().should('have.text', 'siem-kibana'); @@ -213,21 +213,22 @@ describe('url state', () => { cy.get(ANOMALIES_TAB).should( 'have.attr', 'href', - "/app/security/hosts/siem-kibana/anomalies?sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))&query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')" + "/app/security/hosts/siem-kibana/anomalies?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))&query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')" ); + cy.get(BREADCRUMBS) .eq(1) .should( 'have.attr', 'href', - `/app/security/hosts?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))` + `/app/security/hosts?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))` ); cy.get(BREADCRUMBS) .eq(2) .should( 'have.attr', 'href', - `/app/security/hosts/siem-kibana?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))` + `/app/security/hosts/siem-kibana?query=(language:kuery,query:'agent.type:%20%22auditbeat%22%20')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')),timeline:(linkTo:!(global),timerange:(from:'2019-08-01T20:03:29.186Z',kind:absolute,to:'2023-01-01T21:33:29.186Z')))&sourcerer=(default:(id:security-solution-default,selectedPatterns:!('auditbeat-*')))` ); }); diff --git a/x-pack/plugins/security_solution/public/app/home/index.tsx b/x-pack/plugins/security_solution/public/app/home/index.tsx index 602e2709f2a2a..2597f1ab41ff2 100644 --- a/x-pack/plugins/security_solution/public/app/home/index.tsx +++ b/x-pack/plugins/security_solution/public/app/home/index.tsx @@ -23,7 +23,7 @@ import { useUpgradeSecurityPackages } from '../../common/hooks/use_upgrade_secur import { GlobalHeader } from './global_header'; import { SecuritySolutionTemplateWrapper } from './template_wrapper'; import { ConsoleManager } from '../../management/components/console/components/console_manager'; - +import { useSyncGlobalQueryString } from '../../common/utils/global_query_string'; interface HomePageProps { children: React.ReactNode; onAppLeave: (handler: AppLeaveHandler) => void; @@ -36,7 +36,7 @@ const HomePageComponent: React.FC = ({ setHeaderActionMenu, }) => { const { pathname } = useLocation(); - + useSyncGlobalQueryString(); useInitSourcerer(getScopeFromPath(pathname)); const { browserFields, indexPattern } = useSourcererDataView(getScopeFromPath(pathname)); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts index e0c4467bf5ae0..f35f8be0006c9 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts @@ -16,7 +16,7 @@ import { AdministrationSubTab } from '../../../../management/types'; import { renderHook } from '@testing-library/react-hooks'; import { TestProviders } from '../../../mock'; import { GetSecuritySolutionUrl } from '../../link_to'; -import { APP_UI_ID } from '../../../../../common/constants'; +import { APP_UI_ID, SecurityPageName } from '../../../../../common/constants'; import { useDeepEqualSelector } from '../../../hooks/use_selector'; import { useIsGroupedNavigationEnabled } from '../helpers'; import { navTabs } from '../../../../app/home/home_navigations'; @@ -55,7 +55,7 @@ const mockDefaultTab = (pageName: string): SiemRouteType | undefined => { }; const getMockObject = ( - pageName: string, + pageName: SecurityPageName, pathName: string, detailName: string | undefined ): RouteSpyState & ObjectWithNavTabs => ({ @@ -100,7 +100,6 @@ const getMockObject = ( }, }, }, - sourcerer: {}, }, }; }); @@ -191,7 +190,7 @@ describe('Navigation Breadcrumbs', () => { describe('getBreadcrumbsForRoute', () => { test('should return Overview breadcrumbs when supplied overview pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('overview', '/', undefined), + getMockObject(SecurityPageName.overview, '/', undefined), getSecuritySolutionUrl, false ); @@ -206,7 +205,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Host breadcrumbs when supplied hosts pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('hosts', '/', undefined), + getMockObject(SecurityPageName.hosts, '/', undefined), getSecuritySolutionUrl, false ); @@ -222,7 +221,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Network breadcrumbs when supplied network pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('network', '/', undefined), + getMockObject(SecurityPageName.network, '/', undefined), getSecuritySolutionUrl, false ); @@ -238,7 +237,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Timelines breadcrumbs when supplied timelines pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('timelines', '/', undefined), + getMockObject(SecurityPageName.timelines, '/', undefined), getSecuritySolutionUrl, false ); @@ -253,7 +252,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Host Details breadcrumbs when supplied a pathname with hostName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('hosts', '/', hostName), + getMockObject(SecurityPageName.hosts, '/', hostName), getSecuritySolutionUrl, false ); @@ -270,7 +269,7 @@ describe('Navigation Breadcrumbs', () => { test('should return IP Details breadcrumbs when supplied pathname with ipv4', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('network', '/', ipv4), + getMockObject(SecurityPageName.network, '/', ipv4), getSecuritySolutionUrl, false ); @@ -287,7 +286,7 @@ describe('Navigation Breadcrumbs', () => { test('should return IP Details breadcrumbs when supplied pathname with ipv6', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('network', '/', ipv6Encoded), + getMockObject(SecurityPageName.network, '/', ipv6Encoded), getSecuritySolutionUrl, false ); @@ -304,7 +303,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Alerts breadcrumbs when supplied alerts pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('alerts', '/alerts', undefined), + getMockObject(SecurityPageName.alerts, '/alerts', undefined), getSecuritySolutionUrl, false ); @@ -319,7 +318,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Exceptions breadcrumbs when supplied exceptions pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('exceptions', '/exceptions', undefined), + getMockObject(SecurityPageName.exceptions, '/exceptions', undefined), getSecuritySolutionUrl, false ); @@ -334,7 +333,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Rules breadcrumbs when supplied rules pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('rules', '/rules', undefined), + getMockObject(SecurityPageName.rules, '/rules', undefined), getSecuritySolutionUrl, false ); @@ -349,7 +348,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Rules breadcrumbs when supplied rules Creation pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('rules', '/rules/create', undefined), + getMockObject(SecurityPageName.rules, '/rules/create', undefined), getSecuritySolutionUrl, false ); @@ -368,7 +367,7 @@ describe('Navigation Breadcrumbs', () => { const mockRuleName = 'ALERT_RULE_NAME'; const breadcrumbs = getBreadcrumbsForRoute( { - ...getMockObject('rules', `/rules/id/${mockDetailName}`, undefined), + ...getMockObject(SecurityPageName.rules, `/rules/id/${mockDetailName}`, undefined), detailName: mockDetailName, state: { ruleName: mockRuleName, @@ -392,7 +391,7 @@ describe('Navigation Breadcrumbs', () => { const mockRuleName = 'ALERT_RULE_NAME'; const breadcrumbs = getBreadcrumbsForRoute( { - ...getMockObject('rules', `/rules/id/${mockDetailName}/edit`, undefined), + ...getMockObject(SecurityPageName.rules, `/rules/id/${mockDetailName}/edit`, undefined), detailName: mockDetailName, state: { ruleName: mockRuleName, @@ -417,7 +416,7 @@ describe('Navigation Breadcrumbs', () => { test('should return null breadcrumbs when supplied Cases pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('cases', '/', undefined), + getMockObject(SecurityPageName.case, '/', undefined), getSecuritySolutionUrl, false ); @@ -431,7 +430,7 @@ describe('Navigation Breadcrumbs', () => { }; const breadcrumbs = getBreadcrumbsForRoute( { - ...getMockObject('cases', `/${sampleCase.id}`, sampleCase.id), + ...getMockObject(SecurityPageName.case, `/${sampleCase.id}`, sampleCase.id), state: { caseTitle: sampleCase.name }, }, getSecuritySolutionUrl, @@ -442,7 +441,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Admin breadcrumbs when supplied endpoints pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('administration', '/endpoints', undefined), + getMockObject(SecurityPageName.administration, '/endpoints', undefined), getSecuritySolutionUrl, false ); @@ -461,22 +460,26 @@ describe('Navigation Breadcrumbs', () => { test('should call chrome breadcrumb service with correct breadcrumbs', () => { const navigateToUrlMock = jest.fn(); const { result } = renderHook(() => useSetBreadcrumbs(), { wrapper: TestProviders }); - result.current(getMockObject('hosts', '/', hostName), chromeMock, navigateToUrlMock); + result.current( + getMockObject(SecurityPageName.hosts, '/', hostName), + chromeMock, + navigateToUrlMock + ); expect(setBreadcrumbsMock).toBeCalledWith([ expect.objectContaining({ text: 'Security', - href: "securitySolutionUI/get_started?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/get_started?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", onClick: expect.any(Function), }), expect.objectContaining({ text: 'Hosts', - href: "securitySolutionUI/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/hosts?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", onClick: expect.any(Function), }), expect.objectContaining({ text: 'siem-kibana', - href: "securitySolutionUI/hosts/siem-kibana?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/hosts/siem-kibana?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", onClick: expect.any(Function), }), { @@ -496,7 +499,7 @@ describe('Navigation Breadcrumbs', () => { describe('getBreadcrumbsForRoute', () => { test('should return Overview breadcrumbs when supplied overview pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('overview', '/', undefined), + getMockObject(SecurityPageName.overview, '/', undefined), getSecuritySolutionUrl, true ); @@ -515,7 +518,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Host breadcrumbs when supplied hosts pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('hosts', '/', undefined), + getMockObject(SecurityPageName.hosts, '/', undefined), getSecuritySolutionUrl, true ); @@ -532,7 +535,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Network breadcrumbs when supplied network pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('network', '/', undefined), + getMockObject(SecurityPageName.network, '/', undefined), getSecuritySolutionUrl, true ); @@ -549,7 +552,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Timelines breadcrumbs when supplied timelines pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('timelines', '/', undefined), + getMockObject(SecurityPageName.timelines, '/', undefined), getSecuritySolutionUrl, true ); @@ -564,7 +567,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Host Details breadcrumbs when supplied a pathname with hostName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('hosts', '/', hostName), + getMockObject(SecurityPageName.hosts, '/', hostName), getSecuritySolutionUrl, true ); @@ -582,7 +585,7 @@ describe('Navigation Breadcrumbs', () => { test('should return IP Details breadcrumbs when supplied pathname with ipv4', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('network', '/', ipv4), + getMockObject(SecurityPageName.network, '/', ipv4), getSecuritySolutionUrl, true ); @@ -600,7 +603,7 @@ describe('Navigation Breadcrumbs', () => { test('should return IP Details breadcrumbs when supplied pathname with ipv6', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('network', '/', ipv6Encoded), + getMockObject(SecurityPageName.network, '/', ipv6Encoded), getSecuritySolutionUrl, true ); @@ -618,7 +621,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Alerts breadcrumbs when supplied alerts pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('alerts', '/alerts', undefined), + getMockObject(SecurityPageName.alerts, '/alerts', undefined), getSecuritySolutionUrl, true ); @@ -633,7 +636,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Exceptions breadcrumbs when supplied exceptions pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('exceptions', '/exceptions', undefined), + getMockObject(SecurityPageName.exceptions, '/exceptions', undefined), getSecuritySolutionUrl, true ); @@ -649,7 +652,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Rules breadcrumbs when supplied rules pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('rules', '/rules', undefined), + getMockObject(SecurityPageName.rules, '/rules', undefined), getSecuritySolutionUrl, true ); @@ -665,7 +668,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Rules breadcrumbs when supplied rules Creation pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('rules', '/rules/create', undefined), + getMockObject(SecurityPageName.rules, '/rules/create', undefined), getSecuritySolutionUrl, true ); @@ -685,7 +688,7 @@ describe('Navigation Breadcrumbs', () => { const mockRuleName = 'ALERT_RULE_NAME'; const breadcrumbs = getBreadcrumbsForRoute( { - ...getMockObject('rules', `/rules/id/${mockDetailName}`, undefined), + ...getMockObject(SecurityPageName.rules, `/rules/id/${mockDetailName}`, undefined), detailName: mockDetailName, state: { ruleName: mockRuleName, @@ -710,7 +713,7 @@ describe('Navigation Breadcrumbs', () => { const mockRuleName = 'ALERT_RULE_NAME'; const breadcrumbs = getBreadcrumbsForRoute( { - ...getMockObject('rules', `/rules/id/${mockDetailName}/edit`, undefined), + ...getMockObject(SecurityPageName.rules, `/rules/id/${mockDetailName}/edit`, undefined), detailName: mockDetailName, state: { ruleName: mockRuleName, @@ -736,7 +739,7 @@ describe('Navigation Breadcrumbs', () => { test('should return null breadcrumbs when supplied Cases pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('cases', '/', undefined), + getMockObject(SecurityPageName.case, '/', undefined), getSecuritySolutionUrl, true ); @@ -750,7 +753,7 @@ describe('Navigation Breadcrumbs', () => { }; const breadcrumbs = getBreadcrumbsForRoute( { - ...getMockObject('cases', `/${sampleCase.id}`, sampleCase.id), + ...getMockObject(SecurityPageName.case, `/${sampleCase.id}`, sampleCase.id), state: { caseTitle: sampleCase.name }, }, getSecuritySolutionUrl, @@ -761,7 +764,7 @@ describe('Navigation Breadcrumbs', () => { test('should return Admin breadcrumbs when supplied endpoints pageName', () => { const breadcrumbs = getBreadcrumbsForRoute( - getMockObject('administration', '/endpoints', undefined), + getMockObject(SecurityPageName.administration, '/endpoints', undefined), getSecuritySolutionUrl, true ); @@ -781,9 +784,13 @@ describe('Navigation Breadcrumbs', () => { test('should call chrome breadcrumb service with correct breadcrumbs', () => { const navigateToUrlMock = jest.fn(); const { result } = renderHook(() => useSetBreadcrumbs(), { wrapper: TestProviders }); - result.current(getMockObject('hosts', '/', hostName), chromeMock, navigateToUrlMock); + result.current( + getMockObject(SecurityPageName.hosts, '/', hostName), + chromeMock, + navigateToUrlMock + ); const searchString = - "?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))"; + "?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))"; expect(setBreadcrumbsMock).toBeCalledWith([ expect.objectContaining({ diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts index 1449ff66b3317..7ca61bf9a8e83 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts @@ -84,7 +84,7 @@ export const getBreadcrumbsForRoute = ( } const newMenuLeadingBreadcrumbs = getLeadingBreadcrumbsForSecurityPage( - spyState.pageName as SecurityPageName, + spyState.pageName, getSecuritySolutionUrl, object.navTabs, isGroupedNavigationEnabled diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/helpers.ts b/x-pack/plugins/security_solution/public/common/components/navigation/helpers.ts index b2d91492b3ae1..16bf3a074d884 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/helpers.ts @@ -20,28 +20,31 @@ import { } from '../url_state/helpers'; import { SearchNavTab } from './types'; -import { SourcererUrlState } from '../../store/sourcerer/model'; import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features'; import { useUiSetting$ } from '../../lib/kibana'; import { ENABLE_GROUPED_NAVIGATION } from '../../../../common/constants'; -export const getSearch = (tab: SearchNavTab, urlState: UrlState): string => { +export const getSearch = ( + tab: SearchNavTab, + urlState: UrlState, + globalQueryString: string +): string => { if (tab && tab.urlKey != null && !isAdministration(tab.urlKey)) { - return getUrlStateSearch(urlState); + // TODO: Temporary code while we are migrating all query strings to global_query_string_manager + if (globalQueryString.length > 0) { + return `${getUrlStateSearch(urlState)}&${globalQueryString}`; + } else { + return getUrlStateSearch(urlState); + } } + return ''; }; export const getUrlStateSearch = (urlState: UrlState): string => ALL_URL_STATE_KEYS.reduce( (myLocation: Location, urlKey: KeyUrlState) => { - let urlStateToReplace: - | Filter[] - | Query - | SourcererUrlState - | TimelineUrl - | UrlInputsModel - | string = ''; + let urlStateToReplace: Filter[] | Query | TimelineUrl | UrlInputsModel | string = ''; if (urlKey === CONSTANTS.appQuery && urlState.query != null) { if (urlState.query.query === '') { @@ -57,8 +60,6 @@ export const getUrlStateSearch = (urlState: UrlState): string => } } else if (urlKey === CONSTANTS.timerange) { urlStateToReplace = urlState[CONSTANTS.timerange]; - } else if (urlKey === CONSTANTS.sourcerer) { - urlStateToReplace = urlState[CONSTANTS.sourcerer]; } else if (urlKey === CONSTANTS.timeline && urlState[CONSTANTS.timeline] != null) { const timeline = urlState[CONSTANTS.timeline]; if (timeline.id === '') { diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx index f70b77b15dc8c..ef2c0a36437b5 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/index.test.tsx @@ -15,6 +15,7 @@ import { HostsTableType } from '../../../hosts/store/model'; import { RouteSpyState } from '../../utils/route/types'; import { TabNavigationComponentProps, SecuritySolutionTabNavigationProps } from './types'; import { TimelineTabs } from '../../../../common/types/timeline'; +import { SecurityPageName } from '../../../app/types'; jest.mock('react-router-dom', () => { const original = jest.requireActual('react-router-dom'); @@ -61,7 +62,7 @@ describe('SIEM Navigation', () => { const mockProps: TabNavigationComponentProps & SecuritySolutionTabNavigationProps & RouteSpyState = { - pageName: 'hosts', + pageName: SecurityPageName.hosts, pathName: '/', detailName: undefined, search: '', @@ -92,7 +93,6 @@ describe('SIEM Navigation', () => { }, [CONSTANTS.appQuery]: { query: '', language: 'kuery' }, [CONSTANTS.filters]: [], - [CONSTANTS.sourcerer]: {}, [CONSTANTS.timeline]: { activeTab: TimelineTabs.query, id: '', diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/index.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/index.tsx index 8491171e65bca..ed296b70b31b0 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/index.tsx @@ -84,7 +84,6 @@ export const TabNavigationComponent: React.FC< navTabs={navTabs} pageName={pageName} pathName={pathName} - sourcerer={urlState.sourcerer} savedQuery={urlState.savedQuery} tabName={tabName} timeline={urlState.timeline} diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/security_side_nav/security_side_nav.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/security_side_nav/security_side_nav.tsx index 8db77bae34a80..9ca8b1cf64bda 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/security_side_nav/security_side_nav.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/security_side_nav/security_side_nav.tsx @@ -130,7 +130,7 @@ const useSideNavItems = () => { const useSelectedId = (): SecurityPageName => { const [{ pageName }] = useRouteSpy(); const selectedId = useMemo(() => { - const [rootLinkInfo] = getAncestorLinksInfo(pageName as SecurityPageName); + const [rootLinkInfo] = getAncestorLinksInfo(pageName); return rootLinkInfo?.id ?? ''; }, [pageName]); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx index 594ceb1485adc..f5a05cb20925c 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx @@ -15,6 +15,7 @@ import { RouteSpyState } from '../../../utils/route/types'; import { CONSTANTS } from '../../url_state/constants'; import { TabNavigationComponent } from '.'; import { TabNavigationProps } from './types'; +import { SecurityPageName } from '../../../../app/types'; jest.mock('../../link_to'); jest.mock('../../../lib/kibana/kibana_react', () => { @@ -54,7 +55,7 @@ describe('Table Navigation', () => { const mockRiskyHostEnabled = true; const mockProps: TabNavigationProps & RouteSpyState = { - pageName: 'hosts', + pageName: SecurityPageName.hosts, pathName: '/hosts', detailName: hostName, search: '', @@ -89,7 +90,6 @@ describe('Table Navigation', () => { }, [CONSTANTS.appQuery]: { query: 'host.name:"siem-es"', language: 'kuery' }, [CONSTANTS.filters]: [], - [CONSTANTS.sourcerer]: {}, [CONSTANTS.timeline]: { activeTab: TimelineTabs.query, id: '', diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts index 5630978bae87a..b1bf150f9e1c8 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/types.ts @@ -8,7 +8,6 @@ import type { Filter, Query } from '@kbn/es-query'; import { UrlInputsModel } from '../../../store/inputs/model'; import { CONSTANTS } from '../../url_state/constants'; -import { SourcererUrlState } from '../../../store/sourcerer/model'; import { TimelineUrl } from '../../../../timelines/store/timeline/model'; import { SecuritySolutionTabNavigationProps } from '../types'; @@ -21,7 +20,6 @@ export interface TabNavigationProps extends SecuritySolutionTabNavigationProps { [CONSTANTS.appQuery]?: Query; [CONSTANTS.filters]?: Filter[]; [CONSTANTS.savedQuery]?: string; - [CONSTANTS.sourcerer]: SourcererUrlState; [CONSTANTS.timerange]: UrlInputsModel; [CONSTANTS.timeline]: TimelineUrl; } diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_get_url_search.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_get_url_search.tsx index 9ec86ee2b24ef..4de646f860498 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_get_url_search.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_get_url_search.tsx @@ -8,6 +8,7 @@ import { useCallback, useMemo } from 'react'; import { useDeepEqualSelector } from '../../hooks/use_selector'; +import { useGlobalQueryString } from '../../utils/global_query_string'; import { makeMapStateToProps } from '../url_state/helpers'; import { getSearch, getUrlStateSearch } from './helpers'; import { SearchNavTab } from './types'; @@ -15,13 +16,27 @@ import { SearchNavTab } from './types'; export const useGetUrlSearch = (tab?: SearchNavTab) => { const mapState = makeMapStateToProps(); const { urlState } = useDeepEqualSelector(mapState); - const urlSearch = useMemo(() => (tab ? getSearch(tab, urlState) : ''), [tab, urlState]); + const globalQueryString = useGlobalQueryString(); + const urlSearch = useMemo( + () => (tab ? getSearch(tab, urlState, globalQueryString) : ''), + [tab, urlState, globalQueryString] + ); + return urlSearch; }; export const useGetUrlStateQueryString = () => { const mapState = makeMapStateToProps(); const { urlState } = useDeepEqualSelector(mapState); - const getUrlStateQueryString = useCallback(() => getUrlStateSearch(urlState), [urlState]); + const globalQueryString = useGlobalQueryString(); + const getUrlStateQueryString = useCallback(() => { + // TODO: Temporary code while we are migrating all query strings to global_query_string_manager + if (globalQueryString.length > 0) { + return `${getUrlStateSearch(urlState)}&${globalQueryString}`; + } + + return getUrlStateSearch(urlState); + }, [urlState, globalQueryString]); + return getUrlStateQueryString; }; diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/__snapshots__/index.test.tsx.snap index 0be5c860e22a2..293fddddf1ba2 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/__snapshots__/index.test.tsx.snap @@ -8,10 +8,10 @@ Object { "id": "main", "items": Array [ Object { - "data-href": "securitySolutionUI/get_started?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/get_started?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-get_started", "disabled": false, - "href": "securitySolutionUI/get_started?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/get_started?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "get_started", "isSelected": false, "name": "Get started", @@ -24,20 +24,20 @@ Object { "id": "dashboards", "items": Array [ Object { - "data-href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-overview", "disabled": false, - "href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "overview", "isSelected": false, "name": "Overview", "onClick": [Function], }, Object { - "data-href": "securitySolutionUI/detection_response?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/detection_response?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-detection_response", "disabled": false, - "href": "securitySolutionUI/detection_response?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/detection_response?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "detection_response", "isSelected": false, "name": "Detection & Response", @@ -50,30 +50,30 @@ Object { "id": "detect", "items": Array [ Object { - "data-href": "securitySolutionUI/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-alerts", "disabled": false, - "href": "securitySolutionUI/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "alerts", "isSelected": false, "name": "Alerts", "onClick": [Function], }, Object { - "data-href": "securitySolutionUI/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-rules", "disabled": false, - "href": "securitySolutionUI/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "rules", "isSelected": false, "name": "Rules", "onClick": [Function], }, Object { - "data-href": "securitySolutionUI/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-exceptions", "disabled": false, - "href": "securitySolutionUI/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "exceptions", "isSelected": false, "name": "Exception lists", @@ -86,30 +86,30 @@ Object { "id": "explore", "items": Array [ Object { - "data-href": "securitySolutionUI/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-hosts", "disabled": false, - "href": "securitySolutionUI/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "hosts", "isSelected": true, "name": "Hosts", "onClick": [Function], }, Object { - "data-href": "securitySolutionUI/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-network", "disabled": false, - "href": "securitySolutionUI/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "network", "isSelected": false, "name": "Network", "onClick": [Function], }, Object { - "data-href": "securitySolutionUI/users?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/users?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-users", "disabled": false, - "href": "securitySolutionUI/users?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/users?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "users", "isSelected": false, "name": "Users", @@ -122,10 +122,10 @@ Object { "id": "investigate", "items": Array [ Object { - "data-href": "securitySolutionUI/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-timelines", "disabled": false, - "href": "securitySolutionUI/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "timelines", "isSelected": false, "name": "Timelines", diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx index c2e733edf66d5..db7d06f899b5c 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx @@ -32,7 +32,6 @@ describe('useSecuritySolutionNavigation', () => { const mockUrlState = { [CONSTANTS.appQuery]: { query: 'host.name:"security-solution-es"', language: 'kuery' }, [CONSTANTS.savedQuery]: '', - [CONSTANTS.sourcerer]: {}, [CONSTANTS.timeline]: { activeTab: TimelineTabs.query, id: '', @@ -165,10 +164,10 @@ describe('useSecuritySolutionNavigation', () => { ); expect(caseNavItem).toMatchInlineSnapshot(` Object { - "data-href": "securitySolutionUI/cases?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/cases?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-cases", "disabled": false, - "href": "securitySolutionUI/cases?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/cases?query=(language:kuery,query:'host.name:%22security-solution-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "cases", "isSelected": false, "name": "Cases", diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx index e8ea703fe7171..f0a51e0b8a39a 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.tsx @@ -76,7 +76,6 @@ export const useSecuritySolutionNavigation = () => { filters: urlState.filters, navTabs: enabledNavTabs, pageName, - sourcerer: urlState.sourcerer, savedQuery: urlState.savedQuery, tabName, timeline: urlState.timeline, diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx index be131f168464a..f9a766ed3d875 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx @@ -18,6 +18,7 @@ import { NavTab, SecurityNavGroupKey } from '../types'; import { SecurityPageName } from '../../../../../common/constants'; import { useCanSeeHostIsolationExceptionsMenu } from '../../../../management/pages/host_isolation_exceptions/view/hooks'; import { useIsExperimentalFeatureEnabled } from '../../../hooks/use_experimental_features'; +import { useGlobalQueryString } from '../../../utils/global_query_string'; export const usePrimaryNavigationItems = ({ navTabs, @@ -25,11 +26,13 @@ export const usePrimaryNavigationItems = ({ ...urlStateProps }: PrimaryNavigationItemsProps): Array> => { const { navigateTo, getAppUrl } = useNavigation(); + const globalQueryString = useGlobalQueryString(); + const getSideNav = useCallback( (tab: NavTab) => { const { id, name, disabled } = tab; const isSelected = selectedTabId === id; - const urlSearch = getSearch(tab, urlStateProps); + const urlSearch = getSearch(tab, urlStateProps, globalQueryString); const handleClick = (ev: React.MouseEvent) => { ev.preventDefault(); @@ -49,7 +52,7 @@ export const usePrimaryNavigationItems = ({ onClick: handleClick, }; }, - [getAppUrl, navigateTo, selectedTabId, urlStateProps] + [getAppUrl, navigateTo, selectedTabId, urlStateProps, globalQueryString] ); const navItemsToDisplay = usePrimaryNavigationItemsToDisplay(navTabs); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx index 1123fd50a53e6..888d9f2d8ee6b 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_primary_navigation.tsx @@ -24,7 +24,6 @@ export const usePrimaryNavigation = ({ navTabs, pageName, savedQuery, - sourcerer, tabName, timeline, timerange, @@ -53,7 +52,6 @@ export const usePrimaryNavigation = ({ filters, query, savedQuery, - sourcerer, timeline, timerange, }); diff --git a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx index dbc57bb30c77f..0220963110ce6 100644 --- a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx @@ -54,6 +54,16 @@ jest.mock('@kbn/kibana-react-plugin/public', () => { }; }); +const mockUpdateUrlParam = jest.fn(); +jest.mock('../../utils/global_query_string', () => { + const original = jest.requireActual('../../utils/global_query_string'); + + return { + ...original, + useUpdateUrlParam: () => mockUpdateUrlParam, + }; +}); + const mockOptions = DEFAULT_INDEX_PATTERN.map((index) => ({ label: index, value: index })); const defaultProps = { @@ -411,6 +421,50 @@ describe('Sourcerer component', () => { }) ); }); + + it('onSave updates the URL param', () => { + store = createStore( + { + ...mockGlobalState, + sourcerer: { + ...mockGlobalState.sourcerer, + kibanaDataViews: [ + mockGlobalState.sourcerer.defaultDataView, + { + ...mockGlobalState.sourcerer.defaultDataView, + id: '1234', + title: 'filebeat-*', + patternList: ['filebeat-*'], + }, + ], + sourcererScopes: { + ...mockGlobalState.sourcerer.sourcererScopes, + [SourcererScopeName.default]: { + ...mockGlobalState.sourcerer.sourcererScopes[SourcererScopeName.default], + selectedDataViewId: id, + selectedPatterns: patternListNoSignals.slice(0, 2), + }, + }, + }, + }, + SUB_PLUGINS_REDUCER, + kibanaObservable, + storage + ); + + const wrapper = mount( + + + + ); + wrapper.find(`[data-test-subj="sourcerer-trigger"]`).first().simulate('click'); + wrapper.find(`[data-test-subj="comboBoxInput"]`).first().simulate('click'); + wrapper.find(`[data-test-subj="sourcerer-combo-option"]`).first().simulate('click'); + wrapper.find(`[data-test-subj="sourcerer-save"]`).first().simulate('click'); + + expect(mockUpdateUrlParam).toHaveBeenCalledTimes(1); + }); + it('resets to default index pattern', async () => { const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx index ad3b11a74e81d..0255bb6b58065 100644 --- a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx @@ -20,7 +20,7 @@ import { useDispatch } from 'react-redux'; import * as i18n from './translations'; import { sourcererActions, sourcererModel, sourcererSelectors } from '../../store/sourcerer'; import { useDeepEqualSelector } from '../../hooks/use_selector'; -import { SourcererScopeName } from '../../store/sourcerer/model'; +import { SourcererScopeName, SourcererUrlState } from '../../store/sourcerer/model'; import { usePickIndexPatterns } from './use_pick_index_patterns'; import { FormRow, PopoverContent, StyledButton, StyledFormRow } from './helpers'; import { TemporarySourcerer } from './temporary'; @@ -29,6 +29,8 @@ import { useUpdateDataView } from './use_update_data_view'; import { Trigger } from './trigger'; import { AlertsCheckbox, SaveButtons, SourcererCallout } from './sub_components'; import { useSignalHelpers } from '../../containers/sourcerer/use_signal_helpers'; +import { useUpdateUrlParam } from '../../utils/global_query_string'; +import { CONSTANTS } from '../url_state/constants'; export interface SourcererComponentProps { scope: sourcererModel.SourcererScopeName; @@ -38,6 +40,8 @@ export const Sourcerer = React.memo(({ scope: scopeId } const dispatch = useDispatch(); const isDetectionsSourcerer = scopeId === SourcererScopeName.detections; const isTimelineSourcerer = scopeId === SourcererScopeName.timeline; + const isDefaultSourcerer = scopeId === SourcererScopeName.default; + const updateUrlParam = useUpdateUrlParam(CONSTANTS.sourcerer); const sourcererScopeSelector = useMemo(() => sourcererSelectors.getSourcererScopeSelector(), []); const { @@ -144,8 +148,17 @@ export const Sourcerer = React.memo(({ scope: scopeId } shouldValidateSelectedPatterns, }) ); + + if (isDefaultSourcerer) { + updateUrlParam({ + [SourcererScopeName.default]: { + id: newSelectedDataView, + selectedPatterns: newSelectedPatterns, + }, + }); + } }, - [dispatch, scopeId] + [dispatch, scopeId, isDefaultSourcerer, updateUrlParam] ); const onChangeDataView = useCallback( diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/helpers.test.ts b/x-pack/plugins/security_solution/public/common/components/url_state/helpers.test.ts index ba806da195461..f8df77e8ff624 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/helpers.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/url_state/helpers.test.ts @@ -8,6 +8,7 @@ import { navTabs } from '../../../app/home/home_navigations'; import { getTitle, isQueryStateEmpty } from './helpers'; import { CONSTANTS } from './constants'; +import { ValueUrlState } from './types'; describe('Helpers Url_State', () => { describe('getTitle', () => { @@ -45,7 +46,7 @@ describe('Helpers Url_State', () => { }); test('returns true if url key is "query" and queryState is empty string', () => { - const result = isQueryStateEmpty({}, CONSTANTS.appQuery); + const result = isQueryStateEmpty('', CONSTANTS.appQuery); expect(result).toBeTruthy(); }); @@ -72,7 +73,7 @@ describe('Helpers Url_State', () => { // TODO: Is this a bug, or intended? test('returns false if url key is "timeline" and queryState is empty', () => { - const result = isQueryStateEmpty({}, CONSTANTS.timeline); + const result = isQueryStateEmpty({} as ValueUrlState, CONSTANTS.timeline); expect(result).toBeFalsy(); }); diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/helpers.ts b/x-pack/plugins/security_solution/public/common/components/url_state/helpers.ts index 71b6852943ebf..681045be404e0 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/components/url_state/helpers.ts @@ -24,8 +24,6 @@ import { formatDate } from '../super_date_picker'; import { NavTab } from '../navigation/types'; import { CONSTANTS, UrlStateType } from './constants'; import { ReplaceStateInLocation, KeyUrlState, ValueUrlState } from './types'; -import { sourcererSelectors } from '../../store/sourcerer'; -import { SourcererScopeName, SourcererUrlState } from '../../store/sourcerer/model'; export const isDetectionsPages = (pageName: string) => pageName === SecurityPageName.alerts || @@ -49,7 +47,10 @@ export const encodeRisonUrlState = (state: any) => encode(state); export const getQueryStringFromLocation = (search: string) => search.substring(1); -export const getParamFromQueryString = (queryString: string, key: string) => { +export const getParamFromQueryString = ( + queryString: string, + key: string +): string | undefined | null => { const parsedQueryString = parse(queryString, { sort: false }); const queryParam = parsedQueryString[key]; @@ -128,7 +129,6 @@ export const makeMapStateToProps = () => { const getGlobalFiltersQuerySelector = inputsSelectors.globalFiltersQuerySelector(); const getGlobalSavedQuerySelector = inputsSelectors.globalSavedQuerySelector(); const getTimeline = timelineSelectors.getTimelineByIdSelector(); - const getSourcererScopes = sourcererSelectors.scopesSelector(); const mapStateToProps = (state: State) => { const inputState = getInputsSelector(state); const { linkTo: globalLinkTo, timerange: globalTimerange } = inputState.global; @@ -159,25 +159,10 @@ export const makeMapStateToProps = () => { [CONSTANTS.savedQuery]: savedQuery.id, }; } - const sourcerer = getSourcererScopes(state); - const activeScopes: SourcererScopeName[] = Object.keys(sourcerer) as SourcererScopeName[]; - const selectedPatterns: SourcererUrlState = activeScopes - .filter((scope) => scope === SourcererScopeName.default) - .reduce( - (acc, scope) => ({ - ...acc, - [scope]: { - id: sourcerer[scope]?.selectedDataViewId, - selectedPatterns: sourcerer[scope]?.selectedPatterns, - }, - }), - {} - ); return { urlState: { ...searchAttr, - [CONSTANTS.sourcerer]: selectedPatterns, [CONSTANTS.timerange]: { global: { [CONSTANTS.timerange]: globalTimerange, diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx index 02fefd46f031d..50072d96fe96f 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/url_state/index.test.tsx @@ -125,6 +125,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -159,6 +160,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -189,6 +191,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -218,6 +221,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -227,7 +231,7 @@ describe('UrlStateContainer', () => { ).toEqual({ hash: '', pathname: examplePath, - search: `?query=(language:kuery,query:'host.name:%22siem-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, + search: `?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, state: '', }); } @@ -246,6 +250,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: 'out of sync path', + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -265,6 +270,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -284,6 +290,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -309,6 +316,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -334,6 +342,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -356,6 +365,7 @@ describe('UrlStateContainer', () => { (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); const wrapper = mount( diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/index_mocked.test.tsx b/x-pack/plugins/security_solution/public/common/components/url_state/index_mocked.test.tsx index 4e87be0fb5316..1162a449acdc6 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/index_mocked.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/url_state/index_mocked.test.tsx @@ -88,6 +88,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); const wrapper = mount( @@ -126,7 +127,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => hash: '', pathname: '/network', search: - "?query=(language:kuery,query:'host.name:%22siem-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", state: '', }); }); @@ -142,6 +143,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); const wrapper = mount( @@ -160,7 +162,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => hash: '', pathname: '/network', search: - "?query=(language:kuery,query:'host.name:%22siem-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + "?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", state: '', }); }); @@ -176,6 +178,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); const wrapper = mount( @@ -195,42 +198,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => hash: '', pathname: '/network', search: - "?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))&timeline=(id:hello_timeline_id,isOpen:!t)", - state: '', - }); - }); - - test('sourcerer redux state updates the url', () => { - mockProps = getMockPropsObj({ - page: CONSTANTS.networkPage, - examplePath: '/network', - namespaceLower: 'network', - pageName: SecurityPageName.network, - detailName: undefined, - }).noSearch.undefinedQuery; - - (useLocation as jest.Mock).mockReturnValue({ - pathname: mockProps.pathName, - }); - - const wrapper = mount( - useUrlStateHooks(args)} /> - ); - const newUrlState = { - ...mockProps.urlState, - sourcerer: ['cool', 'patterns'], - }; - - wrapper.setProps({ - hookProps: { ...mockProps, urlState: newUrlState, isInitializing: false }, - }); - wrapper.update(); - - expect(mockHistory.replace.mock.calls[1][0]).toStrictEqual({ - hash: '', - pathname: '/network', - search: - "?sourcerer=!(cool,patterns)&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + "?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))&timeline=(id:hello_timeline_id,isOpen:!t)", state: '', }); }); @@ -286,6 +254,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); const wrapper = mount( @@ -297,6 +266,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: updatedMockProps.pathName, + search: mockProps.search, }); wrapper.setProps({ @@ -307,7 +277,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => expect(mockHistory.replace.mock.calls[1][0]).toStrictEqual({ hash: '', pathname: MANAGEMENT_PATH, - search: '?', + search: mockProps.search, state: '', }); }); @@ -363,6 +333,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); const wrapper = mount( @@ -374,6 +345,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: updatedMockProps.pathName, + search: mockProps.search, }); wrapper.setProps({ @@ -384,7 +356,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => expect(mockHistory.replace.mock.calls[1][0]).toStrictEqual({ hash: '', pathname: DASHBOARDS_PATH, - search: '?', + search: mockProps.search, state: '', }); }); @@ -401,6 +373,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); mount( useUrlStateHooks(args)} />); @@ -409,7 +382,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => hash: '', pathname: examplePath, search: - "?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + "?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", state: '', }); } @@ -433,6 +406,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); const wrapper = mount( @@ -440,11 +414,12 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => ); expect(mockHistory.replace.mock.calls[0][0].search).toEqual( - "?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))" + "?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))" ); (useLocation as jest.Mock).mockReturnValue({ pathname: updatedProps.pathName, + search: mockProps.search, }); wrapper.setProps({ hookProps: updatedProps }); @@ -452,7 +427,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => wrapper.update(); expect(mockHistory.replace.mock.calls[1][0].search).toEqual( - "?query=(language:kuery,query:'host.name:%22siem-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))" + "?query=(language:kuery,query:'host.name:%22siem-es%22')&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))" ); }); @@ -478,6 +453,7 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => (useLocation as jest.Mock).mockReturnValue({ pathname: mockProps.pathName, + search: mockProps.search, }); const wrapper = mount( @@ -485,11 +461,12 @@ describe('UrlStateContainer - lodash.throttle mocked to test update url', () => ); expect(mockHistory.replace.mock.calls[0][0].search).toEqual( - "?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))" + "?timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))" ); (useLocation as jest.Mock).mockReturnValue({ pathname: updatedMockProps.pathName, + search: mockProps.search, }); wrapper.setProps({ hookProps: updatedMockProps }); diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx b/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx index 0f7e93f1befca..a417ad7c5950f 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx +++ b/x-pack/plugins/security_solution/public/common/components/url_state/initialize_redux_by_url.tsx @@ -11,7 +11,7 @@ import { Dispatch } from 'redux'; import { useCallback, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import type { Filter, Query } from '@kbn/es-query'; -import { inputsActions, sourcererActions } from '../../store/actions'; +import { inputsActions } from '../../store/actions'; import { InputsModelId, TimeRangeKinds } from '../../store/inputs/constants'; import { UrlInputsModel, @@ -21,14 +21,13 @@ import { } from '../../store/inputs/model'; import { TimelineUrl } from '../../../timelines/store/timeline/model'; import { CONSTANTS } from './constants'; -import { decodeRisonUrlState, isDetectionsPages } from './helpers'; +import { decodeRisonUrlState } from './helpers'; import { normalizeTimeRange } from './normalize_time_range'; import { SetInitialStateFromUrl } from './types'; import { queryTimelineById, dispatchUpdateTimeline, } from '../../../timelines/components/open_timeline/helpers'; -import { SourcererScopeName, SourcererUrlState } from '../../store/sourcerer/model'; import { timelineActions } from '../../../timelines/store/timeline'; export const useSetInitialStateFromUrl = () => { @@ -54,23 +53,6 @@ export const useSetInitialStateFromUrl = () => { if (urlKey === CONSTANTS.timerange) { updateTimerange(newUrlStateString, dispatch); } - if (urlKey === CONSTANTS.sourcerer) { - const sourcererState = decodeRisonUrlState(newUrlStateString); - if (sourcererState != null) { - const activeScopes: SourcererScopeName[] = Object.keys(sourcererState).filter( - (key) => !(key === SourcererScopeName.default && isDetectionsPages(pageName)) - ) as SourcererScopeName[]; - activeScopes.forEach((scope) => - dispatch( - sourcererActions.setSelectedDataView({ - id: scope, - selectedDataViewId: sourcererState[scope]?.id ?? null, - selectedPatterns: sourcererState[scope]?.selectedPatterns ?? [], - }) - ) - ); - } - } if (urlKey === CONSTANTS.appQuery && indexPattern != null) { const appQuery = decodeRisonUrlState(newUrlStateString); diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/test_dependencies.ts b/x-pack/plugins/security_solution/public/common/components/url_state/test_dependencies.ts index 03ec5b0dcf940..6b8c3e3fe252b 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/test_dependencies.ts +++ b/x-pack/plugins/security_solution/public/common/components/url_state/test_dependencies.ts @@ -120,7 +120,6 @@ export const defaultProps: UrlStateContainerPropTypes = { id: '', isOpen: false, }, - [CONSTANTS.sourcerer]: {}, }, history: { ...mockHistory, @@ -132,7 +131,7 @@ export const getMockProps = ( location = defaultLocation, kqlQueryKey = CONSTANTS.networkPage, kqlQueryValue: Query | null, - pageName: string, + pageName: SecurityPageName, detailName: string | undefined ): UrlStateContainerPropTypes => ({ ...defaultProps, @@ -154,7 +153,7 @@ interface GetMockPropsObj { examplePath: string; namespaceLower: string; page: LocationTypes; - pageName: string; + pageName: SecurityPageName; detailName: string | undefined; } @@ -270,7 +269,7 @@ export const getMockPropsObj = ({ page, examplePath, pageName, detailName }: Get // silly that this needs to be an array and not an object // https://jestjs.io/docs/en/api#testeachtable-name-fn-timeout export const testCases: Array< - [LocationTypes, string, string, string, string | null, string, undefined | string] + [LocationTypes, string, string, string, string | null, SecurityPageName, undefined | string] > = [ [ /* page */ CONSTANTS.networkPage, diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/types.ts b/x-pack/plugins/security_solution/public/common/components/url_state/types.ts index 8633987b7c1c5..caf2ad77a7245 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/types.ts +++ b/x-pack/plugins/security_solution/public/common/components/url_state/types.ts @@ -13,13 +13,11 @@ import { RouteSpyState } from '../../utils/route/types'; import { SecurityNav } from '../navigation/types'; import { CONSTANTS, UrlStateType } from './constants'; -import { SourcererUrlState } from '../../store/sourcerer/model'; export const ALL_URL_STATE_KEYS: KeyUrlState[] = [ CONSTANTS.appQuery, CONSTANTS.filters, CONSTANTS.savedQuery, - CONSTANTS.sourcerer, CONSTANTS.timerange, CONSTANTS.timeline, ]; @@ -43,7 +41,6 @@ export interface UrlState { [CONSTANTS.appQuery]?: Query; [CONSTANTS.filters]?: Filter[]; [CONSTANTS.savedQuery]?: string; - [CONSTANTS.sourcerer]: SourcererUrlState; [CONSTANTS.timerange]: UrlInputsModel; [CONSTANTS.timeline]: TimelineUrl; } diff --git a/x-pack/plugins/security_solution/public/common/components/url_state/use_url_state.tsx b/x-pack/plugins/security_solution/public/common/components/url_state/use_url_state.tsx index e787b3a750e91..7a5706aec578f 100644 --- a/x-pack/plugins/security_solution/public/common/components/url_state/use_url_state.tsx +++ b/x-pack/plugins/security_solution/public/common/components/url_state/use_url_state.tsx @@ -41,7 +41,6 @@ import { TimelineUrl } from '../../../timelines/store/timeline/model'; import { UrlInputsModel } from '../../store/inputs/model'; import { queryTimelineByIdOnUrlChange } from './query_timeline_by_id_on_url_change'; import { getLinkInfo } from '../../links'; -import { SecurityPageName } from '../../../app/types'; import { useIsGroupedNavigationEnabled } from '../navigation/helpers'; function usePrevious(value: PreviousLocationUrlState) { @@ -57,17 +56,16 @@ export const useUrlStateHooks = ({ navTabs, pageName, urlState, - search, pathName, history, }: UrlStateContainerPropTypes) => { const [isFirstPageLoad, setIsFirstPageLoad] = useState(true); const { filterManager, savedQueries } = useKibana().services.data.query; - const { pathname: browserPathName } = useLocation(); + const { pathname: browserPathName, search } = useLocation(); const prevProps = usePrevious({ pathName, pageName, urlState, search }); const isGroupedNavEnabled = useIsGroupedNavigationEnabled(); - const linkInfo = pageName ? getLinkInfo(pageName as SecurityPageName) : undefined; + const linkInfo = pageName ? getLinkInfo(pageName) : undefined; const { setInitialStateFromUrl, updateTimeline, updateTimelineIsLoading } = useSetInitialStateFromUrl(); diff --git a/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.test.tsx index c577f45508e8a..737f4cf628765 100644 --- a/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.test.tsx @@ -13,7 +13,11 @@ import { Provider } from 'react-redux'; import { getScopeFromPath, useInitSourcerer, useSourcererDataView } from '.'; import { mockPatterns } from './mocks'; import { RouteSpyState } from '../../utils/route/types'; -import { DEFAULT_INDEX_PATTERN, SecurityPageName } from '../../../../common/constants'; +import { + DEFAULT_DATA_VIEW_ID, + DEFAULT_INDEX_PATTERN, + SecurityPageName, +} from '../../../../common/constants'; import { createStore } from '../../store'; import { useUserInfo, @@ -25,9 +29,12 @@ import { mockGlobalState, SUB_PLUGINS_REDUCER, mockSourcererState, + TestProviders, } from '../../mock'; import { SelectedDataView, SourcererScopeName } from '../../store/sourcerer/model'; import { postSourcererDataView } from './api'; +import { sourcererActions } from '../../store/sourcerer'; +import { useInitializeUrlParam, useUpdateUrlParam } from '../../utils/global_query_string'; const mockRouteSpy: RouteSpyState = { pageName: SecurityPageName.overview, @@ -40,6 +47,7 @@ const mockDispatch = jest.fn(); const mockUseUserInfo = useUserInfo as jest.Mock; jest.mock('../../../detections/components/user_info'); jest.mock('./api'); +jest.mock('../../utils/global_query_string'); jest.mock('react-redux', () => { const original = jest.requireActual('react-redux'); @@ -52,6 +60,8 @@ jest.mock('../../utils/route/use_route_spy', () => ({ useRouteSpy: () => [mockRouteSpy], })); +(useInitializeUrlParam as jest.Mock).mockImplementation((_, onInitialize) => onInitialize({})); + const mockSearch = jest.fn(); const mockAddWarning = jest.fn(); @@ -188,6 +198,50 @@ describe('Sourcerer Hooks', () => { }); }); + it('initilizes dataview with data from query string', async () => { + const selectedPatterns = ['testPattern-*']; + const selectedDataViewId = 'security-solution-default'; + (useInitializeUrlParam as jest.Mock).mockImplementation((_, onInitialize) => + onInitialize({ + [SourcererScopeName.default]: { + id: selectedDataViewId, + selectedPatterns, + }, + }) + ); + + renderHook(() => useInitSourcerer(), { + wrapper: ({ children }) => {children}, + }); + + expect(mockDispatch).toHaveBeenCalledWith( + sourcererActions.setSelectedDataView({ + id: SourcererScopeName.default, + selectedDataViewId, + selectedPatterns, + }) + ); + }); + + it('sets default selected patterns to the URL when there is no sorcerer URL param in the query string', async () => { + const updateUrlParam = jest.fn(); + (useUpdateUrlParam as jest.Mock).mockReturnValue(updateUrlParam); + (useInitializeUrlParam as jest.Mock).mockImplementation((_, onInitialize) => + onInitialize(null) + ); + + renderHook(() => useInitSourcerer(), { + wrapper: ({ children }) => {children}, + }); + + expect(updateUrlParam).toHaveBeenCalledWith({ + [SourcererScopeName.default]: { + id: DEFAULT_DATA_VIEW_ID, + selectedPatterns: DEFAULT_INDEX_PATTERN, + }, + }); + }); + it('calls addWarning if defaultDataView has an error', async () => { store = createStore( { diff --git a/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.tsx b/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.tsx index 140f00e63a0a3..b29379790dd5b 100644 --- a/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/sourcerer/index.tsx @@ -14,17 +14,18 @@ import { SelectedDataView, SourcererDataView, SourcererScopeName, + SourcererUrlState, } from '../../store/sourcerer/model'; import { useUserInfo } from '../../../detections/components/user_info'; import { timelineSelectors } from '../../../timelines/store/timeline'; import { ALERTS_PATH, - CASES_PATH, HOSTS_PATH, USERS_PATH, NETWORK_PATH, OVERVIEW_PATH, RULES_PATH, + CASES_PATH, } from '../../../../common/constants'; import { TimelineId } from '../../../../common/types'; import { useDeepEqualSelector } from '../../hooks/use_selector'; @@ -37,6 +38,8 @@ import { useAppToasts } from '../../hooks/use_app_toasts'; import { postSourcererDataView } from './api'; import { useDataView } from '../source/use_data_view'; import { useFetchIndex } from '../source'; +import { useInitializeUrlParam, useUpdateUrlParam } from '../../utils/global_query_string'; +import { CONSTANTS } from '../../components/url_state/constants'; export const useInitSourcerer = ( scopeId: SourcererScopeName.default | SourcererScopeName.detections = SourcererScopeName.default @@ -46,6 +49,7 @@ export const useInitSourcerer = ( const initialTimelineSourcerer = useRef(true); const initialDetectionSourcerer = useRef(true); const { loading: loadingSignalIndex, isSignalIndexExists, signalIndexName } = useUserInfo(); + const updateUrlParam = useUpdateUrlParam(CONSTANTS.sourcerer); const getDataViewsSelector = useMemo( () => sourcererSelectors.getSourcererDataViewsSelector(), @@ -88,6 +92,41 @@ export const useInitSourcerer = ( } = useDeepEqualSelector((state) => scopeIdSelector(state, SourcererScopeName.timeline)); const { indexFieldsSearch } = useDataView(); + const onInitializeUrlParam = useCallback( + (initialState: SourcererUrlState | null) => { + // Initialize the store with value from UrlParam. + if (initialState != null) { + (Object.keys(initialState) as SourcererScopeName[]).forEach((scope) => { + if ( + !(scope === SourcererScopeName.default && scopeId === SourcererScopeName.detections) + ) { + dispatch( + sourcererActions.setSelectedDataView({ + id: scope, + selectedDataViewId: initialState[scope]?.id ?? null, + selectedPatterns: initialState[scope]?.selectedPatterns ?? [], + }) + ); + } + }); + } else { + // Initialize the UrlParam with values from the store. + // It isn't strictly necessary but I am keeping it for compatibility with the previous implementation. + if (scopeDataViewId) { + updateUrlParam({ + [SourcererScopeName.default]: { + id: scopeDataViewId, + selectedPatterns, + }, + }); + } + } + }, + [dispatch, scopeDataViewId, scopeId, selectedPatterns, updateUrlParam] + ); + + useInitializeUrlParam(CONSTANTS.sourcerer, onInitializeUrlParam); + /* * Note for future engineer: * we changed the logic to not fetch all the index fields for every data view on the loading of the app diff --git a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.test.tsx b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.test.tsx index 5095a60215135..480ecdb3674ff 100644 --- a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.test.tsx @@ -37,16 +37,22 @@ describe('useGlobalTime', () => { expect(result1.to).toBe(0); }); - test('clear all queries at unmount', () => { - const { rerender } = renderHook(() => useGlobalTime()); - act(() => rerender()); + test('clear all queries at unmount when clearAllQuery is set to true', () => { + const { unmount } = renderHook(() => useGlobalTime()); + unmount(); expect(mockDispatch.mock.calls[0][0].type).toEqual( 'x-pack/security_solution/local/inputs/DELETE_ALL_QUERY' ); }); - test('do NOT clear all queries at unmount', () => { - const { rerender } = renderHook(() => useGlobalTime(false)); + test('do NOT clear all queries at unmount when clearAllQuery is set to false.', () => { + const { unmount } = renderHook(() => useGlobalTime(false)); + unmount(); + expect(mockDispatch.mock.calls.length).toBe(0); + }); + + test('do NOT clear all queries when setting state and clearAllQuery is set to true', () => { + const { rerender } = renderHook(() => useGlobalTime()); act(() => rerender()); expect(mockDispatch.mock.calls.length).toBe(0); }); diff --git a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx index 885b3cfdcac3f..960a23e7898f6 100644 --- a/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx +++ b/x-pack/plugins/security_solution/public/common/containers/use_global_time/index.tsx @@ -33,15 +33,17 @@ export const useGlobalTime = (clearAllQuery: boolean = true) => { ); useEffect(() => { - if (isInitializing) { - setIsInitializing(false); - } + setIsInitializing(false); + }, []); + + // This effect must not have any mutable dependencies. Otherwise, the cleanup function gets called before the component unmounts. + useEffect(() => { return () => { if (clearAllQuery) { dispatch(inputsActions.deleteAllQuery({ id: 'global' })); } }; - }, [clearAllQuery, dispatch, isInitializing]); + }, [dispatch, clearAllQuery]); const memoizedReturn = useMemo( () => ({ diff --git a/x-pack/plugins/security_solution/public/common/mock/global_state.ts b/x-pack/plugins/security_solution/public/common/mock/global_state.ts index d252553586a8b..89f4dab31c750 100644 --- a/x-pack/plugins/security_solution/public/common/mock/global_state.ts +++ b/x-pack/plugins/security_solution/public/common/mock/global_state.ts @@ -388,6 +388,7 @@ export const mockGlobalState: State = { }, }, }, + globalUrlParam: {}, /** * These state's are wrapped in `Immutable`, but for compatibility with the overall app architecture, * they are cast to mutable versions here. diff --git a/x-pack/plugins/security_solution/public/common/store/global_url_param/actions.ts b/x-pack/plugins/security_solution/public/common/store/global_url_param/actions.ts new file mode 100644 index 0000000000000..0b3c90e158151 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/store/global_url_param/actions.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import actionCreatorFactory from 'typescript-fsa'; + +const actionCreator = actionCreatorFactory('x-pack/security_solution/local/global_url_param'); + +export const registerUrlParam = actionCreator<{ key: string; initialValue: string | null }>( + 'REGISTER_URL_PARAM' +); + +export const deregisterUrlParam = actionCreator<{ key: string }>('DEREGISTER_URL_PARAM'); + +export const updateUrlParam = actionCreator<{ key: string; value: string | null }>( + 'UPDATE_URL_PARAM' +); diff --git a/x-pack/plugins/security_solution/public/common/store/global_url_param/index.ts b/x-pack/plugins/security_solution/public/common/store/global_url_param/index.ts new file mode 100644 index 0000000000000..1ee5a84c1653d --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/store/global_url_param/index.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 * as globalUrlParamActions from './actions'; +import * as globalUrlParamSelectors from './selectors'; + +export { globalUrlParamActions, globalUrlParamSelectors }; + +export * from './reducer'; diff --git a/x-pack/plugins/security_solution/public/common/store/global_url_param/reducer.test.ts b/x-pack/plugins/security_solution/public/common/store/global_url_param/reducer.test.ts new file mode 100644 index 0000000000000..dbe7dbeb05eab --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/store/global_url_param/reducer.test.ts @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { deregisterUrlParam, registerUrlParam, updateUrlParam } from './actions'; +import { globalUrlParamReducer, initialGlobalUrlParam } from './reducer'; + +const error = jest.spyOn(console, 'error').mockImplementation(() => {}); + +describe('globalUrlParamReducer', () => { + describe('#registerUrlParam', () => { + it('registers the URL param', () => { + const key = 'testKey'; + const initialValue = 'testValue'; + const state = globalUrlParamReducer( + initialGlobalUrlParam, + registerUrlParam({ key, initialValue }) + ); + + expect(state).toEqual({ [key]: initialValue }); + }); + + it('throws exception when a key is register twice', () => { + const key = 'testKey'; + const initialValue = 'testValue'; + const newState = globalUrlParamReducer( + initialGlobalUrlParam, + registerUrlParam({ key, initialValue }) + ); + + globalUrlParamReducer(newState, registerUrlParam({ key, initialValue })); + + expect(error).toHaveBeenCalledWith("Url param key 'testKey' is already being used."); + }); + }); + + describe('#deregisterUrlParam', () => { + it('deregisters the URL param', () => { + const key = 'testKey'; + const initialValue = 'testValue'; + let state = globalUrlParamReducer( + initialGlobalUrlParam, + registerUrlParam({ key, initialValue }) + ); + + expect(state).toEqual({ [key]: initialValue }); + + state = globalUrlParamReducer(initialGlobalUrlParam, deregisterUrlParam({ key })); + + expect(state).toEqual({}); + }); + }); + + describe('#updateUrlParam', () => { + it('updates URL param', () => { + const key = 'testKey'; + const value = 'new test value'; + + const state = globalUrlParamReducer( + { [key]: 'old test value' }, + updateUrlParam({ key, value }) + ); + + expect(state).toEqual({ [key]: value }); + }); + + it("doesn't update the URL param if key isn't registered", () => { + const key = 'testKey'; + const value = 'testValue'; + + const state = globalUrlParamReducer(initialGlobalUrlParam, updateUrlParam({ key, value })); + + expect(state).toEqual(initialGlobalUrlParam); + }); + + it("doesn't update the state if new value is equal to store value", () => { + const key = 'testKey'; + const value = 'testValue'; + const intialState = { [key]: value }; + + const state = globalUrlParamReducer(intialState, updateUrlParam({ key, value })); + + expect(state).toBe(intialState); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/store/global_url_param/reducer.ts b/x-pack/plugins/security_solution/public/common/store/global_url_param/reducer.ts new file mode 100644 index 0000000000000..5e7d91515e9b6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/store/global_url_param/reducer.ts @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { reducerWithInitialState } from 'typescript-fsa-reducers'; +import { registerUrlParam, updateUrlParam, deregisterUrlParam } from './actions'; + +export type GlobalUrlParam = Record; + +export const initialGlobalUrlParam: GlobalUrlParam = {}; + +export const globalUrlParamReducer = reducerWithInitialState(initialGlobalUrlParam) + .case(registerUrlParam, (state, { key, initialValue }) => { + // It doesn't allow the query param to be used twice + if (state[key] !== undefined) { + // eslint-disable-next-line no-console + console.error(`Url param key '${key}' is already being used.`); + return state; + } + + return { + ...state, + [key]: initialValue, + }; + }) + .case(deregisterUrlParam, (state, { key }) => { + const nextState = { ...state }; + + delete nextState[key]; + + return nextState; + }) + .case(updateUrlParam, (state, { key, value }) => { + // Only update the URL after the query param is registered and if the current value is different than the previous value + if (state[key] === undefined || state[key] === value) { + return state; + } + + return { + ...state, + [key]: value, + }; + }) + .build(); diff --git a/x-pack/plugins/security_solution/public/common/store/global_url_param/selectors.ts b/x-pack/plugins/security_solution/public/common/store/global_url_param/selectors.ts new file mode 100644 index 0000000000000..0bff4f0b12d88 --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/store/global_url_param/selectors.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { GlobalUrlParam } from '.'; +import { State } from '../types'; + +export const selectGlobalUrlParam = (state: State): GlobalUrlParam => state.globalUrlParam; diff --git a/x-pack/plugins/security_solution/public/common/store/reducer.ts b/x-pack/plugins/security_solution/public/common/store/reducer.ts index 538657064be90..23da338112fc1 100644 --- a/x-pack/plugins/security_solution/public/common/store/reducer.ts +++ b/x-pack/plugins/security_solution/public/common/store/reducer.ts @@ -24,6 +24,7 @@ import { AppAction } from './actions'; import { initDataView, SourcererModel, SourcererScopeName } from './sourcerer/model'; import { ExperimentalFeatures } from '../../../common/experimental_features'; import { getScopePatternListSelection } from './sourcerer/helpers'; +import { globalUrlParamReducer, initialGlobalUrlParam } from './global_url_param'; export type SubPluginsInitReducer = HostsPluginReducer & UsersPluginReducer & @@ -36,7 +37,7 @@ export type SubPluginsInitReducer = HostsPluginReducer & export const createInitialState = ( pluginsInitState: Omit< SecuritySubPlugins['store']['initialState'], - 'app' | 'dragAndDrop' | 'inputs' | 'sourcerer' + 'app' | 'dragAndDrop' | 'inputs' | 'sourcerer' | 'globalUrlParam' >, { defaultDataView, @@ -100,6 +101,7 @@ export const createInitialState = ( kibanaDataViews: kibanaDataViews.map((dataView) => ({ ...initDataView, ...dataView })), signalIndexName, }, + globalUrlParam: initialGlobalUrlParam, }; return preloadedState; @@ -116,5 +118,6 @@ export const createReducer: ( dragAndDrop: dragAndDropReducer, inputs: inputsReducer, sourcerer: sourcererReducer, + globalUrlParam: globalUrlParamReducer, ...pluginsReducer, }); diff --git a/x-pack/plugins/security_solution/public/common/store/types.ts b/x-pack/plugins/security_solution/public/common/store/types.ts index 226ab872ca2ee..491877830034e 100644 --- a/x-pack/plugins/security_solution/public/common/store/types.ts +++ b/x-pack/plugins/security_solution/public/common/store/types.ts @@ -20,6 +20,7 @@ import { TimelinePluginState } from '../../timelines/store/timeline'; import { NetworkPluginState } from '../../network/store'; import { ManagementPluginState } from '../../management'; import { UsersPluginState } from '../../users/store'; +import { GlobalUrlParam } from './global_url_param'; export type StoreState = HostsPluginState & UsersPluginState & @@ -31,6 +32,7 @@ export type StoreState = HostsPluginState & dragAndDrop: DragAndDropState; inputs: InputsState; sourcerer: SourcererState; + globalUrlParam: GlobalUrlParam; }; /** * The redux `State` type for the Security App. diff --git a/x-pack/plugins/security_solution/public/common/utils/global_query_string/index.test.tsx b/x-pack/plugins/security_solution/public/common/utils/global_query_string/index.test.tsx new file mode 100644 index 0000000000000..8ba1a78d98fcf --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/utils/global_query_string/index.test.tsx @@ -0,0 +1,303 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { renderHook } from '@testing-library/react-hooks'; +import { + useInitializeUrlParam, + useGlobalQueryString, + useSyncGlobalQueryString, + useUpdateUrlParam, +} from '.'; +import { GlobalUrlParam, globalUrlParamActions } from '../../store/global_url_param'; +import { mockHistory } from '../route/mocks'; +import { + createSecuritySolutionStorageMock, + kibanaObservable, + mockGlobalState, + SUB_PLUGINS_REDUCER, + TestProviders, +} from '../../mock'; +import { createStore } from '../../store'; +import { LinkInfo } from '../../links'; +import { SecurityPageName } from '../../../app/types'; + +const mockDispatch = jest.fn(); + +jest.mock('react-redux', () => { + const original = jest.requireActual('react-redux'); + return { + ...original, + useDispatch: () => mockDispatch, + }; +}); + +const mockLocation = jest.fn(); + +jest.mock('react-router-dom', () => ({ + ...jest.requireActual('react-router-dom'), + useHistory: () => mockHistory, + useLocation: () => mockLocation(), +})); + +const defaultLinkInfo: LinkInfo = { + id: SecurityPageName.alerts, + path: '/test', + title: 'test title', + skipUrlState: false, +}; + +const mockLinkInfo = jest.fn().mockResolvedValue(defaultLinkInfo); + +jest.mock('../../links', () => ({ + ...jest.requireActual('../../links'), + getLinkInfo: () => mockLinkInfo(), +})); + +describe('global query string', () => { + const { storage } = createSecuritySolutionStorageMock(); + + const makeStore = (globalUrlParam: GlobalUrlParam) => + createStore( + { + ...mockGlobalState, + globalUrlParam, + }, + SUB_PLUGINS_REDUCER, + kibanaObservable, + storage + ); + + const makeWrapper = (globalUrlParam?: GlobalUrlParam) => { + const wrapper = ({ children }: { children: React.ReactElement }) => ( + {children} + ); + return wrapper; + }; + + beforeAll(() => { + // allow window.location.search to be redefined + Object.defineProperty(window, 'location', { + value: { + search: '?', + }, + }); + }); + beforeEach(() => { + jest.clearAllMocks(); + window.location.search = '?'; + }); + describe('useInitializeUrlParam', () => { + it('calls onInitialize with decoded URL param value', () => { + const urlParamKey = 'testKey'; + mockLocation.mockReturnValue({ search: '?testKey=(test:(value:123))' }); + + const onInitialize = jest.fn(); + + renderHook(() => useInitializeUrlParam(urlParamKey, onInitialize), { + wrapper: makeWrapper(), + }); + + expect(onInitialize).toHaveBeenCalledWith({ test: { value: 123 } }); + }); + + it('deregister during unmount', () => { + const urlParamKey = 'testKey'; + mockLocation.mockReturnValue({ search: "?testKey='123'" }); + + const { unmount } = renderHook(() => useInitializeUrlParam(urlParamKey, () => {}), { + wrapper: makeWrapper(), + }); + unmount(); + + expect(mockDispatch).toBeCalledWith( + globalUrlParamActions.deregisterUrlParam({ + key: urlParamKey, + }) + ); + }); + + it('calls registerUrlParam global URL param action', () => { + const urlParamKey = 'testKey'; + const initialValue = 123; + mockLocation.mockReturnValue({ search: `?testKey=${initialValue}` }); + + renderHook(() => useInitializeUrlParam(urlParamKey, () => {}), { + wrapper: makeWrapper(), + }); + + expect(mockDispatch).toBeCalledWith( + globalUrlParamActions.registerUrlParam({ + key: urlParamKey, + initialValue: initialValue.toString(), + }) + ); + }); + }); + + describe('updateUrlParam', () => { + it('dispatch updateUrlParam action', () => { + const urlParamKey = 'testKey'; + const value = { test: 123 }; + const encodedVaue = '(test:123)'; + + const globalUrlParam = { + [urlParamKey]: 'oldValue', + }; + + const { + result: { current: updateUrlParam }, + } = renderHook(() => useUpdateUrlParam(urlParamKey), { + wrapper: makeWrapper(globalUrlParam), + }); + updateUrlParam(value); + + expect(mockDispatch).toBeCalledWith( + globalUrlParamActions.updateUrlParam({ + key: urlParamKey, + value: encodedVaue, + }) + ); + }); + + it('dispatch updateUrlParam action with null value', () => { + const urlParamKey = 'testKey'; + + const { + result: { current: updateUrlParam }, + } = renderHook(() => useUpdateUrlParam(urlParamKey), { + wrapper: makeWrapper(), + }); + updateUrlParam(null); + + expect(mockDispatch).toBeCalledWith( + globalUrlParamActions.updateUrlParam({ + key: urlParamKey, + value: null, + }) + ); + }); + }); + + describe('useGlobalQueryString', () => { + it('returns global query string', () => { + const store = createStore( + { + ...mockGlobalState, + globalUrlParam: { + testNumber: '123', + testObject: '(test:321)', + testNull: null, + testEmpty: '', + }, + }, + SUB_PLUGINS_REDUCER, + kibanaObservable, + storage + ); + const wrapper = ({ children }: { children: React.ReactElement }) => ( + {children} + ); + + const { result } = renderHook(() => useGlobalQueryString(), { wrapper }); + + expect(result.current).toEqual('testNumber=123&testObject=(test:321)'); + }); + }); + + describe('useSyncGlobalQueryString', () => { + it("doesn't delete other URL params when updating one", async () => { + const urlParamKey = 'testKey'; + const value = '123'; + const globalUrlParam = { + [urlParamKey]: value, + }; + window.location.search = `?firstKey=111&${urlParamKey}=oldValue&lastKey=999`; + + renderHook(() => useSyncGlobalQueryString(), { wrapper: makeWrapper(globalUrlParam) }); + + expect(mockHistory.replace).toHaveBeenCalledWith({ + search: `firstKey=111&${urlParamKey}=${value}&lastKey=999`, + }); + }); + + it('updates URL params', async () => { + const urlParamKey1 = 'testKey1'; + const value1 = '1111'; + const urlParamKey2 = 'testKey2'; + const value2 = '2222'; + const globalUrlParam = { + [urlParamKey1]: value1, + [urlParamKey2]: value2, + }; + window.location.search = `?`; + + renderHook(() => useSyncGlobalQueryString(), { wrapper: makeWrapper(globalUrlParam) }); + + expect(mockHistory.replace).toHaveBeenCalledWith({ + search: `${urlParamKey1}=${value1}&${urlParamKey2}=${value2}`, + }); + }); + + it('deletes URL param when value is null', async () => { + const urlParamKey = 'testKey'; + const globalUrlParam = { + [urlParamKey]: null, + }; + window.location.search = `?${urlParamKey}=oldValue`; + + renderHook(() => useSyncGlobalQueryString(), { wrapper: makeWrapper(globalUrlParam) }); + + expect(mockHistory.replace).toHaveBeenCalledWith({ + search: '', + }); + }); + + it('deletes URL param when page has skipUrlState=true', async () => { + const urlParamKey = 'testKey'; + const value = 'testValue'; + const globalUrlParam = { + [urlParamKey]: value, + }; + window.location.search = `?${urlParamKey}=${value}`; + mockLinkInfo.mockReturnValue({ ...defaultLinkInfo, skipUrlState: true }); + + renderHook(() => useSyncGlobalQueryString(), { wrapper: makeWrapper(globalUrlParam) }); + + expect(mockHistory.replace).toHaveBeenCalledWith({ + search: '', + }); + }); + + it('does not replace URL param when the value does not change', async () => { + const urlParamKey = 'testKey'; + const value = 'testValue'; + const globalUrlParam = { + [urlParamKey]: value, + }; + window.location.search = `?${urlParamKey}=${value}`; + + renderHook(() => useSyncGlobalQueryString(), { wrapper: makeWrapper(globalUrlParam) }); + + expect(mockHistory.replace).not.toHaveBeenCalledWith(); + }); + + it('does not replace URL param when the page doe not exist', async () => { + const urlParamKey = 'testKey'; + const value = 'testValue'; + const globalUrlParam = { + [urlParamKey]: value, + }; + window.location.search = `?${urlParamKey}=oldValue`; + mockLinkInfo.mockReturnValue(undefined); + + renderHook(() => useSyncGlobalQueryString(), { wrapper: makeWrapper(globalUrlParam) }); + + expect(mockHistory.replace).not.toHaveBeenCalledWith(); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/common/utils/global_query_string/index.ts b/x-pack/plugins/security_solution/public/common/utils/global_query_string/index.ts new file mode 100644 index 0000000000000..4d2b266f9622a --- /dev/null +++ b/x-pack/plugins/security_solution/public/common/utils/global_query_string/index.ts @@ -0,0 +1,144 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as H from 'history'; +import { parse, ParsedQuery, stringify } from 'query-string'; +import { useCallback, useEffect, useMemo } from 'react'; + +import { url } from '@kbn/kibana-utils-plugin/public'; +import { isEmpty, pickBy } from 'lodash/fp'; +import { useHistory, useLocation } from 'react-router-dom'; +import { useDispatch } from 'react-redux'; +import { + decodeRisonUrlState, + encodeRisonUrlState, + getParamFromQueryString, + getQueryStringFromLocation, +} from '../../components/url_state/helpers'; +import { useShallowEqualSelector } from '../../hooks/use_selector'; +import { globalUrlParamActions, globalUrlParamSelectors } from '../../store/global_url_param'; +import { useRouteSpy } from '../route/use_route_spy'; +import { getLinkInfo } from '../../links'; + +/** + * Adds urlParamKey and the initial value to redux store. + * + * Please call this hook at the highest possible level of the rendering tree. + * So it is only called when the application starts instead of on every page. + * + * @param urlParamKey Must not change. + * @param onInitialize Called once when initializing. + */ +export const useInitializeUrlParam = ( + urlParamKey: string, + /** + * @param state Decoded URL param value. + */ + onInitialize: (state: State | null) => void +) => { + const dispatch = useDispatch(); + const { search } = useLocation(); + + useEffect(() => { + const initialValue = getParamFromQueryString(getQueryStringFromLocation(search), urlParamKey); + + dispatch( + globalUrlParamActions.registerUrlParam({ + key: urlParamKey, + initialValue: initialValue ?? null, + }) + ); + + // execute consumer initialization + onInitialize(decodeRisonUrlState(initialValue ?? undefined)); + + return () => { + dispatch(globalUrlParamActions.deregisterUrlParam({ key: urlParamKey })); + }; + // eslint-disable-next-line react-hooks/exhaustive-deps -- It must run only once when the application is initializing. + }, []); +}; + +/** + * Updates URL parameters in the url. + * + * Make sure to call `useInitializeUrlParam` before calling this function. + */ +export const useUpdateUrlParam = (urlParamKey: string) => { + const dispatch = useDispatch(); + + const updateUrlParam = useCallback( + (value: State | null) => { + const encodedValue = value !== null ? encodeRisonUrlState(value) : null; + dispatch(globalUrlParamActions.updateUrlParam({ key: urlParamKey, value: encodedValue })); + }, + [dispatch, urlParamKey] + ); + + return updateUrlParam; +}; + +export const useGlobalQueryString = (): string => { + const globalUrlParam = useShallowEqualSelector(globalUrlParamSelectors.selectGlobalUrlParam); + + const globalQueryString = useMemo( + () => encodeQueryString(pickBy((value) => !isEmpty(value), globalUrlParam)), + [globalUrlParam] + ); + + return globalQueryString; +}; + +/** + * - It hides / shows the global query depending on the page. + * - It updates the URL when globalUrlParam store updates. + */ +export const useSyncGlobalQueryString = () => { + const history = useHistory(); + const [{ pageName }] = useRouteSpy(); + const globalUrlParam = useShallowEqualSelector(globalUrlParamSelectors.selectGlobalUrlParam); + + useEffect(() => { + const linkInfo = getLinkInfo(pageName) ?? { skipUrlState: true }; + const params = Object.entries(globalUrlParam).map(([key, value]) => ({ + key, + value: linkInfo.skipUrlState ? null : value, + })); + + if (params.length > 0) { + // window.location.search provides the most updated representation of the url search. + // It prevents unnecessary re-renders which useLocation would create because 'replaceUrlParams' does update the location. + // window.location.search also guarantees that we don't overwrite URL param managed outside react-router. + replaceUrlParams(params, history, window.location.search); + } + }, [globalUrlParam, pageName, history]); +}; + +const encodeQueryString = (urlParams: ParsedQuery): string => + stringify(url.encodeQuery(urlParams), { sort: false, encode: false }); + +const replaceUrlParams = ( + params: Array<{ key: string; value: string | null }>, + history: H.History, + search: string +) => { + const urlParams = parse(search, { sort: false }); + + params.forEach(({ key, value }) => { + if (value == null || value === '') { + delete urlParams[key]; + } else { + urlParams[key] = value; + } + }); + + const newSearch = encodeQueryString(urlParams); + + if (getQueryStringFromLocation(search) !== newSearch) { + history.replace({ search: newSearch }); + } +}; diff --git a/x-pack/plugins/security_solution/public/common/utils/route/helpers.ts b/x-pack/plugins/security_solution/public/common/utils/route/helpers.ts index 1066680621242..9e4740b6f4adf 100644 --- a/x-pack/plugins/security_solution/public/common/utils/route/helpers.ts +++ b/x-pack/plugins/security_solution/public/common/utils/route/helpers.ts @@ -7,11 +7,12 @@ import { noop } from 'lodash/fp'; import { createContext, Dispatch } from 'react'; +import { SecurityPageName } from '../../../app/types'; import { RouteSpyState, RouteSpyAction } from './types'; export const initRouteSpy: RouteSpyState = { - pageName: '', + pageName: SecurityPageName.noPage, detailName: undefined, tabName: undefined, search: '', diff --git a/x-pack/plugins/security_solution/public/common/utils/route/index.test.tsx b/x-pack/plugins/security_solution/public/common/utils/route/index.test.tsx index f450b7d26d2f7..03ccabf5ecce9 100644 --- a/x-pack/plugins/security_solution/public/common/utils/route/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/utils/route/index.test.tsx @@ -13,6 +13,7 @@ import { ManageRoutesSpy } from './manage_spy_routes'; import { SpyRouteComponent } from './spy_routes'; import { useRouteSpy } from './use_route_spy'; import { generateHistoryMock, generateRoutesMock } from './mocks'; +import { SecurityPageName } from '../../../app/types'; const mockUseRouteSpy: jest.Mock = useRouteSpy as jest.Mock; jest.mock('./use_route_spy', () => ({ @@ -81,7 +82,7 @@ describe('Spy Routes', () => { flowTarget: undefined, }, }} - pageName="hosts" + pageName={SecurityPageName.hosts} /> ); @@ -127,7 +128,7 @@ describe('Spy Routes', () => { flowTarget: undefined, }, }} - pageName="hosts" + pageName={SecurityPageName.hosts} /> ); @@ -146,7 +147,7 @@ describe('Spy Routes', () => { path: newPathname, url: newPathname, params: { - pageName: 'hosts', + pageName: SecurityPageName.hosts, detailName: undefined, tabName: HostsTableType.authentications, search: '', @@ -162,7 +163,7 @@ describe('Spy Routes', () => { route: { detailName: undefined, history: mockHistoryValue, - pageName: 'hosts', + pageName: SecurityPageName.hosts, pathName: newPathname, tabName: HostsTableType.authentications, search: '?updated="true"', diff --git a/x-pack/plugins/security_solution/public/common/utils/route/mocks.ts b/x-pack/plugins/security_solution/public/common/utils/route/mocks.ts index 19b9e93fa5476..a904c4485aaa3 100644 --- a/x-pack/plugins/security_solution/public/common/utils/route/mocks.ts +++ b/x-pack/plugins/security_solution/public/common/utils/route/mocks.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { SecurityPageName } from '../../../app/types'; import { RouteSpyState } from './types'; type Action = 'PUSH' | 'POP' | 'REPLACE'; @@ -35,7 +36,7 @@ export const generateHistoryMock = () => ({ export const mockHistory = generateHistoryMock(); export const generateRoutesMock = (): RouteSpyState => ({ - pageName: '', + pageName: SecurityPageName.noPage, detailName: undefined, tabName: undefined, search: '', diff --git a/x-pack/plugins/security_solution/public/common/utils/route/spy_routes.tsx b/x-pack/plugins/security_solution/public/common/utils/route/spy_routes.tsx index ab48ec0b6e006..12ae848a59efa 100644 --- a/x-pack/plugins/security_solution/public/common/utils/route/spy_routes.tsx +++ b/x-pack/plugins/security_solution/public/common/utils/route/spy_routes.tsx @@ -15,7 +15,7 @@ import { useRouteSpy } from './use_route_spy'; import { SecurityPageName } from '../../../../common/constants'; export const SpyRouteComponent = memo< - SpyRouteProps & { location: H.Location; pageName: string | undefined } + SpyRouteProps & { location: H.Location; pageName: SecurityPageName | undefined } >( ({ location: { pathname, search }, diff --git a/x-pack/plugins/security_solution/public/common/utils/route/types.ts b/x-pack/plugins/security_solution/public/common/utils/route/types.ts index 67f59e6eec0d9..7cab113eadf0b 100644 --- a/x-pack/plugins/security_solution/public/common/utils/route/types.ts +++ b/x-pack/plugins/security_solution/public/common/utils/route/types.ts @@ -16,6 +16,7 @@ import { NetworkRouteType } from '../../../network/pages/navigation/types'; import { AdministrationSubTab as AdministrationType } from '../../../management/types'; import { FlowTarget } from '../../../../common/search_strategy'; import { UsersTableType } from '../../../users/store/model'; +import { SecurityPageName } from '../../../app/types'; export type SiemRouteType = | HostsTableType @@ -24,7 +25,7 @@ export type SiemRouteType = | AdministrationType | UsersTableType; export interface RouteSpyState { - pageName: string; + pageName: SecurityPageName; detailName: string | undefined; tabName: SiemRouteType | undefined; search: string; diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.test.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.test.tsx index 37c48487912e0..30f027aa9a619 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.test.tsx @@ -18,12 +18,17 @@ import { const dateNow = new Date('2022-04-08T12:00:00.000Z').valueOf(); const mockDateNow = jest.fn().mockReturnValue(dateNow); Date.now = jest.fn(() => mockDateNow()) as unknown as DateConstructor['now']; +const mockSetQuery = jest.fn(); +const mockDeleteQuery = jest.fn(); jest.mock('../../../../common/containers/use_global_time', () => { return { - useGlobalTime: jest - .fn() - .mockReturnValue({ from: '2022-04-05T12:00:00.000Z', to: '2022-04-08T12:00:00.000Z' }), + useGlobalTime: jest.fn().mockReturnValue({ + from: '2022-04-05T12:00:00.000Z', + to: '2022-04-08T12:00:00.000Z', + setQuery: () => mockSetQuery(), + deleteQuery: () => mockDeleteQuery(), + }), }; }); jest.mock('../../../../common/lib/kibana'); @@ -101,6 +106,36 @@ describe('useCasesByStatus', () => { }); }); + test('it should call setQuery when fetching', async () => { + await act(async () => { + const { waitForNextUpdate } = renderHook( + () => useCasesByStatus({ skip: false }), + { + wrapper: TestProviders, + } + ); + await waitForNextUpdate(); + await waitForNextUpdate(); + expect(mockSetQuery).toHaveBeenCalled(); + }); + }); + + test('it should call deleteQuery when unmounting', async () => { + await act(async () => { + const { waitForNextUpdate, unmount } = renderHook< + UseCasesByStatusProps, + UseCasesByStatusResults + >(() => useCasesByStatus({ skip: false }), { + wrapper: TestProviders, + }); + await waitForNextUpdate(); + + unmount(); + + expect(mockDeleteQuery).toHaveBeenCalled(); + }); + }); + test('skip', async () => { const abortSpy = jest.spyOn(AbortController.prototype, 'abort'); await act(async () => { diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.tsx b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.tsx index 580f91dea6d7d..3f903e1e73803 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_by_status/use_cases_by_status.tsx @@ -6,7 +6,8 @@ */ import { CasesStatus } from '@kbn/cases-plugin/common/ui'; -import { useState, useEffect } from 'react'; +import { useState, useEffect, useMemo } from 'react'; +import uuid from 'uuid'; import { APP_ID } from '../../../../../common/constants'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; import { useKibana } from '../../../../common/lib/kibana'; @@ -28,8 +29,9 @@ export const useCasesByStatus = ({ skip = false }) => { const { services: { cases }, } = useKibana(); - const { to, from } = useGlobalTime(); - + const { to, from, setQuery, deleteQuery } = useGlobalTime(); + // create a unique, but stable (across re-renders) query id + const uniqueQueryId = useMemo(() => `useCaseItems-${uuid.v4()}`, []); const [updatedAt, setUpdatedAt] = useState(Date.now()); const [isLoading, setIsLoading] = useState(true); const [casesCounts, setCasesCounts] = useState(null); @@ -64,6 +66,12 @@ export const useCasesByStatus = ({ skip = false }) => { if (!skip) { fetchCases(); + setQuery({ + id: uniqueQueryId, + inspect: null, + loading: false, + refetch: fetchCases, + }); } if (skip) { @@ -75,8 +83,9 @@ export const useCasesByStatus = ({ skip = false }) => { return () => { isSubscribed = false; abortCtrl.abort(); + deleteQuery({ id: uniqueQueryId }); }; - }, [cases.api.cases, from, skip, to]); + }, [cases.api.cases, from, skip, to, setQuery, deleteQuery, uniqueQueryId]); return { closed: casesCounts?.countClosedCases ?? 0, diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.test.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.test.ts index d112aaac7d5ad..2e2578b0d7294 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.test.ts +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.test.ts @@ -38,8 +38,12 @@ jest.mock('../../../../common/lib/kibana', () => ({ const from = '2020-07-07T08:20:18.966Z'; const to = '2020-07-08T08:20:18.966Z'; +const mockSetQuery = jest.fn(); +const mockDeleteQuery = jest.fn(); -const mockUseGlobalTime = jest.fn().mockReturnValue({ from, to }); +const mockUseGlobalTime = jest + .fn() + .mockReturnValue({ from, to, setQuery: mockSetQuery, deleteQuery: mockDeleteQuery }); jest.mock('../../../../common/containers/use_global_time', () => { return { useGlobalTime: (...props: unknown[]) => mockUseGlobalTime(...props), @@ -100,6 +104,31 @@ describe('useCaseItems', () => { }); }); + test('it should call setQuery when fetching', async () => { + mockCasesApi.mockReturnValue(mockCasesResult); + await act(async () => { + const { waitForNextUpdate } = renderUseCaseItems(); + + await waitForNextUpdate(); + await waitForNextUpdate(); + + expect(mockSetQuery).toHaveBeenCalled(); + }); + }); + + test('it should call deleteQuery when unmounting', async () => { + await act(async () => { + const { waitForNextUpdate, unmount } = renderUseCaseItems(); + + await waitForNextUpdate(); + await waitForNextUpdate(); + + unmount(); + + expect(mockDeleteQuery).toHaveBeenCalled(); + }); + }); + it('should return new updatedAt', async () => { const newDateNow = new Date('2022-04-08T14:00:00.000Z').valueOf(); mockDateNow.mockReturnValue(newDateNow); diff --git a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.ts b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.ts index c0645f263c770..709fe8c125655 100644 --- a/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.ts +++ b/x-pack/plugins/security_solution/public/overview/components/detection_response/cases_table/use_case_items.ts @@ -5,11 +5,12 @@ * 2.0. */ -import { useState, useEffect } from 'react'; +import { useState, useEffect, useMemo } from 'react'; import { CaseStatuses } from '@kbn/cases-plugin/common'; import { Cases } from '@kbn/cases-plugin/common/ui'; +import uuid from 'uuid'; import { APP_ID } from '../../../../../common/constants'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; import { useKibana } from '../../../../common/lib/kibana'; @@ -40,10 +41,12 @@ export const useCaseItems: UseCaseItems = ({ skip }) => { const { services: { cases }, } = useKibana(); - const { to, from } = useGlobalTime(); + const { to, from, setQuery, deleteQuery } = useGlobalTime(); const [isLoading, setIsLoading] = useState(true); const [updatedAt, setUpdatedAt] = useState(Date.now()); const [items, setItems] = useState([]); + // create a unique, but stable (across re-renders) query id + const uniqueQueryId = useMemo(() => `useCaseItems-${uuid.v4()}`, []); useEffect(() => { let isSubscribed = true; @@ -75,6 +78,13 @@ export const useCaseItems: UseCaseItems = ({ skip }) => { if (!skip) { fetchCases(); + + setQuery({ + id: uniqueQueryId, + inspect: null, + loading: false, + refetch: fetchCases, + }); } if (skip) { @@ -86,8 +96,9 @@ export const useCaseItems: UseCaseItems = ({ skip }) => { return () => { isSubscribed = false; abortCtrl.abort(); + deleteQuery({ id: uniqueQueryId }); }; - }, [cases.api.cases, from, skip, to]); + }, [cases.api.cases, from, skip, to, setQuery, deleteQuery, uniqueQueryId]); return { items, isLoading, updatedAt }; }; diff --git a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/__snapshots__/field_renderers.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/__snapshots__/field_renderers.test.tsx.snap index 923509ccfccab..db8bf464ce17e 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/field_renderers/__snapshots__/field_renderers.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/field_renderers/__snapshots__/field_renderers.test.tsx.snap @@ -146,7 +146,7 @@ exports[`Field Renderers #hostIdRenderer it renders correctly against snapshot 1 raspberrypi @@ -201,7 +201,7 @@ exports[`Field Renderers #hostNameRenderer it renders correctly against snapshot raspberrypi diff --git a/x-pack/plugins/security_solution/scripts/endpoint/action_responder/run_in_auto_mode.ts b/x-pack/plugins/security_solution/scripts/endpoint/action_responder/run_in_auto_mode.ts index a765eba2d062d..29b5f66786d08 100644 --- a/x-pack/plugins/security_solution/scripts/endpoint/action_responder/run_in_auto_mode.ts +++ b/x-pack/plugins/security_solution/scripts/endpoint/action_responder/run_in_auto_mode.ts @@ -126,19 +126,5 @@ const parseCommentTokens = (comment: string): CommentTokens => { }; const getActionComment = (action: ActionDetails): string => { - const actionRequest = action.logEntries.find( - (entry) => entry.type === 'fleetAction' || entry.type === 'action' - ); - - if (actionRequest) { - if (actionRequest.type === 'fleetAction') { - return actionRequest.item.data.data.comment ?? ''; - } - - if (actionRequest.type === 'action') { - return actionRequest.item.data.EndpointActions.data.comment ?? ''; - } - } - - return ''; + return action.comment ?? ''; }; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts index 5d024488d4958..ec8466b80f105 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/response_actions.ts @@ -31,6 +31,7 @@ import { GET_RUNNING_PROCESSES_ROUTE, ISOLATE_HOST_ROUTE, UNISOLATE_HOST_ROUTE, + ENDPOINT_ACTIONS_INDEX, } from '../../../../common/endpoint/constants'; import type { EndpointAction, @@ -257,7 +258,7 @@ function responseActionRequestHandler( { - index: `${ENDPOINT_ACTIONS_DS}-default`, + index: ENDPOINT_ACTIONS_INDEX, body: { ...doc, }, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.fixtures.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.fixtures.ts index 67a1b16211098..31b383f2a033e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.fixtures.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/query_builders.fixtures.ts @@ -57,7 +57,7 @@ export const expectedCompleteUnitedIndexQuery = { { range: { 'united.agent.last_checkin': { - lt: 'now-120s', + lt: 'now-300s', }, }, }, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/agent_status.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/agent_status.test.ts index 427ab33d04b1b..2d2f46b410026 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/agent_status.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/metadata/support/agent_status.test.ts @@ -93,7 +93,7 @@ describe('test filtering endpoint hosts by agent status', () => { const status = ['healthy']; const kuery = buildStatusesKuery(status); const expected = - '(not (united.agent.last_checkin < now-120s AND not ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*))) AND not ( ((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) )) AND not ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*))) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*)))'; + '(not (united.agent.last_checkin < now-300s AND not ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*))) AND not ( ((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) )) AND not ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*))) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*)))'; expect(kuery).toEqual(expected); }); @@ -101,7 +101,7 @@ describe('test filtering endpoint hosts by agent status', () => { const status = ['offline']; const kuery = buildStatusesKuery(status); const expected = - '(united.agent.last_checkin < now-120s AND not ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*))) AND not ( ((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) ))'; + '(united.agent.last_checkin < now-300s AND not ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*))) AND not ( ((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) ))'; expect(kuery).toEqual(expected); }); @@ -132,7 +132,7 @@ describe('test filtering endpoint hosts by agent status', () => { const statuses = ['offline', 'unhealthy']; const kuery = buildStatusesKuery(statuses); const expected = - '(united.agent.last_checkin < now-120s AND not ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*))) AND not ( ((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) ) OR (united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*)))'; + '(united.agent.last_checkin < now-300s AND not ((united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*))) AND not ( ((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*) ) OR (united.agent.last_checkin_status:error or united.agent.last_checkin_status:degraded) AND not (((united.agent.upgrade_started_at:*) and not (united.agent.upgraded_at:*)) or (not (united.agent.last_checkin:*)) or (united.agent.unenrollment_started_at:*)))'; expect(kuery).toEqual(expected); }); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.test.ts index 32730fd4d4dbd..4f869bdd5e19b 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.test.ts @@ -39,82 +39,20 @@ describe('When using `getActionDetailsById()', () => { }); it('should return expected output', async () => { + const doc = actionRequests.hits.hits[0]._source; await expect(getActionDetailsById(esClient, '123')).resolves.toEqual({ agents: ['agent-a'], - command: 'isolate', + command: 'unisolate', completedAt: '2022-04-30T16:08:47.449Z', wasSuccessful: true, errors: undefined, id: '123', isCompleted: true, isExpired: false, - logEntries: [ - { - item: { - data: { - '@timestamp': '2022-04-30T16:08:47.449Z', - EndpointActions: { - action_id: '123', - completed_at: '2022-04-30T16:08:47.449Z', - data: { - command: 'unisolate', - comment: '', - }, - started_at: expect.any(String), - }, - agent: { - id: 'agent-a', - }, - error: undefined, - }, - id: expect.any(String), - }, - type: 'response', - }, - { - item: { - data: { - '@timestamp': '2022-04-30T16:08:47.449Z', - action_data: { - command: 'unisolate', - comment: '', - }, - action_id: '123', - agent_id: 'agent-a', - completed_at: '2022-04-30T16:08:47.449Z', - error: '', - started_at: expect.any(String), - }, - id: expect.any(String), - }, - type: 'fleetResponse', - }, - { - item: { - data: { - '@timestamp': '2022-04-27T16:08:47.449Z', - EndpointActions: { - action_id: '123', - data: { - command: 'isolate', - comment: '5wb6pu6kh2xix5i', - }, - expiration: expect.any(String), - input_type: 'endpoint', - type: 'INPUT_ACTION', - }, - agent: { id: 'agent-a' }, - user: { - id: expect.any(String), - }, - error: undefined, - }, - id: expect.any(String), - }, - type: 'action', - }, - ], startedAt: '2022-04-27T16:08:47.449Z', + comment: doc?.EndpointActions.data.comment, + createdBy: doc?.user.id, + parameters: doc?.EndpointActions.data.parameters, }); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.ts index bd1017866da87..ad6cf41976f01 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_details_by_id.ts @@ -23,7 +23,7 @@ import type { LogsEndpointAction, LogsEndpointActionResponse, } from '../../../../common/endpoint/types'; -import { catchAndWrapError, getTimeSortedActionListLogEntries } from '../../utils'; +import { catchAndWrapError } from '../../utils'; import { EndpointError } from '../../../../common/endpoint/errors'; import { NotFoundError } from '../../errors'; import { ACTION_RESPONSE_INDICES, ACTIONS_SEARCH_PAGE_SIZE } from './constants'; @@ -116,15 +116,14 @@ export const getActionDetailsById = async ( agents: normalizedActionRequest.agents, command: normalizedActionRequest.command, startedAt: normalizedActionRequest.createdAt, - logEntries: getTimeSortedActionListLogEntries([ - ...actionRequestsLogEntries, - ...actionResponses, - ]), isCompleted, completedAt, wasSuccessful, errors, isExpired: !isCompleted && normalizedActionRequest.expiration < new Date().toISOString(), + createdBy: normalizedActionRequest.createdBy, + comment: normalizedActionRequest.comment, + parameters: normalizedActionRequest.parameters, }; return actionDetails; diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_list.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_list.test.ts index 048b24e723eac..52370377b3ee4 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_list.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_list.test.ts @@ -42,6 +42,7 @@ describe('When using `getActionList()', () => { }); it('should return expected output', async () => { + const doc = actionRequests.hits.hits[0]._source; await expect(getActionList({ esClient, logger, page: 1, pageSize: 10 })).resolves.toEqual({ page: 0, pageSize: 10, @@ -53,80 +54,17 @@ describe('When using `getActionList()', () => { data: [ { agents: ['agent-a'], - command: 'isolate', + command: 'unisolate', completedAt: '2022-04-30T16:08:47.449Z', wasSuccessful: true, errors: undefined, id: '123', isCompleted: true, isExpired: false, - logEntries: [ - { - item: { - data: { - '@timestamp': '2022-04-30T16:08:47.449Z', - EndpointActions: { - action_id: '123', - completed_at: '2022-04-30T16:08:47.449Z', - data: { - command: 'unisolate', - comment: '', - }, - started_at: expect.any(String), - }, - agent: { - id: 'agent-a', - }, - error: undefined, - }, - id: expect.any(String), - }, - type: 'response', - }, - { - item: { - data: { - '@timestamp': '2022-04-30T16:08:47.449Z', - action_data: { - command: 'unisolate', - comment: '', - }, - action_id: '123', - agent_id: 'agent-a', - completed_at: '2022-04-30T16:08:47.449Z', - error: '', - started_at: expect.any(String), - }, - id: expect.any(String), - }, - type: 'fleetResponse', - }, - { - item: { - data: { - '@timestamp': '2022-04-27T16:08:47.449Z', - EndpointActions: { - action_id: '123', - data: { - command: 'isolate', - comment: '5wb6pu6kh2xix5i', - }, - expiration: expect.any(String), - input_type: 'endpoint', - type: 'INPUT_ACTION', - }, - agent: { id: 'agent-a' }, - user: { - id: expect.any(String), - }, - error: undefined, - }, - id: expect.any(String), - }, - type: 'action', - }, - ], startedAt: '2022-04-27T16:08:47.449Z', + comment: doc?.EndpointActions.data.comment, + createdBy: doc?.user.id, + parameters: doc?.EndpointActions.data.parameters, }, ], total: 1, diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_list.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_list.ts index fccdb4e4adf50..2bbd44db7cc9d 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_list.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_list.ts @@ -9,11 +9,7 @@ import { ElasticsearchClient, Logger } from '@kbn/core/server'; import { CustomHttpRequestError } from '../../../utils/custom_http_request_error'; import type { ActionDetails, ActionListApiResponse } from '../../../../common/endpoint/types'; -import { - getActions, - getActionResponses, - getTimeSortedActionListLogEntries, -} from '../../utils/action_list_helpers'; +import { getActions, getActionResponses } from '../../utils/action_list_helpers'; import { formatEndpointActionResults, @@ -157,10 +153,6 @@ const getActionDetailsList = async ({ // compute action details list for each action id const actionDetails: ActionDetails[] = normalizedActionRequests.map((action) => { - // pick only those actions that match the current action id - const matchedActions = formattedActionRequests.filter( - (categorizedAction) => categorizedAction.item.data.EndpointActions.action_id === action.id - ); // pick only those responses that match the current action id const matchedResponses = categorizedResponses.filter((categorizedResponse) => categorizedResponse.type === 'response' @@ -179,13 +171,14 @@ const getActionDetailsList = async ({ agents: action.agents, command: action.command, startedAt: action.createdAt, - // sort the list by @timestamp in desc order, newest first - logEntries: getTimeSortedActionListLogEntries([...matchedActions, ...matchedResponses]), isCompleted, completedAt, wasSuccessful, errors, isExpired: !isCompleted && action.expiration < new Date().toISOString(), + createdBy: action.createdBy, + comment: action.comment, + parameters: action.parameters, }; }); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/utils.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/utils.test.ts index 469f85e2519a2..4e40a749f6a8a 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/utils.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/utils.test.ts @@ -70,13 +70,14 @@ describe('When using Actions service utilities', () => { ) ).toEqual({ agents: ['6e6796b0-af39-4f12-b025-fcb06db499e5'], - command: 'isolate', + command: 'unisolate', comment: expect.any(String), createdAt: '2022-04-27T16:08:47.449Z', createdBy: 'elastic', expiration: '2022-04-29T16:08:47.449Z', id: '90d62689-f72d-4a05-b5e3-500cad0dc366', type: 'ACTION_REQUEST', + parameters: undefined, }); }); @@ -89,13 +90,14 @@ describe('When using Actions service utilities', () => { ) ).toEqual({ agents: ['90d62689-f72d-4a05-b5e3-500cad0dc366'], - command: 'isolate', + command: 'unisolate', comment: expect.any(String), createdAt: '2022-04-27T16:08:47.449Z', createdBy: 'Shanel', expiration: '2022-05-10T16:08:47.449Z', id: '1d6e6796-b0af-496f-92b0-25fcb06db499', type: 'ACTION_REQUEST', + parameters: undefined, }); }); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/utils.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/utils.ts index 149bafe490f79..d50149e61c1c6 100644 --- a/x-pack/plugins/security_solution/server/endpoint/services/actions/utils.ts +++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/utils.ts @@ -16,11 +16,13 @@ import type { ActivityLogActionResponse, ActivityLogEntry, EndpointAction, + EndpointActionDataParameterTypes, EndpointActionResponse, EndpointActivityLogAction, EndpointActivityLogActionResponse, LogsEndpointAction, LogsEndpointActionResponse, + ResponseActions, } from '../../../../common/endpoint/types'; import { ActivityLogItemTypes } from '../../../../common/endpoint/types'; /** @@ -50,8 +52,9 @@ interface NormalizedActionRequest { agents: string[]; createdBy: string; createdAt: string; - command: string; + command: ResponseActions; comment?: string; + parameters?: EndpointActionDataParameterTypes; } /** @@ -76,6 +79,7 @@ export const mapToNormalizedActionRequest = ( expiration: actionRequest.EndpointActions.expiration, id: actionRequest.EndpointActions.action_id, type, + parameters: actionRequest.EndpointActions.data.parameters, }; } @@ -89,6 +93,7 @@ export const mapToNormalizedActionRequest = ( expiration: actionRequest.expiration, id: actionRequest.action_id, type, + parameters: actionRequest.data.parameters, }; }; diff --git a/x-pack/plugins/security_solution/server/endpoint/utils/action_list_helpers.ts b/x-pack/plugins/security_solution/server/endpoint/utils/action_list_helpers.ts index 6cb752136dffc..1dd4c8ffca7be 100644 --- a/x-pack/plugins/security_solution/server/endpoint/utils/action_list_helpers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/utils/action_list_helpers.ts @@ -14,7 +14,6 @@ import type { TransportResult } from '@elastic/elasticsearch'; import { ENDPOINT_ACTIONS_INDEX } from '../../../common/endpoint/constants'; import type { LogsEndpointAction, - ActionListApiResponse, EndpointActionResponse, LogsEndpointActionResponse, } from '../../../common/endpoint/types'; @@ -27,17 +26,6 @@ const queryOptions = Object.freeze({ ignore: [404], }); -// This is same as the one for audit log -// but we want to deprecate audit log at some point -// thus creating this one for sorting action list log entries -export const getTimeSortedActionListLogEntries = ( - data: ActionListApiResponse['data'][number]['logEntries'] -): ActionListApiResponse['data'][number]['logEntries'] => { - return data.sort((a, b) => - new Date(b.item.data['@timestamp']) > new Date(a.item.data['@timestamp']) ? 1 : -1 - ); -}; - export const getActions = async ({ commands, elasticAgentIds, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts index 526c686961f12..91d92a4d076ef 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/query/create_query_alert_type.test.ts @@ -89,7 +89,7 @@ describe('Custom Query Alerts', () => { params, }); - expect(ruleDataClient.getWriter().bulk).not.toHaveBeenCalled(); + expect((await ruleDataClient.getWriter()).bulk).not.toHaveBeenCalled(); expect(eventsTelemetry.queueTelemetryEvents).not.toHaveBeenCalled(); }); @@ -131,7 +131,7 @@ describe('Custom Query Alerts', () => { await executor({ params }); - expect(ruleDataClient.getWriter().bulk).toHaveBeenCalled(); + expect((await ruleDataClient.getWriter()).bulk).toHaveBeenCalled(); expect(eventsTelemetry.queueTelemetryEvents).toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/synthetics/e2e/config.ts b/x-pack/plugins/synthetics/e2e/config.ts index 8f55b497e61ca..ed71896a8fffe 100644 --- a/x-pack/plugins/synthetics/e2e/config.ts +++ b/x-pack/plugins/synthetics/e2e/config.ts @@ -52,11 +52,11 @@ async function config({ readConfigFile }: FtrConfigProviderContext) { // define custom kibana server args here `--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`, `--elasticsearch.ignoreVersionMismatch=${process.env.CI ? 'false' : 'true'}`, - `--uiSettings.overrides.theme:darkMode=true`, `--elasticsearch.username=kibana_system`, `--elasticsearch.password=changeme`, '--xpack.reporting.enabled=false', `--xpack.uptime.service.manifestUrl=${manifestUrl}`, + `--xpack.uptime.service.showExperimentalLocations=true`, `--xpack.uptime.service.username=${ process.env.SYNTHETICS_REMOTE_ENABLED ? serviceUsername diff --git a/x-pack/plugins/synthetics/e2e/journeys/index.ts b/x-pack/plugins/synthetics/e2e/journeys/index.ts index 1d9fe3e8f33d3..47d77dcafd544 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/index.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/index.ts @@ -5,7 +5,7 @@ * 2.0. */ export * from './alerts'; -// export * from './synthetics'; // TODO: Enable these in a follow up PR +export * from './synthetics'; export * from './data_view_permissions'; export * from './uptime.journey'; export * from './step_duration.journey'; diff --git a/x-pack/plugins/synthetics/e2e/journeys/synthetics/getting_started.journey.ts b/x-pack/plugins/synthetics/e2e/journeys/synthetics/getting_started.journey.ts index acef9e96e7f2d..40035e9c70923 100644 --- a/x-pack/plugins/synthetics/e2e/journeys/synthetics/getting_started.journey.ts +++ b/x-pack/plugins/synthetics/e2e/journeys/synthetics/getting_started.journey.ts @@ -7,7 +7,6 @@ import { journey, step, expect, before, Page } from '@elastic/synthetics'; import { syntheticsAppPageProvider } from '../../page_objects/synthetics_app'; -import { byTestId } from '../utils'; journey(`Getting Started Page`, async ({ page, params }: { page: Page; params: any }) => { const syntheticsApp = syntheticsAppPageProvider({ page, kibanaUrl: params.kibanaUrl }); @@ -16,7 +15,6 @@ journey(`Getting Started Page`, async ({ page, params }: { page: Page; params: a await syntheticsApp.fillFirstMonitorDetails({ url: 'https://www.elastic.co', locations: ['us_central'], - apmServiceName: 'synthetics', }); }; @@ -34,9 +32,13 @@ journey(`Getting Started Page`, async ({ page, params }: { page: Page; params: a expect(await invalid.isVisible()).toBeFalsy(); }); - step('shows validation error on touch', async () => { - await page.click(byTestId('urls-input')); - await page.click(byTestId('comboBoxInput')); + step('enable monitor management', async () => { + await syntheticsApp.enableMonitorManagement(true); + }); + + step('shows validation error on submit', async () => { + await page.click('text=Create monitor'); + expect(await page.isVisible('text=URL is required')).toBeTruthy(); }); @@ -47,6 +49,5 @@ journey(`Getting Started Page`, async ({ page, params }: { page: Page; params: a step('it navigates to details page after saving', async () => { await page.click('text=Dismiss'); - expect(await page.isVisible('text=My first monitor')).toBeTruthy(); }); }); diff --git a/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx b/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx index 1444e4282012f..13ef33a726163 100644 --- a/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx +++ b/x-pack/plugins/synthetics/e2e/page_objects/synthetics_app.tsx @@ -8,14 +8,19 @@ import { Page } from '@elastic/synthetics'; import { loginPageProvider } from './login'; import { utilsPageProvider } from './utils'; +const SIXTY_SEC_TIMEOUT = { + timeout: 60 * 1000, +}; + export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kibanaUrl: string }) { const remoteKibanaUrl = process.env.SYNTHETICS_REMOTE_KIBANA_URL; const remoteUsername = process.env.SYNTHETICS_REMOTE_KIBANA_USERNAME; const remotePassword = process.env.SYNTHETICS_REMOTE_KIBANA_PASSWORD; const isRemote = Boolean(process.env.SYNTHETICS_REMOTE_ENABLED); const basePath = isRemote ? remoteKibanaUrl : kibanaUrl; - const monitorManagement = `${basePath}/app/synthetics/manage-monitors`; + const monitorManagement = `${basePath}/app/synthetics/monitors`; const addMonitor = `${basePath}/app/uptime/add-monitor`; + return { ...loginPageProvider({ page, @@ -40,7 +45,7 @@ export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kib }, async getAddMonitorButton() { - return await this.findByTestSubj('syntheticsAddMonitorBtn'); + return await this.findByText('Create monitor'); }, async navigateToAddMonitor() { @@ -65,23 +70,46 @@ export function syntheticsAppPageProvider({ page, kibanaUrl }: { page: Page; kib async selectLocations({ locations }: { locations: string[] }) { for (let i = 0; i < locations.length; i++) { - await page.click(this.byTestId(`syntheticsServiceLocation--${locations[i]}`)); + await page.click( + this.byTestId(`syntheticsServiceLocation--${locations[i]}`), + SIXTY_SEC_TIMEOUT + ); } }, - async fillFirstMonitorDetails({ - url, - apmServiceName, - locations, - }: { - url: string; - apmServiceName: string; - locations: string[]; - }) { + async fillFirstMonitorDetails({ url, locations }: { url: string; locations: string[] }) { await this.fillByTestSubj('urls-input', url); await page.click(this.byTestId('comboBoxInput')); await this.selectLocations({ locations }); await page.click(this.byTestId('urls-input')); }, + + async enableMonitorManagement(shouldEnable: boolean = true) { + const isEnabled = await this.checkIsEnabled(); + if (isEnabled === shouldEnable) { + return; + } + const [toggle, button] = await Promise.all([ + page.$(this.byTestId('syntheticsEnableSwitch')), + page.$(this.byTestId('syntheticsEnableButton')), + ]); + + if (toggle === null && button === null) { + return null; + } + if (toggle) { + if (isEnabled !== shouldEnable) { + await toggle.click(); + } + } else { + await button?.click(); + } + }, + async checkIsEnabled() { + await page.waitForTimeout(5 * 1000); + const addMonitorBtn = await this.getAddMonitorButton(); + const isDisabled = await addMonitorBtn.isDisabled(); + return !isDisabled; + }, }; } diff --git a/x-pack/plugins/synthetics/e2e/parse_args_params.ts b/x-pack/plugins/synthetics/e2e/parse_args_params.ts index 9e7819bee5d2e..a69cae912dfee 100644 --- a/x-pack/plugins/synthetics/e2e/parse_args_params.ts +++ b/x-pack/plugins/synthetics/e2e/parse_args_params.ts @@ -13,7 +13,7 @@ const { argv } = yargs(process.argv.slice(2)) type: 'boolean', description: 'Start in headless mode', }) - .option('pauseOnError', { + .option('bail', { default: false, type: 'boolean', description: 'Pause on error', diff --git a/x-pack/plugins/synthetics/e2e/synthetics_run.ts b/x-pack/plugins/synthetics/e2e/synthetics_run.ts index 345e153a8c86c..64f4e2a8ba2f6 100644 --- a/x-pack/plugins/synthetics/e2e/synthetics_run.ts +++ b/x-pack/plugins/synthetics/e2e/synthetics_run.ts @@ -10,7 +10,7 @@ import { SyntheticsRunner } from './synthetics_start'; import { argv } from './parse_args_params'; -const { headless, grep, pauseOnError } = argv; +const { headless, grep, bail: pauseOnError } = argv; async function runE2ETests({ readConfigFile }: FtrConfigProviderContext) { const kibanaConfig = await readConfigFile(require.resolve('./config.ts')); diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/pages/synthetics_page_template.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/pages/synthetics_page_template.tsx index 95ec1c5a62975..220aa0f119b2d 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/common/pages/synthetics_page_template.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/common/pages/synthetics_page_template.tsx @@ -69,6 +69,7 @@ export const SyntheticsPageTemplateComponent: React.FC {showLoading && } diff --git a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/page_header/monitors_page_header.tsx b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/page_header/monitors_page_header.tsx index 8dbeaa74d618d..7ac40ae361ae6 100644 --- a/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/page_header/monitors_page_header.tsx +++ b/x-pack/plugins/synthetics/public/apps/synthetics/components/monitors_page/management/page_header/monitors_page_header.tsx @@ -9,6 +9,7 @@ import React, { useContext } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; import { EuiBetaBadge, EuiButton, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { useEnablement } from '../../../../hooks'; import { MONITOR_ADD_ROUTE } from '../../../../../../../common/constants'; import { SyntheticsSettingsContext } from '../../../../contexts/synthetics_settings_context'; @@ -18,6 +19,10 @@ import { BETA_TOOLTIP_MESSAGE } from '../labels'; export const MonitorsPageHeader = () => { const { basePath } = useContext(SyntheticsSettingsContext); + const { + enablement: { isEnabled }, + } = useEnablement(); + return ( @@ -38,6 +43,8 @@ export const MonitorsPageHeader = () => { iconSide="left" iconType="plusInCircleFilled" href={`${basePath}/app/uptime${MONITOR_ADD_ROUTE}`} + isDisabled={!isEnabled} + data-test-subj="syntheticsAddMonitorBtn" > pageHeader={pageHeader} data-test-subj={noDataConfig ? 'data-missing' : undefined} noDataConfig={isMainRoute && !loading ? noDataConfig : undefined} + isPageDataLoaded={Boolean(loading === false && isMainRoute && data)} {...pageTemplateProps} > {showLoading && } diff --git a/x-pack/plugins/synthetics/scripts/base_e2e.js b/x-pack/plugins/synthetics/scripts/base_e2e.js index 9def92fdbb0e3..57076de7d7339 100644 --- a/x-pack/plugins/synthetics/scripts/base_e2e.js +++ b/x-pack/plugins/synthetics/scripts/base_e2e.js @@ -27,6 +27,11 @@ const { argv } = yargs(process.argv.slice(2)) type: 'boolean', description: 'Opens the Synthetics Test Runner', }) + .option('pauseOnError', { + default: false, + type: 'boolean', + description: 'Pause the Synthetics Test Runner on error', + }) .option('kibana-install-dir', { default: '', type: 'string', @@ -44,7 +49,7 @@ const { argv } = yargs(process.argv.slice(2)) }) .help(); -const { server, runner, open, kibanaInstallDir, headless, grep } = argv; +const { server, runner, open, kibanaInstallDir, headless, grep, pauseOnError } = argv; let ftrScript = 'functional_tests'; if (server) { @@ -67,7 +72,7 @@ function executeSyntheticsRunner(dirPath) { ); } else if (runner) { childProcess.execSync( - `node ../../../../scripts/${ftrScript} --config ${config} --kibana-install-dir '${kibanaInstallDir}' --headless ${headless} --grep '${grep}'`, + `node ../../../../scripts/${ftrScript} --config ${config} --kibana-install-dir '${kibanaInstallDir}' --headless ${headless} --bail ${pauseOnError} --grep '${grep}'`, { cwd: dirPath, stdio: 'inherit', diff --git a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts index 4ca5ef8b3004e..7cbd2468811c3 100644 --- a/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts +++ b/x-pack/plugins/synthetics/server/routes/monitor_cruds/add_monitor.ts @@ -14,6 +14,7 @@ import { } from '../../../common/runtime_types'; import { UMRestApiRouteFactory } from '../../legacy_uptime/routes/types'; import { API_URLS } from '../../../common/constants'; +import { DEFAULT_FIELDS } from '../../../common/constants/monitor_defaults'; import { syntheticsMonitorType } from '../../legacy_uptime/lib/saved_objects/synthetics_monitor'; import { validateMonitor } from './monitor_validation'; import { sendTelemetryEvents, formatTelemetryEvent } from '../telemetry/monitor_upgrade_sender'; @@ -29,8 +30,13 @@ export const addSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ }, handler: async ({ request, response, savedObjectsClient, server }): Promise => { const monitor: SyntheticsMonitor = request.body as SyntheticsMonitor; + const monitorType = monitor[ConfigKey.MONITOR_TYPE]; + const monitorWithDefaults = { + ...DEFAULT_FIELDS[monitorType], + ...monitor, + }; - const validationResult = validateMonitor(monitor as MonitorFields); + const validationResult = validateMonitor(monitorWithDefaults as MonitorFields); if (!validationResult.valid) { const { reason: message, details, payload } = validationResult; @@ -43,7 +49,7 @@ export const addSyntheticsMonitorRoute: UMRestApiRouteFactory = () => ({ newMonitor = await savedObjectsClient.create( syntheticsMonitorType, formatSecrets({ - ...monitor, + ...monitorWithDefaults, revision: 1, }) ); diff --git a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts index 92d598192844b..207945d4e95d1 100644 --- a/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts +++ b/x-pack/plugins/synthetics/server/synthetics_service/normalizers/browser.ts @@ -101,7 +101,7 @@ export const normalizeProjectMonitor = ({ [ConfigKey.ORIGINAL_SPACE]: namespace || defaultFields[ConfigKey.ORIGINAL_SPACE], [ConfigKey.CUSTOM_HEARTBEAT_ID]: `${monitor.id}-${projectId}-${namespace}`, [ConfigKey.TIMEOUT]: null, - [ConfigKey.ENABLED]: monitor.enabled || defaultFields[ConfigKey.ENABLED], + [ConfigKey.ENABLED]: monitor.enabled ?? defaultFields[ConfigKey.ENABLED], }; return { ...DEFAULT_FIELDS[DataStream.BROWSER], diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index f410b448c6075..fb00f7dd69b40 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -9990,22 +9990,11 @@ "xpack.crossClusterReplication.unfollowLeaderIndex.confirmModal.singleUnfollowDescription": "L'index suiveur sera converti en index standard. Il ne sera plus affiché dans la réplication inter-clusters, mais vous pouvez le gérer dans la page Gestion des index. Cette opération ne peut pas être annulée.", "xpack.crossClusterReplication.unfollowLeaderIndex.confirmModal.unfollowMultipleTitle": "Annuler le suivi de {count} index meneurs ?", "xpack.crossClusterReplication.unfollowLeaderIndex.confirmModal.unfollowSingleTitle": "Annuler le suivi de l'index meneur \"{name}\" ?", - "xpack.csp.active_frameworks": "Frameworks actifs", "xpack.csp.benchmarks.integrationsNotFoundForNameMessage": " pour \"{name}\"", "xpack.csp.benchmarks.integrationsNotFoundMessage": "Aucune intégration Benchmark trouvée", "xpack.csp.benchmarks.integrationsNotFoundWithFiltersMessage": "Nous n'avons trouvé aucune intégration Benchmark avec les filtres ci-dessus.", "xpack.csp.benchmarks.searchPlaceholder": "par exemple, le nom d'un benchmark", "xpack.csp.benchmarks.totalIntegrationsCountMessage": "Affichage de {pageCount} sur {totalCount, plural, one {# intégration} other {# intégrations}}", - "xpack.csp.cloud_posture": "Niveau du cloud", - "xpack.csp.cloud_posture_score": "Score du niveau du cloud", - "xpack.csp.coming_soon": "Bientôt disponible", - "xpack.csp.compliance_score": "Score de conformité", - "xpack.csp.compliance_trend": "Tendance de conformité", - "xpack.csp.complianceDashboard.failedFindingsChartLabel": "Échec des résultats", - "xpack.csp.complianceDashboard.noDataConfig.actionDescription": "Vous pouvez essayer de récupérer vos données", - "xpack.csp.complianceDashboard.noDataConfig.actionTitle": "Réessayer", - "xpack.csp.complianceDashboard.noDataConfig.pageTitle": "Tableau de bord de conformité de la sécurité du cloud", - "xpack.csp.complianceDashboard.noDataConfig.solutionNameLabel": "Niveau de sécurité du cloud", "xpack.csp.cspPageTemplate.defaultNoDataConfig.pageTitle": "Aucune donnée trouvée", "xpack.csp.cspPageTemplate.defaultNoDataConfig.solutionNameLabel": "Niveau de sécurité du cloud", "xpack.csp.cspPageTemplate.packageNotInstalled.buttonLabel": "Ajouter une intégration CIS", @@ -10013,9 +10002,6 @@ "xpack.csp.cspPageTemplate.packageNotInstalled.pageTitle": "Installer l'intégration pour commencer", "xpack.csp.cspPageTemplate.packageNotInstalled.solutionNameLabel": "Niveau de sécurité du cloud", "xpack.csp.cspSettings.rules": "Règles de sécurité du CSP - ", - "xpack.csp.error": "Erreur", - "xpack.csp.failed": "Échoué", - "xpack.csp.findings": "Résultats", "xpack.csp.findings.agentLabel": "Agent", "xpack.csp.findings.architectureLabel": "Architecture", "xpack.csp.findings.auditLabel": "Audit", @@ -10061,13 +10047,9 @@ "xpack.csp.findings.typeLabel": "Type", "xpack.csp.findings.uidLabel": "UID", "xpack.csp.findings.versionLabel": "Version", - "xpack.csp.open_cases": "Cas ouverts", "xpack.csp.pageTemplate.errorDetails.errorBodyTitle": "{body}", "xpack.csp.pageTemplate.errorDetails.errorCodeTitle": "{error} {statusCode}", "xpack.csp.pageTemplate.loadErrorMessage": "Nous n'avons pas pu récupérer vos données sur le niveau de sécurité du cloud.", - "xpack.csp.passed": "Approuvé", - "xpack.csp.posture_score": "Score du niveau", - "xpack.csp.posture_score_trend": "Tendance du score du niveau", "xpack.csp.rules.activateAllButtonLabel": "Activer {count, plural, one {# règle} other {# règles}}", "xpack.csp.rules.bulkActionsButtonLabel": "Actions groupées", "xpack.csp.rules.cancelButtonLabel": "Annuler", @@ -10090,10 +10072,6 @@ "xpack.csp.rules.tableHeader.lastModificationLabel": "Dernière modification de l'intégration {timeAgo} ", "xpack.csp.rules.unknownErrorMessage": "Erreur inconnue", "xpack.csp.rules.updateFailedMessage": "Échec de la mise à jour", - "xpack.csp.status": "STATUT", - "xpack.csp.total_failures": "Total des échecs", - "xpack.csp.total_resources": "Total des ressources", - "xpack.csp.view_all_failed_findings": "Afficher tous les échecs des résultats", "xpack.dashboard.components.DashboardDrilldownConfig.chooseDestinationDashboard": "Choisir le tableau de bord de destination", "xpack.dashboard.components.DashboardDrilldownConfig.openInNewTab": "Ouvrir le tableau de bord dans un nouvel onglet", "xpack.dashboard.components.DashboardDrilldownConfig.useCurrentDateRange": "Utiliser la plage de dates du tableau de bord d'origine", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index c4bc0ad2f8620..2fabe19d88ba5 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10088,22 +10088,11 @@ "xpack.crossClusterReplication.unfollowLeaderIndex.confirmModal.singleUnfollowDescription": "フォロワーインデックスは標準のインデックスに変換されます。今後クラスター横断レプリケーションには表示されませんが、インデックス管理で管理できます。この操作は元に戻すことができません。", "xpack.crossClusterReplication.unfollowLeaderIndex.confirmModal.unfollowMultipleTitle": "{count} 件のリーダーインデックスのフォローを解除しますか?", "xpack.crossClusterReplication.unfollowLeaderIndex.confirmModal.unfollowSingleTitle": "「{name}」のリーダーインデックスのフォローを解除しますか?", - "xpack.csp.active_frameworks": "アクティブなフレームワーク", "xpack.csp.benchmarks.integrationsNotFoundForNameMessage": " \"{name}\"", "xpack.csp.benchmarks.integrationsNotFoundMessage": "ベンチマーク統合が見つかりません", "xpack.csp.benchmarks.integrationsNotFoundWithFiltersMessage": "上記のフィルターでベンチマーク統合が見つかりませんでした。", "xpack.csp.benchmarks.searchPlaceholder": "例:ベンチマーク名", "xpack.csp.benchmarks.totalIntegrationsCountMessage": "{pageCount}/{totalCount, plural, other {#個の統合}}を表示しています", - "xpack.csp.cloud_posture": "クラウド態勢", - "xpack.csp.cloud_posture_score": "クラウド態勢スコア", - "xpack.csp.coming_soon": "まもなくリリース", - "xpack.csp.compliance_score": "コンプライアンススコア", - "xpack.csp.compliance_trend": "コンプライアンス傾向", - "xpack.csp.complianceDashboard.failedFindingsChartLabel": "失敗した調査結果", - "xpack.csp.complianceDashboard.noDataConfig.actionDescription": "データの再取得を試行できます", - "xpack.csp.complianceDashboard.noDataConfig.actionTitle": "再試行", - "xpack.csp.complianceDashboard.noDataConfig.pageTitle": "クラウドセキュリティコンプライアンスダッシュボード", - "xpack.csp.complianceDashboard.noDataConfig.solutionNameLabel": "クラウドセキュリティ態勢", "xpack.csp.cspPageTemplate.defaultNoDataConfig.pageTitle": "データが見つかりません", "xpack.csp.cspPageTemplate.defaultNoDataConfig.solutionNameLabel": "クラウドセキュリティ態勢", "xpack.csp.cspPageTemplate.packageNotInstalled.buttonLabel": "CIS統合を追加", @@ -10111,9 +10100,6 @@ "xpack.csp.cspPageTemplate.packageNotInstalled.pageTitle": "開始するには統合をインストールしてください", "xpack.csp.cspPageTemplate.packageNotInstalled.solutionNameLabel": "クラウドセキュリティ態勢", "xpack.csp.cspSettings.rules": "CSPセキュリティルール - ", - "xpack.csp.error": "エラー", - "xpack.csp.failed": "失敗", - "xpack.csp.findings": "調査結果", "xpack.csp.findings.agentLabel": "エージェント", "xpack.csp.findings.architectureLabel": "アーキテクチャー", "xpack.csp.findings.auditLabel": "監査", @@ -10159,13 +10145,9 @@ "xpack.csp.findings.typeLabel": "型", "xpack.csp.findings.uidLabel": "UID", "xpack.csp.findings.versionLabel": "バージョン", - "xpack.csp.open_cases": "ケースを開く", "xpack.csp.pageTemplate.errorDetails.errorBodyTitle": "{body}", "xpack.csp.pageTemplate.errorDetails.errorCodeTitle": "{error} {statusCode}", "xpack.csp.pageTemplate.loadErrorMessage": "クラウドセキュリティ態勢データを取得できませんでした", - "xpack.csp.passed": "合格", - "xpack.csp.posture_score": "態勢スコア", - "xpack.csp.posture_score_trend": "態勢スコア傾向", "xpack.csp.rules.activateAllButtonLabel": "{count, plural, other {#個のルール}}をアクティブ化", "xpack.csp.rules.activatedLabel": "有効化", "xpack.csp.rules.bulkActionsButtonLabel": "一括アクション", @@ -10191,10 +10173,6 @@ "xpack.csp.rules.tableHeader.lastModificationLabel": "統合{timeAgo}の前回変更日 ", "xpack.csp.rules.unknownErrorMessage": "不明なエラー", "xpack.csp.rules.updateFailedMessage": "更新が失敗しました", - "xpack.csp.status": "ステータス", - "xpack.csp.total_failures": "合計失敗数", - "xpack.csp.total_resources": "合計リソース数", - "xpack.csp.view_all_failed_findings": "すべてのフィールド調査結果を表示", "xpack.dashboard.components.DashboardDrilldownConfig.chooseDestinationDashboard": "対象ダッシュボードを選択", "xpack.dashboard.components.DashboardDrilldownConfig.openInNewTab": "新しいタブでダッシュボードを開く", "xpack.dashboard.components.DashboardDrilldownConfig.useCurrentDateRange": "元のダッシュボードから日付範囲を使用", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 3cf3a38b00848..9706cc5dd6f68 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -10104,22 +10104,11 @@ "xpack.crossClusterReplication.unfollowLeaderIndex.confirmModal.singleUnfollowDescription": "Follower 索引将转换为标准索引。它不再显示在跨集群复制中,但您可以在“索引管理”中管理它。此操作无法撤消。", "xpack.crossClusterReplication.unfollowLeaderIndex.confirmModal.unfollowMultipleTitle": "取消跟随 {count} 个 Leader 索引?", "xpack.crossClusterReplication.unfollowLeaderIndex.confirmModal.unfollowSingleTitle": "取消跟随“{name}”的 Leader 索引?", - "xpack.csp.active_frameworks": "活动框架", "xpack.csp.benchmarks.integrationsNotFoundForNameMessage": " 对于“{name}”", "xpack.csp.benchmarks.integrationsNotFoundMessage": "找不到基准集成", "xpack.csp.benchmarks.integrationsNotFoundWithFiltersMessage": "使用上述筛选,我们无法找到任何基准集成。", "xpack.csp.benchmarks.searchPlaceholder": "例如,基准名称", "xpack.csp.benchmarks.totalIntegrationsCountMessage": "正在显示 {pageCount}/{totalCount, plural, other {# 个集成}}", - "xpack.csp.cloud_posture": "云态势", - "xpack.csp.cloud_posture_score": "云态势分数", - "xpack.csp.coming_soon": "即将推出", - "xpack.csp.compliance_score": "合规性分数", - "xpack.csp.compliance_trend": "合规性趋势", - "xpack.csp.complianceDashboard.failedFindingsChartLabel": "失败的结果", - "xpack.csp.complianceDashboard.noDataConfig.actionDescription": "您可以尝试重新提取数据", - "xpack.csp.complianceDashboard.noDataConfig.actionTitle": "重试", - "xpack.csp.complianceDashboard.noDataConfig.pageTitle": "云安全合规性仪表板", - "xpack.csp.complianceDashboard.noDataConfig.solutionNameLabel": "云安全态势", "xpack.csp.cspPageTemplate.defaultNoDataConfig.pageTitle": "未找到任何数据", "xpack.csp.cspPageTemplate.defaultNoDataConfig.solutionNameLabel": "云安全态势", "xpack.csp.cspPageTemplate.packageNotInstalled.buttonLabel": "添加 CIS 集成", @@ -10127,9 +10116,6 @@ "xpack.csp.cspPageTemplate.packageNotInstalled.pageTitle": "安装集成以开始", "xpack.csp.cspPageTemplate.packageNotInstalled.solutionNameLabel": "云安全态势", "xpack.csp.cspSettings.rules": "CSP 安全规则 - ", - "xpack.csp.error": "错误", - "xpack.csp.failed": "失败", - "xpack.csp.findings": "结果", "xpack.csp.findings.agentLabel": "代理", "xpack.csp.findings.architectureLabel": "架构", "xpack.csp.findings.auditLabel": "审计", @@ -10175,13 +10161,9 @@ "xpack.csp.findings.typeLabel": "类型", "xpack.csp.findings.uidLabel": "UID", "xpack.csp.findings.versionLabel": "版本", - "xpack.csp.open_cases": "未结案例", "xpack.csp.pageTemplate.errorDetails.errorBodyTitle": "{body}", "xpack.csp.pageTemplate.errorDetails.errorCodeTitle": "{error} {statusCode}", "xpack.csp.pageTemplate.loadErrorMessage": "我们无法提取您的云安全态势数据", - "xpack.csp.passed": "通过", - "xpack.csp.posture_score": "态势分数", - "xpack.csp.posture_score_trend": "态势分数趋势", "xpack.csp.rules.activateAllButtonLabel": "激活 {count, plural, other {# 个规则}}", "xpack.csp.rules.activatedLabel": "已激活", "xpack.csp.rules.bulkActionsButtonLabel": "批处理操作", @@ -10207,10 +10189,6 @@ "xpack.csp.rules.tableHeader.lastModificationLabel": "上次修改集成 {timeAgo} ", "xpack.csp.rules.unknownErrorMessage": "未知错误", "xpack.csp.rules.updateFailedMessage": "更新失败", - "xpack.csp.status": "状态", - "xpack.csp.total_failures": "失败总数", - "xpack.csp.total_resources": "资源总数", - "xpack.csp.view_all_failed_findings": "查看所有失败的结果", "xpack.dashboard.components.DashboardDrilldownConfig.chooseDestinationDashboard": "选择目标仪表板", "xpack.dashboard.components.DashboardDrilldownConfig.openInNewTab": "在新选项卡中打开仪表板", "xpack.dashboard.components.DashboardDrilldownConfig.useCurrentDateRange": "使用源仪表板的日期范围", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx index 13adb84d5039b..4a64ebba43f68 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/index.tsx @@ -40,9 +40,6 @@ export const RuleTagFilter = suspendedComponentWithProps( export const RuleStatusFilter = suspendedComponentWithProps( lazy(() => import('./rules_list/components/rule_status_filter')) ); -export const RuleTagBadge = suspendedComponentWithProps( - lazy(() => import('./rules_list/components/rule_tag_badge')) -); export const RuleEventLogList = suspendedComponentWithProps( lazy(() => import('./rule_details/components/rule_event_log_list')) ); @@ -52,3 +49,6 @@ export const RulesList = suspendedComponentWithProps( export const RulesListNotifyBadge = suspendedComponentWithProps( lazy(() => import('./rules_list/components/rules_list_notify_badge')) ); +export const RuleTagBadge = suspendedComponentWithProps( + lazy(() => import('./rules_list/components/rule_tag_badge')) +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.test.tsx index 606d60ff6bfeb..a1d3b20206dbd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.test.tsx @@ -56,4 +56,12 @@ describe('RuleTagBadge', () => { expect(onClickMock).toHaveBeenCalledTimes(2); }); + + it('shows all the tags without clicking when passing "spread" props with "true"', () => { + const wrapper = mountWithIntl(); + expect(wrapper.find('[data-test-subj="tagsOutPopover"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="ruleTagBadgeItem-a"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="ruleTagBadgeItem-b"]').exists()).toBeTruthy(); + expect(wrapper.find('[data-test-subj="ruleTagBadgeItem-c"]').exists()).toBeTruthy(); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.tsx index c7da398d14403..4c968dde75811 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rule_tag_badge.tsx @@ -7,7 +7,7 @@ import React, { useMemo } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiPopover, EuiBadge, EuiPopoverTitle } from '@elastic/eui'; +import { EuiPopover, EuiBadge, EuiPopoverTitle, EuiFlexGroup } from '@elastic/eui'; const tagTitle = i18n.translate( 'xpack.triggersActionsUI.sections.rules_list.rules_tag_badge.tagTitle', @@ -16,32 +16,43 @@ const tagTitle = i18n.translate( } ); -export interface RuleTagBadgeProps { +export type RuleTagBadgeOptions = 'tagsOutPopover' | 'default'; + +export interface RuleTagBadgeBasicOptions { isOpen: boolean; - tags: string[]; onClick: React.MouseEventHandler; onClose: () => void; +} + +export interface RuleTagBadgeCommonProps { + tagsOutPopover?: boolean; + tags: string[]; badgeDataTestSubj?: string; titleDataTestSubj?: string; tagItemDataTestSubj?: (tag: string) => string; } +export type RuleTagBadgeProps = T extends 'default' + ? RuleTagBadgeBasicOptions & RuleTagBadgeCommonProps + : T extends 'tagsOutPopover' + ? RuleTagBadgeCommonProps + : never; + const containerStyle = { width: '300px', }; const getTagItemDataTestSubj = (tag: string) => `ruleTagBadgeItem-${tag}`; -export const RuleTagBadge = (props: RuleTagBadgeProps) => { +export const RuleTagBadge = (props: RuleTagBadgeProps) => { const { - isOpen = false, + tagsOutPopover = false, tags = [], - onClick, - onClose, badgeDataTestSubj = 'ruleTagBadge', titleDataTestSubj = 'ruleTagPopoverTitle', tagItemDataTestSubj = getTagItemDataTestSubj, } = props; + const { isOpen, onClose, onClick } = props as RuleTagBadgeBasicOptions; const badge = useMemo(() => { return ( @@ -59,7 +70,7 @@ export const RuleTagBadge = (props: RuleTagBadgeProps) => { {tags.length} ); - }, [tags, badgeDataTestSubj, onClick]); + }, [badgeDataTestSubj, onClick, tags.length]); const tagBadges = useMemo( () => @@ -76,9 +87,22 @@ export const RuleTagBadge = (props: RuleTagBadgeProps) => { )), [tags, tagItemDataTestSubj] ); + if (tagsOutPopover) { + return ( + // Put 0 to fix negative left margin value. + + {tagBadges} + + ); + } return ( - + {tagTitle}
{tagBadges}
diff --git a/x-pack/plugins/triggers_actions_ui/public/common/get_rule_tag_badge.tsx b/x-pack/plugins/triggers_actions_ui/public/common/get_rule_tag_badge.tsx index dc889402ab3c5..aa00bb9a2ac6d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/get_rule_tag_badge.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/common/get_rule_tag_badge.tsx @@ -6,9 +6,13 @@ */ import React from 'react'; +import { + RuleTagBadgeProps, + RuleTagBadgeOptions, +} from '../application/sections/rules_list/components/rule_tag_badge'; import { RuleTagBadge } from '../application/sections'; -import type { RuleTagBadgeProps } from '../application/sections/rules_list/components/rule_tag_badge'; - -export const getRuleTagBadgeLazy = (props: RuleTagBadgeProps) => { +export const getRuleTagBadgeLazy = ( + props: RuleTagBadgeProps +) => { return ; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/mocks.ts b/x-pack/plugins/triggers_actions_ui/public/mocks.ts index e05c50b71e0ed..37efdf36eeaed 100644 --- a/x-pack/plugins/triggers_actions_ui/public/mocks.ts +++ b/x-pack/plugins/triggers_actions_ui/public/mocks.ts @@ -21,6 +21,8 @@ import { RuleTypeModel, AlertsTableProps, AlertsTableConfigurationRegistry, + RuleTagBadgeOptions, + RuleTagBadgeProps, } from './types'; import { getAlertsTableLazy } from './common/get_alerts_table'; import { getRuleStatusDropdownLazy } from './common/get_rule_status_dropdown'; @@ -90,8 +92,8 @@ function createStartMock(): TriggersAndActionsUIPublicPluginStart { getRuleStatusFilter: (props) => { return getRuleStatusFilterLazy(props); }, - getRuleTagBadge: (props) => { - return getRuleTagBadgeLazy(props); + getRuleTagBadge: (props: RuleTagBadgeProps) => { + return getRuleTagBadgeLazy(props); }, getRuleEventLogList: (props) => { return getRuleEventLogListLazy(props); diff --git a/x-pack/plugins/triggers_actions_ui/public/plugin.ts b/x-pack/plugins/triggers_actions_ui/public/plugin.ts index a572a0c15030b..f830488a1ecdb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/plugin.ts +++ b/x-pack/plugins/triggers_actions_ui/public/plugin.ts @@ -54,6 +54,7 @@ import type { RuleTagFilterProps, RuleStatusFilterProps, RuleTagBadgeProps, + RuleTagBadgeOptions, RuleEventLogListProps, RulesListNotifyBadgeProps, AlertsTableConfigurationRegistry, @@ -98,7 +99,9 @@ export interface TriggersAndActionsUIPublicPluginStart { getRuleStatusDropdown: (props: RuleStatusDropdownProps) => ReactElement; getRuleTagFilter: (props: RuleTagFilterProps) => ReactElement; getRuleStatusFilter: (props: RuleStatusFilterProps) => ReactElement; - getRuleTagBadge: (props: RuleTagBadgeProps) => ReactElement; + getRuleTagBadge: ( + props: RuleTagBadgeProps + ) => ReactElement>; getRuleEventLogList: (props: RuleEventLogListProps) => ReactElement; getRulesListNotifyBadge: ( props: RulesListNotifyBadgeProps @@ -305,7 +308,7 @@ export class Plugin getRuleStatusFilter: (props: RuleStatusFilterProps) => { return getRuleStatusFilterLazy(props); }, - getRuleTagBadge: (props: RuleTagBadgeProps) => { + getRuleTagBadge: (props: RuleTagBadgeProps) => { return getRuleTagBadgeLazy(props); }, getRuleEventLogList: (props: RuleEventLogListProps) => { diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index d88567adf5d40..7d1e1f7bbadf6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -50,7 +50,10 @@ import { TypeRegistry } from './application/type_registry'; import type { ComponentOpts as RuleStatusDropdownProps } from './application/sections/rules_list/components/rule_status_dropdown'; import type { RuleTagFilterProps } from './application/sections/rules_list/components/rule_tag_filter'; import type { RuleStatusFilterProps } from './application/sections/rules_list/components/rule_status_filter'; -import type { RuleTagBadgeProps } from './application/sections/rules_list/components/rule_tag_badge'; +import type { + RuleTagBadgeProps, + RuleTagBadgeOptions, +} from './application/sections/rules_list/components/rule_tag_badge'; import type { RuleEventLogListProps } from './application/sections/rule_details/components/rule_event_log_list'; import type { CreateConnectorFlyoutProps } from './application/sections/action_connector_form/create_connector_flyout'; import type { EditConnectorFlyoutProps } from './application/sections/action_connector_form/edit_connector_flyout'; @@ -90,6 +93,7 @@ export type { RuleTagFilterProps, RuleStatusFilterProps, RuleTagBadgeProps, + RuleTagBadgeOptions, RuleEventLogListProps, CreateConnectorFlyoutProps, EditConnectorFlyoutProps, diff --git a/x-pack/plugins/ux/e2e/journeys/index.ts b/x-pack/plugins/ux/e2e/journeys/index.ts index 36976caaa458d..9e50945c4e09f 100644 --- a/x-pack/plugins/ux/e2e/journeys/index.ts +++ b/x-pack/plugins/ux/e2e/journeys/index.ts @@ -9,3 +9,4 @@ export * from './core_web_vitals'; export * from './url_ux_query.journey'; export * from './ux_js_errors.journey'; export * from './ux_client_metrics.journey'; +export * from './ux_long_task_metric_journey'; diff --git a/x-pack/plugins/ux/e2e/journeys/ux_client_metrics.journey.ts b/x-pack/plugins/ux/e2e/journeys/ux_client_metrics.journey.ts index 7d0d426d5fd0d..a8abad60e3e5c 100644 --- a/x-pack/plugins/ux/e2e/journeys/ux_client_metrics.journey.ts +++ b/x-pack/plugins/ux/e2e/journeys/ux_client_metrics.journey.ts @@ -43,7 +43,7 @@ journey('UX ClientMetrics', async ({ page, params }) => { }); await loginToKibana({ page, - user: { username: 'viewer_user', password: 'changeme' }, + user: { username: 'viewer', password: 'changeme' }, }); }); diff --git a/x-pack/plugins/ux/e2e/journeys/ux_long_task_metric_journey.ts b/x-pack/plugins/ux/e2e/journeys/ux_long_task_metric_journey.ts new file mode 100644 index 0000000000000..ba4cb014379e1 --- /dev/null +++ b/x-pack/plugins/ux/e2e/journeys/ux_long_task_metric_journey.ts @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { journey, step, before, expect } from '@elastic/synthetics'; +import { UXDashboardDatePicker } from '../page_objects/date_picker'; +import { byTestId, loginToKibana, waitForLoadingToFinish } from './utils'; + +const longestMetric = 'uxLongestTask'; +const countMetric = 'uxLongTaskCount'; +const sumMetric = 'uxSumLongTask'; + +const longestMetricValue = `Longest long task duration + +237 ms`; +const countMetricValue = `No. of long tasks + +3`; +const sumMetricValue = `Total long tasks duration + +428 ms`; + +journey('UX LongTaskMetrics', async ({ page, params }) => { + before(async () => { + await waitForLoadingToFinish({ page }); + }); + + const queryParams = { + percentile: '50', + rangeFrom: '2020-05-18T11:51:00.000Z', + rangeTo: '2021-10-30T06:37:15.536Z', + }; + const queryString = new URLSearchParams(queryParams).toString(); + + const baseUrl = `${params.kibanaUrl}/app/ux`; + + step('Go to UX Dashboard', async () => { + await page.goto(`${baseUrl}?${queryString}`, { + waitUntil: 'networkidle', + }); + await loginToKibana({ + page, + user: { username: 'viewer', password: 'changeme' }, + }); + }); + + step('Set date range', async () => { + const datePickerPage = new UXDashboardDatePicker(page); + await datePickerPage.setDefaultE2eRange(); + }); + + step('Confirm metrics values', async () => { + // Wait until chart data is loaded + page.waitForLoadState('networkidle'); + // wait for first metric to be shown + page.waitForSelector(`text="237 ms"`); + + let metric = await ( + await page.waitForSelector(byTestId(longestMetric)) + ).innerText(); + + expect(metric).toBe(longestMetricValue); + + metric = await ( + await page.waitForSelector(byTestId(countMetric)) + ).innerText(); + + expect(metric).toBe(countMetricValue); + + metric = await ( + await page.waitForSelector(byTestId(sumMetric)) + ).innerText(); + + expect(metric).toBe(sumMetricValue); + }); +}); diff --git a/x-pack/plugins/ux/e2e/synthetics_run.ts b/x-pack/plugins/ux/e2e/synthetics_run.ts index 08db83f4fe659..208428f01344d 100644 --- a/x-pack/plugins/ux/e2e/synthetics_run.ts +++ b/x-pack/plugins/ux/e2e/synthetics_run.ts @@ -9,7 +9,7 @@ import { argv } from '@kbn/synthetics-plugin/e2e/parse_args_params'; import { SyntheticsRunner } from '@kbn/synthetics-plugin/e2e/synthetics_start'; import path from 'path'; -const { headless, grep, pauseOnError } = argv; +const { headless, grep, bail: pauseOnError } = argv; async function runE2ETests({ readConfigFile }: FtrConfigProviderContext) { const kibanaConfig = await readConfigFile( diff --git a/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_home.tsx b/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_home.tsx index aafaf22a9bba3..a6242d0617f0f 100644 --- a/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_home.tsx +++ b/x-pack/plugins/ux/public/components/app/rum_dashboard/rum_home.tsx @@ -62,6 +62,7 @@ export function RumHome() { }} + isPageDataLoaded={isLoading === false} > {isLoading && }
diff --git a/x-pack/plugins/ux/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.test.tsx b/x-pack/plugins/ux/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.test.tsx index be811726ed5a9..c1faa6f5cc8b9 100644 --- a/x-pack/plugins/ux/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.test.tsx +++ b/x-pack/plugins/ux/public/components/app/rum_dashboard/ux_metrics/key_ux_metrics.test.tsx @@ -7,20 +7,18 @@ import React from 'react'; import { render, Matcher } from '@testing-library/react'; -import * as fetcherHook from '../../../../hooks/use_fetcher'; +import * as queryHook from '../../../../hooks/use_long_task_metrics_query'; import { KeyUXMetrics } from './key_ux_metrics'; -import { FETCH_STATUS } from '@kbn/observability-plugin/public'; describe('KeyUXMetrics', () => { it('renders metrics with correct formats', () => { - jest.spyOn(fetcherHook, 'useFetcher').mockReturnValue({ + jest.spyOn(queryHook, 'useLongTaskMetricsQuery').mockReturnValue({ data: { noOfLongTasks: 3.0009765625, sumOfLongTasks: 520.4375, longestLongTask: 271.4375, }, - status: FETCH_STATUS.SUCCESS, - refetch: jest.fn(), + loading: false, }); const { getAllByText } = render( { - if (uxQuery) { - return callApmApi('GET /internal/apm/ux/long-task-metrics', { - params: { - query: { - ...uxQuery, - }, - }, - }); - } - return Promise.resolve(null); - }, - [uxQuery] - ); + const { data: longTaskData, loading: loadingLongTask } = + useLongTaskMetricsQuery(); // Note: FCP value is in ms unit return ( @@ -99,6 +83,7 @@ export function KeyUXMetrics({ data, loading }: Props) { } - isLoading={status !== 'success'} + isLoading={!!loadingLongTask} /> } - isLoading={status !== 'success'} + isLoading={!!loadingLongTask} /> } - isLoading={status !== 'success'} + isLoading={!!loadingLongTask} /> diff --git a/x-pack/plugins/ux/public/hooks/use_long_task_metrics_query.tsx b/x-pack/plugins/ux/public/hooks/use_long_task_metrics_query.tsx new file mode 100644 index 0000000000000..e693c529d3285 --- /dev/null +++ b/x-pack/plugins/ux/public/hooks/use_long_task_metrics_query.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 { useEsSearch } from '@kbn/observability-plugin/public'; +import { useMemo } from 'react'; +import { useDataView } from '../components/app/rum_dashboard/local_uifilters/use_data_view'; +import { longTaskMetricsQuery } from '../services/data/long_task_metrics_query'; +import { callDateMath } from '../services/data/call_date_math'; +import { useLegacyUrlParams } from '../context/url_params_context/use_url_params'; + +export function useLongTaskMetricsQuery() { + const { + rangeId, + urlParams: { start, end, searchTerm, percentile }, + uxUiFilters, + } = useLegacyUrlParams(); + const { dataViewTitle } = useDataView(); + const { data: esQueryResponse, loading } = useEsSearch( + { + index: dataViewTitle, + ...longTaskMetricsQuery( + callDateMath(start), + callDateMath(end), + percentile, + searchTerm, + uxUiFilters + ), + }, + [start, end, percentile, searchTerm, uxUiFilters, rangeId, dataViewTitle], + { name: 'UxLongTaskMetrics' } + ); + + const data = useMemo(() => { + if (!esQueryResponse) return {}; + + const pkey = Number(percentile).toFixed(1); + + const { longTaskSum, longTaskCount, longTaskMax } = + esQueryResponse.aggregations ?? {}; + + return { + noOfLongTasks: longTaskCount?.values[pkey] ?? 0, + sumOfLongTasks: longTaskSum?.values[pkey] ?? 0, + longestLongTask: longTaskMax?.values[pkey] ?? 0, + }; + }, [esQueryResponse, percentile]); + + return { data, loading }; +} diff --git a/x-pack/plugins/ux/public/services/data/__snapshots__/long_task_metrics_query.test.ts.snap b/x-pack/plugins/ux/public/services/data/__snapshots__/long_task_metrics_query.test.ts.snap new file mode 100644 index 0000000000000..55639e3a3f6b4 --- /dev/null +++ b/x-pack/plugins/ux/public/services/data/__snapshots__/long_task_metrics_query.test.ts.snap @@ -0,0 +1,77 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`longTaskMetricsQuery fetches long task metrics 1`] = ` +Object { + "body": Object { + "aggs": Object { + "longTaskCount": Object { + "percentiles": Object { + "field": "transaction.experience.longtask.count", + "hdr": Object { + "number_of_significant_value_digits": 3, + }, + "percents": Array [ + 50, + ], + }, + }, + "longTaskMax": Object { + "percentiles": Object { + "field": "transaction.experience.longtask.max", + "hdr": Object { + "number_of_significant_value_digits": 3, + }, + "percents": Array [ + 50, + ], + }, + }, + "longTaskSum": Object { + "percentiles": Object { + "field": "transaction.experience.longtask.sum", + "hdr": Object { + "number_of_significant_value_digits": 3, + }, + "percents": Array [ + 50, + ], + }, + }, + }, + "query": Object { + "bool": Object { + "filter": Array [ + Object { + "range": Object { + "@timestamp": Object { + "format": "epoch_millis", + "gte": 0, + "lte": 50000, + }, + }, + }, + Object { + "term": Object { + "transaction.type": "page-load", + }, + }, + Object { + "terms": Object { + "processor.event": Array [ + "transaction", + ], + }, + }, + Object { + "exists": Object { + "field": "transaction.marks.navigationTiming.fetchStart", + }, + }, + ], + "must_not": Array [], + }, + }, + "size": 0, + }, +} +`; \ No newline at end of file diff --git a/x-pack/plugins/ux/public/services/data/long_task_metrics_query.test.ts b/x-pack/plugins/ux/public/services/data/long_task_metrics_query.test.ts new file mode 100644 index 0000000000000..40cbd3d1e6e52 --- /dev/null +++ b/x-pack/plugins/ux/public/services/data/long_task_metrics_query.test.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 { longTaskMetricsQuery } from './long_task_metrics_query'; + +describe('longTaskMetricsQuery', () => { + it('fetches long task metrics', () => { + const query = longTaskMetricsQuery(0, 50000, 50, '', { + environment: 'ENVIRONMENT_ALL', + }); + expect(query).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/apm/server/routes/rum_client/get_long_task_metrics.ts b/x-pack/plugins/ux/public/services/data/long_task_metrics_query.ts similarity index 62% rename from x-pack/plugins/apm/server/routes/rum_client/get_long_task_metrics.ts rename to x-pack/plugins/ux/public/services/data/long_task_metrics_query.ts index 29ef955e19aa4..4f965c970bd2f 100644 --- a/x-pack/plugins/apm/server/routes/rum_client/get_long_task_metrics.ts +++ b/x-pack/plugins/ux/public/services/data/long_task_metrics_query.ts @@ -5,27 +5,23 @@ * 2.0. */ -import { getRumPageLoadTransactionsProjection } from '../../projections/rum_page_load_transactions'; -import { mergeProjection } from '../../projections/util/merge_projection'; -import { SetupUX } from './route'; +import { mergeProjection } from '../../../common/utils/merge_projection'; +import { SetupUX, UxUIFilters } from '../../../typings/ui_filters'; +import { PERCENTILE_DEFAULT } from './core_web_vitals_query'; +import { getRumPageLoadTransactionsProjection } from './projections'; const LONG_TASK_SUM_FIELD = 'transaction.experience.longtask.sum'; const LONG_TASK_COUNT_FIELD = 'transaction.experience.longtask.count'; const LONG_TASK_MAX_FIELD = 'transaction.experience.longtask.max'; -export async function getLongTaskMetrics({ - setup, - urlQuery, - percentile = 50, - start, - end, -}: { - setup: SetupUX; - urlQuery?: string; - percentile?: number; - start: number; - end: number; -}) { +export function longTaskMetricsQuery( + start: number, + end: number, + percentile: number = PERCENTILE_DEFAULT, + urlQuery?: string, + uiFilters?: UxUIFilters +) { + const setup: SetupUX = { uiFilters: uiFilters ? uiFilters : {} }; const projection = getRumPageLoadTransactionsProjection({ setup, urlQuery, @@ -68,18 +64,5 @@ export async function getLongTaskMetrics({ }, }); - const { apmEventClient } = setup; - - const response = await apmEventClient.search('get_long_task_metrics', params); - - const pkey = percentile.toFixed(1); - - const { longTaskSum, longTaskCount, longTaskMax } = - response.aggregations ?? {}; - - return { - noOfLongTasks: longTaskCount?.values[pkey] ?? 0, - sumOfLongTasks: longTaskSum?.values[pkey] ?? 0, - longestLongTask: longTaskMax?.values[pkey] ?? 0, - }; + return params; } diff --git a/x-pack/test/accessibility/apps/rollup_jobs.ts b/x-pack/test/accessibility/apps/rollup_jobs.ts new file mode 100644 index 0000000000000..2acf48d5f049f --- /dev/null +++ b/x-pack/test/accessibility/apps/rollup_jobs.ts @@ -0,0 +1,92 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { FtrProviderContext } from '../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'settings', 'header', 'rollup']); + const a11y = getService('a11y'); + const testSubjects = getService('testSubjects'); + const kibanaServer = getService('kibanaServer'); + const esArchiver = getService('esArchiver'); + const es = getService('es'); + + describe('Stack management- rollup a11y tests', () => { + const rollupJobName = `rollup${Date.now().toString()}`; + before(async () => { + await esArchiver.loadIfNeeded('test/functional/fixtures/es_archiver/logstash_functional'); + await kibanaServer.uiSettings.update({ + defaultIndex: 'logstash-*', + }); + await PageObjects.settings.navigateTo(); + await PageObjects.rollup.clickRollupJobsTab(); + }); + + it('empty state', async () => { + await a11y.testAppSnapshot(); + }); + + describe('create a rollup job wizard', async () => { + it('step 1 - logistics', async () => { + await testSubjects.click('createRollupJobButton'); + await PageObjects.rollup.verifyStepIsActive(1); + await a11y.testAppSnapshot(); + }); + + it('step 2 - date histogram', async () => { + await PageObjects.rollup.addRollupNameandIndexPattern(rollupJobName, 'logstash*'); + await PageObjects.rollup.verifyIndexPatternAccepted(); + await PageObjects.rollup.setIndexName('rollupindex'); + await PageObjects.rollup.moveToNextStep(2); + await PageObjects.rollup.verifyStepIsActive(2); + await a11y.testAppSnapshot(); + }); + + it('step 3 - terms', async () => { + await PageObjects.rollup.setJobInterval('24h'); + await PageObjects.rollup.moveToNextStep(3); + await PageObjects.rollup.verifyStepIsActive(3); + await a11y.testAppSnapshot(); + }); + + it('step 4 - histogram', async () => { + await PageObjects.rollup.moveToNextStep(4); + await PageObjects.rollup.verifyStepIsActive(4); + await a11y.testAppSnapshot(); + }); + + it('step 5 - metrics', async () => { + await PageObjects.rollup.moveToNextStep(5); + await PageObjects.rollup.verifyStepIsActive(5); + await a11y.testAppSnapshot(); + }); + + it('step 6 - review and save', async () => { + await PageObjects.rollup.moveToNextStep(6); + await PageObjects.rollup.verifyStepIsActive(6); + await a11y.testAppSnapshot(); + }); + + it('submit form and snapshot rollup flyout', async () => { + await PageObjects.rollup.saveJob(false); + await a11y.testAppSnapshot(); + }); + + it('rollup table', async () => { + await PageObjects.rollup.closeFlyout(); + await a11y.testAppSnapshot(); + }); + }); + + after(async () => { + await es.transport.request({ + path: `/_rollup/job/${rollupJobName}`, + method: 'DELETE', + }); + await esArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); + }); + }); +} diff --git a/x-pack/test/accessibility/apps/watcher.ts b/x-pack/test/accessibility/apps/watcher.ts new file mode 100644 index 0000000000000..85a11db0122ab --- /dev/null +++ b/x-pack/test/accessibility/apps/watcher.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// a11y tests for spaces, space selection and space creation and feature controls + +import { FtrProviderContext } from '../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'home', 'header', 'watcher', 'security']); + const a11y = getService('a11y'); + + describe('Kibana Stack Management Watcher a11y tests', () => { + before(async () => { + await PageObjects.common.navigateToApp('watcher'); + }); + + it('renders the watcher page without a11y errors', async () => { + await a11y.testAppSnapshot(); + }); + + it('a11y tests for create watch button', async function () { + await PageObjects.watcher.createWatch('test', 'test'); + await a11y.testAppSnapshot(); + }); + + it('a11y tests for the watch list page', async function () { + await PageObjects.watcher.getWatch('test'); + await a11y.testAppSnapshot(); + }); + + it('a11y tests for deleting the watches', async function () { + await PageObjects.watcher.deleteWatch(); + await a11y.testAppSnapshot(); + }); + }); +} diff --git a/x-pack/test/accessibility/config.ts b/x-pack/test/accessibility/config.ts index e5e7cabcc4bae..5b45153395323 100644 --- a/x-pack/test/accessibility/config.ts +++ b/x-pack/test/accessibility/config.ts @@ -48,6 +48,8 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { require.resolve('./apps/tags'), require.resolve('./apps/search_sessions'), require.resolve('./apps/stack_monitoring'), + require.resolve('./apps/watcher'), + require.resolve('./apps/rollup_jobs'), ], pageObjects, diff --git a/x-pack/test/api_integration/apis/ml/filters/get_filters_stats.ts b/x-pack/test/api_integration/apis/ml/filters/get_filters_stats.ts new file mode 100644 index 0000000000000..9e6c560c135c2 --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/filters/get_filters_stats.ts @@ -0,0 +1,229 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { Job } from '@kbn/ml-plugin/common/types/anomaly_detection_jobs'; +import { FilterStats } from '@kbn/ml-plugin/common/types/filters'; +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { USER } from '../../../../functional/services/ml/security_common'; +import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; + +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertestWithoutAuth'); + const ml = getService('ml'); + + // @ts-expect-error not full interface + const jobConfig1: Job = { + job_id: `fq_filter_stats_1`, + description: 'mean(responsetime) partition=airline on farequote dataset with 1h bucket span', + groups: ['farequote', 'automated', 'multi-metric'], + analysis_config: { + bucket_span: '1h', + influencers: ['airline'], + detectors: [ + { + function: 'mean', + field_name: 'responsetime', + partition_field_name: 'airline', + detector_description: 'mean(responsetime) partitionfield=airline', + custom_rules: [ + { + actions: ['skip_result'], + scope: { + airline: { + filter_id: 'ignore_a_airlines', + filter_type: 'include', + }, + }, + }, + { + actions: ['skip_result'], + scope: { + airline: { + filter_id: 'ignore_b_airlines', + filter_type: 'include', + }, + }, + }, + ], + }, + ], + }, + data_description: { time_field: '@timestamp' }, + analysis_limits: { model_memory_limit: '20mb' }, + model_plot_config: { enabled: true }, + }; + + // @ts-expect-error not full interface + const jobConfig2: Job = { + job_id: `fq_filter_stats_2`, + description: 'max(responsetime) partition=airline on farequote dataset with 30m bucket span', + groups: ['farequote', 'automated', 'multi-metric'], + analysis_config: { + bucket_span: '30m', + influencers: ['airline'], + detectors: [ + { + function: 'max', + field_name: 'responsetime', + partition_field_name: 'airline', + detector_description: 'max(responsetime) partitionfield=airline', + }, + { + function: 'min', + field_name: 'responsetime', + partition_field_name: 'airline', + detector_description: 'min(responsetime) partitionfield=airline', + custom_rules: [ + { + actions: ['skip_result'], + conditions: [ + { + applies_to: 'actual', + operator: 'lt', + value: 100, + }, + ], + }, + { + actions: ['skip_result'], + scope: { + airline: { + filter_id: 'ignore_a_airlines', + filter_type: 'include', + }, + }, + }, + ], + }, + ], + }, + data_description: { time_field: '@timestamp' }, + analysis_limits: { model_memory_limit: '20mb' }, + model_plot_config: { enabled: true }, + }; + + const testJobConfigs = [jobConfig1, jobConfig2]; + + const testDataList = [ + { + filterId: 'ignore_a_airlines', + requestBody: { + description: 'Airlines starting with A', + items: ['AAL'], + }, + expected: { + item_count: 1, + used_by: { + jobs: [jobConfig1.job_id, jobConfig2.job_id], + detectors: [ + `${jobConfig1.analysis_config.detectors[0].detector_description} (${jobConfig1.job_id})`, + `${jobConfig2.analysis_config.detectors[1].detector_description} (${jobConfig2.job_id})`, + ], + }, + }, + }, + { + filterId: 'ignore_b_airlines', + requestBody: { + description: 'Airlines starting with B', + items: ['BAA', 'BAB'], + }, + expected: { + item_count: 2, + used_by: { + jobs: [jobConfig1.job_id], + detectors: [ + `${jobConfig1.analysis_config.detectors[0].detector_description} (${jobConfig1.job_id})`, + ], + }, + }, + }, + { + filterId: 'ignore_c_airlines', + requestBody: { + description: 'Airlines starting with C', + items: ['CAA', 'CAB', 'CCC'], + }, + expected: { + item_count: 3, + }, + }, + ]; + + describe('get_filters_stats', function () { + before(async () => { + await ml.testResources.setKibanaTimeZoneToUTC(); + for (const testData of testDataList) { + const { filterId, requestBody } = testData; + await ml.api.createFilter(filterId, requestBody); + } + + for (const job of testJobConfigs) { + await ml.api.createAnomalyDetectionJob(job); + } + }); + + after(async () => { + await ml.api.cleanMlIndices(); + }); + + it(`should fetch all filters stats`, async () => { + const { body, status } = await supertest + .get(`/api/ml/filters/_stats`) + .auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(200, status, body); + + expect(body).to.have.length(testDataList.length); + + // Validate the contents of the stats response + for (const testData of testDataList) { + const { filterId, expected } = testData; + + const actualFilterStats = body.find( + (filterStats: FilterStats) => filterStats.filter_id === filterId + ); + + expect(actualFilterStats).to.have.property('item_count').eql(expected.item_count); + if (expected.used_by !== undefined) { + expect(actualFilterStats).to.have.property('used_by'); + expect(actualFilterStats.used_by).to.have.property('jobs'); + expect(actualFilterStats.used_by.jobs.sort()).to.eql(expected.used_by.jobs.sort()); + expect(actualFilterStats.used_by).to.have.property('detectors'); + expect(actualFilterStats.used_by.detectors.sort()).to.eql( + expected.used_by.detectors.sort() + ); + } else { + expect(actualFilterStats).not.to.have.property('used_by'); + } + } + }); + + it(`should not allow retrieving filters stats for user without required permission`, async () => { + const { body, status } = await supertest + .get(`/api/ml/filters/_stats`) + .auth(USER.ML_VIEWER, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(403, status, body); + + expect(body.error).to.eql('Forbidden'); + expect(body.message).to.eql('Forbidden'); + }); + + it(`should not allow retrieving filters stats for unauthorized user`, async () => { + const { body, status } = await supertest + .get(`/api/ml/filters/_stats`) + .auth(USER.ML_UNAUTHORIZED, ml.securityCommon.getPasswordForUser(USER.ML_UNAUTHORIZED)) + .set(COMMON_REQUEST_HEADERS); + ml.api.assertResponseStatusCode(403, status, body); + + expect(body.error).to.eql('Forbidden'); + expect(body.message).to.eql('Forbidden'); + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/filters/index.ts b/x-pack/test/api_integration/apis/ml/filters/index.ts index bd6f35d02d836..19ab0afd08608 100644 --- a/x-pack/test/api_integration/apis/ml/filters/index.ts +++ b/x-pack/test/api_integration/apis/ml/filters/index.ts @@ -11,6 +11,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { describe('filters', function () { loadTestFile(require.resolve('./create_filters')); loadTestFile(require.resolve('./get_filters')); + loadTestFile(require.resolve('./get_filters_stats')); loadTestFile(require.resolve('./delete_filters')); loadTestFile(require.resolve('./update_filters')); }); diff --git a/x-pack/test/api_integration/apis/osquery/packs.ts b/x-pack/test/api_integration/apis/osquery/packs.ts index 543c01ac92c41..b04f9eaa7ebe2 100644 --- a/x-pack/test/api_integration/apis/osquery/packs.ts +++ b/x-pack/test/api_integration/apis/osquery/packs.ts @@ -81,9 +81,7 @@ export default function ({ getService }: FtrProviderContext) { }); hostedPolicy = agentPolicy; - const { - body: { item: packagePolicy }, - } = await supertest + const packagePolicyResponse = await supertest .post('/api/fleet/package_policies') .set('kbn-xsrf', 'true') .send({ @@ -101,7 +99,15 @@ export default function ({ getService }: FtrProviderContext) { description: '123', id: '123', }); - packagePolicyId = packagePolicy.id; + + if (!packagePolicyResponse.body.item) { + // eslint-disable-next-line no-console + console.error({ MISSING: packagePolicyResponse }); + } + + expect(packagePolicyResponse.status).to.be(200); + + packagePolicyId = packagePolicyResponse.body.item.id; const createPackResponse = await supertest .post('/internal/osquery/packs') diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts index 714ab0b21d06c..df6b6ac42d4ae 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor.ts @@ -7,8 +7,9 @@ import { omit } from 'lodash'; import expect from '@kbn/expect'; import { secretKeys } from '@kbn/synthetics-plugin/common/constants/monitor_management'; -import { HTTPFields } from '@kbn/synthetics-plugin/common/runtime_types'; +import { DataStream, HTTPFields } from '@kbn/synthetics-plugin/common/runtime_types'; import { API_URLS } from '@kbn/synthetics-plugin/common/constants'; +import { DEFAULT_FIELDS } from '@kbn/synthetics-plugin/common/constants/monitor_defaults'; import { ALL_SPACES_ID } from '@kbn/security-plugin/common/constants'; import { format as formatUrl } from 'url'; import supertest from 'supertest'; @@ -46,7 +47,7 @@ export default function ({ getService }: FtrProviderContext) { it('returns bad request if payload is invalid for HTTP monitor', async () => { // Delete a required property to make payload invalid - const newMonitor = { ...httpMonitorJson, 'check.request.headers': undefined }; + const newMonitor = { ...httpMonitorJson, 'check.request.headers': null }; const apiResponse = await supertestAPI .post(API_URLS.SYNTHETICS_MONITORS) @@ -68,6 +69,71 @@ export default function ({ getService }: FtrProviderContext) { expect(apiResponse.body.message).eql('Monitor type is invalid'); }); + it('can create valid monitors without all defaults', async () => { + // Delete a required property to make payload invalid + const newMonitor = { + name: 'Sample name', + type: 'http', + urls: 'https://elastic.co', + locations: [ + { + id: 'eu-west-01', + label: 'Europe West', + geo: { + lat: 33.2343132435, + lon: 73.2342343434, + }, + url: 'https://example-url.com', + isServiceManaged: true, + }, + ], + }; + + const apiResponse = await supertestAPI + .post(API_URLS.SYNTHETICS_MONITORS) + .set('kbn-xsrf', 'true') + .send(newMonitor); + + expect(apiResponse.status).eql(200); + expect(apiResponse.body.attributes).eql( + omit( + { + ...DEFAULT_FIELDS[DataStream.HTTP], + ...newMonitor, + revision: 1, + }, + secretKeys + ) + ); + }); + + it('cannot create a valid monitor without a monitor type', async () => { + // Delete a required property to make payload invalid + const newMonitor = { + name: 'Sample name', + url: 'https://elastic.co', + locations: [ + { + id: 'eu-west-01', + label: 'Europe West', + geo: { + lat: 33.2343132435, + lon: 73.2342343434, + }, + url: 'https://example-url.com', + isServiceManaged: true, + }, + ], + }; + + const apiResponse = await supertestAPI + .post(API_URLS.SYNTHETICS_MONITORS) + .set('kbn-xsrf', 'true') + .send(newMonitor); + + expect(apiResponse.status).eql(400); + }); + it('can create monitor with API key with proper permissions', async () => { await supertestAPI .post('/internal/security/api_key') diff --git a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts index 0445843ddd02e..aae7672f46344 100644 --- a/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts +++ b/x-pack/test/api_integration/apis/uptime/rest/add_monitor_project.ts @@ -629,5 +629,43 @@ export default function ({ getService }: FtrProviderContext) { ]); } }); + + it('project monitors - is able to enable and disable monitors', async () => { + try { + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) + .set('kbn-xsrf', 'true') + .send(projectMonitors); + + await supertest + .put(API_URLS.SYNTHETICS_MONITORS_PROJECT) + .set('kbn-xsrf', 'true') + .send({ + ...projectMonitors, + monitors: [ + { + ...projectMonitors.monitors[0], + enabled: false, + }, + ], + }) + .expect(200); + const response = await supertest + .get(API_URLS.SYNTHETICS_MONITORS) + .query({ + filter: `${syntheticsMonitorType}.attributes.journey_id: ${projectMonitors.monitors[0].id}`, + }) + .set('kbn-xsrf', 'true') + .expect(200); + const { monitors } = response.body; + expect(monitors[0].attributes.enabled).eql(false); + } finally { + await Promise.all([ + projectMonitors.monitors.map((monitor) => { + return deleteMonitor(monitor.id, projectMonitors.project); + }), + ]); + } + }); }); } diff --git a/x-pack/test/apm_api_integration/tests/csm/long_task_metrics.spec.ts b/x-pack/test/apm_api_integration/tests/csm/long_task_metrics.spec.ts deleted file mode 100644 index 61ee97398be9a..0000000000000 --- a/x-pack/test/apm_api_integration/tests/csm/long_task_metrics.spec.ts +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import expect from '@kbn/expect'; -import { FtrProviderContext } from '../../common/ftr_provider_context'; - -export default function rumServicesApiTests({ getService }: FtrProviderContext) { - const registry = getService('registry'); - const apmApiClient = getService('apmApiClient'); - - registry.when('CSM long task metrics without data', { config: 'trial', archives: [] }, () => { - it('returns empty list', async () => { - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/ux/long-task-metrics', - params: { - query: { - start: '2020-09-07T20:35:54.654Z', - end: '2020-09-14T20:35:54.654Z', - uiFilters: '{"serviceName":["elastic-co-rum-test"]}', - }, - }, - }); - - expect(response.status).to.be(200); - expect(response.body).to.eql({ - longestLongTask: 0, - noOfLongTasks: 0, - sumOfLongTasks: 0, - }); - }); - }); - - registry.when( - 'CSM long task metrics with data', - { config: 'trial', archives: ['8.0.0', 'rum_8.0.0'] }, - () => { - it('returns web core vitals values', async () => { - const response = await apmApiClient.readUser({ - endpoint: 'GET /internal/apm/ux/long-task-metrics', - params: { - query: { - start: '2020-09-07T20:35:54.654Z', - end: '2020-09-16T20:35:54.654Z', - uiFilters: '{"serviceName":["kibana-frontend-8_0_0"]}', - }, - }, - }); - - expect(response.status).to.be(200); - - expectSnapshot(response.body).toMatchInline(` - Object { - "longestLongTask": 0, - "noOfLongTasks": 0, - "sumOfLongTasks": 0, - } - `); - }); - } - ); -} diff --git a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts index c0ae9e24c830e..d6dc2bfb4b9ed 100644 --- a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts +++ b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts @@ -19,7 +19,7 @@ import { config, generateData } from './generate_data'; import { getErrorGroupIds } from './get_error_group_ids'; type ErrorGroupsDetailedStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; + APIReturnType<'POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; export default function ApiTest({ getService }: FtrProviderContext) { const registry = getService('registry'); @@ -32,22 +32,22 @@ export default function ApiTest({ getService }: FtrProviderContext) { async function callApi( overrides?: RecursivePartial< - APIClientRequestParamsOf<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>['params'] + APIClientRequestParamsOf<'POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>['params'] > ) { return await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics`, + endpoint: `POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics`, params: { path: { serviceName, ...overrides?.path }, query: { start: new Date(start).toISOString(), end: new Date(end).toISOString(), numBuckets: 20, - groupIds: JSON.stringify(['foo']), environment: 'ENVIRONMENT_ALL', kuery: '', ...overrides?.query, }, + body: { groupIds: JSON.stringify(['foo']), ...overrides?.body }, }, }); } @@ -82,7 +82,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { before(async () => { errorIds = await getErrorGroupIds({ serviceName, start, end, apmApiClient }); const response = await callApi({ - query: { + body: { groupIds: JSON.stringify(errorIds), }, }); @@ -116,7 +116,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { let errorGroupsDetailedStatistics: ErrorGroupsDetailedStatistics; before(async () => { const response = await callApi({ - query: { + body: { groupIds: JSON.stringify(['foo']), }, }); @@ -138,11 +138,13 @@ export default function ApiTest({ getService }: FtrProviderContext) { errorIds = await getErrorGroupIds({ serviceName, start, end, apmApiClient }); const response = await callApi({ query: { - groupIds: JSON.stringify(errorIds), start: moment(end).subtract(7, 'minutes').toISOString(), end: new Date(end).toISOString(), offset: '7m', }, + body: { + groupIds: JSON.stringify(errorIds), + }, }); errorGroupsDetailedStatistics = response.body; }); diff --git a/x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.spec.ts b/x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.spec.ts index 25672acc76227..b83da1bc7131f 100644 --- a/x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.spec.ts +++ b/x-pack/test/apm_api_integration/tests/services/services_detailed_statistics.spec.ts @@ -13,7 +13,7 @@ import { FtrProviderContext } from '../../common/ftr_provider_context'; import { ApmApiError } from '../../common/apm_api_supertest'; type ServicesDetailedStatisticsReturn = - APIReturnType<'GET /internal/apm/services/detailed_statistics'>; + APIReturnType<'POST /internal/apm/services/detailed_statistics'>; export default function ApiTest({ getService }: FtrProviderContext) { const registry = getService('registry'); @@ -31,17 +31,19 @@ export default function ApiTest({ getService }: FtrProviderContext) { () => { it('handles the empty state', async () => { const response = await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/detailed_statistics`, + endpoint: `POST /internal/apm/services/detailed_statistics`, params: { query: { start, end, - serviceNames: JSON.stringify(serviceNames), environment: 'ENVIRONMENT_ALL', kuery: '', offset: '1d', probability: 1, }, + body: { + serviceNames: JSON.stringify(serviceNames), + }, }, }); @@ -59,16 +61,18 @@ export default function ApiTest({ getService }: FtrProviderContext) { let servicesDetailedStatistics: ServicesDetailedStatisticsReturn; before(async () => { const response = await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/detailed_statistics`, + endpoint: `POST /internal/apm/services/detailed_statistics`, params: { query: { start, end, - serviceNames: JSON.stringify(serviceNames), environment: 'ENVIRONMENT_ALL', kuery: '', probability: 1, }, + body: { + serviceNames: JSON.stringify(serviceNames), + }, }, }); expect(response.status).to.be(200); @@ -112,16 +116,18 @@ export default function ApiTest({ getService }: FtrProviderContext) { it('returns empty when empty service names is passed', async () => { try { await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/detailed_statistics`, + endpoint: `POST /internal/apm/services/detailed_statistics`, params: { query: { start, end, - serviceNames: JSON.stringify([]), environment: 'ENVIRONMENT_ALL', kuery: '', probability: 1, }, + body: { + serviceNames: JSON.stringify([]), + }, }, }); expect().fail('Expected API call to throw an error'); @@ -135,16 +141,18 @@ export default function ApiTest({ getService }: FtrProviderContext) { it('filters by environment', async () => { const response = await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/detailed_statistics`, + endpoint: `POST /internal/apm/services/detailed_statistics`, params: { query: { start, end, - serviceNames: JSON.stringify(serviceNames), environment: 'production', kuery: '', probability: 1, }, + body: { + serviceNames: JSON.stringify(serviceNames), + }, }, }); expect(response.status).to.be(200); @@ -153,16 +161,18 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('filters by kuery', async () => { const response = await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/detailed_statistics`, + endpoint: `POST /internal/apm/services/detailed_statistics`, params: { query: { start, end, - serviceNames: JSON.stringify(serviceNames), environment: 'ENVIRONMENT_ALL', kuery: 'transaction.type : "invalid_transaction_type"', probability: 1, }, + body: { + serviceNames: JSON.stringify(serviceNames), + }, }, }); expect(response.status).to.be(200); @@ -178,17 +188,19 @@ export default function ApiTest({ getService }: FtrProviderContext) { let servicesDetailedStatistics: ServicesDetailedStatisticsReturn; before(async () => { const response = await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/detailed_statistics`, + endpoint: `POST /internal/apm/services/detailed_statistics`, params: { query: { start: moment(end).subtract(15, 'minutes').toISOString(), end, - serviceNames: JSON.stringify(serviceNames), offset: '15m', environment: 'ENVIRONMENT_ALL', kuery: '', probability: 1, }, + body: { + serviceNames: JSON.stringify(serviceNames), + }, }, }); diff --git a/x-pack/test/fleet_api_integration/apis/agents/reassign.ts b/x-pack/test/fleet_api_integration/apis/agents/reassign.ts index 52251a5f40133..7c97ff5b79bf9 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/reassign.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/reassign.ts @@ -198,6 +198,31 @@ export default function (providerContext: FtrProviderContext) { }); }); + it('should bulk reassign multiple agents by kuery in batches', async () => { + const { body: unenrolledBody } = await supertest + .post(`/api/fleet/agents/bulk_reassign`) + .set('kbn-xsrf', 'xxx') + .send({ + agents: 'active: true', + policy_id: 'policy2', + batchSize: 2, + }) + .expect(200); + + expect(unenrolledBody).to.eql({ + agent1: { success: true }, + agent2: { success: true }, + agent3: { success: true }, + agent4: { success: true }, + }); + + const { body } = await supertest.get(`/api/fleet/agents`).set('kbn-xsrf', 'xxx'); + expect(body.total).to.eql(4); + body.items.forEach((agent: any) => { + expect(agent.policy_id).to.eql('policy2'); + }); + }); + it('should throw an error for invalid policy id for bulk reassign', async () => { await supertest .post(`/api/fleet/agents/bulk_reassign`) diff --git a/x-pack/test/fleet_api_integration/apis/agents/status.ts b/x-pack/test/fleet_api_integration/apis/agents/status.ts index 75ee62c576669..9fc257f10c81d 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/status.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/status.ts @@ -35,7 +35,7 @@ export default function ({ getService }: FtrProviderContext) { index: AGENTS_INDEX, body: { doc: { - last_checkin: new Date().toISOString(), + last_checkin: new Date(Date.now() - 1000 * 60 * 3).toISOString(), // 2m online }, }, }); @@ -46,7 +46,7 @@ export default function ({ getService }: FtrProviderContext) { index: AGENTS_INDEX, body: { doc: { - last_checkin: new Date(Date.now() - 1000 * 60 * 60 * 60 * 10).toISOString(), + last_checkin: new Date(Date.now() - 1000 * 60 * 6).toISOString(), // 6m offline }, }, }); diff --git a/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts b/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts index 14dd5871a0317..93d0a58b848df 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/unenroll.ts @@ -197,5 +197,27 @@ export default function (providerContext: FtrProviderContext) { const { body } = await supertest.get(`/api/fleet/agents`); expect(body.total).to.eql(0); }); + + it('/agents/bulk_unenroll should allow to unenroll multiple agents by kuery in batches', async () => { + const { body: unenrolledBody } = await supertest + .post(`/api/fleet/agents/bulk_unenroll`) + .set('kbn-xsrf', 'xxx') + .send({ + agents: 'active: true', + revoke: true, + batchSize: 2, + }) + .expect(200); + + expect(unenrolledBody).to.eql({ + agent1: { success: true }, + agent2: { success: true }, + agent3: { success: true }, + agent4: { success: true }, + }); + + const { body } = await supertest.get(`/api/fleet/agents`); + expect(body.total).to.eql(0); + }); }); } diff --git a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts index 599488baf6707..c52efca4e86af 100644 --- a/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts +++ b/x-pack/test/fleet_api_integration/apis/agents/upgrade.ts @@ -21,7 +21,7 @@ export default function (providerContext: FtrProviderContext) { const kibanaServer = getService('kibanaServer'); const supertestWithoutAuth = getService('supertestWithoutAuth'); - describe('Agents upgrade', () => { + describe('fleet_upgrade_agent', () => { skipIfNoDockerRegistry(providerContext); before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/fleet/agents'); @@ -483,6 +483,52 @@ export default function (providerContext: FtrProviderContext) { expect(typeof agent2data.body.item.upgrade_started_at).to.be('undefined'); }); + it('should bulk upgrade multiple agents by kuery in batches', async () => { + await es.update({ + id: 'agent1', + refresh: 'wait_for', + index: AGENTS_INDEX, + body: { + doc: { + local_metadata: { elastic: { agent: { upgradeable: true, version: '0.0.0' } } }, + }, + }, + }); + await es.update({ + id: 'agent2', + refresh: 'wait_for', + index: AGENTS_INDEX, + body: { + doc: { + local_metadata: { + elastic: { + agent: { upgradeable: false, version: '0.0.0' }, + }, + }, + upgrade_started_at: undefined, + }, + }, + }); + + const { body: unenrolledBody } = await supertest + .post(`/api/fleet/agents/bulk_upgrade`) + .set('kbn-xsrf', 'xxx') + .send({ + agents: 'active:true', + version: fleetServerVersion, + batchSize: 2, + }) + .expect(200); + + expect(unenrolledBody).to.eql({ + agent4: { success: false, error: 'agent4 is not upgradeable' }, + agent3: { success: false, error: 'agent3 is not upgradeable' }, + agent2: { success: false, error: 'agent2 is not upgradeable' }, + agent1: { success: true }, + agentWithFS: { success: false, error: 'agentWithFS is not upgradeable' }, + }); + }); + it('should not upgrade an unenrolling agent during bulk_upgrade', async () => { await supertest.post(`/api/fleet/agents/agent1/unenroll`).set('kbn-xsrf', 'xxx').send({ revoke: true, diff --git a/x-pack/test/fleet_api_integration/apis/download_sources/crud.ts b/x-pack/test/fleet_api_integration/apis/download_sources/crud.ts new file mode 100644 index 0000000000000..0d0916be10171 --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/download_sources/crud.ts @@ -0,0 +1,253 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../api_integration/ftr_provider_context'; +import { skipIfNoDockerRegistry } from '../../helpers'; +import { setupFleetAndAgents } from '../agents/services'; + +export default function (providerContext: FtrProviderContext) { + const { getService } = providerContext; + const supertest = getService('supertest'); + const esArchiver = getService('esArchiver'); + + describe('fleet_download_sources_crud', async function () { + skipIfNoDockerRegistry(providerContext); + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'); + await esArchiver.load('x-pack/test/functional/es_archives/fleet/empty_fleet_server'); + }); + setupFleetAndAgents(providerContext); + + let defaultDownloadSourceId: string; + + before(async function () { + const { body: response } = await supertest + .get(`/api/fleet/agent_download_sources`) + .expect(200); + + const defaultDownloadSource = response.items.find((item: any) => item.is_default); + if (!defaultDownloadSource) { + throw new Error('default download source not set'); + } + defaultDownloadSourceId = defaultDownloadSource.id; + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/empty_kibana'); + await esArchiver.unload('x-pack/test/functional/es_archives/fleet/empty_fleet_server'); + }); + + describe('GET /agent_download_sources', () => { + it('should list the default download source host', async () => { + const { body: downloadSource } = await supertest + .get(`/api/fleet/agent_download_sources`) + .expect(200); + + expect(downloadSource.items[0]).to.eql({ + id: 'fleet-default-download-source', + name: 'default', + is_default: true, + host: 'artifactory.elastic.co', + }); + }); + }); + + describe('GET /agent_download_sources/{sourceId}', () => { + it('should return the requested download source host', async () => { + const { body: downloadSource } = await supertest + .get(`/api/fleet/agent_download_sources/${defaultDownloadSourceId}`) + .expect(200); + + expect(downloadSource).to.eql({ + item: { + id: 'fleet-default-download-source', + name: 'default', + is_default: true, + host: 'artifactory.elastic.co', + }, + }); + }); + }); + + describe('PUT /agent_download_sources/{sourceId}', () => { + it('should allow to update an existing download source', async function () { + await supertest + .put(`/api/fleet/agent_download_sources/${defaultDownloadSourceId}`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'new host1', + host: 'https://test.co:403', + is_default: false, + }) + .expect(200); + + const { + body: { item: downloadSource }, + } = await supertest + .get(`/api/fleet/agent_download_sources/${defaultDownloadSourceId}`) + .expect(200); + + expect(downloadSource.host).to.eql('https://test.co:403'); + }); + + it('should allow to update an existing download source', async function () { + await supertest + .put(`/api/fleet/agent_download_sources/${defaultDownloadSourceId}`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'new default host', + host: 'https://test.co', + is_default: true, + }) + .expect(200); + + await supertest.get(`/api/fleet/agent_download_sources`).expect(200); + }); + + it('should return a 404 when updating a non existing download source', async function () { + await supertest + .put(`/api/fleet/agent_download_sources/idonotexists`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'new host1', + host: 'https://test.co', + is_default: true, + }) + .expect(404); + }); + + it('should return a 400 when passing a host that is not a valid uri', async function () { + await supertest + .put(`/api/fleet/agent_download_sources/${defaultDownloadSourceId}`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'new host1', + host: 'not a valid uri', + is_default: true, + }) + .expect(400); + }); + }); + + describe('POST /agent_download_sources', () => { + it('should allow to create a new download source host', async function () { + const { body: postResponse } = await supertest + .post(`/api/fleet/agent_download_sources`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'My download source', + host: 'http://test.fr:443', + is_default: false, + }) + .expect(200); + + const { id: _, ...itemWithoutId } = postResponse.item; + expect(itemWithoutId).to.eql({ + name: 'My download source', + host: 'http://test.fr:443', + is_default: false, + }); + }); + + it('should toggle default download source when creating a new default one', async function () { + await supertest + .post(`/api/fleet/agent_download_sources`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'default download source host 1', + host: 'https://test.co', + is_default: true, + }) + .expect(200); + + const { + body: { item: downloadSource2 }, + } = await supertest + .post(`/api/fleet/agent_download_sources`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'default download source host 2', + host: 'https://test2.co', + is_default: true, + }) + .expect(200); + + const { + body: { items: downloadSources }, + } = await supertest.get(`/api/fleet/agent_download_sources`).expect(200); + + const defaultDownloadSource = downloadSources.filter((item: any) => item.is_default); + expect(defaultDownloadSource).to.have.length(1); + expect(defaultDownloadSource[0].id).eql(downloadSource2.id); + }); + + it('should return a 400 when passing a host that is not a valid uri', async function () { + await supertest + .post(`/api/fleet/agent_download_sources`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'new host1', + host: 'not a valid uri', + is_default: true, + }) + .expect(400); + }); + }); + + describe('DELETE /agent_download_sources/{sourceId}', () => { + let sourceId: string; + let defaultDSIdToDelete: string; + + before(async () => { + const { body: postResponse } = await supertest + .post(`/api/fleet/agent_download_sources`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'Download source to delete test', + host: 'https://test.co', + }) + .expect(200); + sourceId = postResponse.item.id; + + const { body: defaultDSPostResponse } = await supertest + .post(`/api/fleet/agent_download_sources`) + .set('kbn-xsrf', 'xxxx') + .send({ + name: 'Default download source to delete test', + host: 'https://test.co', + is_default: true, + }) + .expect(200); + defaultDSIdToDelete = defaultDSPostResponse.item.id; + }); + + it('should return a 400 when trying to delete a default download source host ', async function () { + await supertest + .delete(`/api/fleet/agent_download_sources/${defaultDSIdToDelete}`) + .set('kbn-xsrf', 'xxxx') + .expect(400); + }); + + it('should return a 404 when deleting a non existing entry ', async function () { + await supertest + .delete(`/api/fleet/agent_download_sources/idonotexists`) + .set('kbn-xsrf', 'xxxx') + .expect(404); + }); + + it('should allow to delete a download source value ', async function () { + const { body: deleteResponse } = await supertest + .delete(`/api/fleet/agent_download_sources/${sourceId}`) + .set('kbn-xsrf', 'xxxx') + .expect(200); + + expect(deleteResponse.id).to.eql(sourceId); + }); + }); + }); +} diff --git a/x-pack/test/fleet_api_integration/apis/download_sources/index.js b/x-pack/test/fleet_api_integration/apis/download_sources/index.js new file mode 100644 index 0000000000000..96d6fc841209b --- /dev/null +++ b/x-pack/test/fleet_api_integration/apis/download_sources/index.js @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor 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 default function loadTests({ loadTestFile }) { + describe('Agent Download Source Endpoints', () => { + loadTestFile(require.resolve('./crud')); + }); +} diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/kibana/csp_rule_template/sample_csp_rule_template.json b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/kibana/csp_rule_template/sample_csp_rule_template.json index cdcd06876e010..649e06053e88f 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/kibana/csp_rule_template/sample_csp_rule_template.json +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.1.0/kibana/csp_rule_template/sample_csp_rule_template.json @@ -1,16 +1,30 @@ { "attributes": { - "benchmark": { "name": "CIS Kubernetes", "version": "1.4.1" }, - "benchmark_rule_id": "1.1.1", - "default_value": "By default, anonymous access is enabled.", - "description": "'Disable anonymous requests to the API server", - "impact": "Anonymous requests will be rejected.", - "name": "Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)", - "rationale": "When enabled, requests that are not rejected by other configured authentication methods\nare treated as anonymous requests. These requests are then served by the API server. You\nshould rely on authentication to authorize access and disallow anonymous requests.\nIf you are using RBAC authorization, it is generally considered reasonable to allow\nanonymous access to the API Server for health checks and discovery purposes, and hence\nthis recommendation is not scored. However, you should consider whether anonymous\ndiscovery is an acceptable risk for your purposes.", - "rego_rule_id": "cis_k8s.cis_1_1_1", - "remediation": "Edit the API server pod specification file /etc/kubernetes/manifests/kubeapiserver.yaml on the master node and set the below parameter.\n--anonymous-auth=false", - "severity": "low", - "tags": ["Kubernetes", "Containers"] + "audit": "Run the following command on the control plane node:\n```\nps -ef | grep kube-apiserver\n```\nVerify that the `--token-auth-file` argument does not exist.\n", + "benchmark": { + "name": "CIS Kubernetes V1.23", + "version": "v1.0.0" + }, + "default_value": "By default, `--token-auth-file` argument is not set.\n", + "description": "Do not use token based authentication.\n", + "enabled": true, + "id": "6c8f1b4a-9e41-5fdb-b4bf-57b850ea1d29", + "impact": "You will have to configure and use alternate authentication mechanisms such as certificates. Static token based authentication could not be used.\n", + "muted": false, + "name": "Ensure that the --token-auth-file parameter is not set (Automated)", + "profile_applicability": "* Level 1 - Master Node\n", + "rationale": "The token-based authentication utilizes static tokens to authenticate requests to the apiserver. The tokens are stored in clear-text in a file on the apiserver, and cannot be revoked or rotated without restarting the apiserver. Hence, do not use static token-based authentication.\n", + "references": "1. [https://kubernetes.io/docs/admin/authentication/#static-token-file](https://kubernetes.io/docs/admin/authentication/#static-token-file)\n2. [https://kubernetes.io/docs/admin/kube-apiserver/](https://kubernetes.io/docs/admin/kube-apiserver/)\n", + "rego_rule_id": "cis_1_2_2", + "remediation": "Follow the documentation and configure alternate mechanisms for\nauthentication. Then,\nedit the API server pod specification file `/etc/kubernetes/manifests/kube-apiserver.yaml` \non the control plane node and remove the `--token-auth-file=`\nparameter.\n", + "section": "API Server", + "tags": [ + "CIS", + "Kubernetes", + "CIS 1.2.2", + "API Server" + ], + "version": "1.0" }, "id": "sample_csp_rule_template", "type": "csp-rule-template" diff --git a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/csp_rule_template/sample_csp_rule_template.json b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/csp_rule_template/sample_csp_rule_template.json index 97a24faebb3fd..bebc3edd4372e 100644 --- a/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/csp_rule_template/sample_csp_rule_template.json +++ b/x-pack/test/fleet_api_integration/apis/fixtures/test_packages/all_assets/0.2.0/kibana/csp_rule_template/sample_csp_rule_template.json @@ -1,16 +1,30 @@ { "attributes": { - "benchmark": { "name": "CIS Kubernetes", "version": "1.4.1" }, - "benchmark_rule_id": "1.1.2", - "default_value": "By default, anonymous access is enabled.", - "description": "'Disable anonymous requests to the API server", - "impact": "Anonymous requests will be rejected.", - "name": "Ensure that the API server pod specification file permissions are set to 644 or more restrictive (Automated)", - "rationale": "When enabled, requests that are not rejected by other configured authentication methods\nare treated as anonymous requests. These requests are then served by the API server. You\nshould rely on authentication to authorize access and disallow anonymous requests.\nIf you are using RBAC authorization, it is generally considered reasonable to allow\nanonymous access to the API Server for health checks and discovery purposes, and hence\nthis recommendation is not scored. However, you should consider whether anonymous\ndiscovery is an acceptable risk for your purposes.", - "rego_rule_id": "cis_k8s.cis_1_1_1", - "remediation": "Edit the API server pod specification file /etc/kubernetes/manifests/kubeapiserver.yaml on the master node and set the below parameter.\n--anonymous-auth=false", - "severity": "low", - "tags": ["Kubernetes", "Containers"] + "audit": "Run the following command on the control plane node:\n```\nps -ef | grep kube-apiserver\n```\nVerify that the `--token-auth-file` argument does not exist.\n", + "benchmark": { + "name": "CIS Kubernetes V1.23", + "version": "v1.0.0" + }, + "default_value": "By default, `--token-auth-file` argument is not set.\n", + "description": "Do not use token based authentication.\n", + "enabled": true, + "id": "6c8f1b4a-9e41-5fdb-b4bf-57b850ea1d29", + "impact": "You will have to configure and use alternate authentication mechanisms such as certificates. Static token based authentication could not be used.\n", + "muted": false, + "name": "Ensure that the --token-auth-file parameter is not set (Automated)", + "profile_applicability": "* Level 1 - Master Node\n", + "rationale": "The token-based authentication utilizes static tokens to authenticate requests to the apiserver. The tokens are stored in clear-text in a file on the apiserver, and cannot be revoked or rotated without restarting the apiserver. Hence, do not use static token-based authentication.\n", + "references": "1. [https://kubernetes.io/docs/admin/authentication/#static-token-file](https://kubernetes.io/docs/admin/authentication/#static-token-file)\n2. [https://kubernetes.io/docs/admin/kube-apiserver/](https://kubernetes.io/docs/admin/kube-apiserver/)\n", + "rego_rule_id": "cis_1_2_2", + "remediation": "Follow the documentation and configure alternate mechanisms for\nauthentication. Then,\nedit the API server pod specification file `/etc/kubernetes/manifests/kube-apiserver.yaml` \non the control plane node and remove the `--token-auth-file=`\nparameter.\n", + "section": "API Server", + "tags": [ + "CIS", + "Kubernetes", + "CIS 1.2.2", + "API Server" + ], + "version": "1.0" }, "id": "sample_csp_rule_template2", "type": "csp-rule-template" diff --git a/x-pack/test/fleet_api_integration/apis/index.js b/x-pack/test/fleet_api_integration/apis/index.js index 4f9d2026bc531..a2be789b9a982 100644 --- a/x-pack/test/fleet_api_integration/apis/index.js +++ b/x-pack/test/fleet_api_integration/apis/index.js @@ -50,6 +50,9 @@ export default function ({ loadTestFile, getService }) { // Outputs loadTestFile(require.resolve('./outputs')); + // Download sources + loadTestFile(require.resolve('./download_sources')); + // Telemetry loadTestFile(require.resolve('./fleet_telemetry')); diff --git a/x-pack/test/functional/apps/infra/index.ts b/x-pack/test/functional/apps/infra/index.ts index d574c747bf041..9b6e33da3178d 100644 --- a/x-pack/test/functional/apps/infra/index.ts +++ b/x-pack/test/functional/apps/infra/index.ts @@ -10,6 +10,7 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default ({ loadTestFile }: FtrProviderContext) => { describe('InfraOps App', function () { loadTestFile(require.resolve('./feature_controls')); + loadTestFile(require.resolve('./tour')); describe('Metrics UI', function () { loadTestFile(require.resolve('./home_page')); diff --git a/x-pack/test/functional/apps/infra/tour.ts b/x-pack/test/functional/apps/infra/tour.ts new file mode 100644 index 0000000000000..9806115c6129f --- /dev/null +++ b/x-pack/test/functional/apps/infra/tour.ts @@ -0,0 +1,126 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../ftr_provider_context'; + +export default ({ getPageObjects, getService }: FtrProviderContext) => { + const browser = getService('browser'); + const esArchiver = getService('esArchiver'); + const pageObjects = getPageObjects(['common', 'infraHome']); + const find = getService('find'); + + const setInitialTourState = async (activeStep?: number) => { + await browser.setLocalStorageItem( + 'xpack.observability.tourState', + JSON.stringify({ + activeStep: activeStep || 1, + isTourActive: true, + }) + ); + await browser.refresh(); + }; + + describe('Onboarding Observability tour', function () { + this.tags('includeFirefox'); + + before(async () => { + await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'); + await pageObjects.common.navigateToApp('observability'); + }); + + after(async () => { + await esArchiver.unload('x-pack/test/functional/es_archives/infra/metrics_and_logs'); + await browser.removeLocalStorageItem('xpack.observability.tourState'); + }); + + describe('Tour enabled', () => { + it('can complete tour', async () => { + await setInitialTourState(); + + // Step 1: Overview + await pageObjects.infraHome.waitForTourStep('overviewStep'); + await pageObjects.infraHome.clickTourNextButton(); + + // Step 2: Streams + await pageObjects.infraHome.waitForTourStep('streamStep'); + await pageObjects.infraHome.clickTourNextButton(); + + // Step 3: Metrics explorer + await pageObjects.infraHome.waitForTourStep('metricsExplorerStep'); + await pageObjects.infraHome.clickTourNextButton(); + + // Step 4: Traces + await pageObjects.infraHome.waitForTourStep('tracesStep'); + await pageObjects.infraHome.clickTourNextButton(); + + // Step 5: Alerts + await pageObjects.infraHome.waitForTourStep('alertStep'); + await pageObjects.infraHome.clickTourNextButton(); + + // Step 6: Guided setup + await pageObjects.infraHome.waitForTourStep('guidedSetupStep'); + await pageObjects.infraHome.clickTourEndButton(); + await pageObjects.infraHome.ensureTourStepIsClosed('guidedSetupStep'); + }); + + it('can skip tour', async () => { + await setInitialTourState(); + + await pageObjects.infraHome.waitForTourStep('overviewStep'); + await pageObjects.infraHome.clickTourSkipButton(); + + // Verify current step ("Overview") is not displayed + await pageObjects.infraHome.ensureTourStepIsClosed('overviewStep'); + // Verify next step ("Streams") is not displayed + await pageObjects.infraHome.ensureTourStepIsClosed('streamStep'); + + await browser.refresh(); + + // Verify current step ("Overview") is not displayed after browser refresh, + // i.e., localStorage has been updated to not show the tour again + await pageObjects.infraHome.ensureTourStepIsClosed('overviewStep'); + }); + + it('can start mid-tour', async () => { + await setInitialTourState(5); + + // Step 5: Alerts + await pageObjects.infraHome.waitForTourStep('alertStep'); + await pageObjects.infraHome.clickTourNextButton(); + + // Step 6: Guided setup + await pageObjects.infraHome.waitForTourStep('guidedSetupStep'); + await pageObjects.infraHome.clickTourEndButton(); + await pageObjects.infraHome.ensureTourStepIsClosed('guidedSetupStep'); + }); + + it('navigates the user to the guided setup step', async () => { + // For brevity, starting the tour at step 5 + await setInitialTourState(5); + + await pageObjects.infraHome.waitForTourStep('alertStep'); + + // Click on Alerts link + await (await find.byCssSelector('[data-nav-id="alerts"]')).click(); + + // Verify user correctly navigated to the Alerts page + const alertsPageUrl = await browser.getCurrentUrl(); + expect(alertsPageUrl).to.contain('/app/observability/alerts'); + + // Verify Step 5 persists on Alerts page, then continue with tour + await pageObjects.infraHome.waitForTourStep('alertStep'); + await pageObjects.infraHome.clickTourNextButton(); + + // Verify user navigated back to the overview page, and guided setup step renders (Step 6) + await pageObjects.infraHome.waitForTourStep('guidedSetupStep'); + const overviewPageUrl = await browser.getCurrentUrl(); + expect(overviewPageUrl).to.contain('/app/observability/overview'); + }); + }); + }); +}; diff --git a/x-pack/test/functional/es_archives/fleet/agents/data.json b/x-pack/test/functional/es_archives/fleet/agents/data.json index 048ab6bf0853c..2011e2bb221b2 100644 --- a/x-pack/test/functional/es_archives/fleet/agents/data.json +++ b/x-pack/test/functional/es_archives/fleet/agents/data.json @@ -9,7 +9,8 @@ "policy_id": "policy1", "type": "PERMANENT", "local_metadata": {}, - "user_provided_metadata": {} + "user_provided_metadata": {}, + "enrolled_at": "2022-06-21T12:14:25Z" } } } @@ -25,7 +26,8 @@ "policy_id": "policy1", "type": "PERMANENT", "local_metadata": {}, - "user_provided_metadata": {} + "user_provided_metadata": {}, + "enrolled_at": "2022-06-21T12:15:25Z" } } } @@ -41,7 +43,8 @@ "policy_id": "policy1", "type": "PERMANENT", "local_metadata": {}, - "user_provided_metadata": {} + "user_provided_metadata": {}, + "enrolled_at": "2022-06-21T12:16:25Z" } } } @@ -57,7 +60,8 @@ "policy_id": "policy1", "type": "PERMANENT", "local_metadata": {}, - "user_provided_metadata": {} + "user_provided_metadata": {}, + "enrolled_at": "2022-06-21T12:17:25Z" } } } diff --git a/x-pack/test/functional/page_objects/infra_home_page.ts b/x-pack/test/functional/page_objects/infra_home_page.ts index 5a3cb70757b0d..10c2c8237aedc 100644 --- a/x-pack/test/functional/page_objects/infra_home_page.ts +++ b/x-pack/test/functional/page_objects/infra_home_page.ts @@ -328,5 +328,25 @@ export function InfraHomePageProvider({ getService, getPageObjects }: FtrProvide async closeAlertFlyout() { await testSubjects.click('euiFlyoutCloseButton'); }, + + async waitForTourStep(tourStep: string) { + await retry.waitFor('tour step', () => testSubjects.exists(tourStep)); + }, + + async ensureTourStepIsClosed(tourStep: string) { + await testSubjects.missingOrFail(tourStep); + }, + + async clickTourNextButton() { + await testSubjects.click('nextButton'); + }, + + async clickTourEndButton() { + await testSubjects.click('endButton'); + }, + + async clickTourSkipButton() { + await testSubjects.click('skipButton'); + }, }; } diff --git a/x-pack/test/functional/page_objects/rollup_page.ts b/x-pack/test/functional/page_objects/rollup_page.ts index 28ad65f60a49b..f485de8ebac0c 100644 --- a/x-pack/test/functional/page_objects/rollup_page.ts +++ b/x-pack/test/functional/page_objects/rollup_page.ts @@ -13,6 +13,7 @@ export class RollupPageObject extends FtrService { private readonly log = this.ctx.getService('log'); private readonly find = this.ctx.getService('find'); private readonly header = this.ctx.getPageObject('header'); + private readonly retry = this.ctx.getService('retry'); async createNewRollUpJob( jobName: string, @@ -56,6 +57,13 @@ export class RollupPageObject extends FtrService { await this.saveJob(startImmediately); } + async clickRollupJobsTab() { + await this.testSubjects.click('rollup_jobs'); + await this.retry.waitFor('create policy button to be visible', async () => { + return await this.testSubjects.isDisplayed('createRollupJobButton'); + }); + } + async verifyStepIsActive(stepNumber = 0) { await this.testSubjects.exists(`createRollupStep${stepNumber}--active`); } @@ -106,6 +114,16 @@ export class RollupPageObject extends FtrService { } await this.testSubjects.click('rollupJobSaveButton'); await this.header.waitUntilLoadingHasFinished(); + await this.retry.waitFor('detail flyout', async () => { + return await this.testSubjects.isDisplayed('rollupJobDetailsFlyoutTitle'); + }); + } + + async closeFlyout() { + await this.testSubjects.click('euiFlyoutCloseButton'); + await this.retry.waitFor('rollup list table', async () => { + return await this.testSubjects.isDisplayed('rollupJobsListTable'); + }); } async getJobList() { diff --git a/x-pack/test/functional/services/ml/anomalies_table.ts b/x-pack/test/functional/services/ml/anomalies_table.ts index 3cb5f2966718a..7d51539d77002 100644 --- a/x-pack/test/functional/services/ml/anomalies_table.ts +++ b/x-pack/test/functional/services/ml/anomalies_table.ts @@ -173,5 +173,10 @@ export function MachineLearningAnomaliesTableProvider({ getService }: FtrProvide async scrollTableIntoView() { await testSubjects.scrollIntoView('mlAnomaliesTable'); }, + + async scrollRowIntoView(rowIndex: number) { + const rowSubj = await this.getRowSubjByRowIndex(rowIndex); + await testSubjects.scrollIntoView(rowSubj); + }, }; } diff --git a/x-pack/test/performance/journeys/login/config.ts b/x-pack/test/performance/journeys/login/config.ts index 230713eba3024..f7d960582955a 100644 --- a/x-pack/test/performance/journeys/login/config.ts +++ b/x-pack/test/performance/journeys/login/config.ts @@ -14,6 +14,33 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { const config = { testFiles, + scalabilitySetup: { + warmup: { + stages: [ + { + action: 'constantConcurrentUsers', + maxUsersCount: 10, + duration: '30s', + }, + { + action: 'rampConcurrentUsers', + minUsersCount: 10, + maxUsersCount: 50, + duration: '2m', + }, + ], + }, + test: { + stages: [ + { + action: 'constantConcurrentUsers', + maxUsersCount: 50, + duration: '5m', + }, + ], + }, + maxDuration: '10m', + }, ...performanceConfig.getAll(), }; diff --git a/x-pack/test/performance/journeys/promotion_tracking_dashboard/config.ts b/x-pack/test/performance/journeys/promotion_tracking_dashboard/config.ts index fb8d500aa7c09..34e9538316c23 100644 --- a/x-pack/test/performance/journeys/promotion_tracking_dashboard/config.ts +++ b/x-pack/test/performance/journeys/promotion_tracking_dashboard/config.ts @@ -15,6 +15,33 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { const config = { testFiles, ...performanceConfig.getAll(), + scalabilitySetup: { + warmup: { + stages: [ + { + action: 'constantConcurrentUsers', + maxUsersCount: 10, + duration: '30s', + }, + { + action: 'rampConcurrentUsers', + minUsersCount: 10, + maxUsersCount: 50, + duration: '2m', + }, + ], + }, + test: { + stages: [ + { + action: 'constantConcurrentUsers', + maxUsersCount: 50, + duration: '5m', + }, + ], + }, + maxDuration: '10m', + }, }; const apmGlobalLabels = { diff --git a/x-pack/test/performance/services/performance.ts b/x-pack/test/performance/services/performance.ts index 3034883c93e31..2afd9f3e78393 100644 --- a/x-pack/test/performance/services/performance.ts +++ b/x-pack/test/performance/services/performance.ts @@ -9,6 +9,7 @@ import Url from 'url'; import { inspect } from 'util'; +import { setTimeout } from 'timers/promises'; import apm, { Span, Transaction } from 'elastic-apm-node'; import playwright, { ChromiumBrowser, Page, BrowserContext, CDPSession } from 'playwright'; import { FtrService, FtrProviderContext } from '../ftr_provider_context'; @@ -35,14 +36,45 @@ export class PerformanceTestingService extends FtrService { ctx.getService('lifecycle').beforeTests.add(() => { apm.start({ serviceName: 'functional test runner', + environment: process.env.CI ? 'ci' : 'development', + active: this.config.get(`kbnTestServer.env`).ELASTIC_APM_ACTIVE !== 'false', serverUrl: this.config.get(`kbnTestServer.env`).ELASTIC_APM_SERVER_URL, secretToken: this.config.get(`kbnTestServer.env`).ELASTIC_APM_SECRET_TOKEN, globalLabels: this.config.get(`kbnTestServer.env`).ELASTIC_APM_GLOBAL_LABELS, + transactionSampleRate: + this.config.get(`kbnTestServer.env`).ELASTIC_APM_TRANSACTION_SAMPLE_RATE, + logger: process.env.VERBOSE_APM_LOGGING + ? { + warn(...args: any[]) { + console.log('APM WARN', ...args); + }, + info(...args: any[]) { + console.log('APM INFO', ...args); + }, + fatal(...args: any[]) { + console.log('APM FATAL', ...args); + }, + error(...args: any[]) { + console.log('APM ERROR', ...args); + }, + debug(...args: any[]) { + console.log('APM DEBUG', ...args); + }, + trace(...args: any[]) { + console.log('APM TRACE', ...args); + }, + } + : undefined, }); }); ctx.getService('lifecycle').cleanup.add(async () => { await this.shutdownBrowser(); + await new Promise((resolve) => apm.flush(() => resolve())); + // wait for the HTTP request that apm.flush() starts, which we + // can't track but hope is complete within 3 seconds + // https://github.com/elastic/apm-agent-nodejs/issues/2088 + await setTimeout(3000); }); } @@ -173,7 +205,6 @@ export class PerformanceTestingService extends FtrService { private async tearDown(page: Page, client: CDPSession, context: BrowserContext) { if (page) { - apm.flush(); await client.detach(); await page.close(); await context.close(); diff --git a/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/population_analysis.ts b/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/population_analysis.ts index dd1f5f222c8de..a4e65d4f87da4 100644 --- a/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/population_analysis.ts +++ b/x-pack/test/screenshot_creation/apps/ml_docs/anomaly_detection/population_analysis.ts @@ -109,8 +109,14 @@ export default function ({ getService }: FtrProviderContext) { await ml.anomalyExplorer.scrollChartsContainerIntoView(); await ml.anomaliesTable.ensureDetailsOpen(0); + await ml.anomaliesTable.scrollRowIntoView(0); await ml.testExecution.logTestStep('take screenshot'); - await mlScreenshots.takeScreenshot('ml-population-anomaly', screenshotDirectories); + await mlScreenshots.takeScreenshot( + 'ml-population-anomaly', + screenshotDirectories, + 1500, + 1300 + ); }); }); } diff --git a/x-pack/test/screenshot_creation/services/ml_screenshots.ts b/x-pack/test/screenshot_creation/services/ml_screenshots.ts index c0228c6a2b8b1..b354b11712c5f 100644 --- a/x-pack/test/screenshot_creation/services/ml_screenshots.ts +++ b/x-pack/test/screenshot_creation/services/ml_screenshots.ts @@ -8,12 +8,18 @@ import { FtrProviderContext } from '../ftr_provider_context'; export function MachineLearningScreenshotsProvider({ getService }: FtrProviderContext) { + const browser = getService('browser'); const ml = getService('ml'); const screenshot = getService('screenshots'); + const DEFAULT_WIDTH = 1920; + const DEFAULT_HEIGHT = 1080; + return { - async takeScreenshot(name: string, subDirectories: string[]) { + async takeScreenshot(name: string, subDirectories: string[], width?: number, height?: number) { + await browser.setWindowSize(width ?? DEFAULT_WIDTH, height ?? DEFAULT_HEIGHT); await screenshot.take(`${name}_new`, undefined, subDirectories); + await browser.setWindowSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); }, async removeFocusFromElement() { diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_authz.ts b/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_authz.ts index c0b15090cda1e..1b5efd3654e3c 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_authz.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/endpoint_authz.ts @@ -94,12 +94,12 @@ export default function ({ getService }: FtrProviderContext) { { method: 'post', path: KILL_PROCESS_ROUTE, - body: { endpoint_ids: ['one'], parameters: { entity_id: 1234 } }, + body: { endpoint_ids: ['one'], parameters: { entity_id: 'abc123' } }, }, { method: 'post', path: SUSPEND_PROCESS_ROUTE, - body: { endpoint_ids: ['one'], parameters: { entity_id: 1234 } }, + body: { endpoint_ids: ['one'], parameters: { entity_id: 'abc123' } }, }, ]; diff --git a/yarn.lock b/yarn.lock index 5233110b1f99f..b50aae1e20538 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2919,7 +2919,7 @@ version "0.0.0" uid "" -"@kbn/aiops-utils@link:bazel-bin/packages/kbn-aiops-utils": +"@kbn/aiops-utils@link:bazel-bin/x-pack/packages/ml/aiops_utils": version "0.0.0" uid "" @@ -3099,6 +3099,18 @@ version "0.0.0" uid "" +"@kbn/core-fatal-errors-browser-internal@link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser-internal": + version "0.0.0" + uid "" + +"@kbn/core-fatal-errors-browser-mocks@link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser-mocks": + version "0.0.0" + uid "" + +"@kbn/core-fatal-errors-browser@link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser": + version "0.0.0" + uid "" + "@kbn/core-i18n-browser-internal@link:bazel-bin/packages/core/i18n/core-i18n-browser-internal": version "0.0.0" uid "" @@ -3255,10 +3267,6 @@ version "0.0.0" uid "" -"@kbn/kbn-ci-stats-performance-metrics@link:bazel-bin/packages/kbn-kbn-ci-stats-performance-metrics": - version "0.0.0" - uid "" - "@kbn/kibana-json-schema@link:bazel-bin/packages/kbn-kibana-json-schema": version "0.0.0" uid "" @@ -6366,7 +6374,7 @@ version "0.0.0" uid "" -"@types/kbn__aiops-utils@link:bazel-bin/packages/kbn-aiops-utils/npm_module_types": +"@types/kbn__aiops-utils@link:bazel-bin/x-pack/packages/ml/aiops_utils/npm_module_types": version "0.0.0" uid "" @@ -6542,6 +6550,18 @@ version "0.0.0" uid "" +"@types/kbn__core-fatal-errors-browser-internal@link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser-internal/npm_module_types": + version "0.0.0" + uid "" + +"@types/kbn__core-fatal-errors-browser-mocks@link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser-mocks/npm_module_types": + version "0.0.0" + uid "" + +"@types/kbn__core-fatal-errors-browser@link:bazel-bin/packages/core/fatal-errors/core-fatal-errors-browser/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__core-i18n-browser-internal@link:bazel-bin/packages/core/i18n/core-i18n-browser-internal/npm_module_types": version "0.0.0" uid "" @@ -24025,11 +24045,6 @@ randexp@0.4.6: discontinuous-range "1.0.0" ret "~0.1.10" -random-word-slugs@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/random-word-slugs/-/random-word-slugs-0.0.5.tgz#6ccd6c7ea320be9fbc19507f8c3a7d4a970ff61f" - integrity sha512-KwelmWsWHiMl3MKauB5usAIPg2FgwAku+FVYEuf32yyhZmEh3Fq4nXBxeUAgXB2F+G/HTeDsqXsmuupmOMnjRg== - randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"