diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 63fdf3044be5f..4dc48e657542b 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -782,6 +782,9 @@ packages/core/integrations/core-integrations-browser-mocks @elastic/kibana-core
packages/core/lifecycle/core-lifecycle-browser @elastic/kibana-core
packages/core/lifecycle/core-lifecycle-browser-internal @elastic/kibana-core
packages/core/lifecycle/core-lifecycle-browser-mocks @elastic/kibana-core
+packages/core/lifecycle/core-lifecycle-server @elastic/kibana-core
+packages/core/lifecycle/core-lifecycle-server-internal @elastic/kibana-core
+packages/core/lifecycle/core-lifecycle-server-mocks @elastic/kibana-core
packages/core/logging/core-logging-server @elastic/kibana-core
packages/core/logging/core-logging-server-internal @elastic/kibana-core
packages/core/logging/core-logging-server-mocks @elastic/kibana-core
@@ -805,6 +808,9 @@ packages/core/plugins/core-plugins-base-server-internal @elastic/kibana-core
packages/core/plugins/core-plugins-browser @elastic/kibana-core
packages/core/plugins/core-plugins-browser-internal @elastic/kibana-core
packages/core/plugins/core-plugins-browser-mocks @elastic/kibana-core
+packages/core/plugins/core-plugins-server @elastic/kibana-core
+packages/core/plugins/core-plugins-server-internal @elastic/kibana-core
+packages/core/plugins/core-plugins-server-mocks @elastic/kibana-core
packages/core/preboot/core-preboot-server @elastic/kibana-core
packages/core/preboot/core-preboot-server-internal @elastic/kibana-core
packages/core/preboot/core-preboot-server-mocks @elastic/kibana-core
diff --git a/api_docs/actions.devdocs.json b/api_docs/actions.devdocs.json
index 0f63f83fedf12..278caf26266e3 100644
--- a/api_docs/actions.devdocs.json
+++ b/api_docs/actions.devdocs.json
@@ -772,6 +772,102 @@
}
],
"initialIsOpen": false
+ },
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.UnsecuredActionsClient",
+ "type": "Class",
+ "tags": [],
+ "label": "UnsecuredActionsClient",
+ "description": [],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "children": [
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.UnsecuredActionsClient.Unnamed",
+ "type": "Function",
+ "tags": [],
+ "label": "Constructor",
+ "description": [],
+ "signature": [
+ "any"
+ ],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "children": [
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.UnsecuredActionsClient.Unnamed.$1",
+ "type": "Object",
+ "tags": [],
+ "label": "params",
+ "description": [],
+ "signature": [
+ "UnsecuredActionsClientOpts"
+ ],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "isRequired": true
+ }
+ ],
+ "returnComment": []
+ },
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.UnsecuredActionsClient.bulkEnqueueExecution",
+ "type": "Function",
+ "tags": [],
+ "label": "bulkEnqueueExecution",
+ "description": [],
+ "signature": [
+ "(requesterId: string, actionsToExecute: ",
+ "ExecuteOptions",
+ "[]) => Promise"
+ ],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "children": [
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.UnsecuredActionsClient.bulkEnqueueExecution.$1",
+ "type": "string",
+ "tags": [],
+ "label": "requesterId",
+ "description": [],
+ "signature": [
+ "string"
+ ],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "isRequired": true
+ },
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.UnsecuredActionsClient.bulkEnqueueExecution.$2",
+ "type": "Array",
+ "tags": [],
+ "label": "actionsToExecute",
+ "description": [],
+ "signature": [
+ "ExecuteOptions",
+ "[]"
+ ],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "isRequired": true
+ }
+ ],
+ "returnComment": []
+ }
+ ],
+ "initialIsOpen": false
}
],
"functions": [
@@ -1494,6 +1590,70 @@
],
"initialIsOpen": false
},
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.IUnsecuredActionsClient",
+ "type": "Interface",
+ "tags": [],
+ "label": "IUnsecuredActionsClient",
+ "description": [],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "children": [
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.IUnsecuredActionsClient.bulkEnqueueExecution",
+ "type": "Function",
+ "tags": [],
+ "label": "bulkEnqueueExecution",
+ "description": [],
+ "signature": [
+ "(requesterId: string, actionsToExecute: ",
+ "ExecuteOptions",
+ "[]) => Promise"
+ ],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "children": [
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.IUnsecuredActionsClient.bulkEnqueueExecution.$1",
+ "type": "string",
+ "tags": [],
+ "label": "requesterId",
+ "description": [],
+ "signature": [
+ "string"
+ ],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "isRequired": true
+ },
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.IUnsecuredActionsClient.bulkEnqueueExecution.$2",
+ "type": "Array",
+ "tags": [],
+ "label": "actionsToExecute",
+ "description": [],
+ "signature": [
+ "ExecuteOptions",
+ "[]"
+ ],
+ "path": "x-pack/plugins/actions/server/unsecured_actions_client/unsecured_actions_client.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "isRequired": true
+ }
+ ],
+ "returnComment": []
+ }
+ ],
+ "initialIsOpen": false
+ },
{
"parentPluginId": "actions",
"id": "def-server.PreConfiguredAction",
@@ -2240,6 +2400,29 @@
"deprecated": false,
"trackAdoption": false
},
+ {
+ "parentPluginId": "actions",
+ "id": "def-server.PluginStartContract.getUnsecuredActionsClient",
+ "type": "Function",
+ "tags": [],
+ "label": "getUnsecuredActionsClient",
+ "description": [],
+ "signature": [
+ "() => ",
+ {
+ "pluginId": "actions",
+ "scope": "server",
+ "docId": "kibActionsPluginApi",
+ "section": "def-server.IUnsecuredActionsClient",
+ "text": "IUnsecuredActionsClient"
+ }
+ ],
+ "path": "x-pack/plugins/actions/server/plugin.ts",
+ "deprecated": false,
+ "trackAdoption": false,
+ "children": [],
+ "returnComment": []
+ },
{
"parentPluginId": "actions",
"id": "def-server.PluginStartContract.renderActionParameterTemplates",
diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx
index d644934bb674c..97fa8a58713eb 100644
--- a/api_docs/actions.mdx
+++ b/api_docs/actions.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions
title: "actions"
image: https://source.unsplash.com/400x175/?github
description: API docs for the actions plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions']
---
import actionsObj from './actions.devdocs.json';
@@ -21,7 +21,7 @@ Contact [Response Ops](https://github.com/orgs/elastic/teams/response-ops) for q
| Public API count | Any count | Items lacking comments | Missing exports |
|-------------------|-----------|------------------------|-----------------|
-| 214 | 0 | 209 | 23 |
+| 225 | 0 | 220 | 24 |
## Client
diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx
index 7a76f4d13c19b..f4a0edb8fdad4 100644
--- a/api_docs/advanced_settings.mdx
+++ b/api_docs/advanced_settings.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings
title: "advancedSettings"
image: https://source.unsplash.com/400x175/?github
description: API docs for the advancedSettings plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'advancedSettings']
---
import advancedSettingsObj from './advanced_settings.devdocs.json';
diff --git a/api_docs/aiops.mdx b/api_docs/aiops.mdx
index 2e6699edb8a1c..8e2dc536c4852 100644
--- a/api_docs/aiops.mdx
+++ b/api_docs/aiops.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops
title: "aiops"
image: https://source.unsplash.com/400x175/?github
description: API docs for the aiops plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'aiops']
---
import aiopsObj from './aiops.devdocs.json';
diff --git a/api_docs/alerting.mdx b/api_docs/alerting.mdx
index 758497cc8d70e..dcdfced09dea9 100644
--- a/api_docs/alerting.mdx
+++ b/api_docs/alerting.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting
title: "alerting"
image: https://source.unsplash.com/400x175/?github
description: API docs for the alerting plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting']
---
import alertingObj from './alerting.devdocs.json';
diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json
index b59192b6334c8..ff8a1c84b2964 100644
--- a/api_docs/apm.devdocs.json
+++ b/api_docs/apm.devdocs.json
@@ -110,13 +110,7 @@
"text": "APMPlugin"
},
" implements ",
- {
- "pluginId": "core",
- "scope": "server",
- "docId": "kibCorePluginApi",
- "section": "def-server.Plugin",
- "text": "Plugin"
- },
+ "Plugin",
"<",
{
"pluginId": "apm",
@@ -157,13 +151,7 @@
"label": "initContext",
"description": [],
"signature": [
- {
- "pluginId": "core",
- "scope": "server",
- "docId": "kibCorePluginApi",
- "section": "def-server.PluginInitializerContext",
- "text": "PluginInitializerContext"
- },
+ "PluginInitializerContext",
""
],
"path": "x-pack/plugins/apm/server/plugin.ts",
@@ -183,13 +171,7 @@
"description": [],
"signature": [
"(core: ",
- {
- "pluginId": "core",
- "scope": "server",
- "docId": "kibCorePluginApi",
- "section": "def-server.CoreSetup",
- "text": "CoreSetup"
- },
+ "CoreSetup",
"<",
"APMPluginStartDependencies",
", unknown>, plugins: ",
@@ -220,13 +202,7 @@
"label": "core",
"description": [],
"signature": [
- {
- "pluginId": "core",
- "scope": "server",
- "docId": "kibCorePluginApi",
- "section": "def-server.CoreSetup",
- "text": "CoreSetup"
- },
+ "CoreSetup",
"<",
"APMPluginStartDependencies",
", unknown>"
@@ -263,13 +239,7 @@
"description": [],
"signature": [
"(core: ",
- {
- "pluginId": "core",
- "scope": "server",
- "docId": "kibCorePluginApi",
- "section": "def-server.CoreStart",
- "text": "CoreStart"
- },
+ "CoreStart",
") => void"
],
"path": "x-pack/plugins/apm/server/plugin.ts",
@@ -284,13 +254,7 @@
"label": "core",
"description": [],
"signature": [
- {
- "pluginId": "core",
- "scope": "server",
- "docId": "kibCorePluginApi",
- "section": "def-server.CoreStart",
- "text": "CoreStart"
- }
+ "CoreStart"
],
"path": "x-pack/plugins/apm/server/plugin.ts",
"deprecated": false,
@@ -753,7 +717,7 @@
"label": "APIEndpoint",
"description": [],
"signature": [
- "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/title\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics_by_transaction_name\" | \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/top_erroneous_transactions\" | \"POST /internal/apm/latency/overall_distribution/transactions\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/nodes\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/summary\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/dependency\" | \"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}/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/service_groups/services_count\" | \"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/rule_types/transaction_error_rate/chart_preview\" | \"GET /internal/apm/rule_types/transaction_duration/chart_preview\" | \"GET /internal/apm/rule_types/error_count/chart_preview\" | \"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/fleet/java_agent_versions\" | \"GET /internal/apm/dependencies/top_dependencies\" | \"GET /internal/apm/dependencies/upstream_services\" | \"GET /internal/apm/dependencies/metadata\" | \"GET /internal/apm/dependencies/charts/latency\" | \"GET /internal/apm/dependencies/charts/throughput\" | \"GET /internal/apm/dependencies/charts/error_rate\" | \"GET /internal/apm/dependencies/operations\" | \"GET /internal/apm/dependencies/charts/distribution\" | \"GET /internal/apm/dependencies/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/storage_explorer\" | \"GET /internal/apm/services/{serviceName}/storage_details\" | \"GET /internal/apm/storage_chart\" | \"GET /internal/apm/storage_explorer/privileges\" | \"GET /internal/apm/storage_explorer_summary_stats\" | \"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\" | \"GET /internal/apm/settings/labs\""
+ "\"POST /internal/apm/data_view/static\" | \"GET /internal/apm/data_view/title\" | \"GET /internal/apm/environments\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/groups/main_statistics_by_transaction_name\" | \"POST /internal/apm/services/{serviceName}/errors/groups/detailed_statistics\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}\" | \"GET /internal/apm/services/{serviceName}/errors/distribution\" | \"GET /internal/apm/services/{serviceName}/errors/{groupId}/top_erroneous_transactions\" | \"POST /internal/apm/latency/overall_distribution/transactions\" | \"GET /internal/apm/services/{serviceName}/metrics/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/nodes\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/charts\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/summary\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/functions_overview\" | \"GET /internal/apm/services/{serviceName}/metrics/serverless/active_instances\" | \"GET /internal/apm/observability_overview\" | \"GET /internal/apm/observability_overview/has_data\" | \"GET /internal/apm/service-map\" | \"GET /internal/apm/service-map/service/{serviceName}\" | \"GET /internal/apm/service-map/dependency\" | \"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}/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/service_groups/services_count\" | \"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/rule_types/transaction_error_rate/chart_preview\" | \"GET /internal/apm/rule_types/transaction_duration/chart_preview\" | \"GET /internal/apm/rule_types/error_count/chart_preview\" | \"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/fleet/java_agent_versions\" | \"GET /internal/apm/dependencies/top_dependencies\" | \"GET /internal/apm/dependencies/upstream_services\" | \"GET /internal/apm/dependencies/metadata\" | \"GET /internal/apm/dependencies/charts/latency\" | \"GET /internal/apm/dependencies/charts/throughput\" | \"GET /internal/apm/dependencies/charts/error_rate\" | \"GET /internal/apm/dependencies/operations\" | \"GET /internal/apm/dependencies/charts/distribution\" | \"GET /internal/apm/dependencies/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/storage_explorer\" | \"GET /internal/apm/services/{serviceName}/storage_details\" | \"GET /internal/apm/storage_chart\" | \"GET /internal/apm/storage_explorer/privileges\" | \"GET /internal/apm/storage_explorer_summary_stats\" | \"GET /internal/apm/storage_explorer/is_cross_cluster_search\" | \"GET /internal/apm/storage_explorer/get_services\" | \"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\" | \"GET /internal/apm/settings/labs\""
],
"path": "x-pack/plugins/apm/server/routes/apm_routes/get_global_apm_server_route_repository.ts",
"deprecated": false,
@@ -1027,6 +991,76 @@
"SpanLinkDetails",
"[]; }, ",
"APMRouteCreateOptions",
+ ">; \"GET /internal/apm/storage_explorer/get_services\": ",
+ "ServerRoute",
+ "<\"GET /internal/apm/storage_explorer/get_services\", ",
+ "TypeC",
+ "<{ query: ",
+ "IntersectionC",
+ "<[",
+ "TypeC",
+ "<{ indexLifecyclePhase: ",
+ "UnionC",
+ "<[",
+ "LiteralC",
+ "<",
+ "IndexLifecyclePhaseSelectOption",
+ ".All>, ",
+ "LiteralC",
+ "<",
+ "IndexLifecyclePhaseSelectOption",
+ ".Hot>, ",
+ "LiteralC",
+ "<",
+ "IndexLifecyclePhaseSelectOption",
+ ".Warm>, ",
+ "LiteralC",
+ "<",
+ "IndexLifecyclePhaseSelectOption",
+ ".Cold>, ",
+ "LiteralC",
+ "<",
+ "IndexLifecyclePhaseSelectOption",
+ ".Frozen>]>; }>, ",
+ "TypeC",
+ "<{ environment: ",
+ "UnionC",
+ "<[",
+ "LiteralC",
+ "<\"ENVIRONMENT_NOT_DEFINED\">, ",
+ "LiteralC",
+ "<\"ENVIRONMENT_ALL\">, ",
+ "BrandC",
+ "<",
+ "StringC",
+ ", ",
+ "NonEmptyStringBrand",
+ ">]>; }>, ",
+ "TypeC",
+ "<{ kuery: ",
+ "StringC",
+ "; }>]>; }>, ",
+ {
+ "pluginId": "apm",
+ "scope": "server",
+ "docId": "kibApmPluginApi",
+ "section": "def-server.APMRouteHandlerResources",
+ "text": "APMRouteHandlerResources"
+ },
+ ", { services: { serviceName: string; }[]; }, ",
+ "APMRouteCreateOptions",
+ ">; \"GET /internal/apm/storage_explorer/is_cross_cluster_search\": ",
+ "ServerRoute",
+ "<\"GET /internal/apm/storage_explorer/is_cross_cluster_search\", undefined, ",
+ {
+ "pluginId": "apm",
+ "scope": "server",
+ "docId": "kibApmPluginApi",
+ "section": "def-server.APMRouteHandlerResources",
+ "text": "APMRouteHandlerResources"
+ },
+ ", { isCrossClusterSearch: boolean; }, ",
+ "APMRouteCreateOptions",
">; \"GET /internal/apm/storage_explorer_summary_stats\": ",
"ServerRoute",
"<\"GET /internal/apm/storage_explorer_summary_stats\", ",
@@ -1093,7 +1127,7 @@
"section": "def-server.APMRouteHandlerResources",
"text": "APMRouteHandlerResources"
},
- ", { tracesPerMinute: number; numberOfServices: number; estimatedSize: number; dailyDataGeneration: number; }, ",
+ ", { tracesPerMinute: number; numberOfServices: number; totalSize: number; diskSpaceUsedPct: number; estimatedIncrementalSize: number; dailyDataGeneration: number; }, ",
"APMRouteCreateOptions",
">; \"GET /internal/apm/storage_explorer/privileges\": ",
"ServerRoute",
@@ -1253,7 +1287,7 @@
"section": "def-common.ProcessorEvent",
"text": "ProcessorEvent"
},
- "; docs: number; size: number; }[]; }, ",
+ "; docs: number; size: number; }[]; indicesStats: { indexName: string; numberOfDocs: number; primary?: string | number | undefined; replica?: string | number | undefined; size?: number | undefined; dataStream?: string | undefined; lifecyclePhase?: string | undefined; }[]; }, ",
"APMRouteCreateOptions",
">; \"GET /internal/apm/storage_explorer\": ",
"ServerRoute",
diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx
index 913c686a7a008..e22939b28442c 100644
--- a/api_docs/apm.mdx
+++ b/api_docs/apm.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm
title: "apm"
image: https://source.unsplash.com/400x175/?github
description: API docs for the apm plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm']
---
import apmObj from './apm.devdocs.json';
diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx
index 0188bd4bbd567..f16f3cf9d25eb 100644
--- a/api_docs/banners.mdx
+++ b/api_docs/banners.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners
title: "banners"
image: https://source.unsplash.com/400x175/?github
description: API docs for the banners plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'banners']
---
import bannersObj from './banners.devdocs.json';
diff --git a/api_docs/bfetch.mdx b/api_docs/bfetch.mdx
index 3a48b2eb21a9f..25221b9f93372 100644
--- a/api_docs/bfetch.mdx
+++ b/api_docs/bfetch.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch
title: "bfetch"
image: https://source.unsplash.com/400x175/?github
description: API docs for the bfetch plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'bfetch']
---
import bfetchObj from './bfetch.devdocs.json';
diff --git a/api_docs/canvas.mdx b/api_docs/canvas.mdx
index f9ea21275a294..f54c7efaa9edf 100644
--- a/api_docs/canvas.mdx
+++ b/api_docs/canvas.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas
title: "canvas"
image: https://source.unsplash.com/400x175/?github
description: API docs for the canvas plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'canvas']
---
import canvasObj from './canvas.devdocs.json';
diff --git a/api_docs/cases.mdx b/api_docs/cases.mdx
index 17c2f0bc24b98..9645e8dcf1d0a 100644
--- a/api_docs/cases.mdx
+++ b/api_docs/cases.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases
title: "cases"
image: https://source.unsplash.com/400x175/?github
description: API docs for the cases plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cases']
---
import casesObj from './cases.devdocs.json';
diff --git a/api_docs/charts.mdx b/api_docs/charts.mdx
index 1292beac03c9e..5631dbdeca13b 100644
--- a/api_docs/charts.mdx
+++ b/api_docs/charts.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts
title: "charts"
image: https://source.unsplash.com/400x175/?github
description: API docs for the charts plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts']
---
import chartsObj from './charts.devdocs.json';
diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx
index 0be814b32854f..5b2a574909627 100644
--- a/api_docs/cloud.mdx
+++ b/api_docs/cloud.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud
title: "cloud"
image: https://source.unsplash.com/400x175/?github
description: API docs for the cloud plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud']
---
import cloudObj from './cloud.devdocs.json';
diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx
index c59647a5538b5..e1909e7a093af 100644
--- a/api_docs/cloud_chat.mdx
+++ b/api_docs/cloud_chat.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChat
title: "cloudChat"
image: https://source.unsplash.com/400x175/?github
description: API docs for the cloudChat plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat']
---
import cloudChatObj from './cloud_chat.devdocs.json';
diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx
index 8427d221e4f63..1c78ae2cbf9ef 100644
--- a/api_docs/cloud_experiments.mdx
+++ b/api_docs/cloud_experiments.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments
title: "cloudExperiments"
image: https://source.unsplash.com/400x175/?github
description: API docs for the cloudExperiments plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudExperiments']
---
import cloudExperimentsObj from './cloud_experiments.devdocs.json';
diff --git a/api_docs/cloud_security_posture.mdx b/api_docs/cloud_security_posture.mdx
index 58e7f8a3c0e94..281cebcabf59e 100644
--- a/api_docs/cloud_security_posture.mdx
+++ b/api_docs/cloud_security_posture.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture
title: "cloudSecurityPosture"
image: https://source.unsplash.com/400x175/?github
description: API docs for the cloudSecurityPosture plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudSecurityPosture']
---
import cloudSecurityPostureObj from './cloud_security_posture.devdocs.json';
diff --git a/api_docs/console.mdx b/api_docs/console.mdx
index cd10bdee5aeb3..7a9eaac825214 100644
--- a/api_docs/console.mdx
+++ b/api_docs/console.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console
title: "console"
image: https://source.unsplash.com/400x175/?github
description: API docs for the console plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console']
---
import consoleObj from './console.devdocs.json';
diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx
index 12050905e2c74..d3472eb71af70 100644
--- a/api_docs/controls.mdx
+++ b/api_docs/controls.mdx
@@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls
title: "controls"
image: https://source.unsplash.com/400x175/?github
description: API docs for the controls plugin
-date: 2022-10-26
+date: 2022-10-27
tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls']
---
import controlsObj from './controls.devdocs.json';
diff --git a/api_docs/core.devdocs.json b/api_docs/core.devdocs.json
index 969cd53cae5ba..34c162ad5a2a1 100644
--- a/api_docs/core.devdocs.json
+++ b/api_docs/core.devdocs.json
@@ -592,6 +592,30 @@
"plugin": "@kbn/core-analytics-server-internal",
"path": "packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts"
},
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
{
"plugin": "@kbn/core-root-browser-internal",
"path": "packages/core/root/core-root-browser-internal/src/core_system.ts"
@@ -994,6 +1018,22 @@
"plugin": "@kbn/core-execution-context-browser-internal",
"path": "packages/core/execution-context/core-execution-context-browser-internal/src/execution_context_service.ts"
},
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
{
"plugin": "@kbn/core-status-server-internal",
"path": "packages/core/status/core-status-server-internal/src/status_service.ts"
@@ -19467,6 +19507,30 @@
"plugin": "@kbn/core-analytics-server-internal",
"path": "packages/core/analytics/core-analytics-server-internal/src/analytics_service.ts"
},
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
{
"plugin": "@kbn/core-root-browser-internal",
"path": "packages/core/root/core-root-browser-internal/src/core_system.ts"
@@ -19869,6 +19933,22 @@
"plugin": "@kbn/core-execution-context-browser-internal",
"path": "packages/core/execution-context/core-execution-context-browser-internal/src/execution_context_service.ts"
},
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts"
+ },
{
"plugin": "@kbn/core-status-server-internal",
"path": "packages/core/status/core-status-server-internal/src/status_service.ts"
@@ -20197,20 +20277,23 @@
"\nA plugin with asynchronous lifecycle methods.\n"
],
"signature": [
- {
- "pluginId": "core",
- "scope": "server",
- "docId": "kibCorePluginApi",
- "section": "def-server.AsyncPlugin",
- "text": "AsyncPlugin"
- },
+ "AsyncPlugin",
""
],
- "path": "src/core/server/plugins/types.ts",
+ "path": "node_modules/@types/kbn__core-plugins-server/index.d.ts",
"deprecated": true,
"removeBy": "8.8.0",
"trackAdoption": false,
- "references": [],
+ "references": [
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin.ts"
+ },
+ {
+ "plugin": "@kbn/core-plugins-server-internal",
+ "path": "packages/core/plugins/core-plugins-server-internal/src/plugin.ts"
+ }
+ ],
"children": [
{
"parentPluginId": "core",
@@ -20221,16 +20304,10 @@
"description": [],
"signature": [
"(core: ",
- {
- "pluginId": "core",
- "scope": "server",
- "docId": "kibCorePluginApi",
- "section": "def-server.CoreSetup",
- "text": "CoreSetup"
- },
+ "CoreSetup",
"
@@ -72,12 +72,12 @@ export const StepOne = ({ guidedOnboarding }: GuidedOnboardingExampleAppDeps) =>
onFinish={() => setIsTourStepOpen(false)}
step={1}
stepsTotal={1}
- title="Step Add data"
+ title="Step 1"
anchorPosition="rightUp"
>
{
- await guidedOnboardingApi?.completeGuideStep('search', 'add_data');
+ await guidedOnboardingApi?.completeGuideStep('testGuide', 'step1');
}}
>
Complete step 1
diff --git a/examples/guided_onboarding_example/public/components/step_three.tsx b/examples/guided_onboarding_example/public/components/step_three.tsx
index ffe9d87993611..eefb38165beed 100644
--- a/examples/guided_onboarding_example/public/components/step_three.tsx
+++ b/examples/guided_onboarding_example/public/components/step_three.tsx
@@ -30,7 +30,7 @@ export const StepThree = (props: StepThreeProps) => {
useEffect(() => {
const subscription = guidedOnboardingApi
- ?.isGuideStepActive$('search', 'search_experience')
+ ?.isGuideStepActive$('testGuide', 'step3')
.subscribe((isStepActive) => {
setIsTourStepOpen(isStepActive);
});
@@ -53,9 +53,17 @@ export const StepThree = (props: StepThreeProps) => {
+
+
+
@@ -73,12 +81,12 @@ export const StepThree = (props: StepThreeProps) => {
}}
step={1}
stepsTotal={1}
- title="Step Build search experience"
+ title="Step 3"
anchorPosition="rightUp"
>
{
- await guidedOnboardingApi?.completeGuideStep('search', 'search_experience');
+ await guidedOnboardingApi?.completeGuideStep('testGuide', 'step3');
}}
>
Complete step 3
diff --git a/examples/guided_onboarding_example/public/components/step_two.tsx b/examples/guided_onboarding_example/public/components/step_two.tsx
index 07f4fd7e63e0c..89c0c37e46e4a 100644
--- a/examples/guided_onboarding_example/public/components/step_two.tsx
+++ b/examples/guided_onboarding_example/public/components/step_two.tsx
@@ -6,37 +6,17 @@
* Side Public License, v 1.
*/
-import React, { useEffect, useState } from 'react';
+import React from 'react';
-import { EuiButton, EuiSpacer, EuiText, EuiTitle, EuiTourStep } from '@elastic/eui';
+import { EuiText, EuiTitle } from '@elastic/eui';
-import { GuidedOnboardingPluginStart } from '@kbn/guided-onboarding-plugin/public/types';
import { FormattedMessage } from '@kbn/i18n-react';
import {
EuiPageContentHeader_Deprecated as EuiPageContentHeader,
EuiPageContentBody_Deprecated as EuiPageContentBody,
} from '@elastic/eui';
-interface StepTwoProps {
- guidedOnboarding: GuidedOnboardingPluginStart;
-}
-
-export const StepTwo = (props: StepTwoProps) => {
- const {
- guidedOnboarding: { guidedOnboardingApi },
- } = props;
-
- const [isTourStepOpen, setIsTourStepOpen] = useState(false);
-
- useEffect(() => {
- const subscription = guidedOnboardingApi
- ?.isGuideStepActive$('search', 'browse_docs')
- .subscribe((isStepActive) => {
- setIsTourStepOpen(isStepActive);
- });
- return () => subscription?.unsubscribe();
- }, [guidedOnboardingApi]);
-
+export const StepTwo = () => {
return (
<>
@@ -54,36 +34,11 @@ export const StepTwo = (props: StepTwoProps) => {
-
-
- Click this button to complete step 2.
-
- }
- isStepOpen={isTourStepOpen}
- minWidth={300}
- onFinish={() => {
- setIsTourStepOpen(false);
- }}
- step={1}
- stepsTotal={1}
- title="Step Browse documents"
- anchorPosition="rightUp"
- >
- {
- await guidedOnboardingApi?.completeGuideStep('search', 'browse_docs');
- }}
- >
- Complete step 2
-
-
>
);
diff --git a/package.json b/package.json
index 7144902af8e39..bb7cd79238c33 100644
--- a/package.json
+++ b/package.json
@@ -241,6 +241,9 @@
"@kbn/core-lifecycle-browser": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-browser",
"@kbn/core-lifecycle-browser-internal": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-browser-internal",
"@kbn/core-lifecycle-browser-mocks": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-browser-mocks",
+ "@kbn/core-lifecycle-server": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-server",
+ "@kbn/core-lifecycle-server-internal": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-server-internal",
+ "@kbn/core-lifecycle-server-mocks": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-server-mocks",
"@kbn/core-logging-server": "link:bazel-bin/packages/core/logging/core-logging-server",
"@kbn/core-logging-server-internal": "link:bazel-bin/packages/core/logging/core-logging-server-internal",
"@kbn/core-logging-server-mocks": "link:bazel-bin/packages/core/logging/core-logging-server-mocks",
@@ -264,6 +267,9 @@
"@kbn/core-plugins-browser": "link:bazel-bin/packages/core/plugins/core-plugins-browser",
"@kbn/core-plugins-browser-internal": "link:bazel-bin/packages/core/plugins/core-plugins-browser-internal",
"@kbn/core-plugins-browser-mocks": "link:bazel-bin/packages/core/plugins/core-plugins-browser-mocks",
+ "@kbn/core-plugins-server": "link:bazel-bin/packages/core/plugins/core-plugins-server",
+ "@kbn/core-plugins-server-internal": "link:bazel-bin/packages/core/plugins/core-plugins-server-internal",
+ "@kbn/core-plugins-server-mocks": "link:bazel-bin/packages/core/plugins/core-plugins-server-mocks",
"@kbn/core-preboot-server": "link:bazel-bin/packages/core/preboot/core-preboot-server",
"@kbn/core-preboot-server-internal": "link:bazel-bin/packages/core/preboot/core-preboot-server-internal",
"@kbn/core-preboot-server-mocks": "link:bazel-bin/packages/core/preboot/core-preboot-server-mocks",
@@ -979,6 +985,9 @@
"@types/kbn__core-lifecycle-browser": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-browser/npm_module_types",
"@types/kbn__core-lifecycle-browser-internal": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-browser-internal/npm_module_types",
"@types/kbn__core-lifecycle-browser-mocks": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-browser-mocks/npm_module_types",
+ "@types/kbn__core-lifecycle-server": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-server/npm_module_types",
+ "@types/kbn__core-lifecycle-server-internal": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-server-internal/npm_module_types",
+ "@types/kbn__core-lifecycle-server-mocks": "link:bazel-bin/packages/core/lifecycle/core-lifecycle-server-mocks/npm_module_types",
"@types/kbn__core-logging-server": "link:bazel-bin/packages/core/logging/core-logging-server/npm_module_types",
"@types/kbn__core-logging-server-internal": "link:bazel-bin/packages/core/logging/core-logging-server-internal/npm_module_types",
"@types/kbn__core-logging-server-mocks": "link:bazel-bin/packages/core/logging/core-logging-server-mocks/npm_module_types",
@@ -1002,6 +1011,9 @@
"@types/kbn__core-plugins-browser": "link:bazel-bin/packages/core/plugins/core-plugins-browser/npm_module_types",
"@types/kbn__core-plugins-browser-internal": "link:bazel-bin/packages/core/plugins/core-plugins-browser-internal/npm_module_types",
"@types/kbn__core-plugins-browser-mocks": "link:bazel-bin/packages/core/plugins/core-plugins-browser-mocks/npm_module_types",
+ "@types/kbn__core-plugins-server": "link:bazel-bin/packages/core/plugins/core-plugins-server/npm_module_types",
+ "@types/kbn__core-plugins-server-internal": "link:bazel-bin/packages/core/plugins/core-plugins-server-internal/npm_module_types",
+ "@types/kbn__core-plugins-server-mocks": "link:bazel-bin/packages/core/plugins/core-plugins-server-mocks/npm_module_types",
"@types/kbn__core-preboot-server": "link:bazel-bin/packages/core/preboot/core-preboot-server/npm_module_types",
"@types/kbn__core-preboot-server-internal": "link:bazel-bin/packages/core/preboot/core-preboot-server-internal/npm_module_types",
"@types/kbn__core-preboot-server-mocks": "link:bazel-bin/packages/core/preboot/core-preboot-server-mocks/npm_module_types",
diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel
index b68c27b27f3dd..d14389555251f 100644
--- a/packages/BUILD.bazel
+++ b/packages/BUILD.bazel
@@ -105,6 +105,9 @@ filegroup(
"//packages/core/lifecycle/core-lifecycle-browser:build",
"//packages/core/lifecycle/core-lifecycle-browser-internal:build",
"//packages/core/lifecycle/core-lifecycle-browser-mocks:build",
+ "//packages/core/lifecycle/core-lifecycle-server:build",
+ "//packages/core/lifecycle/core-lifecycle-server-internal:build",
+ "//packages/core/lifecycle/core-lifecycle-server-mocks:build",
"//packages/core/logging/core-logging-server:build",
"//packages/core/logging/core-logging-server-internal:build",
"//packages/core/logging/core-logging-server-mocks:build",
@@ -128,6 +131,9 @@ filegroup(
"//packages/core/plugins/core-plugins-browser:build",
"//packages/core/plugins/core-plugins-browser-internal:build",
"//packages/core/plugins/core-plugins-browser-mocks:build",
+ "//packages/core/plugins/core-plugins-server:build",
+ "//packages/core/plugins/core-plugins-server-internal:build",
+ "//packages/core/plugins/core-plugins-server-mocks:build",
"//packages/core/preboot/core-preboot-server:build",
"//packages/core/preboot/core-preboot-server-internal:build",
"//packages/core/preboot/core-preboot-server-mocks:build",
@@ -454,6 +460,9 @@ filegroup(
"//packages/core/lifecycle/core-lifecycle-browser:build_types",
"//packages/core/lifecycle/core-lifecycle-browser-internal:build_types",
"//packages/core/lifecycle/core-lifecycle-browser-mocks:build_types",
+ "//packages/core/lifecycle/core-lifecycle-server:build_types",
+ "//packages/core/lifecycle/core-lifecycle-server-internal:build_types",
+ "//packages/core/lifecycle/core-lifecycle-server-mocks:build_types",
"//packages/core/logging/core-logging-server:build_types",
"//packages/core/logging/core-logging-server-internal:build_types",
"//packages/core/logging/core-logging-server-mocks:build_types",
@@ -477,6 +486,9 @@ filegroup(
"//packages/core/plugins/core-plugins-browser:build_types",
"//packages/core/plugins/core-plugins-browser-internal:build_types",
"//packages/core/plugins/core-plugins-browser-mocks:build_types",
+ "//packages/core/plugins/core-plugins-server:build_types",
+ "//packages/core/plugins/core-plugins-server-internal:build_types",
+ "//packages/core/plugins/core-plugins-server-mocks:build_types",
"//packages/core/preboot/core-preboot-server:build_types",
"//packages/core/preboot/core-preboot-server-internal:build_types",
"//packages/core/preboot/core-preboot-server-mocks:build_types",
diff --git a/packages/core/lifecycle/core-lifecycle-server-internal/BUILD.bazel b/packages/core/lifecycle/core-lifecycle-server-internal/BUILD.bazel
new file mode 100644
index 0000000000000..f09460293560f
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-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-lifecycle-server-internal"
+PKG_REQUIRE_NAME = "@kbn/core-lifecycle-server-internal"
+
+SOURCE_FILES = glob(
+ [
+ "**/*.ts",
+ ],
+ exclude = [
+ "**/*.config.js",
+ "**/*.mock.*",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/mocks/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+RUNTIME_DEPS = [
+]
+
+TYPES_DEPS = [
+ "@npm//@types/node",
+ "@npm//@types/jest",
+ "//packages/core/logging/core-logging-server-internal:npm_module_types",
+ "//packages/core/analytics/core-analytics-server:npm_module_types",
+ "//packages/core/preboot/core-preboot-server-internal:npm_module_types",
+ "//packages/core/http/core-http-context-server-internal:npm_module_types",
+ "//packages/core/http/core-http-server-internal:npm_module_types",
+ "//packages/core/elasticsearch/core-elasticsearch-server-internal:npm_module_types",
+ "//packages/core/ui-settings/core-ui-settings-server-internal:npm_module_types",
+ "//packages/core/http/core-http-resources-server-internal:npm_module_types",
+ "//packages/core/capabilities/core-capabilities-server:npm_module_types",
+ "//packages/core/doc-links/core-doc-links-server:npm_module_types",
+ "//packages/core/i18n/core-i18n-server:npm_module_types",
+ "//packages/core/environment/core-environment-server-internal:npm_module_types",
+ "//packages/core/execution-context/core-execution-context-server-internal:npm_module_types",
+ "//packages/core/deprecations/core-deprecations-server-internal:npm_module_types",
+ "//packages/core/metrics/core-metrics-server-internal:npm_module_types",
+ "//packages/core/rendering/core-rendering-server-internal:npm_module_types",
+ "//packages/core/saved-objects/core-saved-objects-server-internal:npm_module_types",
+ "//packages/core/status/core-status-server-internal:npm_module_types",
+ "//packages/core/usage-data/core-usage-data-base-server-internal:npm_module_types",
+ "//packages/core/usage-data/core-usage-data-server:npm_module_types",
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+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,
+ declaration_map = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node"],
+ 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/lifecycle/core-lifecycle-server-internal/README.md b/packages/core/lifecycle/core-lifecycle-server-internal/README.md
new file mode 100644
index 0000000000000..b2eecd8ad21ad
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/README.md
@@ -0,0 +1,7 @@
+# @kbn/core-lifecycle-server-internal
+
+
+This package contains the internal types for core's server-side lifecycle contracts:
+- `InternalCorePreboot`
+- `InternalCoreSetup`
+- `InternalCoreStart`
diff --git a/packages/core/lifecycle/core-lifecycle-server-internal/index.ts b/packages/core/lifecycle/core-lifecycle-server-internal/index.ts
new file mode 100644
index 0000000000000..6c3a41be1b49d
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export type { InternalCorePreboot, InternalCoreSetup, InternalCoreStart } from './src';
diff --git a/src/core/server/integration_tests/plugins/plugins_service.test.mocks.ts b/packages/core/lifecycle/core-lifecycle-server-internal/jest.config.js
similarity index 56%
rename from src/core/server/integration_tests/plugins/plugins_service.test.mocks.ts
rename to packages/core/lifecycle/core-lifecycle-server-internal/jest.config.js
index d20d3bc094ac4..039817196b1fe 100644
--- a/src/core/server/integration_tests/plugins/plugins_service.test.mocks.ts
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/jest.config.js
@@ -6,13 +6,8 @@
* Side Public License, v 1.
*/
-export const mockPackage = {
- raw: { __dirname: '/tmp' } as any,
+module.exports = {
+ preset: '@kbn/test/jest_node',
+ rootDir: '../../../..',
+ roots: ['/packages/core/lifecycle/core-lifecycle-server-internal'],
};
-
-jest.doMock('load-json-file', () => ({
- sync: () => mockPackage.raw,
-}));
-
-export const mockDiscover = jest.fn();
-jest.mock('../../plugins/discovery/plugins_discovery', () => ({ discover: mockDiscover }));
diff --git a/packages/core/lifecycle/core-lifecycle-server-internal/kibana.jsonc b/packages/core/lifecycle/core-lifecycle-server-internal/kibana.jsonc
new file mode 100644
index 0000000000000..7f8fa2fc8f6ad
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/core-lifecycle-server-internal",
+ "owner": "@elastic/kibana-core",
+ "runtimeDeps": [],
+ "typeDeps": [],
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-internal/package.json b/packages/core/lifecycle/core-lifecycle-server-internal/package.json
new file mode 100644
index 0000000000000..9b0c909b58e0e
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@kbn/core-lifecycle-server-internal",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "author": "Kibana Core",
+ "license": "SSPL-1.0 OR Elastic License 2.0"
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-internal/src/index.ts b/packages/core/lifecycle/core-lifecycle-server-internal/src/index.ts
new file mode 100644
index 0000000000000..617706c7d53f9
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/src/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 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 { InternalCorePreboot } from './internal_core_preboot';
+export type { InternalCoreSetup } from './internal_core_setup';
+export type { InternalCoreStart } from './internal_core_start';
diff --git a/packages/core/lifecycle/core-lifecycle-server-internal/src/internal_core_preboot.ts b/packages/core/lifecycle/core-lifecycle-server-internal/src/internal_core_preboot.ts
new file mode 100644
index 0000000000000..18f4c605c1b16
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/src/internal_core_preboot.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+import type { InternalLoggingServicePreboot } from '@kbn/core-logging-server-internal';
+import type { AnalyticsServicePreboot } from '@kbn/core-analytics-server';
+import type { InternalPrebootServicePreboot } from '@kbn/core-preboot-server-internal';
+import type { InternalContextPreboot } from '@kbn/core-http-context-server-internal';
+import type { InternalHttpServicePreboot } from '@kbn/core-http-server-internal';
+import type { InternalElasticsearchServicePreboot } from '@kbn/core-elasticsearch-server-internal';
+import type { InternalUiSettingsServicePreboot } from '@kbn/core-ui-settings-server-internal';
+import type { InternalHttpResourcesPreboot } from '@kbn/core-http-resources-server-internal';
+
+/** @internal */
+export interface InternalCorePreboot {
+ analytics: AnalyticsServicePreboot;
+ context: InternalContextPreboot;
+ http: InternalHttpServicePreboot;
+ elasticsearch: InternalElasticsearchServicePreboot;
+ uiSettings: InternalUiSettingsServicePreboot;
+ httpResources: InternalHttpResourcesPreboot;
+ logging: InternalLoggingServicePreboot;
+ preboot: InternalPrebootServicePreboot;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-internal/src/internal_core_setup.ts b/packages/core/lifecycle/core-lifecycle-server-internal/src/internal_core_setup.ts
new file mode 100644
index 0000000000000..5e706cd5f5b0c
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/src/internal_core_setup.ts
@@ -0,0 +1,48 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { AnalyticsServiceSetup } from '@kbn/core-analytics-server';
+import type { CapabilitiesSetup } from '@kbn/core-capabilities-server';
+import type { DocLinksServiceSetup } from '@kbn/core-doc-links-server';
+import type { I18nServiceSetup } from '@kbn/core-i18n-server';
+import type { InternalElasticsearchServiceSetup } from '@kbn/core-elasticsearch-server-internal';
+import type { InternalEnvironmentServiceSetup } from '@kbn/core-environment-server-internal';
+import type { InternalExecutionContextSetup } from '@kbn/core-execution-context-server-internal';
+import type { InternalContextSetup } from '@kbn/core-http-context-server-internal';
+import type { InternalDeprecationsServiceSetup } from '@kbn/core-deprecations-server-internal';
+import type { InternalHttpResourcesSetup } from '@kbn/core-http-resources-server-internal';
+import type { InternalHttpServiceSetup } from '@kbn/core-http-server-internal';
+import type { InternalLoggingServiceSetup } from '@kbn/core-logging-server-internal';
+import type { InternalMetricsServiceSetup } from '@kbn/core-metrics-server-internal';
+import type { InternalRenderingServiceSetup } from '@kbn/core-rendering-server-internal';
+import type { InternalSavedObjectsServiceSetup } from '@kbn/core-saved-objects-server-internal';
+import type { InternalStatusServiceSetup } from '@kbn/core-status-server-internal';
+import type { InternalUiSettingsServiceSetup } from '@kbn/core-ui-settings-server-internal';
+import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
+
+/** @internal */
+export interface InternalCoreSetup {
+ analytics: AnalyticsServiceSetup;
+ capabilities: CapabilitiesSetup;
+ context: InternalContextSetup;
+ docLinks: DocLinksServiceSetup;
+ http: InternalHttpServiceSetup;
+ elasticsearch: InternalElasticsearchServiceSetup;
+ executionContext: InternalExecutionContextSetup;
+ i18n: I18nServiceSetup;
+ savedObjects: InternalSavedObjectsServiceSetup;
+ status: InternalStatusServiceSetup;
+ uiSettings: InternalUiSettingsServiceSetup;
+ environment: InternalEnvironmentServiceSetup;
+ rendering: InternalRenderingServiceSetup;
+ httpResources: InternalHttpResourcesSetup;
+ logging: InternalLoggingServiceSetup;
+ metrics: InternalMetricsServiceSetup;
+ deprecations: InternalDeprecationsServiceSetup;
+ coreUsageData: InternalCoreUsageDataSetup;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-internal/src/internal_core_start.ts b/packages/core/lifecycle/core-lifecycle-server-internal/src/internal_core_start.ts
new file mode 100644
index 0000000000000..e4d777d137b70
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/src/internal_core_start.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { AnalyticsServiceStart } from '@kbn/core-analytics-server';
+import type { CapabilitiesStart } from '@kbn/core-capabilities-server';
+import type { InternalDeprecationsServiceStart } from '@kbn/core-deprecations-server-internal';
+import type { DocLinksServiceStart } from '@kbn/core-doc-links-server';
+import type { InternalElasticsearchServiceStart } from '@kbn/core-elasticsearch-server-internal';
+import type { InternalExecutionContextStart } from '@kbn/core-execution-context-server-internal';
+import type { InternalHttpServiceStart } from '@kbn/core-http-server-internal';
+import type { InternalMetricsServiceStart } from '@kbn/core-metrics-server-internal';
+import type { InternalSavedObjectsServiceStart } from '@kbn/core-saved-objects-server-internal';
+import type { InternalUiSettingsServiceStart } from '@kbn/core-ui-settings-server-internal';
+import type { CoreUsageDataStart } from '@kbn/core-usage-data-server';
+
+/**
+ * @internal
+ */
+export interface InternalCoreStart {
+ analytics: AnalyticsServiceStart;
+ capabilities: CapabilitiesStart;
+ elasticsearch: InternalElasticsearchServiceStart;
+ docLinks: DocLinksServiceStart;
+ http: InternalHttpServiceStart;
+ metrics: InternalMetricsServiceStart;
+ savedObjects: InternalSavedObjectsServiceStart;
+ uiSettings: InternalUiSettingsServiceStart;
+ coreUsageData: CoreUsageDataStart;
+ executionContext: InternalExecutionContextStart;
+ deprecations: InternalDeprecationsServiceStart;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-internal/tsconfig.json b/packages/core/lifecycle/core-lifecycle-server-internal/tsconfig.json
new file mode 100644
index 0000000000000..71bb40fe57f3f
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-internal/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "stripInternal": false,
+ "types": [
+ "jest",
+ "node"
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ ]
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/BUILD.bazel b/packages/core/lifecycle/core-lifecycle-server-mocks/BUILD.bazel
new file mode 100644
index 0000000000000..95f299b0062cd
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/BUILD.bazel
@@ -0,0 +1,143 @@
+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-lifecycle-server-mocks"
+PKG_REQUIRE_NAME = "@kbn/core-lifecycle-server-mocks"
+
+SOURCE_FILES = glob(
+ [
+ "**/*.ts",
+ ],
+ exclude = [
+ "**/*.config.js",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+RUNTIME_DEPS = [
+ "//packages/core/analytics/core-analytics-server-mocks",
+ "//packages/core/capabilities/core-capabilities-server-mocks",
+ "//packages/core/doc-links/core-doc-links-server-mocks",
+ "//packages/core/deprecations/core-deprecations-server-mocks",
+ "//packages/core/elasticsearch/core-elasticsearch-server-mocks",
+ "//packages/core/environment/core-environment-server-mocks",
+ "//packages/core/execution-context/core-execution-context-server-mocks",
+ "//packages/core/http/core-http-context-server-mocks",
+ "//packages/core/http/core-http-server-mocks",
+ "//packages/core/http/core-http-resources-server-mocks",
+ "//packages/core/i18n/core-i18n-server-mocks",
+ "//packages/core/lifecycle/core-lifecycle-server",
+ "//packages/core/metrics/core-metrics-server-mocks",
+ "//packages/core/preboot/core-preboot-server-mocks",
+ "//packages/core/rendering/core-rendering-server-mocks",
+ "//packages/core/saved-objects/core-saved-objects-server-mocks",
+ "//packages/core/status/core-status-server-mocks",
+ "//packages/core/ui-settings/core-ui-settings-server-mocks",
+ "//packages/core/usage-data/core-usage-data-server-mocks",
+
+]
+
+TYPES_DEPS = [
+ "@npm//@types/node",
+ "@npm//@types/jest",
+ "//packages/kbn-utility-types-jest:npm_module_types",
+ "//packages/core/analytics/core-analytics-server-mocks:npm_module_types",
+ "//packages/core/capabilities/core-capabilities-server-mocks:npm_module_types",
+ "//packages/core/doc-links/core-doc-links-server-mocks:npm_module_types",
+ "//packages/core/deprecations/core-deprecations-server-mocks:npm_module_types",
+ "//packages/core/elasticsearch/core-elasticsearch-server-mocks:npm_module_types",
+ "//packages/core/environment/core-environment-server-mocks:npm_module_types",
+ "//packages/core/execution-context/core-execution-context-server-mocks:npm_module_types",
+ "//packages/core/http/core-http-context-server-mocks:npm_module_types",
+ "//packages/core/http/core-http-server-mocks:npm_module_types",
+ "//packages/core/http/core-http-resources-server-mocks:npm_module_types",
+ "//packages/core/i18n/core-i18n-server-mocks:npm_module_types",
+ "//packages/core/lifecycle/core-lifecycle-server:npm_module_types",
+ "//packages/core/metrics/core-metrics-server-mocks:npm_module_types",
+ "//packages/core/preboot/core-preboot-server-mocks:npm_module_types",
+ "//packages/core/rendering/core-rendering-server-mocks:npm_module_types",
+ "//packages/core/saved-objects/core-saved-objects-server-mocks:npm_module_types",
+ "//packages/core/status/core-status-server-mocks:npm_module_types",
+ "//packages/core/ui-settings/core-ui-settings-server-mocks:npm_module_types",
+ "//packages/core/usage-data/core-usage-data-server-mocks:npm_module_types",
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+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,
+ declaration_map = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node"],
+ 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/lifecycle/core-lifecycle-server-mocks/README.md b/packages/core/lifecycle/core-lifecycle-server-mocks/README.md
new file mode 100644
index 0000000000000..6603c268f3d94
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/README.md
@@ -0,0 +1,5 @@
+# @kbn/core-lifecycle-server-mocks
+
+This package contains the mocks for core's server-side lifecycle contracts:
+- `coreLifecycleMock`
+- `coreInternalLifecycleMock`
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/index.ts b/packages/core/lifecycle/core-lifecycle-server-mocks/index.ts
new file mode 100644
index 0000000000000..e17f4db9de973
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/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 { coreLifecycleMock, coreInternalLifecycleMock } from './src';
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/jest.config.js b/packages/core/lifecycle/core-lifecycle-server-mocks/jest.config.js
new file mode 100644
index 0000000000000..3db7ab516cd56
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-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/jest_node',
+ rootDir: '../../../..',
+ roots: ['/packages/core/lifecycle/core-lifecycle-server-mocks'],
+};
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/kibana.jsonc b/packages/core/lifecycle/core-lifecycle-server-mocks/kibana.jsonc
new file mode 100644
index 0000000000000..ea9bbadfd57e9
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/core-lifecycle-server-mocks",
+ "owner": "@elastic/kibana-core",
+ "runtimeDeps": [],
+ "typeDeps": [],
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/package.json b/packages/core/lifecycle/core-lifecycle-server-mocks/package.json
new file mode 100644
index 0000000000000..ce6bae6105a29
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@kbn/core-lifecycle-server-mocks",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "author": "Kibana Core",
+ "license": "SSPL-1.0 OR Elastic License 2.0"
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/src/core_preboot.mock.ts b/packages/core/lifecycle/core-lifecycle-server-mocks/src/core_preboot.mock.ts
new file mode 100644
index 0000000000000..43446f824faed
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/src/core_preboot.mock.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks';
+import { analyticsServiceMock } from '@kbn/core-analytics-server-mocks';
+import { httpServiceMock } from '@kbn/core-http-server-mocks';
+import { prebootServiceMock } from '@kbn/core-preboot-server-mocks';
+import type { MockedKeys } from '@kbn/utility-types-jest';
+import type { CorePreboot } from '@kbn/core-lifecycle-server';
+
+type CorePrebootMockType = MockedKeys & {
+ elasticsearch: ReturnType;
+};
+
+export function createCorePrebootMock() {
+ const mock: CorePrebootMockType = {
+ analytics: analyticsServiceMock.createAnalyticsServicePreboot(),
+ elasticsearch: elasticsearchServiceMock.createPreboot(),
+ http: httpServiceMock.createPrebootContract() as CorePrebootMockType['http'],
+ preboot: prebootServiceMock.createPrebootContract(),
+ };
+
+ return mock;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/src/core_setup.mock.ts b/packages/core/lifecycle/core-lifecycle-server-mocks/src/core_setup.mock.ts
new file mode 100644
index 0000000000000..0c4e25e846cab
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/src/core_setup.mock.ts
@@ -0,0 +1,73 @@
+/*
+ * Copyright 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 { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks';
+import type { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server';
+import { httpServiceMock } from '@kbn/core-http-server-mocks';
+import { httpResourcesMock } from '@kbn/core-http-resources-server-mocks';
+import { uiSettingsServiceMock } from '@kbn/core-ui-settings-server-mocks';
+import type { CoreSetup, StartServicesAccessor } from '@kbn/core-lifecycle-server';
+import type { MockedKeys } from '@kbn/utility-types-jest';
+import { analyticsServiceMock } from '@kbn/core-analytics-server-mocks';
+import { capabilitiesServiceMock } from '@kbn/core-capabilities-server-mocks';
+import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks';
+import { i18nServiceMock } from '@kbn/core-i18n-server-mocks';
+import { savedObjectsServiceMock } from '@kbn/core-saved-objects-server-mocks';
+import { statusServiceMock } from '@kbn/core-status-server-mocks';
+import { loggingServiceMock } from '@kbn/core-logging-server-mocks';
+import { metricsServiceMock } from '@kbn/core-metrics-server-mocks';
+import { deprecationsServiceMock } from '@kbn/core-deprecations-server-mocks';
+import { executionContextServiceMock } from '@kbn/core-execution-context-server-mocks';
+import { coreUsageDataServiceMock } from '@kbn/core-usage-data-server-mocks';
+import { createCoreStartMock } from './core_start.mock';
+
+type CoreSetupMockType = MockedKeys & {
+ elasticsearch: ReturnType;
+ getStartServices: jest.MockedFunction>;
+};
+
+export function createCoreSetupMock({
+ pluginStartDeps = {},
+ pluginStartContract,
+}: {
+ pluginStartDeps?: object;
+ pluginStartContract?: any;
+} = {}) {
+ const httpMock: jest.Mocked = {
+ ...httpServiceMock.createSetupContract(),
+ resources: httpResourcesMock.createRegistrar(),
+ };
+
+ const uiSettingsMock = {
+ register: uiSettingsServiceMock.createSetupContract().register,
+ };
+
+ const mock: CoreSetupMockType = {
+ analytics: analyticsServiceMock.createAnalyticsServiceSetup(),
+ capabilities: capabilitiesServiceMock.createSetupContract(),
+ docLinks: docLinksServiceMock.createSetupContract(),
+ elasticsearch: elasticsearchServiceMock.createSetup(),
+ http: httpMock,
+ i18n: i18nServiceMock.createSetupContract(),
+ savedObjects: savedObjectsServiceMock.createInternalSetupContract(),
+ status: statusServiceMock.createSetupContract(),
+ uiSettings: uiSettingsMock,
+ logging: loggingServiceMock.createSetupContract(),
+ metrics: metricsServiceMock.createSetupContract(),
+ deprecations: deprecationsServiceMock.createSetupContract(),
+ executionContext: executionContextServiceMock.createInternalSetupContract(),
+ coreUsageData: {
+ registerUsageCounter: coreUsageDataServiceMock.createSetupContract().registerUsageCounter,
+ },
+ getStartServices: jest
+ .fn, object, any]>, []>()
+ .mockResolvedValue([createCoreStartMock(), pluginStartDeps, pluginStartContract]),
+ };
+
+ return mock;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/src/core_start.mock.ts b/packages/core/lifecycle/core-lifecycle-server-mocks/src/core_start.mock.ts
new file mode 100644
index 0000000000000..763a9c403eb39
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/src/core_start.mock.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { analyticsServiceMock } from '@kbn/core-analytics-server-mocks';
+import { capabilitiesServiceMock } from '@kbn/core-capabilities-server-mocks';
+import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks';
+import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks';
+import { executionContextServiceMock } from '@kbn/core-execution-context-server-mocks';
+import { httpServiceMock } from '@kbn/core-http-server-mocks';
+import type { CoreStart } from '@kbn/core-lifecycle-server';
+import { metricsServiceMock } from '@kbn/core-metrics-server-mocks';
+import { savedObjectsServiceMock } from '@kbn/core-saved-objects-server-mocks';
+import { uiSettingsServiceMock } from '@kbn/core-ui-settings-server-mocks';
+import { coreUsageDataServiceMock } from '@kbn/core-usage-data-server-mocks';
+import type { MockedKeys } from '@kbn/utility-types-jest';
+
+export function createCoreStartMock() {
+ const mock: MockedKeys = {
+ analytics: analyticsServiceMock.createAnalyticsServiceStart(),
+ capabilities: capabilitiesServiceMock.createStartContract(),
+ docLinks: docLinksServiceMock.createStartContract(),
+ elasticsearch: elasticsearchServiceMock.createStart(),
+ http: httpServiceMock.createStartContract(),
+ metrics: metricsServiceMock.createStartContract(),
+ savedObjects: savedObjectsServiceMock.createStartContract(),
+ uiSettings: uiSettingsServiceMock.createStartContract(),
+ coreUsageData: coreUsageDataServiceMock.createStartContract(),
+ executionContext: executionContextServiceMock.createInternalStartContract(),
+ };
+
+ return mock;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/src/index.ts b/packages/core/lifecycle/core-lifecycle-server-mocks/src/index.ts
new file mode 100644
index 0000000000000..66f9c1d818351
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/src/index.ts
@@ -0,0 +1,27 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { createCorePrebootMock } from './core_preboot.mock';
+import { createCoreSetupMock } from './core_setup.mock';
+import { createCoreStartMock } from './core_start.mock';
+
+import { createInternalCorePrebootMock } from './internal_core_preboot.mock';
+import { createInternalCoreSetupMock } from './internal_core_setup.mock';
+import { createInternalCoreStartMock } from './internal_core_start.mock';
+
+export const coreLifecycleMock = {
+ createPreboot: createCorePrebootMock,
+ createCoreSetup: createCoreSetupMock,
+ createCoreStart: createCoreStartMock,
+};
+
+export const coreInternalLifecycleMock = {
+ createInternalPreboot: createInternalCorePrebootMock,
+ createInternalSetup: createInternalCoreSetupMock,
+ createInternalStart: createInternalCoreStartMock,
+};
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/src/internal_core_preboot.mock.ts b/packages/core/lifecycle/core-lifecycle-server-mocks/src/internal_core_preboot.mock.ts
new file mode 100644
index 0000000000000..08c6d269f1e38
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/src/internal_core_preboot.mock.ts
@@ -0,0 +1,30 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { analyticsServiceMock } from '@kbn/core-analytics-server-mocks';
+import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks';
+import { contextServiceMock } from '@kbn/core-http-context-server-mocks';
+import { httpResourcesMock } from '@kbn/core-http-resources-server-mocks';
+import { httpServiceMock } from '@kbn/core-http-server-mocks';
+import { loggingServiceMock } from '@kbn/core-logging-server-mocks';
+import { prebootServiceMock } from '@kbn/core-preboot-server-mocks';
+import { uiSettingsServiceMock } from '@kbn/core-ui-settings-server-mocks';
+
+export function createInternalCorePrebootMock() {
+ const prebootDeps = {
+ analytics: analyticsServiceMock.createAnalyticsServicePreboot(),
+ context: contextServiceMock.createPrebootContract(),
+ elasticsearch: elasticsearchServiceMock.createInternalPreboot(),
+ http: httpServiceMock.createInternalPrebootContract(),
+ httpResources: httpResourcesMock.createPrebootContract(),
+ uiSettings: uiSettingsServiceMock.createPrebootContract(),
+ logging: loggingServiceMock.createInternalPrebootContract(),
+ preboot: prebootServiceMock.createInternalPrebootContract(),
+ };
+ return prebootDeps;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/src/internal_core_setup.mock.ts b/packages/core/lifecycle/core-lifecycle-server-mocks/src/internal_core_setup.mock.ts
new file mode 100644
index 0000000000000..cddb9a49dab3c
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/src/internal_core_setup.mock.ts
@@ -0,0 +1,50 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { analyticsServiceMock } from '@kbn/core-analytics-server-mocks';
+import { capabilitiesServiceMock } from '@kbn/core-capabilities-server-mocks';
+import { deprecationsServiceMock } from '@kbn/core-deprecations-server-mocks';
+import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks';
+import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks';
+import { environmentServiceMock } from '@kbn/core-environment-server-mocks';
+import { executionContextServiceMock } from '@kbn/core-execution-context-server-mocks';
+import { contextServiceMock } from '@kbn/core-http-context-server-mocks';
+import { httpResourcesMock } from '@kbn/core-http-resources-server-mocks';
+import { httpServiceMock } from '@kbn/core-http-server-mocks';
+import { i18nServiceMock } from '@kbn/core-i18n-server-mocks';
+import { loggingServiceMock } from '@kbn/core-logging-server-mocks';
+import { metricsServiceMock } from '@kbn/core-metrics-server-mocks';
+import { renderingServiceMock } from '@kbn/core-rendering-server-mocks';
+import { savedObjectsServiceMock } from '@kbn/core-saved-objects-server-mocks';
+import { statusServiceMock } from '@kbn/core-status-server-mocks';
+import { uiSettingsServiceMock } from '@kbn/core-ui-settings-server-mocks';
+import { coreUsageDataServiceMock } from '@kbn/core-usage-data-server-mocks';
+
+export function createInternalCoreSetupMock() {
+ const setupDeps = {
+ analytics: analyticsServiceMock.createAnalyticsServiceSetup(),
+ capabilities: capabilitiesServiceMock.createSetupContract(),
+ context: contextServiceMock.createSetupContract(),
+ docLinks: docLinksServiceMock.createSetupContract(),
+ elasticsearch: elasticsearchServiceMock.createInternalSetup(),
+ http: httpServiceMock.createInternalSetupContract(),
+ savedObjects: savedObjectsServiceMock.createInternalSetupContract(),
+ status: statusServiceMock.createInternalSetupContract(),
+ environment: environmentServiceMock.createSetupContract(),
+ i18n: i18nServiceMock.createSetupContract(),
+ httpResources: httpResourcesMock.createSetupContract(),
+ rendering: renderingServiceMock.createSetupContract(),
+ uiSettings: uiSettingsServiceMock.createSetupContract(),
+ logging: loggingServiceMock.createInternalSetupContract(),
+ metrics: metricsServiceMock.createInternalSetupContract(),
+ deprecations: deprecationsServiceMock.createInternalSetupContract(),
+ executionContext: executionContextServiceMock.createInternalSetupContract(),
+ coreUsageData: coreUsageDataServiceMock.createSetupContract(),
+ };
+ return setupDeps;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/src/internal_core_start.mock.ts b/packages/core/lifecycle/core-lifecycle-server-mocks/src/internal_core_start.mock.ts
new file mode 100644
index 0000000000000..6283fa3ce6a88
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/src/internal_core_start.mock.ts
@@ -0,0 +1,36 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { analyticsServiceMock } from '@kbn/core-analytics-server-mocks';
+import { capabilitiesServiceMock } from '@kbn/core-capabilities-server-mocks';
+import { deprecationsServiceMock } from '@kbn/core-deprecations-server-mocks';
+import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks';
+import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks';
+import { executionContextServiceMock } from '@kbn/core-execution-context-server-mocks';
+import { httpServiceMock } from '@kbn/core-http-server-mocks';
+import { metricsServiceMock } from '@kbn/core-metrics-server-mocks';
+import { savedObjectsServiceMock } from '@kbn/core-saved-objects-server-mocks';
+import { uiSettingsServiceMock } from '@kbn/core-ui-settings-server-mocks';
+import { coreUsageDataServiceMock } from '@kbn/core-usage-data-server-mocks';
+
+export function createInternalCoreStartMock() {
+ const startDeps = {
+ analytics: analyticsServiceMock.createAnalyticsServiceStart(),
+ capabilities: capabilitiesServiceMock.createStartContract(),
+ docLinks: docLinksServiceMock.createStartContract(),
+ elasticsearch: elasticsearchServiceMock.createInternalStart(),
+ http: httpServiceMock.createInternalStartContract(),
+ metrics: metricsServiceMock.createInternalStartContract(),
+ savedObjects: savedObjectsServiceMock.createInternalStartContract(),
+ uiSettings: uiSettingsServiceMock.createStartContract(),
+ coreUsageData: coreUsageDataServiceMock.createStartContract(),
+ executionContext: executionContextServiceMock.createInternalStartContract(),
+ deprecations: deprecationsServiceMock.createInternalStartContract(),
+ };
+ return startDeps;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server-mocks/tsconfig.json b/packages/core/lifecycle/core-lifecycle-server-mocks/tsconfig.json
new file mode 100644
index 0000000000000..71bb40fe57f3f
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server-mocks/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "stripInternal": false,
+ "types": [
+ "jest",
+ "node"
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ ]
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server/BUILD.bazel b/packages/core/lifecycle/core-lifecycle-server/BUILD.bazel
new file mode 100644
index 0000000000000..85b3b6ab1ca97
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/BUILD.bazel
@@ -0,0 +1,122 @@
+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-lifecycle-server"
+PKG_REQUIRE_NAME = "@kbn/core-lifecycle-server"
+
+SOURCE_FILES = glob(
+ [
+ "**/*.ts",
+ ],
+ exclude = [
+ "**/*.config.js",
+ "**/*.mock.*",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/mocks/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+RUNTIME_DEPS = [
+]
+
+TYPES_DEPS = [
+ "@npm//@types/node",
+ "@npm//@types/jest",
+ "//packages/core/analytics/core-analytics-server:npm_module_types",
+ "//packages/core/capabilities/core-capabilities-server:npm_module_types",
+ "//packages/core/deprecations/core-deprecations-server:npm_module_types",
+ "//packages/core/doc-links/core-doc-links-server:npm_module_types",
+ "//packages/core/elasticsearch/core-elasticsearch-server:npm_module_types",
+ "//packages/core/execution-context/core-execution-context-server:npm_module_types",
+ "//packages/core/http/core-http-server:npm_module_types",
+ "//packages/core/http/core-http-request-handler-context-server:npm_module_types",
+ "//packages/core/http/core-http-resources-server:npm_module_types",
+ "//packages/core/i18n/core-i18n-server:npm_module_types",
+ "//packages/core/logging/core-logging-server:npm_module_types",
+ "//packages/core/metrics/core-metrics-server:npm_module_types",
+ "//packages/core/preboot/core-preboot-server:npm_module_types",
+ "//packages/core/saved-objects/core-saved-objects-server:npm_module_types",
+ "//packages/core/status/core-status-server:npm_module_types",
+ "//packages/core/ui-settings/core-ui-settings-server:npm_module_types",
+ "//packages/core/usage-data/core-usage-data-server:npm_module_types",
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+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,
+ declaration_map = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node"],
+ 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/lifecycle/core-lifecycle-server/README.md b/packages/core/lifecycle/core-lifecycle-server/README.md
new file mode 100644
index 0000000000000..5d06aa257f81f
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/README.md
@@ -0,0 +1,7 @@
+# @kbn/core-lifecycle-server
+
+This package contains the public types for core's server-side lifecycle contracts and services accessor:
+- `CorePreboot`
+- `CoreSetup`
+- `CoreStart`
+- `StartServicesAccessor`
diff --git a/packages/core/lifecycle/core-lifecycle-server/index.ts b/packages/core/lifecycle/core-lifecycle-server/index.ts
new file mode 100644
index 0000000000000..5e8b379724036
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export type { CorePreboot, CoreSetup, CoreStart, StartServicesAccessor } from './src';
diff --git a/packages/core/lifecycle/core-lifecycle-server/jest.config.js b/packages/core/lifecycle/core-lifecycle-server/jest.config.js
new file mode 100644
index 0000000000000..3d48a32bd7610
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/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/jest_node',
+ rootDir: '../../../..',
+ roots: ['/packages/core/lifecycle/core-lifecycle-server'],
+};
diff --git a/packages/core/lifecycle/core-lifecycle-server/kibana.jsonc b/packages/core/lifecycle/core-lifecycle-server/kibana.jsonc
new file mode 100644
index 0000000000000..867db6cc2dab0
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/core-lifecycle-server",
+ "owner": "@elastic/kibana-core",
+ "runtimeDeps": [],
+ "typeDeps": [],
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server/package.json b/packages/core/lifecycle/core-lifecycle-server/package.json
new file mode 100644
index 0000000000000..da5e093f9c250
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@kbn/core-lifecycle-server",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "author": "Kibana Core",
+ "license": "SSPL-1.0 OR Elastic License 2.0"
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server/src/core_preboot.ts b/packages/core/lifecycle/core-lifecycle-server/src/core_preboot.ts
new file mode 100644
index 0000000000000..893854149d7d2
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/src/core_preboot.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { AnalyticsServicePreboot } from '@kbn/core-analytics-server';
+import type { HttpServicePreboot } from '@kbn/core-http-server';
+import type { PrebootServicePreboot } from '@kbn/core-preboot-server';
+import type { ElasticsearchServicePreboot } from '@kbn/core-elasticsearch-server';
+import type { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server';
+
+/**
+ * Context passed to the `setup` method of `preboot` plugins.
+ * @public
+ */
+export interface CorePreboot {
+ /** {@link AnalyticsServicePreboot} */
+ analytics: AnalyticsServicePreboot;
+ /** {@link ElasticsearchServicePreboot} */
+ elasticsearch: ElasticsearchServicePreboot;
+ /** {@link HttpServicePreboot} */
+ http: HttpServicePreboot;
+ /** {@link PrebootServicePreboot} */
+ preboot: PrebootServicePreboot;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server/src/core_setup.ts b/packages/core/lifecycle/core-lifecycle-server/src/core_setup.ts
new file mode 100644
index 0000000000000..1565e11b13777
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/src/core_setup.ts
@@ -0,0 +1,83 @@
+/*
+ * Copyright 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 { AnalyticsServiceSetup } from '@kbn/core-analytics-server';
+import { CapabilitiesSetup } from '@kbn/core-capabilities-server';
+import { DeprecationsServiceSetup } from '@kbn/core-deprecations-server';
+import { DocLinksServiceSetup } from '@kbn/core-doc-links-server';
+import { ElasticsearchServiceSetup } from '@kbn/core-elasticsearch-server';
+import { ExecutionContextSetup } from '@kbn/core-execution-context-server';
+import { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server';
+import { HttpResources } from '@kbn/core-http-resources-server';
+import { HttpServiceSetup } from '@kbn/core-http-server';
+import { I18nServiceSetup } from '@kbn/core-i18n-server';
+import { LoggingServiceSetup } from '@kbn/core-logging-server';
+import { MetricsServiceSetup } from '@kbn/core-metrics-server';
+import { SavedObjectsServiceSetup } from '@kbn/core-saved-objects-server';
+import { StatusServiceSetup } from '@kbn/core-status-server';
+import { UiSettingsServiceSetup } from '@kbn/core-ui-settings-server';
+import { CoreUsageDataSetup } from '@kbn/core-usage-data-server';
+import { CoreStart } from './core_start';
+
+/**
+ * Context passed to the `setup` method of `standard` plugins.
+ *
+ * @typeParam TPluginsStart - the type of the consuming plugin's start dependencies. Should be the same
+ * as the consuming {@link Plugin}'s `TPluginsStart` type. Used by `getStartServices`.
+ * @typeParam TStart - the type of the consuming plugin's start contract. Should be the same as the
+ * consuming {@link Plugin}'s `TStart` type. Used by `getStartServices`.
+ * @public
+ */
+export interface CoreSetup {
+ /** {@link AnalyticsServiceSetup} */
+ analytics: AnalyticsServiceSetup;
+ /** {@link CapabilitiesSetup} */
+ capabilities: CapabilitiesSetup;
+ /** {@link DocLinksServiceSetup} */
+ docLinks: DocLinksServiceSetup;
+ /** {@link ElasticsearchServiceSetup} */
+ elasticsearch: ElasticsearchServiceSetup;
+ /** {@link ExecutionContextSetup} */
+ executionContext: ExecutionContextSetup;
+ /** {@link HttpServiceSetup} */
+ http: HttpServiceSetup & {
+ /** {@link HttpResources} */
+ resources: HttpResources;
+ };
+ /** {@link I18nServiceSetup} */
+ i18n: I18nServiceSetup;
+ /** {@link LoggingServiceSetup} */
+ logging: LoggingServiceSetup;
+ /** {@link MetricsServiceSetup} */
+ metrics: MetricsServiceSetup;
+ /** {@link SavedObjectsServiceSetup} */
+ savedObjects: SavedObjectsServiceSetup;
+ /** {@link StatusServiceSetup} */
+ status: StatusServiceSetup;
+ /** {@link UiSettingsServiceSetup} */
+ uiSettings: UiSettingsServiceSetup;
+ /** {@link DeprecationsServiceSetup} */
+ deprecations: DeprecationsServiceSetup;
+ /** {@link StartServicesAccessor} */
+ getStartServices: StartServicesAccessor;
+ /** @internal {@link CoreUsageDataSetup} */
+ coreUsageData: CoreUsageDataSetup;
+}
+
+/**
+ * Allows plugins to get access to APIs available in start inside async handlers.
+ * Promise will not resolve until Core and plugin dependencies have completed `start`.
+ * This should only be used inside handlers registered during `setup` that will only be executed
+ * after `start` lifecycle.
+ *
+ * @public
+ */
+export type StartServicesAccessor<
+ TPluginsStart extends object = object,
+ TStart = unknown
+> = () => Promise<[CoreStart, TPluginsStart, TStart]>;
diff --git a/packages/core/lifecycle/core-lifecycle-server/src/core_start.ts b/packages/core/lifecycle/core-lifecycle-server/src/core_start.ts
new file mode 100644
index 0000000000000..53c989154af08
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/src/core_start.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 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 { AnalyticsServiceStart } from '@kbn/core-analytics-server';
+import { CapabilitiesStart } from '@kbn/core-capabilities-server';
+import { DocLinksServiceStart } from '@kbn/core-doc-links-server';
+import { ElasticsearchServiceStart } from '@kbn/core-elasticsearch-server';
+import { ExecutionContextStart } from '@kbn/core-execution-context-server';
+import { HttpServiceStart } from '@kbn/core-http-server';
+import { MetricsServiceStart } from '@kbn/core-metrics-server';
+import { SavedObjectsServiceStart } from '@kbn/core-saved-objects-server';
+import { UiSettingsServiceStart } from '@kbn/core-ui-settings-server';
+import { CoreUsageDataStart } from '@kbn/core-usage-data-server';
+
+/**
+ * Context passed to the plugins `start` method.
+ *
+ * @public
+ */
+export interface CoreStart {
+ /** {@link AnalyticsServiceStart} */
+ analytics: AnalyticsServiceStart;
+ /** {@link CapabilitiesStart} */
+ capabilities: CapabilitiesStart;
+ /** {@link DocLinksServiceStart} */
+ docLinks: DocLinksServiceStart;
+ /** {@link ElasticsearchServiceStart} */
+ elasticsearch: ElasticsearchServiceStart;
+ /** {@link ExecutionContextStart} */
+ executionContext: ExecutionContextStart;
+ /** {@link HttpServiceStart} */
+ http: HttpServiceStart;
+ /** {@link MetricsServiceStart} */
+ metrics: MetricsServiceStart;
+ /** {@link SavedObjectsServiceStart} */
+ savedObjects: SavedObjectsServiceStart;
+ /** {@link UiSettingsServiceStart} */
+ uiSettings: UiSettingsServiceStart;
+ /** @internal {@link CoreUsageDataStart} */
+ coreUsageData: CoreUsageDataStart;
+}
diff --git a/packages/core/lifecycle/core-lifecycle-server/src/index.ts b/packages/core/lifecycle/core-lifecycle-server/src/index.ts
new file mode 100644
index 0000000000000..37f4a6c60fd14
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/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 { CorePreboot } from './core_preboot';
+export type { CoreSetup, StartServicesAccessor } from './core_setup';
+export type { CoreStart } from './core_start';
diff --git a/packages/core/lifecycle/core-lifecycle-server/tsconfig.json b/packages/core/lifecycle/core-lifecycle-server/tsconfig.json
new file mode 100644
index 0000000000000..71bb40fe57f3f
--- /dev/null
+++ b/packages/core/lifecycle/core-lifecycle-server/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "stripInternal": false,
+ "types": [
+ "jest",
+ "node"
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ ]
+}
diff --git a/packages/core/plugins/core-plugins-server-internal/BUILD.bazel b/packages/core/plugins/core-plugins-server-internal/BUILD.bazel
new file mode 100644
index 0000000000000..61044f11d5b51
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-internal/BUILD.bazel
@@ -0,0 +1,155 @@
+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-plugins-server-internal"
+PKG_REQUIRE_NAME = "@kbn/core-plugins-server-internal"
+
+SOURCE_FILES = glob(
+ [
+ "**/*.ts",
+ ],
+ exclude = [
+ "**/*.config.js",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/mocks/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+RUNTIME_DEPS = [
+ "@npm//moment",
+ "@npm//rxjs",
+ "@npm//semver",
+ "@npm//type-detect",
+ "@npm//lodash",
+ "//packages/kbn-std",
+ "//packages/kbn-config",
+ "//packages/kbn-config-schema",
+ "//packages/kbn-logging",
+ "//packages/kbn-utils",
+ "//packages/core/base/core-base-common",
+ "//packages/core/base/core-base-server-internal",
+ "//packages/core/lifecycle/core-lifecycle-server-internal",
+ "//packages/core/elasticsearch/core-elasticsearch-server-internal",
+ "//packages/core/node/core-node-server",
+ "//packages/core/saved-objects/core-saved-objects-base-server-internal",
+ # test dependencies
+ "@npm//mock-fs",
+ "//packages/kbn-config-mocks",
+ "//packages/core/base/core-base-server-mocks",
+ "//packages/core/lifecycle/core-lifecycle-server-mocks",
+ "//packages/core/logging/core-logging-server-mocks",
+ "//packages/core/node/core-node-server-mocks",
+ "//packages/core/plugins/core-plugins-server",
+]
+
+TYPES_DEPS = [
+ "@npm//@types/node",
+ "@npm//@types/jest",
+ "@npm//moment",
+ "@npm//rxjs",
+ "@npm//semver",
+ "@npm//type-detect",
+ "@npm//lodash",
+ "//packages/kbn-std:npm_module_types",
+ "//packages/kbn-config:npm_module_types",
+ "//packages/kbn-config-schema:npm_module_types",
+ "//packages/kbn-logging:npm_module_types",
+ "//packages/kbn-utils:npm_module_types",
+ "//packages/core/base/core-base-common:npm_module_types",
+ "//packages/core/base/core-base-server-internal:npm_module_types",
+ "//packages/core/elasticsearch/core-elasticsearch-server-internal:npm_module_types",
+ "//packages/core/node/core-node-server:npm_module_types",
+ "//packages/core/saved-objects/core-saved-objects-base-server-internal:npm_module_types",
+ "//packages/core/http/core-http-server:npm_module_types",
+ "//packages/core/http/core-http-request-handler-context-server:npm_module_types",
+ "//packages/core/lifecycle/core-lifecycle-server:npm_module_types",
+ "//packages/core/lifecycle/core-lifecycle-server-internal:npm_module_types",
+ "//packages/core/plugins/core-plugins-server:npm_module_types",
+ # test dependencies' mocks
+ "@npm//mock-fs",
+ "//packages/kbn-config-mocks:npm_module_types",
+ "//packages/core/base/core-base-server-mocks:npm_module_types",
+ "//packages/core/lifecycle/core-lifecycle-server-mocks:npm_module_types",
+ "//packages/core/logging/core-logging-server-mocks:npm_module_types",
+ "//packages/core/node/core-node-server-mocks:npm_module_types",
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+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,
+ declaration_map = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node"],
+ 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/plugins/core-plugins-server-internal/README.md b/packages/core/plugins/core-plugins-server-internal/README.md
new file mode 100644
index 0000000000000..7ca4a5600877f
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-internal/README.md
@@ -0,0 +1,3 @@
+# @kbn/core-plugins-server-internal
+
+This package contains the internal types and implementation for Core's server-side `plugins` service.
diff --git a/packages/core/plugins/core-plugins-server-internal/index.ts b/packages/core/plugins/core-plugins-server-internal/index.ts
new file mode 100644
index 0000000000000..072ffda4b4421
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-internal/index.ts
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { PluginsService, PluginWrapper, config, isNewPlatformPlugin } from './src';
+export type {
+ PluginsServiceSetup,
+ PluginsServiceStart,
+ DiscoveredPlugins,
+ PluginDependencies,
+} from './src';
diff --git a/packages/core/plugins/core-plugins-server-internal/jest.config.js b/packages/core/plugins/core-plugins-server-internal/jest.config.js
new file mode 100644
index 0000000000000..08315583a6f6d
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-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/jest_node',
+ rootDir: '../../../..',
+ roots: ['/packages/core/plugins/core-plugins-server-internal'],
+};
diff --git a/packages/core/plugins/core-plugins-server-internal/kibana.jsonc b/packages/core/plugins/core-plugins-server-internal/kibana.jsonc
new file mode 100644
index 0000000000000..2354b5ea2054e
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-internal/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/core-plugins-server-internal",
+ "owner": "@elastic/kibana-core",
+ "runtimeDeps": [],
+ "typeDeps": [],
+}
diff --git a/packages/core/plugins/core-plugins-server-internal/package.json b/packages/core/plugins/core-plugins-server-internal/package.json
new file mode 100644
index 0000000000000..68adae5d08fed
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-internal/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@kbn/core-plugins-server-internal",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "author": "Kibana Core",
+ "license": "SSPL-1.0 OR Elastic License 2.0"
+}
diff --git a/src/core/server/plugins/create_browser_config.test.ts b/packages/core/plugins/core-plugins-server-internal/src/create_browser_config.test.ts
similarity index 98%
rename from src/core/server/plugins/create_browser_config.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/create_browser_config.test.ts
index ca0366b7477fa..11f55d1bc1edb 100644
--- a/src/core/server/plugins/create_browser_config.test.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/create_browser_config.test.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import type { PluginConfigDescriptor } from './types';
+import type { PluginConfigDescriptor } from '@kbn/core-plugins-server';
import { createBrowserConfig } from './create_browser_config';
import { schema, TypeOf } from '@kbn/config-schema';
diff --git a/src/core/server/plugins/create_browser_config.ts b/packages/core/plugins/core-plugins-server-internal/src/create_browser_config.ts
similarity index 98%
rename from src/core/server/plugins/create_browser_config.ts
rename to packages/core/plugins/core-plugins-server-internal/src/create_browser_config.ts
index 0bf812d2e5cce..05844839934b2 100644
--- a/src/core/server/plugins/create_browser_config.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/create_browser_config.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { ExposedToBrowserDescriptor, PluginConfigDescriptor } from './types';
+import { ExposedToBrowserDescriptor, PluginConfigDescriptor } from '@kbn/core-plugins-server';
export const createBrowserConfig = (
config: T,
diff --git a/src/core/server/plugins/discovery/index.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/index.ts
similarity index 100%
rename from src/core/server/plugins/discovery/index.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/index.ts
diff --git a/src/core/server/plugins/discovery/is_camel_case.test.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/is_camel_case.test.ts
similarity index 100%
rename from src/core/server/plugins/discovery/is_camel_case.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/is_camel_case.test.ts
diff --git a/src/core/server/plugins/discovery/is_camel_case.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/is_camel_case.ts
similarity index 100%
rename from src/core/server/plugins/discovery/is_camel_case.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/is_camel_case.ts
diff --git a/src/core/server/plugins/discovery/plugin_discovery_error.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_discovery_error.ts
similarity index 100%
rename from src/core/server/plugins/discovery/plugin_discovery_error.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_discovery_error.ts
diff --git a/src/core/server/plugins/discovery/plugin_manifest_parser.test.mocks.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.test.mocks.ts
similarity index 100%
rename from src/core/server/plugins/discovery/plugin_manifest_parser.test.mocks.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.test.mocks.ts
diff --git a/src/core/server/plugins/discovery/plugin_manifest_parser.test.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.test.ts
similarity index 100%
rename from src/core/server/plugins/discovery/plugin_manifest_parser.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.test.ts
diff --git a/src/core/server/plugins/discovery/plugin_manifest_parser.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.ts
similarity index 99%
rename from src/core/server/plugins/discovery/plugin_manifest_parser.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.ts
index 0a54899856ac1..5402b9218620d 100644
--- a/src/core/server/plugins/discovery/plugin_manifest_parser.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugin_manifest_parser.ts
@@ -13,7 +13,7 @@ import { promisify } from 'util';
import { snakeCase } from 'lodash';
import { isConfigPath, PackageInfo } from '@kbn/config';
import { PluginType } from '@kbn/core-base-common';
-import { PluginManifest } from '../types';
+import { PluginManifest } from '@kbn/core-plugins-server';
import { PluginDiscoveryError } from './plugin_discovery_error';
import { isCamelCase } from './is_camel_case';
diff --git a/src/core/server/plugins/discovery/plugins_discovery.test.mocks.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugins_discovery.test.mocks.ts
similarity index 100%
rename from src/core/server/plugins/discovery/plugins_discovery.test.mocks.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/plugins_discovery.test.mocks.ts
diff --git a/src/core/server/plugins/discovery/plugins_discovery.test.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugins_discovery.test.ts
similarity index 99%
rename from src/core/server/plugins/discovery/plugins_discovery.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/plugins_discovery.test.ts
index 03c86fb46b5eb..8c1c50e8a612c 100644
--- a/src/core/server/plugins/discovery/plugins_discovery.test.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugins_discovery.test.ts
@@ -22,7 +22,7 @@ import type { NodeInfo } from '@kbn/core-node-server';
import { PluginsConfig, PluginsConfigType, config } from '../plugins_config';
import type { InstanceInfo } from '../plugin_context';
import { discover } from './plugins_discovery';
-import { PluginType } from '../types';
+import { PluginType } from '@kbn/core-base-common';
const KIBANA_ROOT = process.cwd();
diff --git a/src/core/server/plugins/discovery/plugins_discovery.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/plugins_discovery.ts
similarity index 100%
rename from src/core/server/plugins/discovery/plugins_discovery.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/plugins_discovery.ts
diff --git a/src/core/server/plugins/discovery/scan_plugin_search_paths.test.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/scan_plugin_search_paths.test.ts
similarity index 100%
rename from src/core/server/plugins/discovery/scan_plugin_search_paths.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/scan_plugin_search_paths.test.ts
diff --git a/src/core/server/plugins/discovery/scan_plugin_search_paths.ts b/packages/core/plugins/core-plugins-server-internal/src/discovery/scan_plugin_search_paths.ts
similarity index 100%
rename from src/core/server/plugins/discovery/scan_plugin_search_paths.ts
rename to packages/core/plugins/core-plugins-server-internal/src/discovery/scan_plugin_search_paths.ts
diff --git a/src/core/server/plugins/index.ts b/packages/core/plugins/core-plugins-server-internal/src/index.ts
similarity index 87%
rename from src/core/server/plugins/index.ts
rename to packages/core/plugins/core-plugins-server-internal/src/index.ts
index 2111d467ef3c2..3eb852b641fcd 100644
--- a/src/core/server/plugins/index.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/index.ts
@@ -15,4 +15,5 @@ export type {
export { config } from './plugins_config';
/** @internal */
export { isNewPlatformPlugin } from './discovery';
-export * from './types';
+export type { PluginDependencies } from './types';
+export { PluginWrapper } from './plugin';
diff --git a/src/core/server/plugins/legacy_config.test.ts b/packages/core/plugins/core-plugins-server-internal/src/legacy_config.test.ts
similarity index 66%
rename from src/core/server/plugins/legacy_config.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/legacy_config.test.ts
index ca7a2d8a5454e..2bd50db020d0e 100644
--- a/src/core/server/plugins/legacy_config.test.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/legacy_config.test.ts
@@ -5,37 +5,17 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
-
import { take } from 'rxjs/operators';
-import { ConfigService, Env } from '@kbn/config';
-import { getEnvOptions, rawConfigServiceMock } from '@kbn/config-mocks';
import { getGlobalConfig, getGlobalConfig$ } from './legacy_config';
-import { REPO_ROOT } from '@kbn/utils';
-import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
import { duration } from 'moment';
import { fromRoot } from '@kbn/utils';
import { ByteSizeValue } from '@kbn/config-schema';
-import { Server } from '../server';
+import { createCoreContextConfigServiceMock } from './test_helpers';
describe('Legacy config', () => {
- let env: Env;
- let logger: ReturnType;
-
- beforeEach(() => {
- env = Env.createDefault(REPO_ROOT, getEnvOptions());
- logger = loggingSystemMock.create();
- });
-
- const createConfigService = (rawConfig: Record = {}): ConfigService => {
- const rawConfigService = rawConfigServiceMock.create({ rawConfig });
- const server = new Server(rawConfigService, env, logger);
- server.setupCoreConfig();
- return server.configService;
- };
-
describe('getGlobalConfig', () => {
it('should return the global config', async () => {
- const configService = createConfigService();
+ const configService = createCoreContextConfigServiceMock();
await configService.validate();
const legacyConfig = getGlobalConfig(configService);
@@ -54,7 +34,7 @@ describe('Legacy config', () => {
describe('getGlobalConfig$', () => {
it('should return an observable for the global config', async () => {
- const configService = createConfigService();
+ const configService = createCoreContextConfigServiceMock();
const legacyConfig = await getGlobalConfig$(configService).pipe(take(1)).toPromise();
diff --git a/src/core/server/plugins/legacy_config.ts b/packages/core/plugins/core-plugins-server-internal/src/legacy_config.ts
similarity index 96%
rename from src/core/server/plugins/legacy_config.ts
rename to packages/core/plugins/core-plugins-server-internal/src/legacy_config.ts
index de86345c5b7ba..46e792d6b226d 100644
--- a/src/core/server/plugins/legacy_config.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/legacy_config.ts
@@ -20,7 +20,7 @@ import {
type SavedObjectsConfigType,
savedObjectsConfig,
} from '@kbn/core-saved-objects-base-server-internal';
-import { SharedGlobalConfig, SharedGlobalConfigKeys } from './types';
+import { SharedGlobalConfig, SharedGlobalConfigKeys } from '@kbn/core-plugins-server';
const createGlobalConfig = ({
elasticsearch,
diff --git a/src/core/server/plugins/plugin.test.ts b/packages/core/plugins/core-plugins-server-internal/src/plugin.test.ts
similarity index 98%
rename from src/core/server/plugins/plugin.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugin.test.ts
index 538c9539b2a68..008b8eaf6665a 100644
--- a/src/core/server/plugins/plugin.test.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/plugin.test.ts
@@ -17,10 +17,11 @@ import type { CoreContext } from '@kbn/core-base-server-internal';
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
import type { NodeInfo } from '@kbn/core-node-server';
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
-import { coreMock } from '../mocks';
-
+import type { PluginManifest } from '@kbn/core-plugins-server';
import { PluginWrapper } from './plugin';
-import { PluginManifest, PluginType } from './types';
+import { PluginType } from '@kbn/core-base-common';
+import { coreInternalLifecycleMock } from '@kbn/core-lifecycle-server-mocks';
+
import {
createPluginInitializerContext,
createPluginSetupContext,
@@ -72,7 +73,7 @@ let coreContext: CoreContext;
let instanceInfo: InstanceInfo;
let nodeInfo: NodeInfo;
-const setupDeps = coreMock.createInternalSetup();
+const setupDeps = coreInternalLifecycleMock.createInternalSetup();
beforeEach(() => {
coreId = Symbol('core');
diff --git a/src/core/server/plugins/plugin.ts b/packages/core/plugins/core-plugins-server-internal/src/plugin.ts
similarity index 97%
rename from src/core/server/plugins/plugin.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugin.ts
index 9ddab175d313a..5446e983676c0 100644
--- a/src/core/server/plugins/plugin.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/plugin.ts
@@ -12,18 +12,17 @@ import { firstValueFrom, Subject } from 'rxjs';
import { isPromise } from '@kbn/std';
import { isConfigSchema } from '@kbn/config-schema';
import type { Logger } from '@kbn/logging';
-import { PluginType } from '@kbn/core-base-common';
-import {
+import { type PluginOpaqueId, PluginType } from '@kbn/core-base-common';
+import type {
AsyncPlugin,
Plugin,
PluginConfigDescriptor,
PluginInitializer,
PluginInitializerContext,
PluginManifest,
- PluginOpaqueId,
PrebootPlugin,
-} from './types';
-import { CorePreboot, CoreSetup, CoreStart } from '..';
+} from '@kbn/core-plugins-server';
+import type { CorePreboot, CoreSetup, CoreStart } from '@kbn/core-lifecycle-server';
const OSS_PATH_REGEX = /[\/|\\]src[\/|\\]plugins[\/|\\]/; // Matches src/plugins directory on POSIX and Windows
const XPACK_PATH_REGEX = /[\/|\\]x-pack[\/|\\]plugins[\/|\\]/; // Matches x-pack/plugins directory on POSIX and Windows
diff --git a/src/core/server/plugins/plugin_context.test.ts b/packages/core/plugins/core-plugins-server-internal/src/plugin_context.test.ts
similarity index 90%
rename from src/core/server/plugins/plugin_context.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugin_context.test.ts
index 803c5ded6a545..978bf62222f07 100644
--- a/src/core/server/plugins/plugin_context.test.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/plugin_context.test.ts
@@ -8,8 +8,7 @@
import { duration } from 'moment';
import { first } from 'rxjs/operators';
-import { REPO_ROOT } from '@kbn/utils';
-import { fromRoot } from '@kbn/utils';
+import { REPO_ROOT, fromRoot } from '@kbn/utils';
import { rawConfigServiceMock, getEnvOptions, configServiceMock } from '@kbn/config-mocks';
import type { CoreContext } from '@kbn/core-base-server-internal';
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
@@ -21,12 +20,15 @@ import {
InstanceInfo,
} from './plugin_context';
-import { PluginManifest, PluginType } from './types';
-import { Server } from '../server';
+import { PluginType } from '@kbn/core-base-common';
+import { PluginManifest } from '@kbn/core-plugins-server';
import { schema, ByteSizeValue } from '@kbn/config-schema';
import { ConfigService, Env } from '@kbn/config';
import { PluginWrapper } from './plugin';
-import { coreMock } from '../mocks';
+
+import { coreInternalLifecycleMock } from '@kbn/core-lifecycle-server-mocks';
+import { mockCoreContext } from '@kbn/core-base-server-mocks';
+import { createCoreContextConfigServiceMock } from './test_helpers';
function createPluginManifest(manifestProps: Partial = {}): PluginManifest {
return {
@@ -54,7 +56,6 @@ describe('createPluginInitializerContext', () => {
let opaqueId: symbol;
let env: Env;
let coreContext: CoreContext;
- let server: Server;
let instanceInfo: InstanceInfo;
let nodeInfo: NodeInfo;
@@ -67,10 +68,11 @@ describe('createPluginInitializerContext', () => {
};
nodeInfo = nodeServiceMock.createInternalPrebootContract();
env = Env.createDefault(REPO_ROOT, getEnvOptions());
- const config$ = rawConfigServiceMock.create({ rawConfig: {} });
- server = new Server(config$, env, logger);
- server.setupCoreConfig();
- coreContext = { coreId, env, logger, configService: server.configService };
+ coreContext = mockCoreContext.create({
+ env,
+ logger,
+ configService: configServiceMock.create(),
+ });
});
describe('context.config', () => {
@@ -115,7 +117,12 @@ describe('createPluginInitializerContext', () => {
});
it('config.globalConfig$ should be an observable for the global config', async () => {
+ const configService = createCoreContextConfigServiceMock();
+
+ coreContext = { coreId, env, logger, configService };
+
const manifest = createPluginManifest();
+
const pluginInitializerContext = createPluginInitializerContext({
coreContext,
opaqueId,
@@ -229,7 +236,7 @@ describe('createPluginPrebootSetupContext', () => {
}),
});
- const corePreboot = coreMock.createInternalPreboot();
+ const corePreboot = coreInternalLifecycleMock.createInternalPreboot();
const prebootSetupContext = createPluginPrebootSetupContext(coreContext, corePreboot, plugin);
const holdSetupPromise = Promise.resolve(undefined);
diff --git a/src/core/server/plugins/plugin_context.ts b/packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts
similarity index 97%
rename from src/core/server/plugins/plugin_context.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts
index 97b165617b68e..d1bec41373c9d 100644
--- a/src/core/server/plugins/plugin_context.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/plugin_context.ts
@@ -11,16 +11,16 @@ import type { CoreContext } from '@kbn/core-base-server-internal';
import type { PluginOpaqueId } from '@kbn/core-base-common';
import type { NodeInfo } from '@kbn/core-node-server';
import type { IRouter, IContextProvider } from '@kbn/core-http-server';
-import type { RequestHandlerContext } from '..';
+import { PluginInitializerContext, PluginManifest } from '@kbn/core-plugins-server';
+import { CorePreboot, CoreSetup, CoreStart } from '@kbn/core-lifecycle-server';
+import type { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server';
import { PluginWrapper } from './plugin';
import {
PluginsServicePrebootSetupDeps,
PluginsServiceSetupDeps,
PluginsServiceStartDeps,
} from './plugins_service';
-import { PluginInitializerContext, PluginManifest } from './types';
import { getGlobalConfig, getGlobalConfig$ } from './legacy_config';
-import { CorePreboot, CoreSetup, CoreStart } from '..';
/** @internal */
export interface InstanceInfo {
diff --git a/src/core/server/plugins/plugins_config.test.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_config.test.ts
similarity index 100%
rename from src/core/server/plugins/plugins_config.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugins_config.test.ts
diff --git a/src/core/server/plugins/plugins_config.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_config.ts
similarity index 100%
rename from src/core/server/plugins/plugins_config.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugins_config.ts
diff --git a/src/core/server/plugins/plugins_service.test.mocks.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.mocks.ts
similarity index 100%
rename from src/core/server/plugins/plugins_service.test.mocks.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.mocks.ts
diff --git a/src/core/server/plugins/plugins_service.test.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts
similarity index 99%
rename from src/core/server/plugins/plugins_service.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts
index 9e234b871d647..4664db6e710c7 100644
--- a/src/core/server/plugins/plugins_service.test.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.test.ts
@@ -19,14 +19,15 @@ import { rawConfigServiceMock, getEnvOptions } from '@kbn/config-mocks';
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
import { environmentServiceMock } from '@kbn/core-environment-server-mocks';
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
-import { coreMock } from '../mocks';
+import { coreInternalLifecycleMock } from '@kbn/core-lifecycle-server-mocks';
import { PluginDiscoveryError } from './discovery';
import { PluginWrapper } from './plugin';
import { PluginsService } from './plugins_service';
import { PluginsSystem } from './plugins_system';
import { config } from './plugins_config';
import { take } from 'rxjs/operators';
-import { DiscoveredPlugin, PluginConfigDescriptor, PluginType } from './types';
+import type { PluginConfigDescriptor } from '@kbn/core-plugins-server';
+import { DiscoveredPlugin, PluginType } from '@kbn/core-base-common';
const MockPluginsSystem: jest.Mock> = PluginsSystem as any;
@@ -40,9 +41,9 @@ let standardMockPluginSystem: jest.Mocked>;
let environmentPreboot: ReturnType;
let nodePreboot: ReturnType;
-const prebootDeps = coreMock.createInternalPreboot();
-const setupDeps = coreMock.createInternalSetup();
-const startDeps = coreMock.createInternalStart();
+const prebootDeps = coreInternalLifecycleMock.createInternalPreboot();
+const setupDeps = coreInternalLifecycleMock.createInternalSetup();
+const startDeps = coreInternalLifecycleMock.createInternalStart();
const logger = loggingSystemMock.create();
expect.addSnapshotSerializer(createAbsolutePathSerializer());
diff --git a/src/core/server/plugins/plugins_service.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts
similarity index 97%
rename from src/core/server/plugins/plugins_service.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts
index 3305ff0a06b43..556cd8331b454 100644
--- a/src/core/server/plugins/plugins_service.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/plugins_service.ts
@@ -14,17 +14,24 @@ import { getFlattenedObject } from '@kbn/std';
import { Logger } from '@kbn/logging';
import type { IConfigService } from '@kbn/config';
import type { CoreContext, CoreService } from '@kbn/core-base-server-internal';
-import type { PluginName } from '@kbn/core-base-common';
+import { type PluginName, PluginType } from '@kbn/core-base-common';
import type { InternalEnvironmentServicePreboot } from '@kbn/core-environment-server-internal';
import type { InternalNodeServicePreboot } from '@kbn/core-node-server-internal';
import type { InternalPluginInfo, UiPlugins } from '@kbn/core-plugins-base-server-internal';
+import {
+ InternalCorePreboot,
+ InternalCoreSetup,
+ InternalCoreStart,
+} from '@kbn/core-lifecycle-server-internal';
+import { PluginConfigDescriptor } from '@kbn/core-plugins-server';
+import type { DiscoveredPlugin } from '@kbn/core-base-common';
import { discover, PluginDiscoveryError, PluginDiscoveryErrorType } from './discovery';
import { PluginWrapper } from './plugin';
-import { DiscoveredPlugin, PluginConfigDescriptor, PluginDependencies, PluginType } from './types';
+
+import type { PluginDependencies } from './types';
import { PluginsConfig, PluginsConfigType } from './plugins_config';
import { PluginsSystem } from './plugins_system';
import { createBrowserConfig } from './create_browser_config';
-import { InternalCorePreboot, InternalCoreSetup, InternalCoreStart } from '../internal_types';
/** @internal */
export type DiscoveredPlugins = {
diff --git a/src/core/server/plugins/plugins_system.test.mocks.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_system.test.mocks.ts
similarity index 100%
rename from src/core/server/plugins/plugins_system.test.mocks.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugins_system.test.mocks.ts
diff --git a/src/core/server/plugins/plugins_system.test.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_system.test.ts
similarity index 98%
rename from src/core/server/plugins/plugins_system.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugins_system.test.ts
index 5dc8507302bc3..4010d548a6219 100644
--- a/src/core/server/plugins/plugins_system.test.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/plugins_system.test.ts
@@ -15,7 +15,7 @@ import {
import { BehaviorSubject } from 'rxjs';
import { REPO_ROOT } from '@kbn/utils';
-import type { PluginName } from '@kbn/core-base-common';
+import { type PluginName, PluginType } from '@kbn/core-base-common';
import type { CoreContext } from '@kbn/core-base-server-internal';
import { Logger } from '@kbn/logging';
import { Env } from '@kbn/config';
@@ -23,9 +23,8 @@ import { configServiceMock, getEnvOptions } from '@kbn/config-mocks';
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
import { PluginWrapper } from './plugin';
-import { PluginType } from './types';
import { PluginsSystem } from './plugins_system';
-import { coreMock } from '../mocks';
+import { coreInternalLifecycleMock } from '@kbn/core-lifecycle-server-mocks';
function createPlugin(
id: string,
@@ -63,9 +62,9 @@ function createPlugin(
});
}
-const prebootDeps = coreMock.createInternalPreboot();
-const setupDeps = coreMock.createInternalSetup();
-const startDeps = coreMock.createInternalStart();
+const prebootDeps = coreInternalLifecycleMock.createInternalPreboot();
+const setupDeps = coreInternalLifecycleMock.createInternalSetup();
+const startDeps = coreInternalLifecycleMock.createInternalStart();
let pluginsSystem: PluginsSystem;
let configService: ReturnType;
diff --git a/src/core/server/plugins/plugins_system.ts b/packages/core/plugins/core-plugins-server-internal/src/plugins_system.ts
similarity index 97%
rename from src/core/server/plugins/plugins_system.ts
rename to packages/core/plugins/core-plugins-server-internal/src/plugins_system.ts
index 57db8e7c70f49..d7c4df71dd4fc 100644
--- a/src/core/server/plugins/plugins_system.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/plugins_system.ts
@@ -7,17 +7,18 @@
*/
import { withTimeout, isPromise } from '@kbn/std';
-import type { PluginName } from '@kbn/core-base-common';
+import type { DiscoveredPlugin, PluginName } from '@kbn/core-base-common';
import type { CoreContext } from '@kbn/core-base-server-internal';
-import { Logger } from '@kbn/logging';
-import { PluginWrapper } from './plugin';
-import { DiscoveredPlugin, PluginDependencies, PluginType } from './types';
+import type { Logger } from '@kbn/logging';
+import { PluginType } from '@kbn/core-base-common';
+import type { PluginWrapper } from './plugin';
+import { type PluginDependencies } from './types';
import {
createPluginPrebootSetupContext,
createPluginSetupContext,
createPluginStartContext,
} from './plugin_context';
-import {
+import type {
PluginsServicePrebootSetupDeps,
PluginsServiceSetupDeps,
PluginsServiceStartDeps,
diff --git a/packages/core/plugins/core-plugins-server-internal/src/test_helpers/create_core_context_config_service.mock.ts b/packages/core/plugins/core-plugins-server-internal/src/test_helpers/create_core_context_config_service.mock.ts
new file mode 100644
index 0000000000000..399d45398eefb
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-internal/src/test_helpers/create_core_context_config_service.mock.ts
@@ -0,0 +1,43 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { IConfigService } from '@kbn/config';
+import { configServiceMock } from '@kbn/config-mocks';
+import { ByteSizeValue } from '@kbn/config-schema';
+import { fromRoot } from '@kbn/utils';
+import { duration } from 'moment';
+import { from } from 'rxjs';
+
+export const createCoreContextConfigServiceMock = (): IConfigService => {
+ const configService = configServiceMock.create();
+ const getPathConfig = (path: string | string[]) => {
+ switch (path) {
+ case 'elasticsearch':
+ return {
+ shardTimeout: duration(30, 's'),
+ requestTimeout: duration(30, 's'),
+ pingTimeout: duration(30, 's'),
+ someOtherProps: 'unused',
+ };
+ case 'path':
+ return { data: fromRoot('data'), someOtherProps: 'unused' };
+ case 'savedObjects':
+ return { maxImportPayloadBytes: new ByteSizeValue(26214400), someOtherProps: 'unused' };
+ default:
+ return {};
+ }
+ };
+ configService.atPath.mockImplementation((path) => {
+ return from([getPathConfig(path)]);
+ });
+ configService.atPathSync.mockImplementation((path) => {
+ return getPathConfig(path);
+ });
+
+ return configService;
+};
diff --git a/packages/core/plugins/core-plugins-server-internal/src/test_helpers/index.ts b/packages/core/plugins/core-plugins-server-internal/src/test_helpers/index.ts
new file mode 100644
index 0000000000000..86ffb0ec8f407
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-internal/src/test_helpers/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 { createCoreContextConfigServiceMock } from './create_core_context_config_service.mock';
diff --git a/src/core/server/plugins/types.test.ts b/packages/core/plugins/core-plugins-server-internal/src/types.test.ts
similarity index 96%
rename from src/core/server/plugins/types.test.ts
rename to packages/core/plugins/core-plugins-server-internal/src/types.test.ts
index 4a0e6052a9901..ea1537bf0649e 100644
--- a/src/core/server/plugins/types.test.ts
+++ b/packages/core/plugins/core-plugins-server-internal/src/types.test.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { ExposedToBrowserDescriptor } from './types';
+import type { ExposedToBrowserDescriptor } from '@kbn/core-plugins-server';
describe('ExposedToBrowserDescriptor', () => {
interface ConfigType {
diff --git a/packages/core/plugins/core-plugins-server-internal/src/types.ts b/packages/core/plugins/core-plugins-server-internal/src/types.ts
new file mode 100644
index 0000000000000..def1a27a4c26f
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-internal/src/types.ts
@@ -0,0 +1,15 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { PluginName, PluginOpaqueId } from '@kbn/core-base-common';
+
+/** @internal */
+export interface PluginDependencies {
+ asNames: ReadonlyMap;
+ asOpaqueIds: ReadonlyMap;
+}
diff --git a/packages/core/plugins/core-plugins-server-internal/tsconfig.json b/packages/core/plugins/core-plugins-server-internal/tsconfig.json
new file mode 100644
index 0000000000000..71bb40fe57f3f
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-internal/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "stripInternal": false,
+ "types": [
+ "jest",
+ "node"
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ ]
+}
diff --git a/packages/core/plugins/core-plugins-server-mocks/BUILD.bazel b/packages/core/plugins/core-plugins-server-mocks/BUILD.bazel
new file mode 100644
index 0000000000000..39ca50e2b847c
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-mocks/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-plugins-server-mocks"
+PKG_REQUIRE_NAME = "@kbn/core-plugins-server-mocks"
+
+SOURCE_FILES = glob(
+ [
+ "**/*.ts",
+ ],
+ exclude = [
+ "**/*.config.js",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+RUNTIME_DEPS = [
+ "//packages/core/plugins/core-plugins-server-internal",
+]
+
+TYPES_DEPS = [
+ "@npm//@types/node",
+ "@npm//@types/jest",
+ "//packages/kbn-utility-types:npm_module_types",
+ "//packages/core/plugins/core-plugins-server-internal:npm_module_types",
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+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,
+ declaration_map = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node"],
+ 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/plugins/core-plugins-server-mocks/README.md b/packages/core/plugins/core-plugins-server-mocks/README.md
new file mode 100644
index 0000000000000..2ec4d6313919f
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-mocks/README.md
@@ -0,0 +1,4 @@
+# @kbn/core-plugins-server-mocks
+
+This package contains mocks for Core's server-side `plugins` service.
+- `pluginsServiceMock`
diff --git a/packages/core/plugins/core-plugins-server-mocks/index.ts b/packages/core/plugins/core-plugins-server-mocks/index.ts
new file mode 100644
index 0000000000000..ebf3e8864ef33
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-mocks/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 { pluginServiceMock } from './src';
diff --git a/packages/core/plugins/core-plugins-server-mocks/jest.config.js b/packages/core/plugins/core-plugins-server-mocks/jest.config.js
new file mode 100644
index 0000000000000..f7924be975ac9
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-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/jest_node',
+ rootDir: '../../../..',
+ roots: ['/packages/core/plugins/core-plugins-server-mocks'],
+};
diff --git a/packages/core/plugins/core-plugins-server-mocks/kibana.jsonc b/packages/core/plugins/core-plugins-server-mocks/kibana.jsonc
new file mode 100644
index 0000000000000..4a1b2c0bd2258
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-mocks/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/core-plugins-server-mocks",
+ "owner": "@elastic/kibana-core",
+ "runtimeDeps": [],
+ "typeDeps": [],
+}
diff --git a/packages/core/plugins/core-plugins-server-mocks/package.json b/packages/core/plugins/core-plugins-server-mocks/package.json
new file mode 100644
index 0000000000000..0af107840be65
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-mocks/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@kbn/core-plugins-server-mocks",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "author": "Kibana Core",
+ "license": "SSPL-1.0 OR Elastic License 2.0"
+}
diff --git a/packages/core/plugins/core-plugins-server-mocks/src/index.ts b/packages/core/plugins/core-plugins-server-mocks/src/index.ts
new file mode 100644
index 0000000000000..30b3d50c22b74
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-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 { pluginServiceMock } from './plugins_service.mock';
diff --git a/src/core/server/plugins/plugins_service.mock.ts b/packages/core/plugins/core-plugins-server-mocks/src/plugins_service.mock.ts
similarity index 93%
rename from src/core/server/plugins/plugins_service.mock.ts
rename to packages/core/plugins/core-plugins-server-mocks/src/plugins_service.mock.ts
index ee7b35a412e80..58c43a4c30eda 100644
--- a/src/core/server/plugins/plugins_service.mock.ts
+++ b/packages/core/plugins/core-plugins-server-mocks/src/plugins_service.mock.ts
@@ -7,7 +7,7 @@
*/
import type { PublicMethodsOf } from '@kbn/utility-types';
-import type { PluginsService, PluginsServiceSetup } from './plugins_service';
+import { PluginsService, type PluginsServiceSetup } from '@kbn/core-plugins-server-internal';
type PluginsServiceMock = jest.Mocked>;
diff --git a/packages/core/plugins/core-plugins-server-mocks/tsconfig.json b/packages/core/plugins/core-plugins-server-mocks/tsconfig.json
new file mode 100644
index 0000000000000..71bb40fe57f3f
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server-mocks/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "stripInternal": false,
+ "types": [
+ "jest",
+ "node"
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ ]
+}
diff --git a/packages/core/plugins/core-plugins-server/BUILD.bazel b/packages/core/plugins/core-plugins-server/BUILD.bazel
new file mode 100644
index 0000000000000..ec304498d123c
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server/BUILD.bazel
@@ -0,0 +1,119 @@
+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-plugins-server"
+PKG_REQUIRE_NAME = "@kbn/core-plugins-server"
+
+SOURCE_FILES = glob(
+ [
+ "**/*.ts",
+ ],
+ exclude = [
+ "**/*.config.js",
+ "**/*.mock.*",
+ "**/*.test.*",
+ "**/*.stories.*",
+ "**/__snapshots__/**",
+ "**/integration_tests/**",
+ "**/mocks/**",
+ "**/scripts/**",
+ "**/storybook/**",
+ "**/test_fixtures/**",
+ "**/test_helpers/**",
+ ],
+)
+
+SRCS = SOURCE_FILES
+
+filegroup(
+ name = "srcs",
+ srcs = SRCS,
+)
+
+NPM_MODULE_EXTRA_FILES = [
+ "package.json",
+]
+
+RUNTIME_DEPS = [
+ "@npm//rxjs",
+ "//packages/kbn-config-schema",
+]
+
+TYPES_DEPS = [
+ "@npm//@types/node",
+ "@npm//@types/jest",
+ "@npm//rxjs",
+ "//packages/kbn-config:npm_module_types",
+ "//packages/kbn-config-schema:npm_module_types",
+ "//packages/kbn-utility-types:npm_module_types",
+ "//packages/kbn-utils:npm_module_types",
+ "//packages/kbn-logging:npm_module_types",
+ "//packages/core/base/core-base-common:npm_module_types",
+ "//packages/core/node/core-node-server:npm_module_types",
+ "//packages/core/elasticsearch/core-elasticsearch-server-internal:npm_module_types",
+ "//packages/core/saved-objects/core-saved-objects-base-server-internal:npm_module_types",
+ "//packages/core/lifecycle/core-lifecycle-server:npm_module_types",
+
+]
+
+jsts_transpiler(
+ name = "target_node",
+ srcs = SRCS,
+ build_pkg_name = package_name(),
+)
+
+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,
+ declaration_map = True,
+ emit_declaration_only = True,
+ out_dir = "target_types",
+ tsconfig = ":tsconfig",
+)
+
+js_library(
+ name = PKG_DIRNAME,
+ srcs = NPM_MODULE_EXTRA_FILES,
+ deps = RUNTIME_DEPS + [":target_node"],
+ 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/plugins/core-plugins-server/README.md b/packages/core/plugins/core-plugins-server/README.md
new file mode 100644
index 0000000000000..1add32cc3e1d4
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server/README.md
@@ -0,0 +1,3 @@
+# @kbn/core-plugins-server
+
+This package contains the public types for core's server-side plugins service.
diff --git a/packages/core/plugins/core-plugins-server/index.ts b/packages/core/plugins/core-plugins-server/index.ts
new file mode 100644
index 0000000000000..47aa0d04ac87c
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server/index.ts
@@ -0,0 +1,23 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 {
+ PrebootPlugin,
+ Plugin,
+ AsyncPlugin,
+ PluginConfigDescriptor,
+ PluginConfigSchema,
+ PluginInitializer,
+ PluginInitializerContext,
+ PluginManifest,
+ SharedGlobalConfig,
+ MakeUsageFromSchema,
+ ExposedToBrowserDescriptor,
+} from './src';
+
+export { SharedGlobalConfigKeys } from './src';
diff --git a/packages/core/plugins/core-plugins-server/jest.config.js b/packages/core/plugins/core-plugins-server/jest.config.js
new file mode 100644
index 0000000000000..f03056c0495e2
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server/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/jest_node',
+ rootDir: '../../../..',
+ roots: ['/packages/core/plugins/core-plugins-server'],
+};
diff --git a/packages/core/plugins/core-plugins-server/kibana.jsonc b/packages/core/plugins/core-plugins-server/kibana.jsonc
new file mode 100644
index 0000000000000..708281a40646b
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server/kibana.jsonc
@@ -0,0 +1,7 @@
+{
+ "type": "shared-common",
+ "id": "@kbn/core-plugins-server",
+ "owner": "@elastic/kibana-core",
+ "runtimeDeps": [],
+ "typeDeps": [],
+}
diff --git a/packages/core/plugins/core-plugins-server/package.json b/packages/core/plugins/core-plugins-server/package.json
new file mode 100644
index 0000000000000..75fda3c2ef661
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server/package.json
@@ -0,0 +1,8 @@
+{
+ "name": "@kbn/core-plugins-server",
+ "private": true,
+ "version": "1.0.0",
+ "main": "./target_node/index.js",
+ "author": "Kibana Core",
+ "license": "SSPL-1.0 OR Elastic License 2.0"
+}
diff --git a/packages/core/plugins/core-plugins-server/src/index.ts b/packages/core/plugins/core-plugins-server/src/index.ts
new file mode 100644
index 0000000000000..94ad27dedbf12
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server/src/index.ts
@@ -0,0 +1,23 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 {
+ PrebootPlugin,
+ Plugin,
+ AsyncPlugin,
+ PluginConfigDescriptor,
+ PluginConfigSchema,
+ PluginInitializer,
+ PluginInitializerContext,
+ PluginManifest,
+ SharedGlobalConfig,
+ MakeUsageFromSchema,
+ ExposedToBrowserDescriptor,
+} from './types';
+
+export { SharedGlobalConfigKeys } from './shared_global_config';
diff --git a/packages/core/plugins/core-plugins-server/src/shared_global_config.ts b/packages/core/plugins/core-plugins-server/src/shared_global_config.ts
new file mode 100644
index 0000000000000..6329b2576ab21
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server/src/shared_global_config.ts
@@ -0,0 +1,14 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 const SharedGlobalConfigKeys = {
+ // We can add more if really needed
+ elasticsearch: ['shardTimeout', 'requestTimeout', 'pingTimeout'] as const,
+ path: ['data'] as const,
+ savedObjects: ['maxImportPayloadBytes'] as const,
+};
diff --git a/src/core/server/plugins/types.ts b/packages/core/plugins/core-plugins-server/src/types.ts
similarity index 94%
rename from src/core/server/plugins/types.ts
rename to packages/core/plugins/core-plugins-server/src/types.ts
index 699631bc4411e..46773971d35ef 100644
--- a/src/core/server/plugins/types.ts
+++ b/packages/core/plugins/core-plugins-server/src/types.ts
@@ -8,9 +8,9 @@
import { Observable } from 'rxjs';
import { Type } from '@kbn/config-schema';
-import { RecursiveReadonly } from '@kbn/utility-types';
-import { PathConfigType } from '@kbn/utils';
-import { LoggerFactory } from '@kbn/logging';
+import type { RecursiveReadonly } from '@kbn/utility-types';
+import type { PathConfigType } from '@kbn/utils';
+import type { LoggerFactory } from '@kbn/logging';
import type {
ConfigPath,
EnvironmentMode,
@@ -21,14 +21,10 @@ import type { PluginName, PluginOpaqueId, PluginType } from '@kbn/core-base-comm
import type { NodeInfo } from '@kbn/core-node-server';
import type { ElasticsearchConfigType } from '@kbn/core-elasticsearch-server-internal';
import type { SavedObjectsConfigType } from '@kbn/core-saved-objects-base-server-internal';
-import { CorePreboot, CoreSetup, CoreStart } from '..';
-
+import type { CorePreboot, CoreSetup, CoreStart } from '@kbn/core-lifecycle-server';
+import { SharedGlobalConfigKeys } from './shared_global_config';
type Maybe = T | undefined;
-// re-exporting for now to avoid adapting all imports, will be removed later on in the migration process
-export type { PluginName, PluginOpaqueId, DiscoveredPlugin } from '@kbn/core-base-common';
-export { PluginType } from '@kbn/core-base-common';
-
/**
* Dedicated type for plugin configuration schema.
*
@@ -131,12 +127,6 @@ export type MakeUsageFromSchema = {
: boolean;
};
-/** @internal */
-export interface PluginDependencies {
- asNames: ReadonlyMap;
- asOpaqueIds: ReadonlyMap;
-}
-
/**
* Describes the set of required and optional properties plugin can define in its
* mandatory JSON manifest file.
@@ -303,13 +293,6 @@ export interface AsyncPlugin<
stop?(): void;
}
-export const SharedGlobalConfigKeys = {
- // We can add more if really needed
- elasticsearch: ['shardTimeout', 'requestTimeout', 'pingTimeout'] as const,
- path: ['data'] as const,
- savedObjects: ['maxImportPayloadBytes'] as const,
-};
-
/**
* @public
*/
diff --git a/packages/core/plugins/core-plugins-server/tsconfig.json b/packages/core/plugins/core-plugins-server/tsconfig.json
new file mode 100644
index 0000000000000..71bb40fe57f3f
--- /dev/null
+++ b/packages/core/plugins/core-plugins-server/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../../../../tsconfig.bazel.json",
+ "compilerOptions": {
+ "declaration": true,
+ "declarationMap": true,
+ "emitDeclarationOnly": true,
+ "outDir": "target_types",
+ "stripInternal": false,
+ "types": [
+ "jest",
+ "node"
+ ]
+ },
+ "include": [
+ "**/*.ts",
+ ]
+}
diff --git a/packages/kbn-ace/BUILD.bazel b/packages/kbn-ace/BUILD.bazel
index 91900928a6bca..7f30af32afa95 100644
--- a/packages/kbn-ace/BUILD.bazel
+++ b/packages/kbn-ace/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_BASE_NAME = "kbn-ace"
+PKG_DIRNAME = "kbn-ace"
PKG_REQUIRE_NAME = "@kbn/ace"
SOURCE_FILES = glob(
@@ -97,7 +97,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -106,9 +106,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-alerts/BUILD.bazel b/packages/kbn-alerts/BUILD.bazel
index 86a23118abfe0..c9e52274d39f5 100644
--- a/packages/kbn-alerts/BUILD.bazel
+++ b/packages/kbn-alerts/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_BASE_NAME = "kbn-alerts"
+PKG_DIRNAME = "kbn-alerts"
PKG_REQUIRE_NAME = "@kbn/alerts"
SOURCE_FILES = glob(
@@ -89,7 +89,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -98,9 +98,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-analytics/BUILD.bazel b/packages/kbn-analytics/BUILD.bazel
index 4c9065c836068..53d0cbf16ddee 100644
--- a/packages/kbn-analytics/BUILD.bazel
+++ b/packages/kbn-analytics/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_BASE_NAME = "kbn-analytics"
+PKG_DIRNAME = "kbn-analytics"
PKG_REQUIRE_NAME = "@kbn/analytics"
SOURCE_FILES = glob(
@@ -92,7 +92,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -101,9 +101,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-apm-config-loader/BUILD.bazel b/packages/kbn-apm-config-loader/BUILD.bazel
index 8d83162d204bc..526193788cd92 100644
--- a/packages/kbn-apm-config-loader/BUILD.bazel
+++ b/packages/kbn-apm-config-loader/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_BASE_NAME = "kbn-apm-config-loader"
+PKG_DIRNAME = "kbn-apm-config-loader"
PKG_REQUIRE_NAME = "@kbn/apm-config-loader"
SOURCE_FILES = glob(
@@ -82,7 +82,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -91,9 +91,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-apm-config-loader/index.ts b/packages/kbn-apm-config-loader/index.ts
index e2027b2e12c7c..24f46c01b4b3f 100644
--- a/packages/kbn-apm-config-loader/index.ts
+++ b/packages/kbn-apm-config-loader/index.ts
@@ -10,3 +10,4 @@ export { getConfiguration } from './src/config_loader';
export { initApm } from './src/init_apm';
export { shouldInstrumentClient } from './src/rum_agent_configuration';
export type { ApmConfiguration } from './src/config';
+export { apmConfigSchema } from './src/apm_config';
diff --git a/packages/kbn-apm-config-loader/src/apm_config.ts b/packages/kbn-apm-config-loader/src/apm_config.ts
new file mode 100644
index 0000000000000..0e7b1b9546288
--- /dev/null
+++ b/packages/kbn-apm-config-loader/src/apm_config.ts
@@ -0,0 +1,21 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { schema } from '@kbn/config-schema';
+
+export const apmConfigSchema = schema.object({
+ apm: schema.object(
+ {
+ active: schema.maybe(schema.boolean()),
+ serverUrl: schema.maybe(schema.uri()),
+ secretToken: schema.maybe(schema.string()),
+ globalLabels: schema.object({}, { unknowns: 'allow' }),
+ },
+ { unknowns: 'allow' }
+ ),
+});
diff --git a/packages/kbn-apm-synthtrace/BUILD.bazel b/packages/kbn-apm-synthtrace/BUILD.bazel
index 1160e8a7a1618..4107a948e27c8 100644
--- a/packages/kbn-apm-synthtrace/BUILD.bazel
+++ b/packages/kbn-apm-synthtrace/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_BASE_NAME = "kbn-apm-synthtrace"
+PKG_DIRNAME = "kbn-apm-synthtrace"
PKG_REQUIRE_NAME = "@kbn/apm-synthtrace"
SOURCE_FILES = glob(
@@ -93,7 +93,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -102,9 +102,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-apm-utils/BUILD.bazel b/packages/kbn-apm-utils/BUILD.bazel
index ab3004dc47d36..41b28d8c11cfc 100644
--- a/packages/kbn-apm-utils/BUILD.bazel
+++ b/packages/kbn-apm-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_BASE_NAME = "kbn-apm-utils"
+PKG_DIRNAME = "kbn-apm-utils"
PKG_REQUIRE_NAME = "@kbn/apm-utils"
SOURCE_FILES = glob(
@@ -72,7 +72,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -81,9 +81,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-babel-plugin-synthetic-packages/BUILD.bazel b/packages/kbn-babel-plugin-synthetic-packages/BUILD.bazel
index da588dab2ce42..a1e6891f23ec5 100644
--- a/packages/kbn-babel-plugin-synthetic-packages/BUILD.bazel
+++ b/packages/kbn-babel-plugin-synthetic-packages/BUILD.bazel
@@ -44,9 +44,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_DIRNAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-babel-preset/BUILD.bazel b/packages/kbn-babel-preset/BUILD.bazel
index 54dc3bafd8ac8..7b4090ceac48e 100644
--- a/packages/kbn-babel-preset/BUILD.bazel
+++ b/packages/kbn-babel-preset/BUILD.bazel
@@ -1,7 +1,7 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "pkg_npm")
-PKG_BASE_NAME = "kbn-babel-preset"
+PKG_DIRNAME = "kbn-babel-preset"
PKG_REQUIRE_NAME = "@kbn/babel-preset"
SOURCE_FILES = glob([
@@ -43,7 +43,7 @@ RUNTIME_DEPS = [
]
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":srcs",
],
@@ -54,9 +54,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-cli-dev-mode/BUILD.bazel b/packages/kbn-cli-dev-mode/BUILD.bazel
index 9b03aaa956b54..90d11fdeb62bb 100644
--- a/packages/kbn-cli-dev-mode/BUILD.bazel
+++ b/packages/kbn-cli-dev-mode/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_BASE_NAME = "kbn-cli-dev-mode"
+PKG_DIRNAME = "kbn-cli-dev-mode"
PKG_REQUIRE_NAME = "@kbn/cli-dev-mode"
SOURCE_FILES = glob(
@@ -110,7 +110,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -119,9 +119,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-config-schema/BUILD.bazel b/packages/kbn-config-schema/BUILD.bazel
index aebd34efa2f08..c14ba00345437 100644
--- a/packages/kbn-config-schema/BUILD.bazel
+++ b/packages/kbn-config-schema/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_BASE_NAME = "kbn-config-schema"
+PKG_DIRNAME = "kbn-config-schema"
PKG_REQUIRE_NAME = "@kbn/config-schema"
SOURCE_FILES = glob(
@@ -82,7 +82,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -91,9 +91,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-config/BUILD.bazel b/packages/kbn-config/BUILD.bazel
index eef3d336b57dd..4e1066bd7a19b 100644
--- a/packages/kbn-config/BUILD.bazel
+++ b/packages/kbn-config/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_BASE_NAME = "kbn-config"
+PKG_DIRNAME = "kbn-config"
PKG_REQUIRE_NAME = "@kbn/config"
SOURCE_FILES = glob(
@@ -101,7 +101,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -110,9 +110,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-crypto/BUILD.bazel b/packages/kbn-crypto/BUILD.bazel
index 4dade7bba6ca2..55ed47a64303a 100644
--- a/packages/kbn-crypto/BUILD.bazel
+++ b/packages/kbn-crypto/BUILD.bazel
@@ -3,7 +3,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_BASE_NAME = "kbn-crypto"
+PKG_DIRNAME = "kbn-crypto"
PKG_REQUIRE_NAME = "@kbn/crypto"
SOURCE_FILES = glob(
@@ -79,7 +79,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -88,9 +88,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-datemath/BUILD.bazel b/packages/kbn-datemath/BUILD.bazel
index ae4e19b9b7c8c..95e93f70e92e1 100644
--- a/packages/kbn-datemath/BUILD.bazel
+++ b/packages/kbn-datemath/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", "ts_project", "pkg_npm", "pkg_npm_types")
-PKG_BASE_NAME = "kbn-datemath"
+PKG_DIRNAME = "kbn-datemath"
PKG_REQUIRE_NAME = "@kbn/datemath"
SOURCE_FILES = glob(
@@ -71,7 +71,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -80,9 +80,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-dev-utils/BUILD.bazel b/packages/kbn-dev-utils/BUILD.bazel
index 42543650a1051..849ea8404f32c 100644
--- a/packages/kbn-dev-utils/BUILD.bazel
+++ b/packages/kbn-dev-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_BASE_NAME = "kbn-dev-utils"
+PKG_DIRNAME = "kbn-dev-utils"
PKG_REQUIRE_NAME = "@kbn/dev-utils"
SOURCE_FILES = glob(
@@ -153,7 +153,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -162,9 +162,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-doc-links/BUILD.bazel b/packages/kbn-doc-links/BUILD.bazel
index c4849085c0ae2..292560832da85 100644
--- a/packages/kbn-doc-links/BUILD.bazel
+++ b/packages/kbn-doc-links/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_BASE_NAME = "kbn-doc-links"
+PKG_DIRNAME = "kbn-doc-links"
PKG_REQUIRE_NAME = "@kbn/doc-links"
SOURCE_FILES = glob(
@@ -82,7 +82,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -91,9 +91,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-docs-utils/BUILD.bazel b/packages/kbn-docs-utils/BUILD.bazel
index 33687685100e1..5564b87e15f13 100644
--- a/packages/kbn-docs-utils/BUILD.bazel
+++ b/packages/kbn-docs-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_BASE_NAME = "kbn-docs-utils"
+PKG_DIRNAME = "kbn-docs-utils"
PKG_REQUIRE_NAME = "@kbn/docs-utils"
SOURCE_FILES = glob(
@@ -86,7 +86,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -95,9 +95,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-ebt-tools/BUILD.bazel b/packages/kbn-ebt-tools/BUILD.bazel
index ca3591e936703..5b318045b9301 100644
--- a/packages/kbn-ebt-tools/BUILD.bazel
+++ b/packages/kbn-ebt-tools/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_BASE_NAME = "kbn-ebt-tools"
+PKG_DIRNAME = "kbn-ebt-tools"
PKG_REQUIRE_NAME = "@kbn/ebt-tools"
SOURCE_FILES = glob(
@@ -72,7 +72,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":tsc_types"],
package_name = PKG_REQUIRE_NAME,
@@ -81,9 +81,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-es-archiver/BUILD.bazel b/packages/kbn-es-archiver/BUILD.bazel
index 7b0f9f0346630..7d214d913aeae 100644
--- a/packages/kbn-es-archiver/BUILD.bazel
+++ b/packages/kbn-es-archiver/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_BASE_NAME = "kbn-es-archiver"
+PKG_DIRNAME = "kbn-es-archiver"
PKG_REQUIRE_NAME = "@kbn/es-archiver"
SOURCE_FILES = glob(
@@ -94,7 +94,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -103,9 +103,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-es-query/BUILD.bazel b/packages/kbn-es-query/BUILD.bazel
index 2a7c445c32aac..a34b58155359d 100644
--- a/packages/kbn-es-query/BUILD.bazel
+++ b/packages/kbn-es-query/BUILD.bazel
@@ -3,7 +3,7 @@ load("@npm//peggy:index.bzl", "peggy")
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_BASE_NAME = "kbn-es-query"
+PKG_DIRNAME = "kbn-es-query"
PKG_REQUIRE_NAME = "@kbn/es-query"
SOURCE_FILES = glob(
@@ -109,7 +109,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [":grammar"],
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -118,9 +118,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-es/BUILD.bazel b/packages/kbn-es/BUILD.bazel
index 23ddda10f36e5..2aeaee4071d53 100644
--- a/packages/kbn-es/BUILD.bazel
+++ b/packages/kbn-es/BUILD.bazel
@@ -1,7 +1,7 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm")
-PKG_BASE_NAME = "kbn-es"
+PKG_DIRNAME = "kbn-es"
PKG_REQUIRE_NAME = "@kbn/es"
SOURCE_FILES = glob(
@@ -57,7 +57,7 @@ jsts_transpiler(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -66,9 +66,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-eslint-config/BUILD.bazel b/packages/kbn-eslint-config/BUILD.bazel
index 73f834f7d5f63..708136256498d 100644
--- a/packages/kbn-eslint-config/BUILD.bazel
+++ b/packages/kbn-eslint-config/BUILD.bazel
@@ -1,7 +1,7 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "pkg_npm")
-PKG_BASE_NAME = "kbn-eslint-config"
+PKG_DIRNAME = "kbn-eslint-config"
PKG_REQUIRE_NAME = "@kbn/eslint-config"
SOURCE_FILES = glob([
@@ -34,7 +34,7 @@ RUNTIME_DEPS = [
]
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":srcs",
],
@@ -45,9 +45,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-eslint-plugin-eslint/BUILD.bazel b/packages/kbn-eslint-plugin-eslint/BUILD.bazel
index c043c4e468db9..0bb2ff549c9f9 100644
--- a/packages/kbn-eslint-plugin-eslint/BUILD.bazel
+++ b/packages/kbn-eslint-plugin-eslint/BUILD.bazel
@@ -1,7 +1,7 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "pkg_npm")
-PKG_BASE_NAME = "kbn-eslint-plugin-eslint"
+PKG_DIRNAME = "kbn-eslint-plugin-eslint"
PKG_REQUIRE_NAME = "@kbn/eslint-plugin-eslint"
SOURCE_FILES = glob(
@@ -46,7 +46,7 @@ RUNTIME_DEPS = [
]
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":srcs",
],
@@ -57,9 +57,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-expect/BUILD.bazel b/packages/kbn-expect/BUILD.bazel
index 415b402a3d05c..70ed34ad091ce 100644
--- a/packages/kbn-expect/BUILD.bazel
+++ b/packages/kbn-expect/BUILD.bazel
@@ -1,7 +1,7 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "pkg_npm")
-PKG_BASE_NAME = "kbn-expect"
+PKG_DIRNAME = "kbn-expect"
PKG_REQUIRE_NAME = "@kbn/expect"
SOURCE_FILES = glob([
@@ -22,7 +22,7 @@ NPM_MODULE_EXTRA_FILES = [
]
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":srcs",
],
@@ -32,9 +32,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-field-types/BUILD.bazel b/packages/kbn-field-types/BUILD.bazel
index 1d5ca19241bba..fa6bf48c39c88 100644
--- a/packages/kbn-field-types/BUILD.bazel
+++ b/packages/kbn-field-types/BUILD.bazel
@@ -3,7 +3,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_BASE_NAME = "kbn-field-types"
+PKG_DIRNAME = "kbn-field-types"
PKG_REQUIRE_NAME = "@kbn/field-types"
SOURCE_FILES = glob(
@@ -87,7 +87,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -96,9 +96,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-flot-charts/BUILD.bazel b/packages/kbn-flot-charts/BUILD.bazel
index d819fa05c7d16..ec2655bc2bbf1 100644
--- a/packages/kbn-flot-charts/BUILD.bazel
+++ b/packages/kbn-flot-charts/BUILD.bazel
@@ -1,7 +1,7 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "pkg_npm")
-PKG_BASE_NAME = "kbn-flot-charts"
+PKG_DIRNAME = "kbn-flot-charts"
PKG_REQUIRE_NAME = "@kbn/flot-charts"
SOURCE_FILES = glob([
@@ -26,7 +26,7 @@ RUNTIME_DEPS = [
]
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":srcs",
],
@@ -37,9 +37,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-generate/BUILD.bazel b/packages/kbn-generate/BUILD.bazel
index 098291d8a0877..e4afaec6069b9 100644
--- a/packages/kbn-generate/BUILD.bazel
+++ b/packages/kbn-generate/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_BASE_NAME = "kbn-generate"
+PKG_DIRNAME = "kbn-generate"
PKG_REQUIRE_NAME = "@kbn/generate"
SOURCE_FILES = glob(
@@ -85,7 +85,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -94,9 +94,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-guided-onboarding/src/components/landing_page/__snapshots__/guide_card_footer.test.tsx.snap b/packages/kbn-guided-onboarding/src/components/landing_page/__snapshots__/guide_card_footer.test.tsx.snap
index 9b18465e91be9..cbb21df42a054 100644
--- a/packages/kbn-guided-onboarding/src/components/landing_page/__snapshots__/guide_card_footer.test.tsx.snap
+++ b/packages/kbn-guided-onboarding/src/components/landing_page/__snapshots__/guide_card_footer.test.tsx.snap
@@ -44,6 +44,19 @@ exports[`guide card footer snapshots should render the footer when the guide is
diff --git a/packages/kbn-guided-onboarding/src/components/landing_page/use_case_card.tsx b/packages/kbn-guided-onboarding/src/components/landing_page/use_case_card.tsx
index ef9373996297c..574b9b18bf2b3 100644
--- a/packages/kbn-guided-onboarding/src/components/landing_page/use_case_card.tsx
+++ b/packages/kbn-guided-onboarding/src/components/landing_page/use_case_card.tsx
@@ -9,7 +9,6 @@
import React, { ReactNode } from 'react';
import { EuiCard, EuiText, EuiImage } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { GuideId } from '../../types';
type UseCaseConstants = {
[key in UseCase]: {
@@ -53,7 +52,7 @@ const constants: UseCaseConstants = {
export type UseCase = 'search' | 'observability' | 'security';
export interface UseCaseCardProps {
- useCase: GuideId;
+ useCase: UseCase;
title: string;
description: string;
footer: ReactNode;
@@ -84,18 +83,13 @@ export const UseCaseCard = ({
);
- const descriptionElement = (
-
- {description}
-
- );
+
return (
}
title={titleElement}
- description={descriptionElement}
+ description={description}
footer={footer}
betaBadgeProps={{
label: constants[useCase].betaBadgeLabel,
diff --git a/packages/kbn-guided-onboarding/src/types.ts b/packages/kbn-guided-onboarding/src/types.ts
index 9a307464cefb8..6b919835da2e7 100644
--- a/packages/kbn-guided-onboarding/src/types.ts
+++ b/packages/kbn-guided-onboarding/src/types.ts
@@ -6,13 +6,14 @@
* Side Public License, v 1.
*/
-export type GuideId = 'observability' | 'security' | 'search';
+export type GuideId = 'observability' | 'security' | 'search' | 'testGuide';
-export type ObservabilityStepIds = 'add_data' | 'view_dashboard' | 'tour_observability';
-export type SecurityStepIds = 'add_data' | 'rules' | 'alertsCases';
-export type SearchStepIds = 'add_data' | 'browse_docs' | 'search_experience';
+type ObservabilityStepIds = 'add_data' | 'view_dashboard' | 'tour_observability';
+type SecurityStepIds = 'add_data' | 'rules' | 'alertsCases';
+type SearchStepIds = 'add_data' | 'browse_docs' | 'search_experience';
+type TestGuideIds = 'step1' | 'step2' | 'step3';
-export type GuideStepIds = ObservabilityStepIds | SecurityStepIds | SearchStepIds;
+export type GuideStepIds = ObservabilityStepIds | SecurityStepIds | SearchStepIds | TestGuideIds;
export interface GuideState {
guideId: GuideId;
diff --git a/packages/kbn-handlebars/BUILD.bazel b/packages/kbn-handlebars/BUILD.bazel
index 4e3d283a0be8e..984366123bafb 100644
--- a/packages/kbn-handlebars/BUILD.bazel
+++ b/packages/kbn-handlebars/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_BASE_NAME = "kbn-handlebars"
+PKG_DIRNAME = "kbn-handlebars"
PKG_REQUIRE_NAME = "@kbn/handlebars"
TYPES_PKG_REQUIRE_NAME = "@types/kbn__handlebars"
@@ -84,7 +84,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -93,9 +93,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-i18n-react/BUILD.bazel b/packages/kbn-i18n-react/BUILD.bazel
index efba43ef1cf34..cfcf823bec4a8 100644
--- a/packages/kbn-i18n-react/BUILD.bazel
+++ b/packages/kbn-i18n-react/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_BASE_NAME = "kbn-i18n-react"
+PKG_DIRNAME = "kbn-i18n-react"
PKG_REQUIRE_NAME = "@kbn/i18n-react"
SOURCE_FILES = glob(
@@ -89,7 +89,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -98,9 +98,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-i18n/BUILD.bazel b/packages/kbn-i18n/BUILD.bazel
index 90079be18cab2..d58fdfc60df1e 100644
--- a/packages/kbn-i18n/BUILD.bazel
+++ b/packages/kbn-i18n/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_BASE_NAME = "kbn-i18n"
+PKG_DIRNAME = "kbn-i18n"
PKG_REQUIRE_NAME = "@kbn/i18n"
SOURCE_FILES = glob(
@@ -89,7 +89,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -98,9 +98,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-interpreter/BUILD.bazel b/packages/kbn-interpreter/BUILD.bazel
index d711715d519c8..e2cd2103ddde9 100644
--- a/packages/kbn-interpreter/BUILD.bazel
+++ b/packages/kbn-interpreter/BUILD.bazel
@@ -3,7 +3,7 @@ load("@npm//peggy:index.bzl", "peggy")
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_BASE_NAME = "kbn-interpreter"
+PKG_DIRNAME = "kbn-interpreter"
PKG_REQUIRE_NAME = "@kbn/interpreter"
SOURCE_FILES = glob(
@@ -101,7 +101,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [":grammar"],
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -110,9 +110,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-io-ts-utils/BUILD.bazel b/packages/kbn-io-ts-utils/BUILD.bazel
index 48641035223e5..322c44f18a5b8 100644
--- a/packages/kbn-io-ts-utils/BUILD.bazel
+++ b/packages/kbn-io-ts-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_BASE_NAME = "kbn-io-ts-utils"
+PKG_DIRNAME = "kbn-io-ts-utils"
PKG_REQUIRE_NAME = "@kbn/io-ts-utils"
SOURCE_FILES = glob(
@@ -88,7 +88,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -97,9 +97,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-language-documentation-popover/BUILD.bazel b/packages/kbn-language-documentation-popover/BUILD.bazel
index d596368bd91ee..2e2eaa3760abb 100644
--- a/packages/kbn-language-documentation-popover/BUILD.bazel
+++ b/packages/kbn-language-documentation-popover/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_BASE_NAME = "kbn-language-documentation-popover"
+PKG_DIRNAME = "kbn-language-documentation-popover"
PKG_REQUIRE_NAME = "@kbn/language-documentation-popover"
SOURCE_FILES = glob(
@@ -101,7 +101,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_webpack"],
package_name = PKG_REQUIRE_NAME,
@@ -110,9 +110,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-logging-mocks/BUILD.bazel b/packages/kbn-logging-mocks/BUILD.bazel
index 1af99a6a62954..78d175af69dec 100644
--- a/packages/kbn-logging-mocks/BUILD.bazel
+++ b/packages/kbn-logging-mocks/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_BASE_NAME = "kbn-logging-mocks"
+PKG_DIRNAME = "kbn-logging-mocks"
PKG_REQUIRE_NAME = "@kbn/logging-mocks"
SOURCE_FILES = glob(
@@ -72,7 +72,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -81,9 +81,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-logging/BUILD.bazel b/packages/kbn-logging/BUILD.bazel
index 4d7668cc09650..cf64d4247f328 100644
--- a/packages/kbn-logging/BUILD.bazel
+++ b/packages/kbn-logging/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_BASE_NAME = "kbn-logging"
+PKG_DIRNAME = "kbn-logging"
PKG_REQUIRE_NAME = "@kbn/logging"
SOURCE_FILES = glob(
@@ -74,7 +74,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -83,9 +83,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-mapbox-gl/BUILD.bazel b/packages/kbn-mapbox-gl/BUILD.bazel
index a55f5f77897d7..e81aa132d1111 100644
--- a/packages/kbn-mapbox-gl/BUILD.bazel
+++ b/packages/kbn-mapbox-gl/BUILD.bazel
@@ -3,7 +3,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_BASE_NAME = "kbn-mapbox-gl"
+PKG_DIRNAME = "kbn-mapbox-gl"
PKG_REQUIRE_NAME = "@kbn/mapbox-gl"
SOURCE_FILES = glob(
@@ -84,7 +84,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -93,9 +93,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-monaco/BUILD.bazel b/packages/kbn-monaco/BUILD.bazel
index 2ed705e1c81c3..dbf1b3f0af065 100644
--- a/packages/kbn-monaco/BUILD.bazel
+++ b/packages/kbn-monaco/BUILD.bazel
@@ -3,7 +3,7 @@ load("@npm//webpack-cli:index.bzl", webpack = "webpack_cli")
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_BASE_NAME = "kbn-monaco"
+PKG_DIRNAME = "kbn-monaco"
PKG_REQUIRE_NAME = "@kbn/monaco"
SOURCE_FILES = glob(
@@ -113,7 +113,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web", ":target_workers"],
package_name = PKG_REQUIRE_NAME,
@@ -122,9 +122,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-optimizer/BUILD.bazel b/packages/kbn-optimizer/BUILD.bazel
index 0701fa141dd9a..530058c9f5d7e 100644
--- a/packages/kbn-optimizer/BUILD.bazel
+++ b/packages/kbn-optimizer/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_BASE_NAME = "kbn-optimizer"
+PKG_DIRNAME = "kbn-optimizer"
PKG_REQUIRE_NAME = "@kbn/optimizer"
SOURCE_FILES = glob(
@@ -133,7 +133,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -142,9 +142,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-plugin-generator/BUILD.bazel b/packages/kbn-plugin-generator/BUILD.bazel
index 587cd546d50fb..d3ad237231c25 100644
--- a/packages/kbn-plugin-generator/BUILD.bazel
+++ b/packages/kbn-plugin-generator/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_BASE_NAME = "kbn-plugin-generator"
+PKG_DIRNAME = "kbn-plugin-generator"
PKG_REQUIRE_NAME = "@kbn/plugin-generator"
SOURCE_FILES = glob(
@@ -102,7 +102,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -111,9 +111,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-plugin-helpers/BUILD.bazel b/packages/kbn-plugin-helpers/BUILD.bazel
index 32f8f0a3720db..c1793269c2fee 100644
--- a/packages/kbn-plugin-helpers/BUILD.bazel
+++ b/packages/kbn-plugin-helpers/BUILD.bazel
@@ -3,7 +3,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_BASE_NAME = "kbn-plugin-helpers"
+PKG_DIRNAME = "kbn-plugin-helpers"
PKG_REQUIRE_NAME = "@kbn/plugin-helpers"
SOURCE_FILES = glob(
@@ -95,7 +95,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -104,9 +104,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-react-field/BUILD.bazel b/packages/kbn-react-field/BUILD.bazel
index 7b4e78f9868f4..0a851c9a156cf 100644
--- a/packages/kbn-react-field/BUILD.bazel
+++ b/packages/kbn-react-field/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_BASE_NAME = "kbn-react-field"
+PKG_DIRNAME = "kbn-react-field"
PKG_REQUIRE_NAME = "@kbn/react-field"
SOURCE_FILES = glob(
@@ -99,7 +99,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_webpack"],
package_name = PKG_REQUIRE_NAME,
@@ -108,9 +108,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-rule-data-utils/BUILD.bazel b/packages/kbn-rule-data-utils/BUILD.bazel
index 61146f0b5de31..788ef54533536 100644
--- a/packages/kbn-rule-data-utils/BUILD.bazel
+++ b/packages/kbn-rule-data-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_BASE_NAME = "kbn-rule-data-utils"
+PKG_DIRNAME = "kbn-rule-data-utils"
PKG_REQUIRE_NAME = "@kbn/rule-data-utils"
SOURCE_FILES = glob(
@@ -86,7 +86,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -95,9 +95,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-safer-lodash-set/BUILD.bazel b/packages/kbn-safer-lodash-set/BUILD.bazel
index 893719c822859..3a5d07ab38904 100644
--- a/packages/kbn-safer-lodash-set/BUILD.bazel
+++ b/packages/kbn-safer-lodash-set/BUILD.bazel
@@ -1,6 +1,6 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm")
-PKG_BASE_NAME = "kbn-safer-lodash-set"
+PKG_DIRNAME = "kbn-safer-lodash-set"
PKG_REQUIRE_NAME = "@kbn/safer-lodash-set"
SOURCE_FILES = glob(
@@ -40,7 +40,7 @@ DEPS = [
]
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":srcs",
],
@@ -51,9 +51,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
@@ -66,7 +64,7 @@ filegroup(
alias(
name = "npm_module_types",
- actual = PKG_BASE_NAME,
+ actual = PKG_DIRNAME,
visibility = ["//visibility:public"],
)
diff --git a/packages/kbn-securitysolution-autocomplete/BUILD.bazel b/packages/kbn-securitysolution-autocomplete/BUILD.bazel
index d09b4cf04c70a..ae396cfb7a18d 100644
--- a/packages/kbn-securitysolution-autocomplete/BUILD.bazel
+++ b/packages/kbn-securitysolution-autocomplete/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_BASE_NAME = "kbn-securitysolution-autocomplete"
+PKG_DIRNAME = "kbn-securitysolution-autocomplete"
PKG_REQUIRE_NAME = "@kbn/securitysolution-autocomplete"
SOURCE_FILES = glob(
@@ -109,7 +109,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -118,9 +118,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-es-utils/BUILD.bazel b/packages/kbn-securitysolution-es-utils/BUILD.bazel
index 6eb3a84e83fce..59dbdb1fa63a6 100644
--- a/packages/kbn-securitysolution-es-utils/BUILD.bazel
+++ b/packages/kbn-securitysolution-es-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_BASE_NAME = "kbn-securitysolution-es-utils"
+PKG_DIRNAME = "kbn-securitysolution-es-utils"
PKG_REQUIRE_NAME = "@kbn/securitysolution-es-utils"
SOURCE_FILES = glob(
@@ -80,7 +80,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -89,9 +89,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ],
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-hook-utils/BUILD.bazel b/packages/kbn-securitysolution-hook-utils/BUILD.bazel
index 6959bfcc69534..ab33e32a0ad4c 100644
--- a/packages/kbn-securitysolution-hook-utils/BUILD.bazel
+++ b/packages/kbn-securitysolution-hook-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_BASE_NAME = "kbn-securitysolution-hook-utils"
+PKG_DIRNAME = "kbn-securitysolution-hook-utils"
PKG_REQUIRE_NAME = "@kbn/securitysolution-hook-utils"
SOURCE_FILES = glob(
@@ -87,7 +87,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -96,9 +96,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ],
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel
index 7ddd3ab480bfc..713f56917c19f 100644
--- a/packages/kbn-securitysolution-io-ts-alerting-types/BUILD.bazel
+++ b/packages/kbn-securitysolution-io-ts-alerting-types/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_BASE_NAME = "kbn-securitysolution-io-ts-alerting-types"
+PKG_DIRNAME = "kbn-securitysolution-io-ts-alerting-types"
PKG_REQUIRE_NAME = "@kbn/securitysolution-io-ts-alerting-types"
SOURCE_FILES = glob(
@@ -90,7 +90,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -99,9 +99,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel
index 7a4388b65053e..718ab4e75c9d8 100644
--- a/packages/kbn-securitysolution-io-ts-list-types/BUILD.bazel
+++ b/packages/kbn-securitysolution-io-ts-list-types/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_BASE_NAME = "kbn-securitysolution-io-ts-list-types"
+PKG_DIRNAME = "kbn-securitysolution-io-ts-list-types"
PKG_REQUIRE_NAME = "@kbn/securitysolution-io-ts-list-types"
SOURCE_FILES = glob(
@@ -91,7 +91,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -100,9 +100,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-io-ts-types/BUILD.bazel b/packages/kbn-securitysolution-io-ts-types/BUILD.bazel
index 85f5a05ed6c44..f09e4139fccca 100644
--- a/packages/kbn-securitysolution-io-ts-types/BUILD.bazel
+++ b/packages/kbn-securitysolution-io-ts-types/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_BASE_NAME = "kbn-securitysolution-io-ts-types"
+PKG_DIRNAME = "kbn-securitysolution-io-ts-types"
PKG_REQUIRE_NAME = "@kbn/securitysolution-io-ts-types"
SOURCE_FILES = glob(
@@ -88,7 +88,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -97,9 +97,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel b/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel
index 6e8d4de3ccfde..eb30bfe8cc433 100644
--- a/packages/kbn-securitysolution-io-ts-utils/BUILD.bazel
+++ b/packages/kbn-securitysolution-io-ts-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_BASE_NAME = "kbn-securitysolution-io-ts-utils"
+PKG_DIRNAME = "kbn-securitysolution-io-ts-utils"
PKG_REQUIRE_NAME = "@kbn/securitysolution-io-ts-utils"
SOURCE_FILES = glob(
@@ -91,7 +91,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -100,9 +100,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-list-api/BUILD.bazel b/packages/kbn-securitysolution-list-api/BUILD.bazel
index 9819e867e3194..39f3f797c569b 100644
--- a/packages/kbn-securitysolution-list-api/BUILD.bazel
+++ b/packages/kbn-securitysolution-list-api/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_BASE_NAME = "kbn-securitysolution-list-api"
+PKG_DIRNAME = "kbn-securitysolution-list-api"
PKG_REQUIRE_NAME = "@kbn/securitysolution-list-api"
SOURCE_FILES = glob(
@@ -90,7 +90,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -99,9 +99,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ],
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-list-constants/BUILD.bazel b/packages/kbn-securitysolution-list-constants/BUILD.bazel
index 5d4a6c2ffb117..779eef5617de1 100644
--- a/packages/kbn-securitysolution-list-constants/BUILD.bazel
+++ b/packages/kbn-securitysolution-list-constants/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_BASE_NAME = "kbn-securitysolution-list-constants"
+PKG_DIRNAME = "kbn-securitysolution-list-constants"
PKG_REQUIRE_NAME = "@kbn/securitysolution-list-constants"
SOURCE_FILES = glob(
@@ -78,7 +78,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -87,9 +87,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ],
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-list-hooks/BUILD.bazel b/packages/kbn-securitysolution-list-hooks/BUILD.bazel
index 93a3d0c683dd5..2487cf359d29e 100644
--- a/packages/kbn-securitysolution-list-hooks/BUILD.bazel
+++ b/packages/kbn-securitysolution-list-hooks/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_BASE_NAME = "kbn-securitysolution-list-hooks"
+PKG_DIRNAME = "kbn-securitysolution-list-hooks"
PKG_REQUIRE_NAME = "@kbn/securitysolution-list-hooks"
SOURCE_FILES = glob(
@@ -97,7 +97,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -106,9 +106,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ],
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-list-utils/BUILD.bazel b/packages/kbn-securitysolution-list-utils/BUILD.bazel
index d1d1a9a3e326a..5155da63bfbc5 100644
--- a/packages/kbn-securitysolution-list-utils/BUILD.bazel
+++ b/packages/kbn-securitysolution-list-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_BASE_NAME = "kbn-securitysolution-list-utils"
+PKG_DIRNAME = "kbn-securitysolution-list-utils"
PKG_REQUIRE_NAME = "@kbn/securitysolution-list-utils"
SOURCE_FILES = glob(
@@ -97,7 +97,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -107,9 +107,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ],
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-rules/BUILD.bazel b/packages/kbn-securitysolution-rules/BUILD.bazel
index e1da8501dffa1..280c7cd0dae50 100644
--- a/packages/kbn-securitysolution-rules/BUILD.bazel
+++ b/packages/kbn-securitysolution-rules/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_BASE_NAME = "kbn-securitysolution-rules"
+PKG_DIRNAME = "kbn-securitysolution-rules"
PKG_REQUIRE_NAME = "@kbn/securitysolution-rules"
SOURCE_FILES = glob(
@@ -85,7 +85,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -94,9 +94,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ],
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-t-grid/BUILD.bazel b/packages/kbn-securitysolution-t-grid/BUILD.bazel
index 39c1aff010f88..d907afc660311 100644
--- a/packages/kbn-securitysolution-t-grid/BUILD.bazel
+++ b/packages/kbn-securitysolution-t-grid/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_BASE_NAME = "kbn-securitysolution-t-grid"
+PKG_DIRNAME = "kbn-securitysolution-t-grid"
PKG_REQUIRE_NAME = "@kbn/securitysolution-t-grid"
SOURCE_FILES = glob(
@@ -86,7 +86,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -95,9 +95,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ],
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-securitysolution-utils/BUILD.bazel b/packages/kbn-securitysolution-utils/BUILD.bazel
index a76553e2fb2c5..68e9ab6dd597b 100644
--- a/packages/kbn-securitysolution-utils/BUILD.bazel
+++ b/packages/kbn-securitysolution-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_BASE_NAME = "kbn-securitysolution-utils"
+PKG_DIRNAME = "kbn-securitysolution-utils"
PKG_REQUIRE_NAME = "@kbn/securitysolution-utils"
SOURCE_FILES = glob(
@@ -85,7 +85,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -94,9 +94,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ],
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-server-http-tools/BUILD.bazel b/packages/kbn-server-http-tools/BUILD.bazel
index 5c73a34ffe5e7..004cfb336f049 100644
--- a/packages/kbn-server-http-tools/BUILD.bazel
+++ b/packages/kbn-server-http-tools/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_BASE_NAME = "kbn-server-http-tools"
+PKG_DIRNAME = "kbn-server-http-tools"
PKG_REQUIRE_NAME = "@kbn/server-http-tools"
SOURCE_FILES = glob(
@@ -89,7 +89,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -98,9 +98,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-server-route-repository/BUILD.bazel b/packages/kbn-server-route-repository/BUILD.bazel
index cbe6172e32e40..7ecc92bbe1a26 100644
--- a/packages/kbn-server-route-repository/BUILD.bazel
+++ b/packages/kbn-server-route-repository/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_BASE_NAME = "kbn-server-route-repository"
+PKG_DIRNAME = "kbn-server-route-repository"
PKG_REQUIRE_NAME = "@kbn/server-route-repository"
SOURCE_FILES = glob(
@@ -96,7 +96,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -105,9 +105,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-spec-to-console/BUILD.bazel b/packages/kbn-spec-to-console/BUILD.bazel
index ee046c6194f7f..9d41b5762d470 100644
--- a/packages/kbn-spec-to-console/BUILD.bazel
+++ b/packages/kbn-spec-to-console/BUILD.bazel
@@ -1,7 +1,7 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "pkg_npm")
-PKG_BASE_NAME = "kbn-spec-to-console"
+PKG_DIRNAME = "kbn-spec-to-console"
PKG_REQUIRE_NAME = "@kbn/spec-to-console"
SOURCE_FILES = glob(
@@ -33,7 +33,7 @@ RUNTIME_DEPS = [
]
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":srcs",
],
@@ -44,9 +44,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-std/BUILD.bazel b/packages/kbn-std/BUILD.bazel
index fb59d13596ab7..f92779194187f 100644
--- a/packages/kbn-std/BUILD.bazel
+++ b/packages/kbn-std/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_BASE_NAME = "kbn-std"
+PKG_DIRNAME = "kbn-std"
PKG_REQUIRE_NAME = "@kbn/std"
SOURCE_FILES = glob(
@@ -83,7 +83,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -92,9 +92,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-storybook/BUILD.bazel b/packages/kbn-storybook/BUILD.bazel
index c85352b8ac914..e58a4954fd44c 100644
--- a/packages/kbn-storybook/BUILD.bazel
+++ b/packages/kbn-storybook/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_BASE_NAME = "kbn-storybook"
+PKG_DIRNAME = "kbn-storybook"
PKG_REQUIRE_NAME = "@kbn/storybook"
SOURCE_FILES = glob(
@@ -115,7 +115,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -124,9 +124,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-telemetry-tools/BUILD.bazel b/packages/kbn-telemetry-tools/BUILD.bazel
index b234f2dd6ea45..d4e2a87075782 100644
--- a/packages/kbn-telemetry-tools/BUILD.bazel
+++ b/packages/kbn-telemetry-tools/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_BASE_NAME = "kbn-telemetry-tools"
+PKG_DIRNAME = "kbn-telemetry-tools"
PKG_REQUIRE_NAME = "@kbn/telemetry-tools"
SOURCE_FILES = glob(
@@ -89,7 +89,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -98,9 +98,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-test-jest-helpers/BUILD.bazel b/packages/kbn-test-jest-helpers/BUILD.bazel
index d31f9184cf2ac..6017936b06552 100644
--- a/packages/kbn-test-jest-helpers/BUILD.bazel
+++ b/packages/kbn-test-jest-helpers/BUILD.bazel
@@ -3,7 +3,7 @@ load("@npm//@babel/cli:index.bzl", "babel")
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_BASE_NAME = "kbn-test-jest-helpers"
+PKG_DIRNAME = "kbn-test-jest-helpers"
PKG_REQUIRE_NAME = "@kbn/test-jest-helpers"
SOURCE_FILES = glob(
@@ -148,7 +148,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -157,9 +157,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-test/BUILD.bazel b/packages/kbn-test/BUILD.bazel
index 1deca3a0f6d07..32eccf2963060 100644
--- a/packages/kbn-test/BUILD.bazel
+++ b/packages/kbn-test/BUILD.bazel
@@ -3,7 +3,7 @@ load("@npm//@babel/cli:index.bzl", "babel")
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_BASE_NAME = "kbn-test"
+PKG_DIRNAME = "kbn-test"
PKG_REQUIRE_NAME = "@kbn/test"
SOURCE_FILES = glob(
@@ -170,7 +170,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -179,9 +179,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-test/src/jest/integration_tests/junit_reporter.test.ts b/packages/kbn-test/src/jest/integration_tests/junit_reporter.test.ts
index 49b52a037e30c..f2bf25067a9bd 100644
--- a/packages/kbn-test/src/jest/integration_tests/junit_reporter.test.ts
+++ b/packages/kbn-test/src/jest/integration_tests/junit_reporter.test.ts
@@ -26,8 +26,7 @@ afterAll(async () => {
});
const parseXml = promisify(xml2js.parseString);
-// FLAKY https://github.com/elastic/kibana/issues/143993
-it.skip(
+it(
'produces a valid junit report for failures',
async () => {
const result = await execa(
diff --git a/packages/kbn-test/src/jest/junit_reporter.ts b/packages/kbn-test/src/jest/junit_reporter.ts
index eb5828120a57b..6a1ce9d51ded9 100644
--- a/packages/kbn-test/src/jest/junit_reporter.ts
+++ b/packages/kbn-test/src/jest/junit_reporter.ts
@@ -60,8 +60,9 @@ export default class JestJUnitReporter extends BaseReporter {
);
const msToIso = (ms: number | null | undefined) =>
- ms ? new Date(ms).toISOString().slice(0, -5) : undefined;
- const msToSec = (ms: number | null | undefined) => (ms ? (ms / 1000).toFixed(3) : undefined);
+ typeof ms === 'number' ? new Date(ms).toISOString().slice(0, -5) : undefined;
+ const msToSec = (ms: number | null | undefined) =>
+ typeof ms === 'number' ? (ms / 1000).toFixed(3) : undefined;
root.att({
name: 'jest',
diff --git a/packages/kbn-timelion-grammar/BUILD.bazel b/packages/kbn-timelion-grammar/BUILD.bazel
index c906223c2253b..3c7ea13cadf64 100644
--- a/packages/kbn-timelion-grammar/BUILD.bazel
+++ b/packages/kbn-timelion-grammar/BUILD.bazel
@@ -2,7 +2,7 @@ load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("@npm//peggy:index.bzl", "peggy")
load("//src/dev/bazel:index.bzl", "pkg_npm")
-PKG_BASE_NAME = "kbn-timelion-grammar"
+PKG_DIRNAME = "kbn-timelion-grammar"
PKG_REQUIRE_NAME = "@kbn/timelion-grammar"
NPM_MODULE_EXTRA_FILES = [
@@ -23,7 +23,7 @@ peggy(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":grammar"
],
@@ -33,9 +33,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-tinymath/BUILD.bazel b/packages/kbn-tinymath/BUILD.bazel
index ffbd74da2d02e..b8ee25a4973b8 100644
--- a/packages/kbn-tinymath/BUILD.bazel
+++ b/packages/kbn-tinymath/BUILD.bazel
@@ -2,7 +2,7 @@ load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("@npm//peggy:index.bzl", "peggy")
load("//src/dev/bazel:index.bzl", "pkg_npm")
-PKG_BASE_NAME = "kbn-tinymath"
+PKG_DIRNAME = "kbn-tinymath"
PKG_REQUIRE_NAME = "@kbn/tinymath"
SOURCE_FILES = glob(
@@ -45,7 +45,7 @@ peggy(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":srcs",
":grammar"
@@ -57,9 +57,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-typed-react-router-config/BUILD.bazel b/packages/kbn-typed-react-router-config/BUILD.bazel
index c14f2b66b9870..e6f1587e537ed 100644
--- a/packages/kbn-typed-react-router-config/BUILD.bazel
+++ b/packages/kbn-typed-react-router-config/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_BASE_NAME = "kbn-typed-react-router-config"
+PKG_DIRNAME = "kbn-typed-react-router-config"
PKG_REQUIRE_NAME = "@kbn/typed-react-router-config"
SOURCE_FILES = glob(
@@ -100,7 +100,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -109,9 +109,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-ui-framework/BUILD.bazel b/packages/kbn-ui-framework/BUILD.bazel
index f38e10eafeec7..2e801955a8524 100644
--- a/packages/kbn-ui-framework/BUILD.bazel
+++ b/packages/kbn-ui-framework/BUILD.bazel
@@ -1,7 +1,7 @@
load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("//src/dev/bazel:index.bzl", "pkg_npm")
-PKG_BASE_NAME = "kbn-ui-framework"
+PKG_DIRNAME = "kbn-ui-framework"
PKG_REQUIRE_NAME = "@kbn/ui-framework"
SOURCE_FILES = glob([
@@ -23,7 +23,7 @@ NPM_MODULE_EXTRA_FILES = [
RUNTIME_DEPS = []
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES + [
":srcs",
],
@@ -34,9 +34,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-ui-shared-deps-npm/BUILD.bazel b/packages/kbn-ui-shared-deps-npm/BUILD.bazel
index c20613e128e49..7f589c7c0a842 100644
--- a/packages/kbn-ui-shared-deps-npm/BUILD.bazel
+++ b/packages/kbn-ui-shared-deps-npm/BUILD.bazel
@@ -3,7 +3,7 @@ load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("@npm//webpack-cli:index.bzl", webpack = "webpack_cli")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
-PKG_BASE_NAME = "kbn-ui-shared-deps-npm"
+PKG_DIRNAME = "kbn-ui-shared-deps-npm"
PKG_REQUIRE_NAME = "@kbn/ui-shared-deps-npm"
SOURCE_FILES = glob(
@@ -154,7 +154,7 @@ webpack(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":shared_built_assets"],
package_name = PKG_REQUIRE_NAME,
@@ -163,9 +163,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-ui-shared-deps-src/BUILD.bazel b/packages/kbn-ui-shared-deps-src/BUILD.bazel
index 4979792e00ee5..0507f18756929 100644
--- a/packages/kbn-ui-shared-deps-src/BUILD.bazel
+++ b/packages/kbn-ui-shared-deps-src/BUILD.bazel
@@ -3,7 +3,7 @@ load("@build_bazel_rules_nodejs//:index.bzl", "js_library")
load("@npm//webpack-cli:index.bzl", webpack = "webpack_cli")
load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project")
-PKG_BASE_NAME = "kbn-ui-shared-deps-src"
+PKG_DIRNAME = "kbn-ui-shared-deps-src"
PKG_REQUIRE_NAME = "@kbn/ui-shared-deps-src"
SOURCE_FILES = glob(
@@ -111,7 +111,7 @@ webpack(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":shared_built_assets"],
package_name = PKG_REQUIRE_NAME,
@@ -120,9 +120,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-ui-theme/BUILD.bazel b/packages/kbn-ui-theme/BUILD.bazel
index a004975293a0b..0a890d07fba0f 100644
--- a/packages/kbn-ui-theme/BUILD.bazel
+++ b/packages/kbn-ui-theme/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_BASE_NAME = "kbn-ui-theme"
+PKG_DIRNAME = "kbn-ui-theme"
PKG_REQUIRE_NAME = "@kbn/ui-theme"
SOURCE_FILES = glob(
@@ -80,7 +80,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -89,9 +89,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-user-profile-components/BUILD.bazel b/packages/kbn-user-profile-components/BUILD.bazel
index fff27d0f68c34..1037d47a79ad4 100644
--- a/packages/kbn-user-profile-components/BUILD.bazel
+++ b/packages/kbn-user-profile-components/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_BASE_NAME = "kbn-user-profile-components"
+PKG_DIRNAME = "kbn-user-profile-components"
PKG_REQUIRE_NAME = "@kbn/user-profile-components"
SOURCE_FILES = glob(
@@ -87,7 +87,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":target_web"],
package_name = PKG_REQUIRE_NAME,
@@ -96,9 +96,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-utility-types-jest/BUILD.bazel b/packages/kbn-utility-types-jest/BUILD.bazel
index 3b8985767b244..589d17734e55a 100644
--- a/packages/kbn-utility-types-jest/BUILD.bazel
+++ b/packages/kbn-utility-types-jest/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_BASE_NAME = "kbn-utility-types-jest"
+PKG_DIRNAME = "kbn-utility-types-jest"
PKG_REQUIRE_NAME = "@kbn/utility-types-jest"
SOURCE_FILES = glob(
@@ -70,7 +70,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -79,9 +79,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-utility-types/BUILD.bazel b/packages/kbn-utility-types/BUILD.bazel
index ad463d9342580..20c640a4b2250 100644
--- a/packages/kbn-utility-types/BUILD.bazel
+++ b/packages/kbn-utility-types/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_BASE_NAME = "kbn-utility-types"
+PKG_DIRNAME = "kbn-utility-types"
PKG_REQUIRE_NAME = "@kbn/utility-types"
SOURCE_FILES = glob(
@@ -74,7 +74,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node"],
package_name = PKG_REQUIRE_NAME,
@@ -83,9 +83,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/packages/kbn-utils/BUILD.bazel b/packages/kbn-utils/BUILD.bazel
index b488b66303910..857ff523a3269 100644
--- a/packages/kbn-utils/BUILD.bazel
+++ b/packages/kbn-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_BASE_NAME = "kbn-utils"
+PKG_DIRNAME = "kbn-utils"
PKG_REQUIRE_NAME = "@kbn/utils"
SOURCE_FILES = glob(
@@ -78,7 +78,7 @@ ts_project(
)
js_library(
- name = PKG_BASE_NAME,
+ name = PKG_DIRNAME,
srcs = NPM_MODULE_EXTRA_FILES,
deps = RUNTIME_DEPS + [":target_node", ":tsc_types"],
package_name = PKG_REQUIRE_NAME,
@@ -87,9 +87,7 @@ js_library(
pkg_npm(
name = "npm_module",
- deps = [
- ":%s" % PKG_BASE_NAME,
- ]
+ deps = [":" + PKG_DIRNAME],
)
filegroup(
diff --git a/src/core/server/core_app/core_app.test.ts b/src/core/server/core_app/core_app.test.ts
index 1ea3eeef29a09..31e4b6176a889 100644
--- a/src/core/server/core_app/core_app.test.ts
+++ b/src/core/server/core_app/core_app.test.ts
@@ -13,7 +13,7 @@ import { mockRouter } from '@kbn/core-http-router-server-mocks';
import type { UiPlugins } from '@kbn/core-plugins-base-server-internal';
import { coreMock, httpServerMock } from '../mocks';
import { httpResourcesMock } from '@kbn/core-http-resources-server-mocks';
-import { PluginType } from '../plugins';
+import { PluginType } from '@kbn/core-base-common';
import { CoreApp } from './core_app';
import { RequestHandlerContext } from '..';
diff --git a/src/core/server/core_app/core_app.ts b/src/core/server/core_app/core_app.ts
index f0940f6abad50..83665512767e7 100644
--- a/src/core/server/core_app/core_app.ts
+++ b/src/core/server/core_app/core_app.ts
@@ -22,7 +22,7 @@ import type {
} from '@kbn/core-http-server';
import type { UiPlugins } from '@kbn/core-plugins-base-server-internal';
import type { HttpResources, HttpResourcesServiceToolkit } from '@kbn/core-http-resources-server';
-import { InternalCorePreboot, InternalCoreSetup } from '../internal_types';
+import { InternalCorePreboot, InternalCoreSetup } from '@kbn/core-lifecycle-server-internal';
import { registerBundleRoutes } from './bundle_routes';
import type { InternalCoreAppRequestHandlerContext } from './internal_types';
diff --git a/src/core/server/index.ts b/src/core/server/index.ts
index 6232a17eb6111..df770c8529ab8 100644
--- a/src/core/server/index.ts
+++ b/src/core/server/index.ts
@@ -29,14 +29,8 @@
*/
import { Type } from '@kbn/config-schema';
-import type { DocLinksServiceStart, DocLinksServiceSetup } from '@kbn/core-doc-links-server';
-import type { AppenderConfigType, LoggingServiceSetup } from '@kbn/core-logging-server';
+import type { AppenderConfigType } from '@kbn/core-logging-server';
import { appendersSchema } from '@kbn/core-logging-server-internal';
-import type {
- AnalyticsServiceSetup,
- AnalyticsServiceStart,
- AnalyticsServicePreboot,
-} from '@kbn/core-analytics-server';
import type {
ExecutionContextSetup,
ExecutionContextStart,
@@ -46,31 +40,13 @@ import type {
RequestHandler,
KibanaResponseFactory,
RouteMethod,
- HttpServicePreboot,
HttpServiceSetup,
- HttpServiceStart,
} from '@kbn/core-http-server';
-import type { PrebootServicePreboot } from '@kbn/core-preboot-server';
-import type { MetricsServiceSetup, MetricsServiceStart } from '@kbn/core-metrics-server';
-import {
- ElasticsearchServiceSetup,
- ElasticsearchServiceStart,
- ElasticsearchServicePreboot,
-} from '@kbn/core-elasticsearch-server';
import { configSchema as elasticsearchConfigSchema } from '@kbn/core-elasticsearch-server-internal';
import type { CapabilitiesSetup, CapabilitiesStart } from '@kbn/core-capabilities-server';
-import type {
- SavedObjectsServiceSetup,
- SavedObjectsServiceStart,
-} from '@kbn/core-saved-objects-server';
-import type { DeprecationsServiceSetup } from '@kbn/core-deprecations-server';
-import type { CoreUsageDataStart, CoreUsageDataSetup } from '@kbn/core-usage-data-server';
-import type { I18nServiceSetup } from '@kbn/core-i18n-server';
-import type { StatusServiceSetup } from '@kbn/core-status-server';
-import type { UiSettingsServiceSetup, UiSettingsServiceStart } from '@kbn/core-ui-settings-server';
import type { RequestHandlerContext } from '@kbn/core-http-request-handler-context-server';
import type { HttpResources } from '@kbn/core-http-resources-server';
-import { PluginsServiceSetup, PluginsServiceStart } from './plugins';
+import type { PluginsServiceSetup, PluginsServiceStart } from '@kbn/core-plugins-server-internal';
export type { PluginOpaqueId } from '@kbn/core-base-common';
export type {
@@ -254,7 +230,6 @@ export type { NodeInfo, NodeRoles } from '@kbn/core-node-server';
export { PluginType } from '@kbn/core-base-common';
export type {
- DiscoveredPlugin,
PrebootPlugin,
Plugin,
AsyncPlugin,
@@ -263,11 +238,12 @@ export type {
PluginInitializer,
PluginInitializerContext,
PluginManifest,
- PluginName,
SharedGlobalConfig,
MakeUsageFromSchema,
ExposedToBrowserDescriptor,
-} from './plugins';
+} from '@kbn/core-plugins-server';
+
+export type { PluginName, DiscoveredPlugin } from '@kbn/core-base-common';
export type {
SavedObject,
@@ -467,106 +443,12 @@ export type {
PrebootCoreRequestHandlerContext,
} from '@kbn/core-http-request-handler-context-server';
-/**
- * Context passed to the `setup` method of `preboot` plugins.
- * @public
- */
-export interface CorePreboot {
- /** {@link AnalyticsServicePreboot} */
- analytics: AnalyticsServicePreboot;
- /** {@link ElasticsearchServicePreboot} */
- elasticsearch: ElasticsearchServicePreboot;
- /** {@link HttpServicePreboot} */
- http: HttpServicePreboot
;
- /** {@link PrebootServicePreboot} */
- preboot: PrebootServicePreboot;
-}
-
-/**
- * Context passed to the `setup` method of `standard` plugins.
- *
- * @typeParam TPluginsStart - the type of the consuming plugin's start dependencies. Should be the same
- * as the consuming {@link Plugin}'s `TPluginsStart` type. Used by `getStartServices`.
- * @typeParam TStart - the type of the consuming plugin's start contract. Should be the same as the
- * consuming {@link Plugin}'s `TStart` type. Used by `getStartServices`.
- * @public
- */
-export interface CoreSetup {
- /** {@link AnalyticsServiceSetup} */
- analytics: AnalyticsServiceSetup;
- /** {@link CapabilitiesSetup} */
- capabilities: CapabilitiesSetup;
- /** {@link DocLinksServiceSetup} */
- docLinks: DocLinksServiceSetup;
- /** {@link ElasticsearchServiceSetup} */
- elasticsearch: ElasticsearchServiceSetup;
- /** {@link ExecutionContextSetup} */
- executionContext: ExecutionContextSetup;
- /** {@link HttpServiceSetup} */
- http: HttpServiceSetup & {
- /** {@link HttpResources} */
- resources: HttpResources;
- };
- /** {@link I18nServiceSetup} */
- i18n: I18nServiceSetup;
- /** {@link LoggingServiceSetup} */
- logging: LoggingServiceSetup;
- /** {@link MetricsServiceSetup} */
- metrics: MetricsServiceSetup;
- /** {@link SavedObjectsServiceSetup} */
- savedObjects: SavedObjectsServiceSetup;
- /** {@link StatusServiceSetup} */
- status: StatusServiceSetup;
- /** {@link UiSettingsServiceSetup} */
- uiSettings: UiSettingsServiceSetup;
- /** {@link DeprecationsServiceSetup} */
- deprecations: DeprecationsServiceSetup;
- /** {@link StartServicesAccessor} */
- getStartServices: StartServicesAccessor;
- /** @internal {@link CoreUsageDataSetup} */
- coreUsageData: CoreUsageDataSetup;
-}
-
-/**
- * Allows plugins to get access to APIs available in start inside async handlers.
- * Promise will not resolve until Core and plugin dependencies have completed `start`.
- * This should only be used inside handlers registered during `setup` that will only be executed
- * after `start` lifecycle.
- *
- * @public
- */
-export type StartServicesAccessor<
- TPluginsStart extends object = object,
- TStart = unknown
-> = () => Promise<[CoreStart, TPluginsStart, TStart]>;
-
-/**
- * Context passed to the plugins `start` method.
- *
- * @public
- */
-export interface CoreStart {
- /** {@link AnalyticsServiceStart} */
- analytics: AnalyticsServiceStart;
- /** {@link CapabilitiesStart} */
- capabilities: CapabilitiesStart;
- /** {@link DocLinksServiceStart} */
- docLinks: DocLinksServiceStart;
- /** {@link ElasticsearchServiceStart} */
- elasticsearch: ElasticsearchServiceStart;
- /** {@link ExecutionContextStart} */
- executionContext: ExecutionContextStart;
- /** {@link HttpServiceStart} */
- http: HttpServiceStart;
- /** {@link MetricsServiceStart} */
- metrics: MetricsServiceStart;
- /** {@link SavedObjectsServiceStart} */
- savedObjects: SavedObjectsServiceStart;
- /** {@link UiSettingsServiceStart} */
- uiSettings: UiSettingsServiceStart;
- /** @internal {@link CoreUsageDataStart} */
- coreUsageData: CoreUsageDataStart;
-}
+export type {
+ CorePreboot,
+ CoreSetup,
+ CoreStart,
+ StartServicesAccessor,
+} from '@kbn/core-lifecycle-server';
export type {
CapabilitiesSetup,
diff --git a/src/core/server/integration_tests/logging/logging.test.ts b/src/core/server/integration_tests/logging/logging.test.ts
index a56449550b3cb..09323239a0ce3 100644
--- a/src/core/server/integration_tests/logging/logging.test.ts
+++ b/src/core/server/integration_tests/logging/logging.test.ts
@@ -8,7 +8,7 @@
import type { LoggerContextConfigInput } from '@kbn/core-logging-server';
import * as kbnTestServer from '../../../test_helpers/kbn_server';
-import { InternalCoreSetup } from '../../internal_types';
+import { InternalCoreSetup } from '@kbn/core-lifecycle-server-internal';
import { Subject } from 'rxjs';
function createRoot() {
diff --git a/src/core/server/integration_tests/plugins/jest.integration.config.js b/src/core/server/integration_tests/plugins/jest.integration.config.js
deleted file mode 100644
index 55bbf66147bb8..0000000000000
--- a/src/core/server/integration_tests/plugins/jest.integration.config.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-module.exports = {
- // TODO replace the line below with
- // preset: '@kbn/test/jest_integration_node
- // to do so, we must fix all integration tests first
- // see https://github.com/elastic/kibana/pull/130255/
- preset: '@kbn/test/jest_integration',
- rootDir: '../../../../..',
- roots: ['/src/core/server/integration_tests/plugins'],
- // must override to match all test given there is no `integration_tests` subfolder
- testMatch: ['**/*.test.{js,mjs,ts,tsx}'],
-};
diff --git a/src/core/server/integration_tests/plugins/plugins_service.test.ts b/src/core/server/integration_tests/plugins/plugins_service.test.ts
deleted file mode 100644
index 2d51b63921bad..0000000000000
--- a/src/core/server/integration_tests/plugins/plugins_service.test.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-// must be before mocks imports to avoid conflicting with `REPO_ROOT` accessor.
-import { REPO_ROOT } from '@kbn/utils';
-import { mockPackage, mockDiscover } from './plugins_service.test.mocks';
-
-import { join } from 'path';
-
-import { ConfigPath, ConfigService, Env } from '@kbn/config';
-import { getEnvOptions, rawConfigServiceMock } from '@kbn/config-mocks';
-import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
-import { environmentServiceMock } from '@kbn/core-environment-server-mocks';
-import { nodeServiceMock } from '@kbn/core-node-server-mocks';
-import { PluginsService } from '../../plugins/plugins_service';
-import { BehaviorSubject, from } from 'rxjs';
-import { config } from '../../plugins/plugins_config';
-import { coreMock } from '../../mocks';
-import { AsyncPlugin, PluginType } from '../../plugins/types';
-import { PluginWrapper } from '../../plugins/plugin';
-
-describe('PluginsService', () => {
- const logger = loggingSystemMock.create();
- const environmentPreboot = environmentServiceMock.createPrebootContract();
- const nodePreboot = nodeServiceMock.createInternalPrebootContract();
- let pluginsService: PluginsService;
-
- const createPlugin = (
- id: string,
- {
- path = id,
- disabled = false,
- version = 'some-version',
- requiredPlugins = [],
- requiredBundles = [],
- optionalPlugins = [],
- kibanaVersion = '7.0.0',
- type = PluginType.standard,
- configPath = [path],
- server = true,
- ui = true,
- owner = { name: 'foo' },
- }: {
- path?: string;
- disabled?: boolean;
- version?: string;
- requiredPlugins?: string[];
- requiredBundles?: string[];
- optionalPlugins?: string[];
- kibanaVersion?: string;
- type?: PluginType;
- configPath?: ConfigPath;
- server?: boolean;
- ui?: boolean;
- owner?: { name: string };
- }
- ): PluginWrapper => {
- return new PluginWrapper({
- path,
- manifest: {
- id,
- version,
- configPath: `${configPath}${disabled ? '-disabled' : ''}`,
- kibanaVersion,
- type,
- requiredPlugins,
- requiredBundles,
- optionalPlugins,
- server,
- ui,
- owner,
- },
- opaqueId: Symbol(id),
- initializerContext: { logger } as any,
- });
- };
-
- beforeEach(async () => {
- mockPackage.raw = {
- branch: 'feature-v1',
- version: 'v1',
- build: {
- distributable: true,
- number: 100,
- sha: 'feature-v1-build-sha',
- },
- };
-
- const env = Env.createDefault(REPO_ROOT, getEnvOptions());
- const config$ = new BehaviorSubject>({
- plugins: {
- initialize: true,
- },
- });
- const rawConfigService = rawConfigServiceMock.create({ rawConfig$: config$ });
- const configService = new ConfigService(rawConfigService, env, logger);
- await configService.setSchema(config.path, config.schema);
-
- pluginsService = new PluginsService({
- coreId: Symbol('core'),
- env,
- logger,
- configService,
- });
- });
-
- it("properly resolves `getStartServices` in plugin's lifecycle", async () => {
- expect.assertions(6);
-
- const pluginPath = 'plugin-path';
-
- mockDiscover.mockReturnValue({
- error$: from([]),
- plugin$: from([
- createPlugin('plugin-id', {
- path: pluginPath,
- configPath: 'path',
- }),
- ]),
- });
-
- let startDependenciesResolved = false;
- let contextFromStart: any = null;
- let contextFromStartService: any = null;
-
- const pluginStartContract = {
- someApi: () => 'foo',
- };
-
- const pluginInitializer = () =>
- ({
- setup: async (coreSetup, deps) => {
- coreSetup.getStartServices().then(([core, plugins, pluginStart]) => {
- startDependenciesResolved = true;
- contextFromStartService = { core, plugins, pluginStart };
- });
- },
- start: async (core, plugins) => {
- contextFromStart = { core, plugins };
- await new Promise((resolve) => setTimeout(resolve, 10));
- expect(startDependenciesResolved).toBe(false);
- return pluginStartContract;
- },
- } as AsyncPlugin);
-
- jest.doMock(
- join(pluginPath, 'server'),
- () => ({
- plugin: pluginInitializer,
- }),
- {
- virtual: true,
- }
- );
-
- await pluginsService.discover({ environment: environmentPreboot, node: nodePreboot });
-
- const prebootDeps = coreMock.createInternalPreboot();
- await pluginsService.preboot(prebootDeps);
-
- const setupDeps = coreMock.createInternalSetup();
- await pluginsService.setup(setupDeps);
-
- expect(startDependenciesResolved).toBe(false);
-
- const startDeps = coreMock.createInternalStart();
- await pluginsService.start(startDeps);
-
- expect(startDependenciesResolved).toBe(true);
- expect(contextFromStart!.core).toEqual(contextFromStartService!.core);
- expect(contextFromStart!.plugins).toEqual(contextFromStartService!.plugins);
- expect(contextFromStartService!.pluginStart).toEqual(pluginStartContract);
- });
-});
diff --git a/src/core/server/integration_tests/saved_objects/migrations/7.7.2_xpack_100k.test.ts b/src/core/server/integration_tests/saved_objects/migrations/7.7.2_xpack_100k.test.ts
index 530a4b92ead6a..225faf5e2c275 100644
--- a/src/core/server/integration_tests/saved_objects/migrations/7.7.2_xpack_100k.test.ts
+++ b/src/core/server/integration_tests/saved_objects/migrations/7.7.2_xpack_100k.test.ts
@@ -13,7 +13,7 @@ import { Env } from '@kbn/config';
import { getEnvOptions } from '@kbn/config-mocks';
import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import * as kbnTestServer from '../../../../test_helpers/kbn_server';
-import { InternalCoreStart } from '../../../internal_types';
+import type { InternalCoreStart } from '@kbn/core-lifecycle-server-internal';
import { Root } from '../../../root';
const kibanaVersion = Env.createDefault(REPO_ROOT, getEnvOptions()).packageInfo.version;
diff --git a/src/core/server/integration_tests/saved_objects/migrations/actions/es_errors.test.ts b/src/core/server/integration_tests/saved_objects/migrations/actions/es_errors.test.ts
index 749be45b35cb7..164fdb19819db 100644
--- a/src/core/server/integration_tests/saved_objects/migrations/actions/es_errors.test.ts
+++ b/src/core/server/integration_tests/saved_objects/migrations/actions/es_errors.test.ts
@@ -7,7 +7,7 @@
*/
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { ElasticsearchClient } from '../../../..';
-import { InternalCoreStart } from '../../../../internal_types';
+import { InternalCoreStart } from '@kbn/core-lifecycle-server-internal';
import * as kbnTestServer from '../../../../../test_helpers/kbn_server';
import { Root } from '../../../../root';
import {
diff --git a/src/core/server/integration_tests/saved_objects/migrations/migration_from_older_v1.test.ts b/src/core/server/integration_tests/saved_objects/migrations/migration_from_older_v1.test.ts
index b18d20deaa0e6..3663297058b0c 100644
--- a/src/core/server/integration_tests/saved_objects/migrations/migration_from_older_v1.test.ts
+++ b/src/core/server/integration_tests/saved_objects/migrations/migration_from_older_v1.test.ts
@@ -16,7 +16,7 @@ import { getEnvOptions } from '@kbn/config-mocks';
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import type { SavedObjectsRawDoc } from '@kbn/core-saved-objects-server';
import * as kbnTestServer from '../../../../test_helpers/kbn_server';
-import { InternalCoreStart } from '../../../internal_types';
+import { InternalCoreStart } from '@kbn/core-lifecycle-server-internal';
import { Root } from '../../../root';
const kibanaVersion = Env.createDefault(REPO_ROOT, getEnvOptions()).packageInfo.version;
diff --git a/src/core/server/integration_tests/saved_objects/migrations/migration_from_same_v1.test.ts b/src/core/server/integration_tests/saved_objects/migrations/migration_from_same_v1.test.ts
index f7c0cced08f0f..97369305591a6 100644
--- a/src/core/server/integration_tests/saved_objects/migrations/migration_from_same_v1.test.ts
+++ b/src/core/server/integration_tests/saved_objects/migrations/migration_from_same_v1.test.ts
@@ -16,7 +16,7 @@ import { getEnvOptions } from '@kbn/config-mocks';
import type { SavedObjectsRawDoc } from '@kbn/core-saved-objects-server';
import * as kbnTestServer from '../../../../test_helpers/kbn_server';
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { InternalCoreStart } from '../../../internal_types';
+import { InternalCoreStart } from '@kbn/core-lifecycle-server-internal';
import { Root } from '../../../root';
const kibanaVersion = Env.createDefault(REPO_ROOT, getEnvOptions()).packageInfo.version;
diff --git a/src/core/server/integration_tests/saved_objects/service/lib/repository.test.ts b/src/core/server/integration_tests/saved_objects/service/lib/repository.test.ts
index a8d77abd65baf..d8107b5162f2e 100644
--- a/src/core/server/integration_tests/saved_objects/service/lib/repository.test.ts
+++ b/src/core/server/integration_tests/saved_objects/service/lib/repository.test.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { InternalCoreStart } from '../../../../internal_types';
+import { InternalCoreStart } from '@kbn/core-lifecycle-server-internal';
import * as kbnTestServer from '../../../../../test_helpers/kbn_server';
import { Root } from '../../../../root';
diff --git a/src/core/server/integration_tests/saved_objects/service/lib/repository_with_proxy.test.ts b/src/core/server/integration_tests/saved_objects/service/lib/repository_with_proxy.test.ts
index f0fdc609d8915..6325d80e9588f 100644
--- a/src/core/server/integration_tests/saved_objects/service/lib/repository_with_proxy.test.ts
+++ b/src/core/server/integration_tests/saved_objects/service/lib/repository_with_proxy.test.ts
@@ -11,7 +11,7 @@ import h2o2 from '@hapi/h2o2';
import { URL } from 'url';
import type { SavedObject } from '@kbn/core-saved-objects-common';
import type { ISavedObjectsRepository } from '@kbn/core-saved-objects-api-server';
-import { InternalCoreSetup, InternalCoreStart } from '../../../../internal_types';
+import type { InternalCoreSetup, InternalCoreStart } from '@kbn/core-lifecycle-server-internal';
import { Root } from '../../../../root';
import * as kbnTestServer from '../../../../../test_helpers/kbn_server';
import {
diff --git a/src/core/server/integration_tests/saved_objects/validation/validator.test.ts b/src/core/server/integration_tests/saved_objects/validation/validator.test.ts
index 008bebdc5731f..1157bd6c7499b 100644
--- a/src/core/server/integration_tests/saved_objects/validation/validator.test.ts
+++ b/src/core/server/integration_tests/saved_objects/validation/validator.test.ts
@@ -15,7 +15,7 @@ import { REPO_ROOT } from '@kbn/utils';
import type { ISavedObjectsRepository } from '@kbn/core-saved-objects-api-server';
import type { SavedObjectsType } from '@kbn/core-saved-objects-server';
import { getEnvOptions } from '@kbn/config-mocks';
-import { InternalCoreSetup, InternalCoreStart } from '../../../internal_types';
+import type { InternalCoreSetup, InternalCoreStart } from '@kbn/core-lifecycle-server-internal';
import { Root } from '../../../root';
import * as kbnTestServer from '../../../../test_helpers/kbn_server';
diff --git a/src/core/server/internal_types.ts b/src/core/server/internal_types.ts
deleted file mode 100644
index c66fdf9a968d2..0000000000000
--- a/src/core/server/internal_types.ts
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0 and the Server Side Public License, v 1; you may not use this file except
- * in compliance with, at your election, the Elastic License 2.0 or the Server
- * Side Public License, v 1.
- */
-
-import type { DocLinksServiceStart, DocLinksServiceSetup } from '@kbn/core-doc-links-server';
-import {
- InternalLoggingServicePreboot,
- InternalLoggingServiceSetup,
-} from '@kbn/core-logging-server-internal';
-import type {
- AnalyticsServicePreboot,
- AnalyticsServiceSetup,
- AnalyticsServiceStart,
-} from '@kbn/core-analytics-server';
-import type { InternalEnvironmentServiceSetup } from '@kbn/core-environment-server-internal';
-import type {
- InternalExecutionContextSetup,
- InternalExecutionContextStart,
-} from '@kbn/core-execution-context-server-internal';
-import type { InternalPrebootServicePreboot } from '@kbn/core-preboot-server-internal';
-import type {
- InternalContextPreboot,
- InternalContextSetup,
-} from '@kbn/core-http-context-server-internal';
-import type {
- InternalHttpServicePreboot,
- InternalHttpServiceSetup,
- InternalHttpServiceStart,
-} from '@kbn/core-http-server-internal';
-import type {
- InternalMetricsServiceSetup,
- InternalMetricsServiceStart,
-} from '@kbn/core-metrics-server-internal';
-import {
- InternalElasticsearchServicePreboot,
- InternalElasticsearchServiceSetup,
- InternalElasticsearchServiceStart,
-} from '@kbn/core-elasticsearch-server-internal';
-import type { CapabilitiesSetup, CapabilitiesStart } from '@kbn/core-capabilities-server';
-import {
- InternalSavedObjectsServiceSetup,
- InternalSavedObjectsServiceStart,
-} from '@kbn/core-saved-objects-server-internal';
-import {
- InternalDeprecationsServiceSetup,
- InternalDeprecationsServiceStart,
-} from '@kbn/core-deprecations-server-internal';
-import type { CoreUsageDataStart } from '@kbn/core-usage-data-server';
-import type { InternalCoreUsageDataSetup } from '@kbn/core-usage-data-base-server-internal';
-import type { I18nServiceSetup } from '@kbn/core-i18n-server';
-import type { InternalStatusServiceSetup } from '@kbn/core-status-server-internal';
-import type {
- InternalUiSettingsServicePreboot,
- InternalUiSettingsServiceSetup,
- InternalUiSettingsServiceStart,
-} from '@kbn/core-ui-settings-server-internal';
-import type { InternalRenderingServiceSetup } from '@kbn/core-rendering-server-internal';
-import type {
- InternalHttpResourcesPreboot,
- InternalHttpResourcesSetup,
-} from '@kbn/core-http-resources-server-internal';
-
-/** @internal */
-export interface InternalCorePreboot {
- analytics: AnalyticsServicePreboot;
- context: InternalContextPreboot;
- http: InternalHttpServicePreboot;
- elasticsearch: InternalElasticsearchServicePreboot;
- uiSettings: InternalUiSettingsServicePreboot;
- httpResources: InternalHttpResourcesPreboot;
- logging: InternalLoggingServicePreboot;
- preboot: InternalPrebootServicePreboot;
-}
-
-/** @internal */
-export interface InternalCoreSetup {
- analytics: AnalyticsServiceSetup;
- capabilities: CapabilitiesSetup;
- context: InternalContextSetup;
- docLinks: DocLinksServiceSetup;
- http: InternalHttpServiceSetup;
- elasticsearch: InternalElasticsearchServiceSetup;
- executionContext: InternalExecutionContextSetup;
- i18n: I18nServiceSetup;
- savedObjects: InternalSavedObjectsServiceSetup;
- status: InternalStatusServiceSetup;
- uiSettings: InternalUiSettingsServiceSetup;
- environment: InternalEnvironmentServiceSetup;
- rendering: InternalRenderingServiceSetup;
- httpResources: InternalHttpResourcesSetup;
- logging: InternalLoggingServiceSetup;
- metrics: InternalMetricsServiceSetup;
- deprecations: InternalDeprecationsServiceSetup;
- coreUsageData: InternalCoreUsageDataSetup;
-}
-
-/**
- * @internal
- */
-export interface InternalCoreStart {
- analytics: AnalyticsServiceStart;
- capabilities: CapabilitiesStart;
- elasticsearch: InternalElasticsearchServiceStart;
- docLinks: DocLinksServiceStart;
- http: InternalHttpServiceStart;
- metrics: InternalMetricsServiceStart;
- savedObjects: InternalSavedObjectsServiceStart;
- uiSettings: InternalUiSettingsServiceStart;
- coreUsageData: CoreUsageDataStart;
- executionContext: InternalExecutionContextStart;
- deprecations: InternalDeprecationsServiceStart;
-}
diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts
index 356fd4deb44d6..028465ebfb8ac 100644
--- a/src/core/server/mocks.ts
+++ b/src/core/server/mocks.ts
@@ -10,38 +10,16 @@ import { of } from 'rxjs';
import { duration } from 'moment';
import { ByteSizeValue } from '@kbn/config-schema';
import { isPromise } from '@kbn/std';
-import type { MockedKeys } from '@kbn/utility-types-jest';
-import { docLinksServiceMock } from '@kbn/core-doc-links-server-mocks';
-import { loggingSystemMock, loggingServiceMock } from '@kbn/core-logging-server-mocks';
-import { analyticsServiceMock } from '@kbn/core-analytics-server-mocks';
-import { environmentServiceMock } from '@kbn/core-environment-server-mocks';
+import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
import { nodeServiceMock } from '@kbn/core-node-server-mocks';
-import { executionContextServiceMock } from '@kbn/core-execution-context-server-mocks';
-import { prebootServiceMock } from '@kbn/core-preboot-server-mocks';
-import { contextServiceMock } from '@kbn/core-http-context-server-mocks';
-import { httpServiceMock } from '@kbn/core-http-server-mocks';
import { elasticsearchServiceMock } from '@kbn/core-elasticsearch-server-mocks';
-import { metricsServiceMock } from '@kbn/core-metrics-server-mocks';
-import { capabilitiesServiceMock } from '@kbn/core-capabilities-server-mocks';
import { typeRegistryMock as savedObjectsTypeRegistryMock } from '@kbn/core-saved-objects-base-server-mocks';
import { savedObjectsServiceMock } from '@kbn/core-saved-objects-server-mocks';
import { savedObjectsClientMock } from '@kbn/core-saved-objects-api-server-mocks';
import { deprecationsServiceMock } from '@kbn/core-deprecations-server-mocks';
-import { coreUsageDataServiceMock } from '@kbn/core-usage-data-server-mocks';
-import { i18nServiceMock } from '@kbn/core-i18n-server-mocks';
-import { statusServiceMock } from '@kbn/core-status-server-mocks';
import { uiSettingsServiceMock } from '@kbn/core-ui-settings-server-mocks';
-import { renderingServiceMock } from '@kbn/core-rendering-server-mocks';
-import { httpResourcesMock } from '@kbn/core-http-resources-server-mocks';
-import type {
- PluginInitializerContext,
- CoreSetup,
- CoreStart,
- StartServicesAccessor,
- CorePreboot,
- RequestHandlerContext,
-} from '.';
-import { SharedGlobalConfig } from './plugins';
+import { coreLifecycleMock, coreInternalLifecycleMock } from '@kbn/core-lifecycle-server-mocks';
+import type { SharedGlobalConfig, PluginInitializerContext } from '@kbn/core-plugins-server';
export { configServiceMock, configDeprecationsMock } from '@kbn/config-mocks';
export { loggingSystemMock } from '@kbn/core-logging-server-mocks';
@@ -132,139 +110,6 @@ function pluginInitializerContextMock(config: T = {} as T) {
return mock;
}
-type CorePrebootMockType = MockedKeys & {
- elasticsearch: ReturnType;
-};
-
-function createCorePrebootMock() {
- const mock: CorePrebootMockType = {
- analytics: analyticsServiceMock.createAnalyticsServicePreboot(),
- elasticsearch: elasticsearchServiceMock.createPreboot(),
- http: httpServiceMock.createPrebootContract() as CorePrebootMockType['http'],
- preboot: prebootServiceMock.createPrebootContract(),
- };
-
- return mock;
-}
-
-type CoreSetupMockType = MockedKeys & {
- elasticsearch: ReturnType;
- getStartServices: jest.MockedFunction>;
-};
-
-function createCoreSetupMock({
- pluginStartDeps = {},
- pluginStartContract,
-}: {
- pluginStartDeps?: object;
- pluginStartContract?: any;
-} = {}) {
- const httpMock: jest.Mocked = {
- ...httpServiceMock.createSetupContract(),
- resources: httpResourcesMock.createRegistrar(),
- };
-
- const uiSettingsMock = {
- register: uiSettingsServiceMock.createSetupContract().register,
- };
-
- const mock: CoreSetupMockType = {
- analytics: analyticsServiceMock.createAnalyticsServiceSetup(),
- capabilities: capabilitiesServiceMock.createSetupContract(),
- docLinks: docLinksServiceMock.createSetupContract(),
- elasticsearch: elasticsearchServiceMock.createSetup(),
- http: httpMock,
- i18n: i18nServiceMock.createSetupContract(),
- savedObjects: savedObjectsServiceMock.createInternalSetupContract(),
- status: statusServiceMock.createSetupContract(),
- uiSettings: uiSettingsMock,
- logging: loggingServiceMock.createSetupContract(),
- metrics: metricsServiceMock.createSetupContract(),
- deprecations: deprecationsServiceMock.createSetupContract(),
- executionContext: executionContextServiceMock.createInternalSetupContract(),
- coreUsageData: {
- registerUsageCounter: coreUsageDataServiceMock.createSetupContract().registerUsageCounter,
- },
- getStartServices: jest
- .fn, object, any]>, []>()
- .mockResolvedValue([createCoreStartMock(), pluginStartDeps, pluginStartContract]),
- };
-
- return mock;
-}
-
-function createCoreStartMock() {
- const mock: MockedKeys = {
- analytics: analyticsServiceMock.createAnalyticsServiceStart(),
- capabilities: capabilitiesServiceMock.createStartContract(),
- docLinks: docLinksServiceMock.createStartContract(),
- elasticsearch: elasticsearchServiceMock.createStart(),
- http: httpServiceMock.createStartContract(),
- metrics: metricsServiceMock.createStartContract(),
- savedObjects: savedObjectsServiceMock.createStartContract(),
- uiSettings: uiSettingsServiceMock.createStartContract(),
- coreUsageData: coreUsageDataServiceMock.createStartContract(),
- executionContext: executionContextServiceMock.createInternalStartContract(),
- };
-
- return mock;
-}
-
-function createInternalCorePrebootMock() {
- const prebootDeps = {
- analytics: analyticsServiceMock.createAnalyticsServicePreboot(),
- context: contextServiceMock.createPrebootContract(),
- elasticsearch: elasticsearchServiceMock.createInternalPreboot(),
- http: httpServiceMock.createInternalPrebootContract(),
- httpResources: httpResourcesMock.createPrebootContract(),
- uiSettings: uiSettingsServiceMock.createPrebootContract(),
- logging: loggingServiceMock.createInternalPrebootContract(),
- preboot: prebootServiceMock.createInternalPrebootContract(),
- };
- return prebootDeps;
-}
-
-function createInternalCoreSetupMock() {
- const setupDeps = {
- analytics: analyticsServiceMock.createAnalyticsServiceSetup(),
- capabilities: capabilitiesServiceMock.createSetupContract(),
- context: contextServiceMock.createSetupContract(),
- docLinks: docLinksServiceMock.createSetupContract(),
- elasticsearch: elasticsearchServiceMock.createInternalSetup(),
- http: httpServiceMock.createInternalSetupContract(),
- savedObjects: savedObjectsServiceMock.createInternalSetupContract(),
- status: statusServiceMock.createInternalSetupContract(),
- environment: environmentServiceMock.createSetupContract(),
- i18n: i18nServiceMock.createSetupContract(),
- httpResources: httpResourcesMock.createSetupContract(),
- rendering: renderingServiceMock.createSetupContract(),
- uiSettings: uiSettingsServiceMock.createSetupContract(),
- logging: loggingServiceMock.createInternalSetupContract(),
- metrics: metricsServiceMock.createInternalSetupContract(),
- deprecations: deprecationsServiceMock.createInternalSetupContract(),
- executionContext: executionContextServiceMock.createInternalSetupContract(),
- coreUsageData: coreUsageDataServiceMock.createSetupContract(),
- };
- return setupDeps;
-}
-
-function createInternalCoreStartMock() {
- const startDeps = {
- analytics: analyticsServiceMock.createAnalyticsServiceStart(),
- capabilities: capabilitiesServiceMock.createStartContract(),
- docLinks: docLinksServiceMock.createStartContract(),
- elasticsearch: elasticsearchServiceMock.createInternalStart(),
- http: httpServiceMock.createInternalStartContract(),
- metrics: metricsServiceMock.createInternalStartContract(),
- savedObjects: savedObjectsServiceMock.createInternalStartContract(),
- uiSettings: uiSettingsServiceMock.createStartContract(),
- coreUsageData: coreUsageDataServiceMock.createStartContract(),
- executionContext: executionContextServiceMock.createInternalStartContract(),
- deprecations: deprecationsServiceMock.createInternalStartContract(),
- };
- return startDeps;
-}
-
function createCoreRequestHandlerContextMock() {
return {
savedObjects: {
@@ -321,12 +166,12 @@ const createCustomRequestHandlerContextMock = (contextParts: T): CustomReques
};
export const coreMock = {
- createPreboot: createCorePrebootMock,
- createSetup: createCoreSetupMock,
- createStart: createCoreStartMock,
- createInternalPreboot: createInternalCorePrebootMock,
- createInternalSetup: createInternalCoreSetupMock,
- createInternalStart: createInternalCoreStartMock,
+ createPreboot: coreLifecycleMock.createPreboot,
+ createSetup: coreLifecycleMock.createCoreSetup,
+ createStart: coreLifecycleMock.createCoreStart,
+ createInternalPreboot: coreInternalLifecycleMock.createInternalPreboot,
+ createInternalSetup: coreInternalLifecycleMock.createInternalSetup,
+ createInternalStart: coreInternalLifecycleMock.createInternalStart,
createPluginInitializerContext: pluginInitializerContextMock,
createRequestHandlerContext: createCoreRequestHandlerContextMock,
createCustomRequestHandlerContext: createCustomRequestHandlerContextMock,
diff --git a/src/core/server/root/elastic_config.ts b/src/core/server/root/elastic_config.ts
new file mode 100644
index 0000000000000..84b2ce394962a
--- /dev/null
+++ b/src/core/server/root/elastic_config.ts
@@ -0,0 +1,22 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 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 { schema, TypeOf } from '@kbn/config-schema';
+import { apmConfigSchema } from '@kbn/apm-config-loader';
+import type { ServiceConfigDescriptor } from '@kbn/core-base-server-internal';
+
+const elasticConfig = schema.object({
+ apm: apmConfigSchema,
+});
+
+export type ElasticConfigType = TypeOf;
+
+export const elasticApmConfig: ServiceConfigDescriptor = {
+ path: 'elastic',
+ schema: elasticConfig,
+};
diff --git a/src/core/server/root/index.ts b/src/core/server/root/index.ts
index 2f3bcce039849..e4a129188ea6b 100644
--- a/src/core/server/root/index.ts
+++ b/src/core/server/root/index.ts
@@ -7,10 +7,20 @@
*/
import { ConnectableObservable, Subscription } from 'rxjs';
-import { first, publishReplay, switchMap, concatMap, tap } from 'rxjs/operators';
+import {
+ first,
+ publishReplay,
+ switchMap,
+ concatMap,
+ tap,
+ distinctUntilChanged,
+} from 'rxjs/operators';
import type { Logger, LoggerFactory } from '@kbn/logging';
import { Env, RawConfigurationProvider } from '@kbn/config';
import { LoggingConfigType, LoggingSystem } from '@kbn/core-logging-server-internal';
+import apm from 'elastic-apm-node';
+import { isEqual } from 'lodash';
+import type { ElasticConfigType } from './elastic_config';
import { Server } from '../server';
/**
@@ -22,6 +32,7 @@ export class Root {
private readonly loggingSystem: LoggingSystem;
private readonly server: Server;
private loggingConfigSubscription?: Subscription;
+ private apmConfigSubscription?: Subscription;
constructor(
rawConfigProvider: RawConfigurationProvider,
@@ -37,7 +48,9 @@ export class Root {
public async preboot() {
try {
this.server.setupCoreConfig();
+ this.setupApmLabelSync();
await this.setupLogging();
+
this.log.debug('prebooting root');
return await this.server.preboot();
} catch (e) {
@@ -85,6 +98,10 @@ export class Root {
this.loggingConfigSubscription.unsubscribe();
this.loggingConfigSubscription = undefined;
}
+ if (this.apmConfigSubscription !== undefined) {
+ this.apmConfigSubscription.unsubscribe();
+ this.apmConfigSubscription = undefined;
+ }
await this.loggingSystem.stop();
if (this.onShutdown !== undefined) {
@@ -92,6 +109,23 @@ export class Root {
}
}
+ private setupApmLabelSync() {
+ const { configService } = this.server;
+
+ // Update APM labels on config change
+ this.apmConfigSubscription = configService
+ .getConfig$()
+ .pipe(
+ switchMap(() => configService.atPath('elastic')),
+ distinctUntilChanged(isEqual),
+ tap((elasticConfig) => {
+ const labels = elasticConfig.apm?.globalLabels || {};
+ apm.addLabels(labels);
+ })
+ )
+ .subscribe();
+ }
+
private async setupLogging() {
const { configService } = this.server;
// Stream that maps config updates to logger updates, including update failures.
diff --git a/src/core/server/server.test.mocks.ts b/src/core/server/server.test.mocks.ts
index 3e1d5c0e3a28f..01f856f6b3a89 100644
--- a/src/core/server/server.test.mocks.ts
+++ b/src/core/server/server.test.mocks.ts
@@ -13,10 +13,10 @@ jest.doMock('@kbn/core-http-server-internal', () => ({
HttpService: jest.fn(() => mockHttpService),
}));
-import { pluginServiceMock } from './plugins/plugins_service.mock';
+import { pluginServiceMock } from '@kbn/core-plugins-server-mocks';
export const mockPluginsService = pluginServiceMock.create();
-jest.doMock('./plugins/plugins_service', () => ({
+jest.doMock('@kbn/core-plugins-server-internal', () => ({
PluginsService: jest.fn(() => mockPluginsService),
}));
diff --git a/src/core/server/server.ts b/src/core/server/server.ts
index 0949b9ee65f8a..1f60c3242215a 100644
--- a/src/core/server/server.ts
+++ b/src/core/server/server.ts
@@ -69,10 +69,18 @@ import type {
import { RenderingService } from '@kbn/core-rendering-server-internal';
import { HttpResourcesService } from '@kbn/core-http-resources-server-internal';
+import {
+ InternalCorePreboot,
+ InternalCoreSetup,
+ InternalCoreStart,
+} from '@kbn/core-lifecycle-server-internal';
+import {
+ DiscoveredPlugins,
+ PluginsService,
+ config as pluginsConfig,
+} from '@kbn/core-plugins-server-internal';
import { CoreApp } from './core_app';
-import { PluginsService, config as pluginsConfig } from './plugins';
-import { InternalCorePreboot, InternalCoreSetup, InternalCoreStart } from './internal_types';
-import { DiscoveredPlugins } from './plugins';
+import { elasticApmConfig } from './root/elastic_config';
const coreId = Symbol('core');
const rootConfigPath = '';
@@ -450,6 +458,7 @@ export class Server {
cspConfig,
deprecationConfig,
elasticsearchConfig,
+ elasticApmConfig,
executionContextConfig,
externalUrlConfig,
httpConfig,
diff --git a/src/core/test_helpers/kbn_server.ts b/src/core/test_helpers/kbn_server.ts
index faa45c52d84b8..64c32c47ca2a9 100644
--- a/src/core/test_helpers/kbn_server.ts
+++ b/src/core/test_helpers/kbn_server.ts
@@ -21,7 +21,7 @@ import {
} from '@kbn/test';
import { CliArgs, Env } from '@kbn/config';
-import { InternalCoreSetup, InternalCoreStart } from '../server/internal_types';
+import type { InternalCoreSetup, InternalCoreStart } from '@kbn/core-lifecycle-server-internal';
import { Root } from '../server/root';
export type HttpMethod = 'delete' | 'get' | 'head' | 'post' | 'put' | 'patch';
diff --git a/src/plugins/custom_integrations/common/language_integrations.ts b/src/plugins/custom_integrations/common/language_integrations.ts
index 9ba914c02fd0d..8a24295096b40 100644
--- a/src/plugins/custom_integrations/common/language_integrations.ts
+++ b/src/plugins/custom_integrations/common/language_integrations.ts
@@ -37,9 +37,9 @@ export const languageIntegrations: LanguageIntegration[] = [
description: i18n.translate('customIntegrations.languageclients.JavascriptDescription', {
defaultMessage: 'Index data to Elasticsearch with the JavaScript client.',
}),
- docUrlTemplate: `${ELASTICSEARCH_CLIENT_URL}/javascript-api/{branch}/introduction.html`,
+ docUrlTemplate: '',
integrationsAppUrl: `/app/integrations/language_clients/javascript/overview`,
- exportLanguageUiComponent: false,
+ exportLanguageUiComponent: true,
},
{
id: 'ruby',
diff --git a/src/plugins/custom_integrations/public/components/fleet_integration/elasticsearch_js/elasticsearch_js_readme.tsx b/src/plugins/custom_integrations/public/components/fleet_integration/elasticsearch_js/elasticsearch_js_readme.tsx
new file mode 100644
index 0000000000000..0202782efe436
--- /dev/null
+++ b/src/plugins/custom_integrations/public/components/fleet_integration/elasticsearch_js/elasticsearch_js_readme.tsx
@@ -0,0 +1,204 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import React, { useState } from 'react';
+
+// eslint-disable-next-line @kbn/eslint/module_migration
+import styled from 'styled-components';
+import cuid from 'cuid';
+
+import {
+ EuiButton,
+ EuiCode,
+ EuiCodeBlock,
+ EuiFlexGroup,
+ EuiFlexItem,
+ EuiPage,
+ EuiPageBody,
+ EuiPageHeader,
+ EuiPageSection,
+ EuiSpacer,
+ EuiText,
+ EuiTitle,
+ EuiPanel,
+ EuiImage,
+} from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n-react';
+import { euiThemeVars } from '@kbn/ui-theme';
+import icon from '../../../assets/language_clients/nodejs.svg';
+
+const CenterColumn = styled(EuiFlexItem)`
+ max-width: 740px;
+`;
+
+const FixedHeader = styled.div`
+ width: 100%;
+ height: 196px;
+ border-bottom: 1px solid ${euiThemeVars.euiColorLightShade};
+`;
+
+const IconPanel = styled(EuiPanel)`
+ padding: ${(props) => props.theme.eui.euiSizeXL};
+ width: ${(props) =>
+ parseFloat(props.theme.eui.euiSize) * 6 + parseFloat(props.theme.eui.euiSizeXL) * 2}px;
+ svg,
+ img {
+ height: ${(props) => parseFloat(props.theme.eui.euiSize) * 6}px;
+ width: ${(props) => parseFloat(props.theme.eui.euiSize) * 6}px;
+ }
+ .euiFlexItem {
+ height: ${(props) => parseFloat(props.theme.eui.euiSize) * 6}px;
+ justify-content: center;
+ }
+`;
+
+const TopFlexGroup = styled(EuiFlexGroup)`
+ max-width: 1150px;
+ margin-left: auto;
+ margin-right: auto;
+ padding: calc(${euiThemeVars.euiSizeXL} * 2) ${euiThemeVars.euiSizeM} 0 ${euiThemeVars.euiSizeM};
+`;
+
+export const ElasticsearchJsClientReadme = () => {
+ const [apiKey, setApiKey] = useState(null);
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+ {`# Grab the Elasticsearch JavaScript client from NPM and install it in your project \n`}
+ {`$ npm install @elastic/elasticsearch@`}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ setApiKey(cuid())} disabled={!!apiKey}>
+ Generate API key
+
+
+
+ {apiKey && (
+
+
+ {apiKey}
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+ index.js,
+ }}
+ />
+
+
+
+
+
+ {`
+// Import the client
+const { Client } = require('@elastic/elasticsearch');
+
+// Instantiate the client with an API key
+const client = new Client({
+ auth: { apiKey: '${apiKey || 'YOUR_API_KEY'}' }
+})
+
+ `}
+
+
+
+
+
+
+ >
+ );
+};
diff --git a/src/plugins/custom_integrations/public/components/fleet_integration/sample/sample_client_readme.tsx b/src/plugins/custom_integrations/public/components/fleet_integration/sample/sample_client_readme.tsx
index c2ca0d62da689..7b932ca9c99f7 100644
--- a/src/plugins/custom_integrations/public/components/fleet_integration/sample/sample_client_readme.tsx
+++ b/src/plugins/custom_integrations/public/components/fleet_integration/sample/sample_client_readme.tsx
@@ -81,7 +81,7 @@ export const SampleClientReadme = () => {
diff --git a/src/plugins/custom_integrations/public/plugin.tsx b/src/plugins/custom_integrations/public/plugin.tsx
index 827d31ce3749d..e1e10f327075c 100755
--- a/src/plugins/custom_integrations/public/plugin.tsx
+++ b/src/plugins/custom_integrations/public/plugin.tsx
@@ -23,6 +23,7 @@ import {
import { CustomIntegrationsServicesProvider } from './services';
import { servicesFactory } from './services/kibana';
import { SampleClientReadme } from './components/fleet_integration/sample/sample_client_readme';
+import { ElasticsearchJsClientReadme } from './components/fleet_integration/elasticsearch_js/elasticsearch_js_readme';
export class CustomIntegrationsPlugin
implements Plugin
@@ -46,7 +47,10 @@ export class CustomIntegrationsPlugin
): CustomIntegrationsStart {
const services = servicesFactory({ coreStart, startPlugins });
- const languageClientsUiComponents = { sample: SampleClientReadme };
+ const languageClientsUiComponents = {
+ sample: SampleClientReadme,
+ javascript: ElasticsearchJsClientReadme,
+ };
const ContextProvider: React.FC = ({ children }) => (
diff --git a/src/plugins/custom_integrations/server/plugin.test.ts b/src/plugins/custom_integrations/server/plugin.test.ts
index 0bfc014ed5cdd..324522a383d83 100644
--- a/src/plugins/custom_integrations/server/plugin.test.ts
+++ b/src/plugins/custom_integrations/server/plugin.test.ts
@@ -37,8 +37,7 @@ describe('CustomIntegrationsPlugin', () => {
description: 'Index data to Elasticsearch with the JavaScript client.',
type: 'ui_link',
shipper: 'language_clients',
- uiInternalPath:
- 'https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/branch/introduction.html',
+ uiInternalPath: '/app/integrations/language_clients/javascript/overview',
isBeta: false,
icons: [{ type: 'svg', src: undefined }],
categories: ['elastic_stack', 'custom', 'language_client'],
@@ -150,7 +149,7 @@ describe('CustomIntegrationsPlugin', () => {
uiExternalLink:
'https://serverlessrepo.aws.amazon.com/applications/eu-central-1/267093732750/elastic-serverless-forwarder',
isBeta: false,
- icons: [{ type: 'svg' }],
+ icons: [{ type: 'svg', src: undefined }],
categories: ['aws', 'custom'],
},
]);
diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts
index 850c6f575904c..6095598ae3788 100644
--- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts
+++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.ts
@@ -13,6 +13,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import { BehaviorSubject, combineLatest, Observable, Subject } from 'rxjs';
import { ViewMode } from '@kbn/embeddable-plugin/public';
+import type { DataView } from '@kbn/data-plugin/common';
import type { IKbnUrlStateStorage } from '@kbn/kibana-utils-plugin/public';
import {
@@ -225,7 +226,14 @@ export const useDashboardAppState = ({
dashboardContainer.controlGroup?.setRelevantDataViewId(newDataViewIds[0]);
}
// fetch all data views. These should be cached locally at this time so we will not need to query ES.
- const allDataViews = await Promise.all(newDataViewIds.map((id) => dataViews.get(id)));
+ const responses = await Promise.allSettled(newDataViewIds.map((id) => dataViews.get(id)));
+ // Keep only fullfilled ones as each panel will handle the rejected ones already on their own
+ const allDataViews = responses
+ .filter(
+ (response): response is PromiseFulfilledResult =>
+ response.status === 'fulfilled'
+ )
+ .map(({ value }) => value);
dashboardContainer.setAllDataViews(allDataViews);
setDashboardAppState((s) => ({ ...s, dataViews: allDataViews }));
},
diff --git a/src/plugins/guided_onboarding/kibana.json b/src/plugins/guided_onboarding/kibana.json
index 22a54e8dd3278..a7c1c3d217c1b 100755
--- a/src/plugins/guided_onboarding/kibana.json
+++ b/src/plugins/guided_onboarding/kibana.json
@@ -10,5 +10,5 @@
"server": true,
"ui": true,
"requiredBundles": ["kibanaReact"],
- "optionalPlugins": []
+ "optionalPlugins": ["cloud"]
}
diff --git a/src/plugins/guided_onboarding/public/constants/guides_config/index.ts b/src/plugins/guided_onboarding/public/constants/guides_config/index.ts
index 9ce81cf9d4698..e2ab4f7e7747f 100644
--- a/src/plugins/guided_onboarding/public/constants/guides_config/index.ts
+++ b/src/plugins/guided_onboarding/public/constants/guides_config/index.ts
@@ -10,9 +10,11 @@ import type { GuidesConfig } from '../../types';
import { securityConfig } from './security';
import { observabilityConfig } from './observability';
import { searchConfig } from './search';
+import { testGuideConfig } from './test_guide';
export const guidesConfig: GuidesConfig = {
security: securityConfig,
observability: observabilityConfig,
search: searchConfig,
+ testGuide: testGuideConfig,
};
diff --git a/src/plugins/guided_onboarding/public/constants/guides_config/security.ts b/src/plugins/guided_onboarding/public/constants/guides_config/security.ts
index d2f9b352b9d81..3930ab66220f0 100644
--- a/src/plugins/guided_onboarding/public/constants/guides_config/security.ts
+++ b/src/plugins/guided_onboarding/public/constants/guides_config/security.ts
@@ -6,25 +6,34 @@
* Side Public License, v 1.
*/
+import { i18n } from '@kbn/i18n';
import type { GuideConfig } from '../../types';
export const securityConfig: GuideConfig = {
- title: 'Get started with SIEM',
+ title: i18n.translate('guidedOnboarding.securityGuide.title', {
+ defaultMessage: 'Elastic Security guided setup',
+ }),
guideName: 'Security',
completedGuideRedirectLocation: {
appID: 'security',
path: '/app/security/dashboards',
},
- description:
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ligula enim, malesuada a finibus vel, cursus sed risus. Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.',
+ description: i18n.translate('guidedOnboarding.securityGuide.description', {
+ defaultMessage: `We'll help you get set up quickly, using Elastic's out-of-the-box integrations.`,
+ }),
steps: [
{
id: 'add_data',
- title: 'Add and view your data',
+ title: i18n.translate('guidedOnboarding.securityGuide.addDataStep.title', {
+ defaultMessage: 'Add data with Elastic Defend',
+ }),
descriptionList: [
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
- 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.',
- 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.',
+ i18n.translate('guidedOnboarding.securityGuide.addDataStep.description1', {
+ defaultMessage: 'Select the Elastic Defend integration to add your data.',
+ }),
+ i18n.translate('guidedOnboarding.securityGuide.addDataStep.description2', {
+ defaultMessage: 'Make sure your data looks good.',
+ }),
],
integration: 'endpoint',
location: {
@@ -34,16 +43,27 @@ export const securityConfig: GuideConfig = {
},
{
id: 'rules',
- title: 'Turn on rules',
+ title: i18n.translate('guidedOnboarding.securityGuide.rulesStep.title', {
+ defaultMessage: 'Turn on rules',
+ }),
descriptionList: [
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
- 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.',
- 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.',
+ i18n.translate('guidedOnboarding.securityGuide.rulesStep.description1', {
+ defaultMessage: 'Load the prebuilt rules.',
+ }),
+ i18n.translate('guidedOnboarding.securityGuide.rulesStep.description2', {
+ defaultMessage: 'Select the rules that you want.',
+ }),
],
manualCompletion: {
- title: 'Manual completion step title',
- description:
- 'Mark the step complete by opening the panel and clicking the button "Mark done"',
+ title: i18n.translate('guidedOnboarding.securityGuide.rulesStep.manualCompletion.title', {
+ defaultMessage: 'Continue with the tour',
+ }),
+ description: i18n.translate(
+ 'guidedOnboarding.securityGuide.rulesStep.manualCompletion.description',
+ {
+ defaultMessage: 'After you’ve enabled the rules you want, click here to continue.',
+ }
+ ),
},
location: {
appID: 'securitySolutionUI',
@@ -52,11 +72,16 @@ export const securityConfig: GuideConfig = {
},
{
id: 'alertsCases',
- title: 'Alerts and cases',
+ title: i18n.translate('guidedOnboarding.securityGuide.alertsStep.title', {
+ defaultMessage: 'Manage alerts and cases',
+ }),
descriptionList: [
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
- 'Nullam ligula enim, malesuada a finibus vel, cursus sed risus.',
- 'Vivamus pretium, elit dictum lacinia aliquet, libero nibh dictum enim, a rhoncus leo magna in sapien.',
+ i18n.translate('guidedOnboarding.securityGuide.alertsStep.description1', {
+ defaultMessage: 'View and triage alerts.',
+ }),
+ i18n.translate('guidedOnboarding.securityGuide.alertsStep.description2', {
+ defaultMessage: 'Create a case.',
+ }),
],
location: {
appID: 'securitySolutionUI',
diff --git a/src/plugins/guided_onboarding/public/constants/guides_config/test_guide.ts b/src/plugins/guided_onboarding/public/constants/guides_config/test_guide.ts
new file mode 100644
index 0000000000000..b357ad497c6b4
--- /dev/null
+++ b/src/plugins/guided_onboarding/public/constants/guides_config/test_guide.ts
@@ -0,0 +1,68 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import type { GuideConfig } from '../../types';
+
+export const testGuideConfig: GuideConfig = {
+ title: 'Test guide for development',
+ description: `This guide is used to test the guided onboarding UI while in development and to run automated tests for the API and UI components.`,
+ guideName: 'Testing example',
+ docs: {
+ text: 'Testing example docs',
+ url: 'example.com',
+ },
+ steps: [
+ {
+ id: 'step1',
+ title: 'Step 1 (completed via an API request)',
+ descriptionList: [
+ `This step is directly completed by clicking the button that uses the API function 'completeGuideStep`,
+ 'Navigate to /guidedOnboardingExample/stepOne to complete the step.',
+ ],
+ location: {
+ appID: 'guidedOnboardingExample',
+ path: 'stepOne',
+ },
+ integration: 'testIntegration',
+ },
+ {
+ id: 'step2',
+ title: 'Step 2 (manual completion after navigation)',
+ descriptionList: [
+ 'This step is set to ready_to_complete on page navigation.',
+ 'After that click the popover on the guide button in the header and mark the step done',
+ ],
+ location: {
+ appID: 'guidedOnboardingExample',
+ path: 'stepTwo',
+ },
+ manualCompletion: {
+ title: 'Manual completion step title',
+ description:
+ 'Mark the step complete by opening the panel and clicking the button "Mark done"',
+ readyToCompleteOnNavigation: true,
+ },
+ },
+ {
+ id: 'step3',
+ title: 'Step 3 (manual completion after click)',
+ descriptionList: [
+ 'This step is completed by clicking a button on the page and then clicking the popover on the guide button in the header and marking the step done',
+ ],
+ manualCompletion: {
+ title: 'Manual completion step title',
+ description:
+ 'Mark the step complete by opening the panel and clicking the button "Mark done"',
+ },
+ location: {
+ appID: 'guidedOnboardingExample',
+ path: 'stepThree',
+ },
+ },
+ ],
+};
diff --git a/src/plugins/guided_onboarding/public/plugin.tsx b/src/plugins/guided_onboarding/public/plugin.tsx
index 5d18eab0ad223..4cf5fa9749a07 100755
--- a/src/plugins/guided_onboarding/public/plugin.tsx
+++ b/src/plugins/guided_onboarding/public/plugin.tsx
@@ -13,7 +13,11 @@ import { I18nProvider } from '@kbn/i18n-react';
import { CoreSetup, CoreStart, Plugin, CoreTheme, ApplicationStart } from '@kbn/core/public';
import { KibanaThemeProvider } from '@kbn/kibana-react-plugin/public';
-import type { GuidedOnboardingPluginSetup, GuidedOnboardingPluginStart } from './types';
+import type {
+ AppPluginStartDependencies,
+ GuidedOnboardingPluginSetup,
+ GuidedOnboardingPluginStart,
+} from './types';
import { GuidePanel } from './components';
import { ApiService, apiService } from './services/api';
@@ -25,22 +29,28 @@ export class GuidedOnboardingPlugin
return {};
}
- public start(core: CoreStart): GuidedOnboardingPluginStart {
+ public start(
+ core: CoreStart,
+ { cloud }: AppPluginStartDependencies
+ ): GuidedOnboardingPluginStart {
const { chrome, http, theme, application } = core;
// Initialize services
apiService.setup(http);
- chrome.navControls.registerExtension({
- order: 1000,
- mount: (target) =>
- this.mount({
- targetDomElement: target,
- theme$: theme.theme$,
- api: apiService,
- application,
- }),
- });
+ // Guided onboarding UI is only available on cloud
+ if (cloud?.isCloudEnabled) {
+ chrome.navControls.registerExtension({
+ order: 1000,
+ mount: (target) =>
+ this.mount({
+ targetDomElement: target,
+ theme$: theme.theme$,
+ api: apiService,
+ application,
+ }),
+ });
+ }
// Return methods that should be available to other plugins
return {
diff --git a/src/plugins/guided_onboarding/public/services/api.mocks.ts b/src/plugins/guided_onboarding/public/services/api.mocks.ts
index 21bb257cad68f..2294607f91b38 100644
--- a/src/plugins/guided_onboarding/public/services/api.mocks.ts
+++ b/src/plugins/guided_onboarding/public/services/api.mocks.ts
@@ -6,84 +6,78 @@
* Side Public License, v 1.
*/
-import type { GuideState } from '@kbn/guided-onboarding';
+import type { GuideState, GuideId, GuideStepIds } from '@kbn/guided-onboarding';
-export const searchAddDataActiveState: GuideState = {
- guideId: 'search',
+export const testGuide: GuideId = 'testGuide';
+export const testGuideFirstStep: GuideStepIds = 'step1';
+export const testGuideManualCompletionStep = 'step2';
+export const testGuideLastStep: GuideStepIds = 'step3';
+export const testIntegration = 'testIntegration';
+export const wrongIntegration = 'notTestIntegration';
+
+export const testGuideStep1ActiveState: GuideState = {
+ guideId: 'testGuide',
isActive: true,
status: 'in_progress',
steps: [
{
- id: 'add_data',
+ id: 'step1',
status: 'active',
},
{
- id: 'browse_docs',
+ id: 'step2',
status: 'inactive',
},
{
- id: 'search_experience',
+ id: 'step3',
status: 'inactive',
},
],
};
-export const securityAddDataInProgressState: GuideState = {
- guideId: 'security',
- status: 'in_progress',
- isActive: true,
+export const testGuideStep1InProgressState: GuideState = {
+ ...testGuideStep1ActiveState,
steps: [
{
- id: 'add_data',
- status: 'in_progress',
- },
- {
- id: 'rules',
- status: 'inactive',
- },
- {
- id: 'alertsCases',
- status: 'inactive',
+ id: testGuideStep1ActiveState.steps[0].id,
+ status: 'in_progress', // update the first step status
},
+ testGuideStep1ActiveState.steps[1],
+ testGuideStep1ActiveState.steps[2],
],
};
-export const securityRulesActiveState: GuideState = {
- guideId: 'security',
- isActive: true,
- status: 'in_progress',
+export const testGuideStep2ActiveState: GuideState = {
+ ...testGuideStep1ActiveState,
steps: [
{
- id: 'add_data',
+ ...testGuideStep1ActiveState.steps[0],
status: 'complete',
},
{
- id: 'rules',
+ id: testGuideStep1ActiveState.steps[1].id,
status: 'active',
},
- {
- id: 'alertsCases',
- status: 'inactive',
- },
+ testGuideStep1ActiveState.steps[2],
],
};
-export const noGuideActiveState: GuideState = {
- guideId: 'security',
- status: 'in_progress',
- isActive: false,
+export const testGuideStep2InProgressState: GuideState = {
+ ...testGuideStep1ActiveState,
steps: [
{
- id: 'add_data',
- status: 'in_progress',
- },
- {
- id: 'rules',
- status: 'inactive',
+ ...testGuideStep1ActiveState.steps[0],
+ status: 'complete',
},
{
- id: 'alertsCases',
- status: 'inactive',
+ id: testGuideStep1ActiveState.steps[1].id,
+ status: 'in_progress',
},
+ testGuideStep1ActiveState.steps[2],
],
};
+
+export const testGuideNotActiveState: GuideState = {
+ ...testGuideStep1ActiveState,
+ isActive: false,
+};
diff --git a/src/plugins/guided_onboarding/public/services/api.test.ts b/src/plugins/guided_onboarding/public/services/api.test.ts
index 2296304166648..56a5755f0ee55 100644
--- a/src/plugins/guided_onboarding/public/services/api.test.ts
+++ b/src/plugins/guided_onboarding/public/services/api.test.ts
@@ -12,20 +12,20 @@ import type { GuideState } from '@kbn/guided-onboarding';
import { firstValueFrom, Subscription } from 'rxjs';
import { API_BASE_PATH } from '../../common/constants';
-import { guidesConfig } from '../constants/guides_config';
import { ApiService } from './api';
import {
- noGuideActiveState,
- searchAddDataActiveState,
- securityAddDataInProgressState,
- securityRulesActiveState,
+ testGuide,
+ testGuideFirstStep,
+ testGuideManualCompletionStep,
+ testGuideStep1ActiveState,
+ testGuideStep1InProgressState,
+ testGuideStep2ActiveState,
+ testGuideNotActiveState,
+ testIntegration,
+ wrongIntegration,
+ testGuideStep2InProgressState,
} from './api.mocks';
-const searchGuide = 'search';
-const firstStep = guidesConfig[searchGuide].steps[0].id;
-const endpointIntegration = 'endpoint';
-const kubernetesIntegration = 'kubernetes';
-
describe('GuidedOnboarding ApiService', () => {
let httpClient: jest.Mocked;
let apiService: ApiService;
@@ -34,7 +34,7 @@ describe('GuidedOnboarding ApiService', () => {
beforeEach(() => {
httpClient = httpServiceMock.createStartContract({ basePath: '/base/path' });
httpClient.get.mockResolvedValue({
- state: [securityAddDataInProgressState],
+ state: [testGuideStep1ActiveState],
});
apiService = new ApiService();
apiService.setup(httpClient);
@@ -57,10 +57,10 @@ describe('GuidedOnboarding ApiService', () => {
});
it('broadcasts the updated state', async () => {
- await apiService.activateGuide(searchGuide, searchAddDataActiveState);
+ await apiService.activateGuide(testGuide, testGuideStep1ActiveState);
const state = await firstValueFrom(apiService.fetchActiveGuideState$());
- expect(state).toEqual(searchAddDataActiveState);
+ expect(state).toEqual(testGuideStep1ActiveState);
});
});
@@ -74,12 +74,12 @@ describe('GuidedOnboarding ApiService', () => {
describe('deactivateGuide', () => {
it('deactivates an existing guide', async () => {
- await apiService.deactivateGuide(searchAddDataActiveState);
+ await apiService.deactivateGuide(testGuideStep1ActiveState);
expect(httpClient.put).toHaveBeenCalledTimes(1);
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
body: JSON.stringify({
- ...searchAddDataActiveState,
+ ...testGuideStep1ActiveState,
isActive: false,
}),
});
@@ -88,17 +88,7 @@ describe('GuidedOnboarding ApiService', () => {
describe('updateGuideState', () => {
it('sends a request to the put API', async () => {
- const updatedState: GuideState = {
- ...searchAddDataActiveState,
- steps: [
- {
- id: searchAddDataActiveState.steps[0].id,
- status: 'in_progress', // update the first step status
- },
- searchAddDataActiveState.steps[1],
- searchAddDataActiveState.steps[2],
- ],
- };
+ const updatedState: GuideState = testGuideStep1InProgressState;
await apiService.updateGuideState(updatedState, false);
expect(httpClient.put).toHaveBeenCalledTimes(1);
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
@@ -109,20 +99,11 @@ describe('GuidedOnboarding ApiService', () => {
describe('isGuideStepActive$', () => {
it('returns true if the step has been started', (done) => {
- const updatedState: GuideState = {
- ...searchAddDataActiveState,
- steps: [
- {
- id: searchAddDataActiveState.steps[0].id,
- status: 'in_progress',
- },
- searchAddDataActiveState.steps[1],
- searchAddDataActiveState.steps[2],
- ],
- };
+ const updatedState: GuideState = testGuideStep1InProgressState;
apiService.updateGuideState(updatedState, false);
+
subscription = apiService
- .isGuideStepActive$(searchGuide, firstStep)
+ .isGuideStepActive$(testGuide, testGuideFirstStep)
.subscribe((isStepActive) => {
if (isStepActive) {
done();
@@ -131,9 +112,8 @@ describe('GuidedOnboarding ApiService', () => {
});
it('returns false if the step is not been started', (done) => {
- apiService.updateGuideState(searchAddDataActiveState, false);
subscription = apiService
- .isGuideStepActive$(searchGuide, firstStep)
+ .isGuideStepActive$(testGuide, testGuideFirstStep)
.subscribe((isStepActive) => {
if (!isStepActive) {
done();
@@ -144,56 +124,44 @@ describe('GuidedOnboarding ApiService', () => {
describe('activateGuide', () => {
it('activates a new guide', async () => {
- await apiService.activateGuide(searchGuide);
+ // update the mock to no active guides
+ httpClient.get.mockResolvedValue({
+ state: [],
+ });
+ apiService.setup(httpClient);
+
+ await apiService.activateGuide(testGuide);
expect(httpClient.put).toHaveBeenCalledTimes(1);
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
- body: JSON.stringify({
- isActive: true,
- status: 'not_started',
- steps: [
- {
- id: 'add_data',
- status: 'active',
- },
- {
- id: 'browse_docs',
- status: 'inactive',
- },
- {
- id: 'search_experience',
- status: 'inactive',
- },
- ],
- guideId: searchGuide,
- }),
+ body: JSON.stringify({ ...testGuideStep1ActiveState, status: 'not_started' }),
});
});
it('reactivates a guide that has already been started', async () => {
- await apiService.activateGuide(searchGuide, searchAddDataActiveState);
+ await apiService.activateGuide(testGuide, testGuideStep1ActiveState);
expect(httpClient.put).toHaveBeenCalledTimes(1);
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
- body: JSON.stringify(searchAddDataActiveState),
+ body: JSON.stringify(testGuideStep1ActiveState),
});
});
});
describe('completeGuide', () => {
const readyToCompleteGuideState: GuideState = {
- ...searchAddDataActiveState,
+ ...testGuideStep1ActiveState,
steps: [
{
- id: 'add_data',
+ ...testGuideStep1ActiveState.steps[0],
status: 'complete',
},
{
- id: 'browse_docs',
+ ...testGuideStep1ActiveState.steps[1],
status: 'complete',
},
{
- id: 'search_experience',
+ ...testGuideStep1ActiveState.steps[2],
status: 'complete',
},
],
@@ -204,7 +172,7 @@ describe('GuidedOnboarding ApiService', () => {
});
it('updates the selected guide and marks it as complete', async () => {
- await apiService.completeGuide(searchGuide);
+ await apiService.completeGuide(testGuide);
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
body: JSON.stringify({
@@ -222,51 +190,39 @@ describe('GuidedOnboarding ApiService', () => {
it('returns undefined if the selected guide has uncompleted steps', async () => {
const incompleteGuideState: GuideState = {
- ...searchAddDataActiveState,
+ ...testGuideStep1ActiveState,
steps: [
{
- id: 'add_data',
+ ...testGuideStep1ActiveState.steps[0],
status: 'complete',
},
{
- id: 'browse_docs',
+ ...testGuideStep1ActiveState.steps[1],
status: 'complete',
},
{
- id: 'search_experience',
+ ...testGuideStep1ActiveState.steps[2],
status: 'in_progress',
},
],
};
await apiService.updateGuideState(incompleteGuideState, false);
- const completedState = await apiService.completeGuide(searchGuide);
+ const completedState = await apiService.completeGuide(testGuide);
expect(completedState).not.toBeDefined();
});
});
describe('startGuideStep', () => {
beforeEach(async () => {
- await apiService.updateGuideState(searchAddDataActiveState, false);
+ await apiService.updateGuideState(testGuideStep1ActiveState, false);
});
it('updates the selected step and marks it as in_progress', async () => {
- await apiService.startGuideStep(searchGuide, firstStep);
+ await apiService.startGuideStep(testGuide, testGuideFirstStep);
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
- body: JSON.stringify({
- ...searchAddDataActiveState,
- isActive: true,
- status: 'in_progress',
- steps: [
- {
- id: searchAddDataActiveState.steps[0].id,
- status: 'in_progress',
- },
- searchAddDataActiveState.steps[1],
- searchAddDataActiveState.steps[2],
- ],
- }),
+ body: JSON.stringify(testGuideStep1InProgressState),
});
});
@@ -278,76 +234,35 @@ describe('GuidedOnboarding ApiService', () => {
describe('completeGuideStep', () => {
it(`completes the step when it's in progress`, async () => {
- const updatedState: GuideState = {
- ...searchAddDataActiveState,
- steps: [
- {
- id: searchAddDataActiveState.steps[0].id,
- status: 'in_progress', // Mark a step as in_progress in order to test the "completeGuideStep" behavior
- },
- searchAddDataActiveState.steps[1],
- searchAddDataActiveState.steps[2],
- ],
- };
- await apiService.updateGuideState(updatedState, false);
+ await apiService.updateGuideState(testGuideStep1InProgressState, false);
- await apiService.completeGuideStep(searchGuide, firstStep);
+ await apiService.completeGuideStep(testGuide, testGuideFirstStep);
// Once on update, once on complete
expect(httpClient.put).toHaveBeenCalledTimes(2);
// Verify the completed step now has a "complete" status, and the subsequent step is "active"
expect(httpClient.put).toHaveBeenLastCalledWith(`${API_BASE_PATH}/state`, {
- body: JSON.stringify({
- ...updatedState,
- steps: [
- {
- id: searchAddDataActiveState.steps[0].id,
- status: 'complete',
- },
- {
- id: searchAddDataActiveState.steps[1].id,
- status: 'active',
- },
- searchAddDataActiveState.steps[2],
- ],
- }),
+ body: JSON.stringify({ ...testGuideStep2ActiveState }),
});
});
it(`marks the step as 'ready_to_complete' if it's configured for manual completion`, async () => {
- const securityRulesInProgressState = {
- ...securityRulesActiveState,
- steps: [
- securityRulesActiveState.steps[0],
- {
- id: securityRulesActiveState.steps[1].id,
- status: 'in_progress',
- },
- securityRulesActiveState.steps[2],
- ],
- };
httpClient.get.mockResolvedValue({
- state: [securityRulesInProgressState],
+ state: [testGuideStep2InProgressState],
});
apiService.setup(httpClient);
- await apiService.completeGuideStep('security', 'rules');
+ await apiService.completeGuideStep(testGuide, testGuideManualCompletionStep);
expect(httpClient.put).toHaveBeenCalledTimes(1);
// Verify the completed step now has a "ready_to_complete" status, and the subsequent step is "inactive"
expect(httpClient.put).toHaveBeenLastCalledWith(`${API_BASE_PATH}/state`, {
body: JSON.stringify({
- ...securityRulesInProgressState,
+ ...testGuideStep2InProgressState,
steps: [
- securityRulesInProgressState.steps[0],
- {
- id: securityRulesInProgressState.steps[1].id,
- status: 'ready_to_complete',
- },
- {
- id: securityRulesInProgressState.steps[2].id,
- status: 'inactive',
- },
+ testGuideStep2InProgressState.steps[0],
+ { ...testGuideStep2InProgressState.steps[1], status: 'ready_to_complete' },
+ testGuideStep2InProgressState.steps[2],
],
}),
});
@@ -359,12 +274,8 @@ describe('GuidedOnboarding ApiService', () => {
});
it('does nothing if the step is not in progress', async () => {
- httpClient.get.mockResolvedValue({
- state: [searchAddDataActiveState],
- });
- apiService.setup(httpClient);
-
- await apiService.completeGuideStep(searchGuide, firstStep);
+ // by default the state set in beforeEach is test guide, step 1 active
+ await apiService.completeGuideStep(testGuide, testGuideFirstStep);
expect(httpClient.put).toHaveBeenCalledTimes(0);
});
});
@@ -372,11 +283,11 @@ describe('GuidedOnboarding ApiService', () => {
describe('isGuidedOnboardingActiveForIntegration$', () => {
it('returns true if the integration is part of the active step', (done) => {
httpClient.get.mockResolvedValue({
- state: [securityAddDataInProgressState],
+ state: [testGuideStep1InProgressState],
});
apiService.setup(httpClient);
subscription = apiService
- .isGuidedOnboardingActiveForIntegration$(endpointIntegration)
+ .isGuidedOnboardingActiveForIntegration$(testIntegration)
.subscribe((isIntegrationInGuideStep) => {
if (isIntegrationInGuideStep) {
done();
@@ -384,13 +295,13 @@ describe('GuidedOnboarding ApiService', () => {
});
});
- it('returns false if another integration is part of the active step', (done) => {
+ it('returns false if the current step has a different integration', (done) => {
httpClient.get.mockResolvedValue({
- state: [securityAddDataInProgressState],
+ state: [testGuideStep1InProgressState],
});
apiService.setup(httpClient);
subscription = apiService
- .isGuidedOnboardingActiveForIntegration$(kubernetesIntegration)
+ .isGuidedOnboardingActiveForIntegration$(wrongIntegration)
.subscribe((isIntegrationInGuideStep) => {
if (!isIntegrationInGuideStep) {
done();
@@ -400,11 +311,11 @@ describe('GuidedOnboarding ApiService', () => {
it('returns false if no guide is active', (done) => {
httpClient.get.mockResolvedValue({
- state: [noGuideActiveState],
+ state: [testGuideNotActiveState],
});
apiService.setup(httpClient);
subscription = apiService
- .isGuidedOnboardingActiveForIntegration$(endpointIntegration)
+ .isGuidedOnboardingActiveForIntegration$(testIntegration)
.subscribe((isIntegrationInGuideStep) => {
if (!isIntegrationInGuideStep) {
done();
@@ -416,35 +327,35 @@ describe('GuidedOnboarding ApiService', () => {
describe('completeGuidedOnboardingForIntegration', () => {
it(`completes the step if it's active for the integration`, async () => {
httpClient.get.mockResolvedValue({
- state: [securityAddDataInProgressState],
+ state: [testGuideStep1InProgressState],
});
apiService.setup(httpClient);
- await apiService.completeGuidedOnboardingForIntegration(endpointIntegration);
+ await apiService.completeGuidedOnboardingForIntegration(testIntegration);
expect(httpClient.put).toHaveBeenCalledTimes(1);
// this assertion depends on the guides config
expect(httpClient.put).toHaveBeenCalledWith(`${API_BASE_PATH}/state`, {
- body: JSON.stringify(securityRulesActiveState),
+ body: JSON.stringify(testGuideStep2ActiveState),
});
});
it(`does nothing if the step has a different integration`, async () => {
httpClient.get.mockResolvedValue({
- state: [securityAddDataInProgressState],
+ state: [testGuideStep1InProgressState],
});
apiService.setup(httpClient);
- await apiService.completeGuidedOnboardingForIntegration(kubernetesIntegration);
+ await apiService.completeGuidedOnboardingForIntegration(wrongIntegration);
expect(httpClient.put).not.toHaveBeenCalled();
});
it(`does nothing if no guide is active`, async () => {
httpClient.get.mockResolvedValue({
- state: [noGuideActiveState],
+ state: [testGuideNotActiveState],
});
apiService.setup(httpClient);
- await apiService.completeGuidedOnboardingForIntegration(endpointIntegration);
+ await apiService.completeGuidedOnboardingForIntegration(testIntegration);
expect(httpClient.put).not.toHaveBeenCalled();
});
});
diff --git a/src/plugins/guided_onboarding/public/services/api.ts b/src/plugins/guided_onboarding/public/services/api.ts
index 688e72fa83243..cd33f9505c546 100644
--- a/src/plugins/guided_onboarding/public/services/api.ts
+++ b/src/plugins/guided_onboarding/public/services/api.ts
@@ -147,10 +147,10 @@ export class ApiService implements GuidedOnboardingApi {
});
const updatedGuide: GuideState = {
+ guideId,
isActive: true,
status: 'not_started',
steps: updatedSteps,
- guideId,
};
return await this.updateGuideState(updatedGuide, true);
diff --git a/src/plugins/guided_onboarding/public/services/helpers.test.ts b/src/plugins/guided_onboarding/public/services/helpers.test.ts
index 9dc7519a02019..82720c4f9d223 100644
--- a/src/plugins/guided_onboarding/public/services/helpers.test.ts
+++ b/src/plugins/guided_onboarding/public/services/helpers.test.ts
@@ -6,51 +6,50 @@
* Side Public License, v 1.
*/
-import { guidesConfig } from '../constants/guides_config';
import { isIntegrationInGuideStep, isLastStep } from './helpers';
import {
- noGuideActiveState,
- securityAddDataInProgressState,
- securityRulesActiveState,
+ testGuide,
+ testGuideFirstStep,
+ testGuideLastStep,
+ testGuideNotActiveState,
+ testGuideStep1InProgressState,
+ testGuideStep2InProgressState,
+ testIntegration,
+ wrongIntegration,
} from './api.mocks';
-const searchGuide = 'search';
-const firstStep = guidesConfig[searchGuide].steps[0].id;
-const lastStep = guidesConfig[searchGuide].steps[guidesConfig[searchGuide].steps.length - 1].id;
-
describe('GuidedOnboarding ApiService helpers', () => {
- // this test suite depends on the guides config
describe('isLastStepActive', () => {
it('returns true if the passed params are for the last step', () => {
- const result = isLastStep(searchGuide, lastStep);
+ const result = isLastStep(testGuide, testGuideLastStep);
expect(result).toBe(true);
});
it('returns false if the passed params are not for the last step', () => {
- const result = isLastStep(searchGuide, firstStep);
+ const result = isLastStep(testGuide, testGuideFirstStep);
expect(result).toBe(false);
});
});
describe('isIntegrationInGuideStep', () => {
it('return true if the integration is defined in the guide step config', () => {
- const result = isIntegrationInGuideStep(securityAddDataInProgressState, 'endpoint');
+ const result = isIntegrationInGuideStep(testGuideStep1InProgressState, testIntegration);
expect(result).toBe(true);
});
it('returns false if a different integration is defined in the guide step', () => {
- const result = isIntegrationInGuideStep(securityAddDataInProgressState, 'kubernetes');
+ const result = isIntegrationInGuideStep(testGuideStep1InProgressState, wrongIntegration);
expect(result).toBe(false);
});
it('returns false if no integration is defined in the guide step', () => {
- const result = isIntegrationInGuideStep(securityRulesActiveState, 'endpoint');
+ const result = isIntegrationInGuideStep(testGuideStep2InProgressState, testIntegration);
expect(result).toBe(false);
});
it('returns false if no guide is active', () => {
- const result = isIntegrationInGuideStep(noGuideActiveState, 'endpoint');
+ const result = isIntegrationInGuideStep(testGuideNotActiveState, testIntegration);
expect(result).toBe(false);
});
it('returns false if no integration passed', () => {
- const result = isIntegrationInGuideStep(securityAddDataInProgressState);
+ const result = isIntegrationInGuideStep(testGuideStep1InProgressState);
expect(result).toBe(false);
});
});
diff --git a/src/plugins/guided_onboarding/public/types.ts b/src/plugins/guided_onboarding/public/types.ts
index a6536e3caf114..3ff0507c494dc 100755
--- a/src/plugins/guided_onboarding/public/types.ts
+++ b/src/plugins/guided_onboarding/public/types.ts
@@ -9,6 +9,7 @@
import { Observable } from 'rxjs';
import { HttpSetup } from '@kbn/core/public';
import type { GuideState, GuideId, GuideStepIds, StepStatus } from '@kbn/guided-onboarding';
+import type { CloudStart } from '@kbn/cloud-plugin/public';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface GuidedOnboardingPluginSetup {}
@@ -17,6 +18,10 @@ export interface GuidedOnboardingPluginStart {
guidedOnboardingApi?: GuidedOnboardingApi;
}
+export interface AppPluginStartDependencies {
+ cloud?: CloudStart;
+}
+
export interface GuidedOnboardingApi {
setup: (httpClient: HttpSetup) => void;
fetchActiveGuideState$: () => Observable;
diff --git a/src/plugins/guided_onboarding/tsconfig.json b/src/plugins/guided_onboarding/tsconfig.json
index 4a024443419ad..2837b97459430 100644
--- a/src/plugins/guided_onboarding/tsconfig.json
+++ b/src/plugins/guided_onboarding/tsconfig.json
@@ -15,5 +15,6 @@
{
"path": "../kibana_react/tsconfig.json"
},
+ { "path": "../../../x-pack/plugins/cloud/tsconfig.json" },
]
}
diff --git a/src/plugins/home/public/application/components/__snapshots__/home.test.tsx.snap b/src/plugins/home/public/application/components/__snapshots__/home.test.tsx.snap
index 3cc05cb41c6f9..53df35833013f 100644
--- a/src/plugins/home/public/application/components/__snapshots__/home.test.tsx.snap
+++ b/src/plugins/home/public/application/components/__snapshots__/home.test.tsx.snap
@@ -28,8 +28,10 @@ exports[`home change home route should render a link to change the default route
"integrations": true,
},
},
+ "navigateToUrl": [MockFunction],
}
}
+ isCloudEnabled={false}
isDarkMode={false}
/>
@@ -37,8 +37,6 @@ exports[`AddData render 1`] = `
{
addBasePath={addBasePathMock}
application={applicationStartMock}
isDarkMode={false}
+ isCloudEnabled={false}
/>
);
expect(component).toMatchSnapshot();
diff --git a/src/plugins/home/public/application/components/add_data/add_data.tsx b/src/plugins/home/public/application/components/add_data/add_data.tsx
index 27f98a85ff4e8..a3cdbd9241020 100644
--- a/src/plugins/home/public/application/components/add_data/add_data.tsx
+++ b/src/plugins/home/public/application/components/add_data/add_data.tsx
@@ -29,9 +29,10 @@ interface Props {
addBasePath: (path: string) => string;
application: ApplicationStart;
isDarkMode: boolean;
+ isCloudEnabled: boolean;
}
-export const AddData: FC = ({ addBasePath, application, isDarkMode }) => {
+export const AddData: FC = ({ addBasePath, application, isDarkMode, isCloudEnabled }) => {
const { trackUiMetric } = getServices();
const canAccessIntegrations = application.capabilities.navLinks.integrations;
if (canAccessIntegrations) {
@@ -59,26 +60,47 @@ export const AddData: FC = ({ addBasePath, application, isDarkMode }) =>
-
+
+ {isCloudEnabled && (
+
+ {/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
+ {
+ trackUiMetric(METRIC_TYPE.CLICK, 'guided_onboarding_link');
+ }}
+ >
+
+
+
+ )}
{/* eslint-disable-next-line @elastic/eui/href-or-on-click */}
{
trackUiMetric(METRIC_TYPE.CLICK, 'home_tutorial_directory');
createAppNavigationHandler('/app/integrations/browse')(event);
}}
+ fullWidth
>
-
+
-
+
-
+
-
+
{
const { chromeServiceMock, applicationServiceMock } =
jest.requireActual('@kbn/core/public/mocks');
const { uiSettingsServiceMock } = jest.requireActual('@kbn/core-ui-settings-browser-mocks');
+ const { cloudMock } = jest.requireActual('@kbn/cloud-plugin/public/mocks');
const uiSettingsMock = uiSettingsServiceMock.createSetupContract();
uiSettingsMock.get.mockReturnValue(false);
return {
getServices: () => ({
+ cloud: cloudMock.createSetup(),
chrome: chromeServiceMock.createStartContract(),
application: applicationServiceMock.createStartContract(),
trackUiMetric: jest.fn(),
diff --git a/src/plugins/home/public/application/components/guided_onboarding/getting_started.tsx b/src/plugins/home/public/application/components/guided_onboarding/getting_started.tsx
index e63676ca3ca72..c82b200dfb6bd 100644
--- a/src/plugins/home/public/application/components/guided_onboarding/getting_started.tsx
+++ b/src/plugins/home/public/application/components/guided_onboarding/getting_started.tsx
@@ -21,6 +21,7 @@ import {
} from '@elastic/eui';
import { css } from '@emotion/react';
+import { useHistory } from 'react-router-dom';
import { METRIC_TYPE } from '@kbn/analytics';
import { i18n } from '@kbn/i18n';
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
@@ -45,9 +46,10 @@ const skipText = i18n.translate('home.guidedOnboarding.gettingStarted.skip.butto
});
export const GettingStarted = () => {
- const { application, trackUiMetric, chrome, guidedOnboardingService, http, uiSettings } =
+ const { application, trackUiMetric, chrome, guidedOnboardingService, http, uiSettings, cloud } =
getServices();
const [guidesState, setGuidesState] = useState([]);
+ const history = useHistory();
useEffect(() => {
chrome.setBreadcrumbs([
@@ -76,6 +78,12 @@ export const GettingStarted = () => {
fetchGuidesState();
}, [fetchGuidesState]);
+ useEffect(() => {
+ if (cloud?.isCloudEnabled === false) {
+ return history.push('/');
+ }
+ }, [cloud, history]);
+
const onSkip = () => {
trackUiMetric(METRIC_TYPE.CLICK, 'guided_onboarding__skipped');
// disable welcome screen on the home page
@@ -92,6 +100,7 @@ export const GettingStarted = () => {
await guidedOnboardingService?.activateGuide(useCase as GuideId, guideState);
// TODO error handling https://github.com/elastic/kibana/issues/139798
};
+
return (
@@ -109,7 +118,7 @@ export const GettingStarted = () => {
{['search', 'observability', 'observabilityLink', 'security'].map((useCase) => {
if (useCase === 'observabilityLink') {
return (
-
+
{
);
}
return (
-
+
({
getServices: () => ({
getBasePath: () => 'path',
@@ -23,6 +24,7 @@ jest.mock('../kibana_services', () => ({
setBreadcrumbs: () => {},
},
application: {
+ navigateToUrl: mockNavigateToUrl,
capabilities: {
navLinks: {
integrations: mockHasIntegrationsPermission,
@@ -59,6 +61,7 @@ describe('home', () => {
return `base_path/${url}`;
},
hasUserDataView: jest.fn(async () => true),
+ isCloudEnabled: false,
};
});
@@ -230,6 +233,16 @@ describe('home', () => {
expect(component.find(Welcome).exists()).toBe(false);
});
+
+ test('should redirect to guided onboarding on Cloud instead of welcome screen', async () => {
+ const isCloudEnabled = true;
+ const hasUserDataView = jest.fn(async () => false);
+
+ const component = await renderHome({ isCloudEnabled, hasUserDataView });
+
+ expect(component.find(Welcome).exists()).toBe(false);
+ expect(mockNavigateToUrl).toHaveBeenCalledTimes(1);
+ });
});
describe('isNewKibanaInstance', () => {
diff --git a/src/plugins/home/public/application/components/home.tsx b/src/plugins/home/public/application/components/home.tsx
index f6b579213d420..707ea99ad8af4 100644
--- a/src/plugins/home/public/application/components/home.tsx
+++ b/src/plugins/home/public/application/components/home.tsx
@@ -33,6 +33,7 @@ export interface HomeProps {
localStorage: Storage;
urlBasePath: string;
hasUserDataView: () => Promise;
+ isCloudEnabled: boolean;
}
interface State {
@@ -126,7 +127,7 @@ export class Home extends Component {
}
private renderNormal() {
- const { addBasePath, solutions } = this.props;
+ const { addBasePath, solutions, isCloudEnabled } = this.props;
const { application, trackUiMetric } = getServices();
const isDarkMode = getServices().uiSettings?.get('theme:darkMode') || false;
const devTools = this.findDirectoryById('console');
@@ -148,7 +149,12 @@ export class Home extends Component {
>
-
+
{
public render() {
const { isLoading, isWelcomeEnabled, isNewKibanaInstance } = this.state;
+ const { isCloudEnabled } = this.props;
+ const { application } = getServices();
if (isWelcomeEnabled) {
if (isLoading) {
return this.renderLoading();
}
if (isNewKibanaInstance) {
+ if (isCloudEnabled) {
+ application.navigateToUrl('./home#/getting_started');
+ return;
+ }
return this.renderWelcome();
}
}
diff --git a/src/plugins/home/public/application/components/home_app.js b/src/plugins/home/public/application/components/home_app.js
index af7b1dec48669..a6cdfec3b62e9 100644
--- a/src/plugins/home/public/application/components/home_app.js
+++ b/src/plugins/home/public/application/components/home_app.js
@@ -79,6 +79,7 @@ export function HomeApp({ directories, solutions }) {
localStorage={localStorage}
urlBasePath={getBasePath()}
hasUserDataView={() => dataViewsService.hasUserDataView()}
+ isCloudEnabled={isCloudEnabled}
/>
diff --git a/src/plugins/home/public/application/components/sample_data/index.tsx b/src/plugins/home/public/application/components/sample_data/index.tsx
index 8ce7a32b66e08..316ba615ce818 100644
--- a/src/plugins/home/public/application/components/sample_data/index.tsx
+++ b/src/plugins/home/public/application/components/sample_data/index.tsx
@@ -45,7 +45,7 @@ export function SampleDataCard({ urlBasePath, onDecline, onConfirm }: Props) {
description={
}
footer={
diff --git a/src/plugins/home/public/application/kibana_services.ts b/src/plugins/home/public/application/kibana_services.ts
index b622cf862f315..af0a94b232fe6 100644
--- a/src/plugins/home/public/application/kibana_services.ts
+++ b/src/plugins/home/public/application/kibana_services.ts
@@ -21,6 +21,7 @@ import { UrlForwardingStart } from '@kbn/url-forwarding-plugin/public';
import { DataViewsContract } from '@kbn/data-views-plugin/public';
import { SharePluginSetup } from '@kbn/share-plugin/public';
import { GuidedOnboardingApi } from '@kbn/guided-onboarding-plugin/public';
+import { CloudSetup } from '@kbn/cloud-plugin/public';
import { TutorialService } from '../services/tutorials';
import { AddDataService } from '../services/add_data';
import { FeatureCatalogueRegistry } from '../services/feature_catalogue';
@@ -51,6 +52,7 @@ export interface HomeKibanaServices {
addDataService: AddDataService;
welcomeService: WelcomeService;
guidedOnboardingService?: GuidedOnboardingApi;
+ cloud?: CloudSetup;
}
let services: HomeKibanaServices | null = null;
diff --git a/src/plugins/home/public/plugin.ts b/src/plugins/home/public/plugin.ts
index c85f920fca6e1..b7270058aae6c 100644
--- a/src/plugins/home/public/plugin.ts
+++ b/src/plugins/home/public/plugin.ts
@@ -105,6 +105,7 @@ export class HomePublicPlugin
featureCatalogue: this.featuresCatalogueRegistry,
welcomeService: this.welcomeService,
guidedOnboardingService: guidedOnboarding.guidedOnboardingApi,
+ cloud,
});
coreStart.chrome.docTitle.change(
i18n.translate('home.pageTitle', { defaultMessage: 'Home' })
diff --git a/src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx b/src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx
index c70f1df820252..07d35b78b58a2 100755
--- a/src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx
+++ b/src/plugins/unified_field_list/public/components/field_stats/field_stats.tsx
@@ -75,7 +75,7 @@ export interface FieldStatsProps {
'data-test-subj'?: string;
overrideMissingContent?: (params: {
element: JSX.Element;
- noDataFound?: boolean;
+ reason: 'no-data' | 'unsupported';
}) => JSX.Element | null;
overrideFooter?: (params: {
element: JSX.Element;
@@ -304,7 +304,7 @@ const FieldStatsComponent: React.FC = ({
return overrideMissingContent
? overrideMissingContent({
- noDataFound: false,
+ reason: 'unsupported',
element: messageNoAnalysis,
})
: messageNoAnalysis;
@@ -338,7 +338,7 @@ const FieldStatsComponent: React.FC = ({
return overrideMissingContent
? overrideMissingContent({
- noDataFound: true,
+ reason: 'no-data',
element: messageNoData,
})
: messageNoData;
@@ -358,12 +358,14 @@ const FieldStatsComponent: React.FC = ({
defaultMessage: 'Top values',
}),
id: 'topValues',
+ 'data-test-subj': `${dataTestSubject}-buttonGroup-topValuesButton`,
},
{
label: i18n.translate('unifiedFieldList.fieldStats.fieldDistributionLabel', {
defaultMessage: 'Distribution',
}),
id: 'histogram',
+ 'data-test-subj': `${dataTestSubject}-buttonGroup-distributionButton`,
},
]}
onChange={(optionId: string) => {
diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts
index 907fe458c6a64..5d6dc036a7bd0 100644
--- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts
+++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.test.ts
@@ -47,6 +47,11 @@ describe('convertToStaticValueColumn', () => {
[{ series, metrics: [metric], dataView }, { visibleSeriesCount: 1 }],
null,
],
+ [
+ 'null if value is not specified',
+ [{ series, metrics: [metric], dataView }, { visibleSeriesCount: 2 }],
+ null,
+ ],
[
'static value column',
[{ series, metrics: [{ ...metric, value: 'some value' }], dataView }],
diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts
index d3e6aef09b1cf..7990107bb5bf9 100644
--- a/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts
+++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/lib/convert/static_value.ts
@@ -32,6 +32,9 @@ export const convertToStaticValueColumn = (
return null;
}
const currentMetric = metrics[metrics.length - 1];
+ if (!currentMetric.value) {
+ return null;
+ }
return {
operationType: 'static_value',
references: [],
@@ -68,7 +71,10 @@ export const convertStaticValueToFormulaColumn = (
return null;
}
const currentMetric = metrics[metrics.length - 1];
- return createFormulaColumn(currentMetric.value ?? '', {
+ if (!currentMetric.value) {
+ return null;
+ }
+ return createFormulaColumn(currentMetric.value, {
series,
metric: currentMetric,
dataView,
diff --git a/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.ts b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.ts
index fbf04a2dcf779..8577623b8bd93 100644
--- a/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.ts
+++ b/src/plugins/vis_types/timeseries/public/convert_to_lens/metric/index.ts
@@ -30,7 +30,8 @@ export const convertToLens: ConvertTsvbToLensVisualization = async (
const seriesNum = model.series.filter((series) => !series.hidden).length;
const indexPatternIds = new Set();
- const visibleSeries = model.series.filter(({ hidden }) => !hidden);
+ // we should get max only 2 series
+ const visibleSeries = model.series.filter(({ hidden }) => !hidden).slice(0, 2);
let currentIndexPattern: DataView | null = null;
for (const series of visibleSeries) {
const datasourceInfo = await getDataSourceInfo(
diff --git a/x-pack/examples/screenshotting_example/server/plugin.ts b/x-pack/examples/screenshotting_example/server/plugin.ts
index 9ca74c6e16353..16a766558ff3f 100644
--- a/x-pack/examples/screenshotting_example/server/plugin.ts
+++ b/x-pack/examples/screenshotting_example/server/plugin.ts
@@ -38,6 +38,7 @@ export class ScreenshottingExamplePlugin implements Plugin {
);
return response.ok({
+ headers: { 'content-type': 'application/json' },
body: JSON.stringify({
metrics,
image: results[0]?.screenshots[0]?.data.toString('base64'),
diff --git a/x-pack/plugins/aiops/server/routes/queries/fetch_frequent_items.ts b/x-pack/plugins/aiops/server/routes/queries/fetch_frequent_items.ts
index aaf9af283c3e1..362cae07273e5 100644
--- a/x-pack/plugins/aiops/server/routes/queries/fetch_frequent_items.ts
+++ b/x-pack/plugins/aiops/server/routes/queries/fetch_frequent_items.ts
@@ -13,6 +13,8 @@ import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import type { Logger } from '@kbn/logging';
import type { ChangePoint, FieldValuePair } from '@kbn/ml-agg-utils';
+const FREQUENT_ITEMS_FIELDS_LIMIT = 15;
+
interface FrequentItemsAggregation extends estypes.AggregationsSamplerAggregation {
fi: {
buckets: Array<{ key: Record; doc_count: number; support: number }>;
@@ -59,10 +61,19 @@ export async function fetchFrequentItems(
emitError: (m: string) => void,
abortSignal?: AbortSignal
) {
- // get unique fields from change points
- const fields = [...new Set(changePoints.map((t) => t.fieldName))];
+ // Sort change points by ascending p-value, necessary to apply the field limit correctly.
+ const sortedChangePoints = changePoints.slice().sort((a, b) => {
+ return (a.pValue ?? 0) - (b.pValue ?? 0);
+ });
+
+ // Get up to 15 unique fields from change points with retained order
+ const fields = sortedChangePoints.reduce((p, c) => {
+ if (p.length < FREQUENT_ITEMS_FIELDS_LIMIT && !p.some((d) => d === c.fieldName)) {
+ p.push(c.fieldName);
+ }
+ return p;
+ }, []);
- // TODO add query params
const query = {
bool: {
minimum_should_match: 2,
@@ -77,7 +88,7 @@ export async function fetchFrequentItems(
},
},
],
- should: changePoints.map((t) => {
+ should: sortedChangePoints.map((t) => {
return { term: { [t.fieldName]: t.fieldValue } };
}),
},
@@ -117,16 +128,18 @@ export async function fetchFrequentItems(
},
};
+ const esBody = {
+ query,
+ aggs,
+ size: 0,
+ track_total_hits: true,
+ };
+
const body = await client.search(
{
index,
size: 0,
- body: {
- query,
- aggs,
- size: 0,
- track_total_hits: true,
- },
+ body: esBody,
},
{ signal: abortSignal, maxRetries: 0 }
);
@@ -167,7 +180,7 @@ export async function fetchFrequentItems(
Object.entries(fis.key).forEach(([key, value]) => {
result.set[key] = value[0];
- const pValue = changePoints.find(
+ const pValue = sortedChangePoints.find(
(t) => t.fieldName === key && t.fieldValue === value[0]
)?.pValue;
diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts
index f1917a079a26d..9326f30dd7828 100644
--- a/x-pack/plugins/alerting/server/types.ts
+++ b/x-pack/plugins/alerting/server/types.ts
@@ -90,21 +90,21 @@ export interface RuleExecutorOptions<
InstanceContext extends AlertInstanceContext = never,
ActionGroupIds extends string = never
> {
- alertId: string;
+ alertId: string; // Is actually the Rule ID. Will be updated as part of https://github.com/elastic/kibana/issues/100115
+ createdBy: string | null;
executionId: string;
- startedAt: Date;
- previousStartedAt: Date | null;
- services: RuleExecutorServices;
+ logger: Logger;
+ name: string;
params: Params;
- state: State;
+ previousStartedAt: Date | null;
rule: SanitizedRuleConfig;
+ services: RuleExecutorServices;
spaceId: string;
- namespace?: string;
- name: string;
+ startedAt: Date;
+ state: State;
tags: string[];
- createdBy: string | null;
updatedBy: string | null;
- logger: Logger;
+ namespace?: string;
}
export interface RuleParamsAndRefs {
diff --git a/x-pack/plugins/apm/common/tutorial/instructions/apm_agent_instructions.ts b/x-pack/plugins/apm/common/tutorial/instructions/apm_agent_instructions.ts
index b1c5fc79816ac..9406942f85179 100644
--- a/x-pack/plugins/apm/common/tutorial/instructions/apm_agent_instructions.ts
+++ b/x-pack/plugins/apm/common/tutorial/instructions/apm_agent_instructions.ts
@@ -519,10 +519,12 @@ export const createDotNetAgentInstructions = (
defaultMessage:
'In case you don’t pass an `IConfiguration` instance to the agent (e.g. in case of non ASP.NET Core applications) \
you can also configure the agent through environment variables. \n \
- See [the documentation]({documentationLink}) for advanced usage.',
+ See [the documentation]({documentationLink}) for advanced usage, including the [Profiler Auto instrumentation]({profilerLink}) quick start.',
values: {
documentationLink:
'{config.docs.base_url}guide/en/apm/agent/dotnet/current/configuration.html',
+ profilerLink:
+ '{config.docs.base_url}guide/en/apm/agent/dotnet/current/setup-auto-instrumentation.html#setup-auto-instrumentation',
},
}
),
diff --git a/x-pack/plugins/apm/public/tutorial/config_agent/agent_config_instructions.tsx b/x-pack/plugins/apm/public/tutorial/config_agent/agent_config_instructions.tsx
index c7244002e59f5..0e4ad1f3f44a0 100644
--- a/x-pack/plugins/apm/public/tutorial/config_agent/agent_config_instructions.tsx
+++ b/x-pack/plugins/apm/public/tutorial/config_agent/agent_config_instructions.tsx
@@ -25,7 +25,7 @@ export function AgentConfigInstructions({
}) {
const defaultValues = {
apmServiceName: 'my-service-name',
- apmEnvironment: 'production',
+ apmEnvironment: 'my-environment',
};
if (variantId === 'openTelemetry') {
@@ -60,7 +60,11 @@ export function AgentConfigInstructions({
/>
-
+
{commands}
>
diff --git a/x-pack/plugins/apm/public/tutorial/config_agent/commands/django.ts b/x-pack/plugins/apm/public/tutorial/config_agent/commands/django.ts
index 4379f15c59cde..15279a71a6573 100644
--- a/x-pack/plugins/apm/public/tutorial/config_agent/commands/django.ts
+++ b/x-pack/plugins/apm/public/tutorial/config_agent/commands/django.ts
@@ -9,8 +9,8 @@ import { i18n } from '@kbn/i18n';
export const djangoVariables = {
apmServiceName: 'SERVICE_NAME',
- apmServerUrl: 'SERVER_URL',
secretToken: 'SECRET_TOKEN',
+ apmServerUrl: 'SERVER_URL',
apmEnvironment: 'ENVIRONMENT',
};
@@ -21,50 +21,50 @@ export const django = `# ${i18n.translate(
}
)}
INSTALLED_APPS = (
-'elasticapm.contrib.django',
-# ...
+ 'elasticapm.contrib.django',
+ # ...
)
ELASTIC_APM = {
-# ${i18n.translate(
- 'xpack.apm.tutorial.djangoClient.configure.commands.setRequiredServiceNameComment',
- {
- defaultMessage: 'Set the required service name. Allowed characters:',
- }
-)}
-# ${i18n.translate(
- 'xpack.apm.tutorial.djangoClient.configure.commands.allowedCharactersComment',
- {
- defaultMessage: 'a-z, A-Z, 0-9, -, _, and space',
- }
-)}
-#'${djangoVariables.apmServiceName}': '{{{apmServiceName}}}',
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.djangoClient.configure.commands.setRequiredServiceNameComment',
+ {
+ defaultMessage: 'Set the required service name. Allowed characters:',
+ }
+ )}
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.djangoClient.configure.commands.allowedCharactersComment',
+ {
+ defaultMessage: 'a-z, A-Z, 0-9, -, _, and space',
+ }
+ )}
+ #'${djangoVariables.apmServiceName}': '{{{apmServiceName}}}',
-# ${i18n.translate(
- 'xpack.apm.tutorial.djangoClient.configure.commands.useIfApmServerRequiresTokenComment',
- {
- defaultMessage: 'Use if APM Server requires a secret token',
- }
-)}
-'${djangoVariables.secretToken}': '{{{secretToken}}}',
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.djangoClient.configure.commands.useIfApmServerRequiresTokenComment',
+ {
+ defaultMessage: 'Use if APM Server requires a secret token',
+ }
+ )}
+ '${djangoVariables.secretToken}': '{{{secretToken}}}',
-# ${i18n.translate(
- 'xpack.apm.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment',
- {
- defaultMessage:
- 'Set the custom APM Server URL (default: {defaultApmServerUrl})',
- values: { defaultApmServerUrl: 'http://localhost:8200' },
- }
-)}
-'${djangoVariables.apmServerUrl}': '{{{apmServerUrl}}}',
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment',
+ {
+ defaultMessage:
+ 'Set the custom APM Server URL (default: {defaultApmServerUrl})',
+ values: { defaultApmServerUrl: 'http://localhost:8200' },
+ }
+ )}
+ '${djangoVariables.apmServerUrl}': '{{{apmServerUrl}}}',
-# ${i18n.translate(
- 'xpack.apm.tutorial.djangoClient.configure.commands.setServiceEnvironmentComment',
- {
- defaultMessage: 'Set the service environment',
- }
-)}
-'${djangoVariables.apmEnvironment}': '{{{apmEnvironment}}}',
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.djangoClient.configure.commands.setServiceEnvironmentComment',
+ {
+ defaultMessage: 'Set the service environment',
+ }
+ )}
+ '${djangoVariables.apmEnvironment}': '{{{apmEnvironment}}}',
}
# ${i18n.translate(
@@ -74,6 +74,6 @@ ELASTIC_APM = {
}
)}
MIDDLEWARE = (
-'elasticapm.contrib.django.middleware.TracingMiddleware',
-#...
+ 'elasticapm.contrib.django.middleware.TracingMiddleware',
+ #...
)`;
diff --git a/x-pack/plugins/apm/public/tutorial/config_agent/commands/flask.ts b/x-pack/plugins/apm/public/tutorial/config_agent/commands/flask.ts
index 11423c4e059db..a6289c0a88c1b 100644
--- a/x-pack/plugins/apm/public/tutorial/config_agent/commands/flask.ts
+++ b/x-pack/plugins/apm/public/tutorial/config_agent/commands/flask.ts
@@ -33,45 +33,45 @@ apm = ElasticAPM(app)
)}
from elasticapm.contrib.flask import ElasticAPM
app.config['ELASTIC_APM'] = {
-# ${i18n.translate(
- 'xpack.apm.tutorial.flaskClient.configure.commands.setRequiredServiceNameComment',
- {
- defaultMessage: 'Set the required service name. Allowed characters:',
- }
-)}
-# ${i18n.translate(
- 'xpack.apm.tutorial.flaskClient.configure.commands.allowedCharactersComment',
- {
- defaultMessage: 'a-z, A-Z, 0-9, -, _, and space',
- }
-)}
-#'${flaskVariables.apmServiceName}': '{{{apmServiceName}}}',
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.flaskClient.configure.commands.setRequiredServiceNameComment',
+ {
+ defaultMessage: 'Set the required service name. Allowed characters:',
+ }
+ )}
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.flaskClient.configure.commands.allowedCharactersComment',
+ {
+ defaultMessage: 'a-z, A-Z, 0-9, -, _, and space',
+ }
+ )}
+ #'${flaskVariables.apmServiceName}': '{{{apmServiceName}}}',
-# ${i18n.translate(
- 'xpack.apm.tutorial.flaskClient.configure.commands.useIfApmServerRequiresTokenComment',
- {
- defaultMessage: 'Use if APM Server requires a secret token',
- }
-)}
-'${flaskVariables.secretToken}': '{{{secretToken}}}',
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.flaskClient.configure.commands.useIfApmServerRequiresTokenComment',
+ {
+ defaultMessage: 'Use if APM Server requires a secret token',
+ }
+ )}
+ '${flaskVariables.secretToken}': '{{{secretToken}}}',
-# ${i18n.translate(
- 'xpack.apm.tutorial.flaskClient.configure.commands.setCustomApmServerUrlComment',
- {
- defaultMessage:
- 'Set the custom APM Server URL (default: {defaultApmServerUrl})',
- values: { defaultApmServerUrl: 'http://localhost:8200' },
- }
-)}
-'${flaskVariables.apmServerUrl}': '{{{apmServerUrl}}}',
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.flaskClient.configure.commands.setCustomApmServerUrlComment',
+ {
+ defaultMessage:
+ 'Set the custom APM Server URL (default: {defaultApmServerUrl})',
+ values: { defaultApmServerUrl: 'http://localhost:8200' },
+ }
+ )}
+ '${flaskVariables.apmServerUrl}': '{{{apmServerUrl}}}',
-# ${i18n.translate(
- 'xpack.apm.tutorial.flaskClient.configure.commands.setServiceEnvironmentComment',
- {
- defaultMessage: 'Set the service environment',
- }
-)}
-'${flaskVariables.apmEnvironment}': '{{{apmEnvironment}}}',
+ # ${i18n.translate(
+ 'xpack.apm.tutorial.flaskClient.configure.commands.setServiceEnvironmentComment',
+ {
+ defaultMessage: 'Set the service environment',
+ }
+ )}
+ '${flaskVariables.apmEnvironment}': '{{{apmEnvironment}}}',
}
apm = ElasticAPM(app)`;
diff --git a/x-pack/plugins/apm/public/tutorial/config_agent/commands/get_apm_agent_commands.test.ts b/x-pack/plugins/apm/public/tutorial/config_agent/commands/get_apm_agent_commands.test.ts
index efbcfae955a55..d01d3acc5d519 100644
--- a/x-pack/plugins/apm/public/tutorial/config_agent/commands/get_apm_agent_commands.test.ts
+++ b/x-pack/plugins/apm/public/tutorial/config_agent/commands/get_apm_agent_commands.test.ts
@@ -10,7 +10,7 @@ import { getApmAgentCommands } from './get_apm_agent_commands';
describe('getCommands', () => {
const defaultValues = {
apmServiceName: 'my-service-name',
- apmEnvironment: 'production',
+ apmEnvironment: 'my-environment',
};
describe('unknown agent', () => {
it('renders empty command', () => {
@@ -37,7 +37,7 @@ describe('getCommands', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.server_url= \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -57,7 +57,7 @@ describe('getCommands', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token=foobar \\\\
-Delastic.apm.server_url=localhost:8220 \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -85,7 +85,7 @@ describe('getCommands', () => {
serviceVersion: '',
// Set the service environment
- environment: 'production'
+ environment: 'my-environment'
})"
`);
});
@@ -113,7 +113,7 @@ describe('getCommands', () => {
serviceVersion: '',
// Set the service environment
- environment: 'production'
+ environment: 'my-environment'
})"
`);
});
@@ -130,18 +130,18 @@ describe('getCommands', () => {
"// Add this to the VERY top of the first file loaded in your app
var apm = require('elastic-apm-node').start({
- // Override the service name from package.json
- // Allowed characters: a-z, A-Z, 0-9, -, _, and space
- serviceName: 'my-service-name',
+ // Override the service name from package.json
+ // Allowed characters: a-z, A-Z, 0-9, -, _, and space
+ serviceName: 'my-service-name',
- // Use if APM Server requires a secret token
- secretToken: '',
+ // Use if APM Server requires a secret token
+ secretToken: '',
- // Set the custom APM Server URL (default: http://localhost:8200)
- serverUrl: '',
+ // Set the custom APM Server URL (default: http://localhost:8200)
+ serverUrl: '',
- // Set the service environment
- environment: 'production'
+ // Set the service environment
+ environment: 'my-environment'
})"
`);
});
@@ -159,18 +159,18 @@ describe('getCommands', () => {
"// Add this to the VERY top of the first file loaded in your app
var apm = require('elastic-apm-node').start({
- // Override the service name from package.json
- // Allowed characters: a-z, A-Z, 0-9, -, _, and space
- serviceName: 'my-service-name',
+ // Override the service name from package.json
+ // Allowed characters: a-z, A-Z, 0-9, -, _, and space
+ serviceName: 'my-service-name',
- // Use if APM Server requires a secret token
- secretToken: 'foobar',
+ // Use if APM Server requires a secret token
+ secretToken: 'foobar',
- // Set the custom APM Server URL (default: http://localhost:8200)
- serverUrl: 'localhost:8220',
+ // Set the custom APM Server URL (default: http://localhost:8200)
+ serverUrl: 'localhost:8220',
- // Set the service environment
- environment: 'production'
+ // Set the service environment
+ environment: 'my-environment'
})"
`);
});
@@ -186,29 +186,29 @@ describe('getCommands', () => {
expect(commands).toMatchInlineSnapshot(`
"# Add the agent to the installed apps
INSTALLED_APPS = (
- 'elasticapm.contrib.django',
- # ...
+ 'elasticapm.contrib.django',
+ # ...
)
ELASTIC_APM = {
- # Set the required service name. Allowed characters:
- # a-z, A-Z, 0-9, -, _, and space
- #'SERVICE_NAME': 'my-service-name',
+ # Set the required service name. Allowed characters:
+ # a-z, A-Z, 0-9, -, _, and space
+ #'SERVICE_NAME': 'my-service-name',
- # Use if APM Server requires a secret token
- 'SECRET_TOKEN': '',
+ # Use if APM Server requires a secret token
+ 'SECRET_TOKEN': '',
- # Set the custom APM Server URL (default: http://localhost:8200)
- 'SERVER_URL': '',
+ # Set the custom APM Server URL (default: http://localhost:8200)
+ 'SERVER_URL': '',
- # Set the service environment
- 'ENVIRONMENT': 'production',
+ # Set the service environment
+ 'ENVIRONMENT': 'my-environment',
}
# To send performance metrics, add our tracing middleware:
MIDDLEWARE = (
- 'elasticapm.contrib.django.middleware.TracingMiddleware',
- #...
+ 'elasticapm.contrib.django.middleware.TracingMiddleware',
+ #...
)"
`);
});
@@ -225,29 +225,29 @@ describe('getCommands', () => {
expect(commands).toMatchInlineSnapshot(`
"# Add the agent to the installed apps
INSTALLED_APPS = (
- 'elasticapm.contrib.django',
- # ...
+ 'elasticapm.contrib.django',
+ # ...
)
ELASTIC_APM = {
- # Set the required service name. Allowed characters:
- # a-z, A-Z, 0-9, -, _, and space
- #'SERVICE_NAME': 'my-service-name',
+ # Set the required service name. Allowed characters:
+ # a-z, A-Z, 0-9, -, _, and space
+ #'SERVICE_NAME': 'my-service-name',
- # Use if APM Server requires a secret token
- 'SECRET_TOKEN': 'foobar',
+ # Use if APM Server requires a secret token
+ 'SECRET_TOKEN': 'foobar',
- # Set the custom APM Server URL (default: http://localhost:8200)
- 'SERVER_URL': 'localhost:8220',
+ # Set the custom APM Server URL (default: http://localhost:8200)
+ 'SERVER_URL': 'localhost:8220',
- # Set the service environment
- 'ENVIRONMENT': 'production',
+ # Set the service environment
+ 'ENVIRONMENT': 'my-environment',
}
# To send performance metrics, add our tracing middleware:
MIDDLEWARE = (
- 'elasticapm.contrib.django.middleware.TracingMiddleware',
- #...
+ 'elasticapm.contrib.django.middleware.TracingMiddleware',
+ #...
)"
`);
});
@@ -269,18 +269,18 @@ describe('getCommands', () => {
# or configure to use ELASTIC_APM in your application's settings
from elasticapm.contrib.flask import ElasticAPM
app.config['ELASTIC_APM'] = {
- # Set the required service name. Allowed characters:
- # a-z, A-Z, 0-9, -, _, and space
- #'SERVICE_NAME': 'my-service-name',
+ # Set the required service name. Allowed characters:
+ # a-z, A-Z, 0-9, -, _, and space
+ #'SERVICE_NAME': 'my-service-name',
- # Use if APM Server requires a secret token
- 'SECRET_TOKEN': '',
+ # Use if APM Server requires a secret token
+ 'SECRET_TOKEN': '',
- # Set the custom APM Server URL (default: http://localhost:8200)
- 'SERVER_URL': '',
+ # Set the custom APM Server URL (default: http://localhost:8200)
+ 'SERVER_URL': '',
- # Set the service environment
- 'ENVIRONMENT': 'production',
+ # Set the service environment
+ 'ENVIRONMENT': 'my-environment',
}
apm = ElasticAPM(app)"
@@ -305,18 +305,18 @@ describe('getCommands', () => {
# or configure to use ELASTIC_APM in your application's settings
from elasticapm.contrib.flask import ElasticAPM
app.config['ELASTIC_APM'] = {
- # Set the required service name. Allowed characters:
- # a-z, A-Z, 0-9, -, _, and space
- #'SERVICE_NAME': 'my-service-name',
+ # Set the required service name. Allowed characters:
+ # a-z, A-Z, 0-9, -, _, and space
+ #'SERVICE_NAME': 'my-service-name',
- # Use if APM Server requires a secret token
- 'SECRET_TOKEN': 'foobar',
+ # Use if APM Server requires a secret token
+ 'SECRET_TOKEN': 'foobar',
- # Set the custom APM Server URL (default: http://localhost:8200)
- 'SERVER_URL': 'localhost:8220',
+ # Set the custom APM Server URL (default: http://localhost:8200)
+ 'SERVER_URL': 'localhost:8220',
- # Set the service environment
- 'ENVIRONMENT': 'production',
+ # Set the service environment
+ 'ENVIRONMENT': 'my-environment',
}
apm = ElasticAPM(app)"
@@ -345,7 +345,7 @@ describe('getCommands', () => {
server_url: ''
# Set the service environment
- environment: 'production'"
+ environment: 'my-environment'"
`);
});
it('renders with secret token and url', () => {
@@ -372,7 +372,7 @@ describe('getCommands', () => {
server_url: 'localhost:8220'
# Set the service environment
- environment: 'production'"
+ environment: 'my-environment'"
`);
});
});
@@ -398,7 +398,7 @@ describe('getCommands', () => {
server_url: '',
# Set the service environment
- environment: 'production'"
+ environment: 'my-environment'"
`);
});
it('renders with secret token and url', () => {
@@ -425,7 +425,7 @@ describe('getCommands', () => {
server_url: 'localhost:8220',
# Set the service environment
- environment: 'production'"
+ environment: 'my-environment'"
`);
});
});
@@ -451,7 +451,7 @@ describe('getCommands', () => {
export ELASTIC_APM_SERVER_URL=
# Set the service environment
- export ELASTIC_APM_ENVIRONMENT=production
+ export ELASTIC_APM_ENVIRONMENT=my-environment
"
`);
});
@@ -479,7 +479,7 @@ describe('getCommands', () => {
export ELASTIC_APM_SERVER_URL=localhost:8220
# Set the service environment
- export ELASTIC_APM_ENVIRONMENT=production
+ export ELASTIC_APM_ENVIRONMENT=my-environment
"
`);
});
@@ -498,7 +498,7 @@ describe('getCommands', () => {
\\"ServiceName\\": \\"my-service-name\\", //allowed characters: a-z, A-Z, 0-9, -, _, and space. Default is the entry assembly of the application
\\"SecretToken\\": \\"\\",
\\"ServerUrl\\": \\"\\", //Set custom APM Server URL (default: http://localhost:8200)
- \\"Environment\\": \\"production\\", // Set the service environment
+ \\"Environment\\": \\"my-environment\\", // Set the service environment
}
}"
`);
@@ -519,7 +519,7 @@ describe('getCommands', () => {
\\"ServiceName\\": \\"my-service-name\\", //allowed characters: a-z, A-Z, 0-9, -, _, and space. Default is the entry assembly of the application
\\"SecretToken\\": \\"foobar\\",
\\"ServerUrl\\": \\"localhost:8220\\", //Set custom APM Server URL (default: http://localhost:8200)
- \\"Environment\\": \\"production\\", // Set the service environment
+ \\"Environment\\": \\"my-environment\\", // Set the service environment
}
}"
`);
@@ -537,7 +537,7 @@ describe('getCommands', () => {
"elastic_apm.service_name=\\"my-service-name\\"
elastic_apm.secret_token=\\"\\"
elastic_apm.server_url=\\"\\"
- elastic_apm.environment=\\"production\\"
+ elastic_apm.environment=\\"my-environment\\"
"
`);
});
@@ -555,7 +555,7 @@ describe('getCommands', () => {
"elastic_apm.service_name=\\"my-service-name\\"
elastic_apm.secret_token=\\"foobar\\"
elastic_apm.server_url=\\"localhost:8220\\"
- elastic_apm.environment=\\"production\\"
+ elastic_apm.environment=\\"my-environment\\"
"
`);
});
diff --git a/x-pack/plugins/apm/public/tutorial/config_agent/commands/java.ts b/x-pack/plugins/apm/public/tutorial/config_agent/commands/java.ts
index 2d056b3a242f3..4edcb6aab2170 100644
--- a/x-pack/plugins/apm/public/tutorial/config_agent/commands/java.ts
+++ b/x-pack/plugins/apm/public/tutorial/config_agent/commands/java.ts
@@ -16,6 +16,6 @@ export const java = `java -javaagent:/path/to/elastic-apm-agent-.jar \\
-${javaVariables.apmServiceName}={{{apmServiceName}}} \\
-${javaVariables.secretToken}={{{secretToken}}} \\
-${javaVariables.apmServerUrl}={{{apmServerUrl}}} \\
--${javaVariables.apmEnvironment}=production \\
+-${javaVariables.apmEnvironment}={{{apmEnvironment}}} \\
-Delastic.apm.application_packages=org.example \\
-jar {{{apmServiceName}}}.jar`;
diff --git a/x-pack/plugins/apm/public/tutorial/config_agent/commands/node.ts b/x-pack/plugins/apm/public/tutorial/config_agent/commands/node.ts
index 8b8ba07a7cb9c..2510599cff94e 100644
--- a/x-pack/plugins/apm/public/tutorial/config_agent/commands/node.ts
+++ b/x-pack/plugins/apm/public/tutorial/config_agent/commands/node.ts
@@ -22,43 +22,43 @@ export const node = `// ${i18n.translate(
)}
var apm = require('elastic-apm-node').start({
-// ${i18n.translate(
- 'xpack.apm.tutorial.nodeClient.configure.commands.setRequiredServiceNameComment',
- {
- defaultMessage: 'Override the service name from package.json',
- }
-)}
-// ${i18n.translate(
- 'xpack.apm.tutorial.nodeClient.configure.commands.allowedCharactersComment',
- {
- defaultMessage: 'Allowed characters: a-z, A-Z, 0-9, -, _, and space',
- }
-)}
-${nodeVariables.apmServiceName}: '{{{apmServiceName}}}',
+ // ${i18n.translate(
+ 'xpack.apm.tutorial.nodeClient.configure.commands.setRequiredServiceNameComment',
+ {
+ defaultMessage: 'Override the service name from package.json',
+ }
+ )}
+ // ${i18n.translate(
+ 'xpack.apm.tutorial.nodeClient.configure.commands.allowedCharactersComment',
+ {
+ defaultMessage: 'Allowed characters: a-z, A-Z, 0-9, -, _, and space',
+ }
+ )}
+ ${nodeVariables.apmServiceName}: '{{{apmServiceName}}}',
-// ${i18n.translate(
- 'xpack.apm.tutorial.nodeClient.configure.commands.useIfApmRequiresTokenComment',
- {
- defaultMessage: 'Use if APM Server requires a secret token',
- }
-)}
-${nodeVariables.secretToken}: '{{{secretToken}}}',
+ // ${i18n.translate(
+ 'xpack.apm.tutorial.nodeClient.configure.commands.useIfApmRequiresTokenComment',
+ {
+ defaultMessage: 'Use if APM Server requires a secret token',
+ }
+ )}
+ ${nodeVariables.secretToken}: '{{{secretToken}}}',
-// ${i18n.translate(
- 'xpack.apm.tutorial.nodeClient.configure.commands.setCustomApmServerUrlComment',
- {
- defaultMessage:
- 'Set the custom APM Server URL (default: {defaultApmServerUrl})',
- values: { defaultApmServerUrl: 'http://localhost:8200' },
- }
-)}
-${nodeVariables.apmServerUrl}: '{{{apmServerUrl}}}',
+ // ${i18n.translate(
+ 'xpack.apm.tutorial.nodeClient.configure.commands.setCustomApmServerUrlComment',
+ {
+ defaultMessage:
+ 'Set the custom APM Server URL (default: {defaultApmServerUrl})',
+ values: { defaultApmServerUrl: 'http://localhost:8200' },
+ }
+ )}
+ ${nodeVariables.apmServerUrl}: '{{{apmServerUrl}}}',
-// ${i18n.translate(
- 'xpack.apm.tutorial.nodeClient.configure.commands.setCustomServiceEnvironmentComment',
- {
- defaultMessage: 'Set the service environment',
- }
-)}
-${nodeVariables.apmEnvironment}: '{{{apmEnvironment}}}'
+ // ${i18n.translate(
+ 'xpack.apm.tutorial.nodeClient.configure.commands.setCustomServiceEnvironmentComment',
+ {
+ defaultMessage: 'Set the service environment',
+ }
+ )}
+ ${nodeVariables.apmEnvironment}: '{{{apmEnvironment}}}'
})`;
diff --git a/x-pack/plugins/apm/public/tutorial/config_agent/index.test.tsx b/x-pack/plugins/apm/public/tutorial/config_agent/index.test.tsx
index b1ebe783518d0..edae01e0b6043 100644
--- a/x-pack/plugins/apm/public/tutorial/config_agent/index.test.tsx
+++ b/x-pack/plugins/apm/public/tutorial/config_agent/index.test.tsx
@@ -90,7 +90,7 @@ describe('TutorialConfigAgent', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.server_url=http://localhost:8200 \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -104,7 +104,7 @@ describe('TutorialConfigAgent', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token=foo token \\\\
-Delastic.apm.server_url=foo url \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -141,7 +141,7 @@ describe('TutorialConfigAgent', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.server_url=http://localhost:8200 \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -177,7 +177,7 @@ describe('TutorialConfigAgent', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.server_url=http://localhost:8200 \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -219,7 +219,7 @@ describe('TutorialConfigAgent', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token=cloud_token \\\\
-Delastic.apm.server_url=cloud_url \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -258,7 +258,7 @@ describe('TutorialConfigAgent', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token=apm_cloud_token \\\\
-Delastic.apm.server_url=apm_cloud_url \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -290,7 +290,7 @@ describe('TutorialConfigAgent', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.server_url=http://localhost:8200 \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -353,7 +353,7 @@ describe('TutorialConfigAgent', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token= \\\\
-Delastic.apm.server_url=http://localhost:8200 \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
@@ -390,7 +390,7 @@ describe('TutorialConfigAgent', () => {
-Delastic.apm.service_name=my-service-name \\\\
-Delastic.apm.secret_token=cloud_token \\\\
-Delastic.apm.server_url=cloud_url \\\\
- -Delastic.apm.environment=production \\\\
+ -Delastic.apm.environment=my-environment \\\\
-Delastic.apm.application_packages=org.example \\\\
-jar my-service-name.jar"
`);
diff --git a/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.ts b/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.ts
index 92ea60d290040..2cf665e0fc094 100644
--- a/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.ts
+++ b/x-pack/plugins/fleet/server/services/epm/kibana/assets/install.ts
@@ -141,6 +141,7 @@ export async function installKibanaAssetsAndReferences({
pkgTitle,
paths,
installedPkg,
+ spaceId,
}: {
savedObjectsClient: SavedObjectsClientContract;
savedObjectsImporter: Pick;
@@ -151,6 +152,7 @@ export async function installKibanaAssetsAndReferences({
pkgTitle: string;
paths: string[];
installedPkg?: SavedObject;
+ spaceId: string;
}) {
const kibanaAssets = await getKibanaAssets(paths);
if (installedPkg) await deleteKibanaSavedObjectsAssets({ savedObjectsClient, installedPkg });
@@ -167,7 +169,6 @@ export async function installKibanaAssetsAndReferences({
pkgName,
kibanaAssets,
});
-
await withPackageSpan('Create and assign package tags', () =>
tagKibanaAssets({
savedObjectTagAssignmentService,
@@ -175,6 +176,7 @@ export async function installKibanaAssetsAndReferences({
kibanaAssets,
pkgTitle,
pkgName,
+ spaceId,
})
);
diff --git a/x-pack/plugins/fleet/server/services/epm/kibana/assets/tag_assets.test.ts b/x-pack/plugins/fleet/server/services/epm/kibana/assets/tag_assets.test.ts
index 3c946217d36b4..d887631240175 100644
--- a/x-pack/plugins/fleet/server/services/epm/kibana/assets/tag_assets.test.ts
+++ b/x-pack/plugins/fleet/server/services/epm/kibana/assets/tag_assets.test.ts
@@ -11,18 +11,18 @@ describe('tagKibanaAssets', () => {
updateTagAssignments: jest.fn(),
} as any;
const savedObjectTagClient = {
- getAll: jest.fn(),
+ get: jest.fn(),
create: jest.fn(),
} as any;
beforeEach(() => {
savedObjectTagAssignmentService.updateTagAssignments.mockReset();
- savedObjectTagClient.getAll.mockReset();
+ savedObjectTagClient.get.mockReset();
savedObjectTagClient.create.mockReset();
});
- it('should create Managed and System tags when tagKibanaAssets with System package', async () => {
- savedObjectTagClient.getAll.mockResolvedValue([]);
+ it('should create Managed and System tags when tagKibanaAssets with System package when no tags exist', async () => {
+ savedObjectTagClient.get.mockRejectedValue(new Error('not found'));
savedObjectTagClient.create.mockImplementation(({ name }: { name: string }) =>
Promise.resolve({ id: name.toLowerCase(), name })
);
@@ -34,6 +34,7 @@ describe('tagKibanaAssets', () => {
kibanaAssets,
pkgTitle: 'System',
pkgName: 'system',
+ spaceId: 'default',
});
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
@@ -42,7 +43,7 @@ describe('tagKibanaAssets', () => {
description: '',
color: '#FFFFFF',
},
- { id: 'managed', overwrite: true, refresh: false }
+ { id: 'fleet-managed-default', overwrite: true, refresh: false }
);
expect(savedObjectTagClient.create).toHaveBeenCalledWith(
{
@@ -50,10 +51,10 @@ describe('tagKibanaAssets', () => {
description: '',
color: '#FFFFFF',
},
- { id: 'system', overwrite: true, refresh: false }
+ { id: 'fleet-pkg-system-default', overwrite: true, refresh: false }
);
expect(savedObjectTagAssignmentService.updateTagAssignments).toHaveBeenCalledWith({
- tags: ['managed', 'system'],
+ tags: ['fleet-managed-default', 'fleet-pkg-system-default'],
assign: kibanaAssets.dashboard,
unassign: [],
refresh: false,
@@ -61,10 +62,7 @@ describe('tagKibanaAssets', () => {
});
it('should only assign Managed and System tags when tags already exist', async () => {
- savedObjectTagClient.getAll.mockResolvedValue([
- { id: 'managed', name: 'Managed' },
- { id: 'system', name: 'System' },
- ]);
+ savedObjectTagClient.get.mockResolvedValue({ name: '', color: '', description: '' });
const kibanaAssets = { dashboard: [{ id: 'dashboard1', type: 'dashboard' }] } as any;
await tagKibanaAssets({
@@ -73,11 +71,12 @@ describe('tagKibanaAssets', () => {
kibanaAssets,
pkgTitle: 'System',
pkgName: 'system',
+ spaceId: 'default',
});
expect(savedObjectTagClient.create).not.toHaveBeenCalled();
expect(savedObjectTagAssignmentService.updateTagAssignments).toHaveBeenCalledWith({
- tags: ['managed', 'system'],
+ tags: ['fleet-managed-default', 'fleet-pkg-system-default'],
assign: kibanaAssets.dashboard,
unassign: [],
refresh: false,
@@ -85,7 +84,7 @@ describe('tagKibanaAssets', () => {
});
it('should skip non taggable asset types', async () => {
- savedObjectTagClient.getAll.mockResolvedValue([]);
+ savedObjectTagClient.get.mockRejectedValue(new Error('tag not found'));
savedObjectTagClient.create.mockImplementation(({ name }: { name: string }) =>
Promise.resolve({ id: name.toLowerCase(), name })
);
@@ -104,10 +103,11 @@ describe('tagKibanaAssets', () => {
kibanaAssets,
pkgTitle: 'System',
pkgName: 'system',
+ spaceId: 'default',
});
expect(savedObjectTagAssignmentService.updateTagAssignments).toHaveBeenCalledWith({
- tags: ['managed', 'system'],
+ tags: ['fleet-managed-default', 'fleet-pkg-system-default'],
assign: [
...kibanaAssets.dashboard,
...kibanaAssets.search,
@@ -129,8 +129,132 @@ describe('tagKibanaAssets', () => {
kibanaAssets,
pkgTitle: 'System',
pkgName: 'system',
+ spaceId: 'default',
});
expect(savedObjectTagAssignmentService.updateTagAssignments).not.toHaveBeenCalled();
});
+
+ it('should use legacy managed tag if it exists', async () => {
+ savedObjectTagClient.get.mockImplementation(async (id: string) => {
+ if (id === 'managed') return { name: 'managed', description: '', color: '' };
+
+ throw new Error('not found');
+ });
+
+ savedObjectTagClient.create.mockImplementation(({ name }: { name: string }) =>
+ Promise.resolve({ id: name.toLowerCase(), name })
+ );
+ const kibanaAssets = { dashboard: [{ id: 'dashboard1', type: 'dashboard' }] } as any;
+
+ await tagKibanaAssets({
+ savedObjectTagAssignmentService,
+ savedObjectTagClient,
+ kibanaAssets,
+ pkgTitle: 'System',
+ pkgName: 'system',
+ spaceId: 'default',
+ });
+
+ expect(savedObjectTagClient.create).not.toHaveBeenCalledWith(
+ {
+ name: 'Managed',
+ description: '',
+ color: '#FFFFFF',
+ },
+ { id: 'fleet-managed-default', overwrite: true, refresh: false }
+ );
+
+ expect(savedObjectTagClient.create).toHaveBeenCalledWith(
+ {
+ name: 'System',
+ description: '',
+ color: '#FFFFFF',
+ },
+ { id: 'fleet-pkg-system-default', overwrite: true, refresh: false }
+ );
+ expect(savedObjectTagAssignmentService.updateTagAssignments).toHaveBeenCalledWith({
+ tags: ['managed', 'fleet-pkg-system-default'],
+ assign: kibanaAssets.dashboard,
+ unassign: [],
+ refresh: false,
+ });
+ });
+
+ it('should use legacy package tag if it exists', async () => {
+ savedObjectTagClient.get.mockImplementation(async (id: string) => {
+ if (id === 'system') return { name: 'system', description: '', color: '' };
+
+ throw new Error('not found');
+ });
+
+ savedObjectTagClient.create.mockImplementation(({ name }: { name: string }) =>
+ Promise.resolve({ id: name.toLowerCase(), name })
+ );
+ const kibanaAssets = { dashboard: [{ id: 'dashboard1', type: 'dashboard' }] } as any;
+
+ await tagKibanaAssets({
+ savedObjectTagAssignmentService,
+ savedObjectTagClient,
+ kibanaAssets,
+ pkgTitle: 'System',
+ pkgName: 'system',
+ spaceId: 'default',
+ });
+
+ expect(savedObjectTagClient.create).toHaveBeenCalledWith(
+ {
+ name: 'Managed',
+ description: '',
+ color: '#FFFFFF',
+ },
+ { id: 'fleet-managed-default', overwrite: true, refresh: false }
+ );
+
+ expect(savedObjectTagClient.create).not.toHaveBeenCalledWith(
+ {
+ name: 'System',
+ description: '',
+ color: '#FFFFFF',
+ },
+ { id: 'system', overwrite: true, refresh: false }
+ );
+ expect(savedObjectTagAssignmentService.updateTagAssignments).toHaveBeenCalledWith({
+ tags: ['fleet-managed-default', 'system'],
+ assign: kibanaAssets.dashboard,
+ unassign: [],
+ refresh: false,
+ });
+ });
+
+ it('should use both legacy tags if they exist', async () => {
+ savedObjectTagClient.get.mockImplementation(async (id: string) => {
+ if (id === 'managed') return { name: 'managed', description: '', color: '' };
+ if (id === 'system') return { name: 'system', description: '', color: '' };
+
+ throw new Error('not found');
+ });
+
+ savedObjectTagClient.create.mockImplementation(({ name }: { name: string }) =>
+ Promise.resolve({ id: name.toLowerCase(), name })
+ );
+ const kibanaAssets = { dashboard: [{ id: 'dashboard1', type: 'dashboard' }] } as any;
+
+ await tagKibanaAssets({
+ savedObjectTagAssignmentService,
+ savedObjectTagClient,
+ kibanaAssets,
+ pkgTitle: 'System',
+ pkgName: 'system',
+ spaceId: 'default',
+ });
+
+ expect(savedObjectTagClient.create).not.toHaveBeenCalled();
+ expect(savedObjectTagAssignmentService.updateTagAssignments).toHaveBeenCalledWith({
+ tags: ['managed', 'system'],
+ assign: kibanaAssets.dashboard,
+ unassign: [],
+ refresh: false,
+ });
+ });
});
diff --git a/x-pack/plugins/fleet/server/services/epm/kibana/assets/tag_assets.ts b/x-pack/plugins/fleet/server/services/epm/kibana/assets/tag_assets.ts
index 842932d71359e..1d61c3c908872 100644
--- a/x-pack/plugins/fleet/server/services/epm/kibana/assets/tag_assets.ts
+++ b/x-pack/plugins/fleet/server/services/epm/kibana/assets/tag_assets.ts
@@ -15,22 +15,45 @@ import { KibanaSavedObjectTypeMapping } from './install';
const TAG_COLOR = '#FFFFFF';
const MANAGED_TAG_NAME = 'Managed';
-const MANAGED_TAG_ID = 'managed';
-
-export async function tagKibanaAssets({
- savedObjectTagAssignmentService,
- savedObjectTagClient,
- kibanaAssets,
- pkgTitle,
- pkgName,
-}: {
+const LEGACY_MANAGED_TAG_ID = 'managed';
+
+const getManagedTagId = (spaceId: string) => `fleet-managed-${spaceId}`;
+const getPackageTagId = (spaceId: string, pkgName: string) => `fleet-pkg-${pkgName}-${spaceId}`;
+const getLegacyPackageTagId = (pkgName: string) => pkgName;
+
+interface TagAssetsParams {
savedObjectTagAssignmentService: IAssignmentService;
savedObjectTagClient: ITagsClient;
kibanaAssets: Record;
pkgTitle: string;
pkgName: string;
-}) {
- const taggableAssets = Object.entries(kibanaAssets).flatMap(([assetType, assets]) => {
+ spaceId: string;
+}
+
+export async function tagKibanaAssets(opts: TagAssetsParams) {
+ const { savedObjectTagAssignmentService, kibanaAssets } = opts;
+ const taggableAssets = getTaggableAssets(kibanaAssets);
+
+ // no assets to tag
+ if (taggableAssets.length === 0) {
+ return;
+ }
+
+ const [managedTagId, packageTagId] = await Promise.all([
+ ensureManagedTag(opts),
+ ensurePackageTag(opts),
+ ]);
+
+ await savedObjectTagAssignmentService.updateTagAssignments({
+ tags: [managedTagId, packageTagId],
+ assign: taggableAssets,
+ unassign: [],
+ refresh: false,
+ });
+}
+
+function getTaggableAssets(kibanaAssets: TagAssetsParams['kibanaAssets']) {
+ return Object.entries(kibanaAssets).flatMap(([assetType, assets]) => {
if (!taggableTypes.includes(KibanaSavedObjectTypeMapping[assetType as KibanaAssetType])) {
return [];
}
@@ -41,41 +64,57 @@ export async function tagKibanaAssets({
return assets;
});
+}
- // no assets to tag
- if (taggableAssets.length === 0) {
- return;
- }
+async function ensureManagedTag(
+ opts: Pick
+): Promise {
+ const { spaceId, savedObjectTagClient } = opts;
- const allTags = await savedObjectTagClient.getAll();
- let managedTag = allTags.find((tag) => tag.name === MANAGED_TAG_NAME);
- if (!managedTag) {
- managedTag = await savedObjectTagClient.create(
- {
- name: MANAGED_TAG_NAME,
- description: '',
- color: TAG_COLOR,
- },
- { id: MANAGED_TAG_ID, overwrite: true, refresh: false }
- );
- }
+ const managedTagId = getManagedTagId(spaceId);
+ const managedTag = await savedObjectTagClient.get(managedTagId).catch(() => {});
- let packageTag = allTags.find((tag) => tag.name === pkgTitle);
- if (!packageTag) {
- packageTag = await savedObjectTagClient.create(
- {
- name: pkgTitle,
- description: '',
- color: TAG_COLOR,
- },
- { id: pkgName, overwrite: true, refresh: false }
- );
- }
+ if (managedTag) return managedTagId;
- await savedObjectTagAssignmentService.updateTagAssignments({
- tags: [managedTag.id, packageTag.id],
- assign: taggableAssets,
- unassign: [],
- refresh: false,
- });
+ const legacyManagedTag = await savedObjectTagClient.get(LEGACY_MANAGED_TAG_ID).catch(() => {});
+
+ if (legacyManagedTag) return LEGACY_MANAGED_TAG_ID;
+
+ await savedObjectTagClient.create(
+ {
+ name: MANAGED_TAG_NAME,
+ description: '',
+ color: TAG_COLOR,
+ },
+ { id: managedTagId, overwrite: true, refresh: false }
+ );
+
+ return managedTagId;
+}
+
+async function ensurePackageTag(
+ opts: Pick
+): Promise {
+ const { spaceId, savedObjectTagClient, pkgName, pkgTitle } = opts;
+
+ const packageTagId = getPackageTagId(spaceId, pkgName);
+ const packageTag = await savedObjectTagClient.get(packageTagId).catch(() => {});
+
+ if (packageTag) return packageTagId;
+
+ const legacyPackageTagId = getLegacyPackageTagId(pkgName);
+ const legacyPackageTag = await savedObjectTagClient.get(legacyPackageTagId).catch(() => {});
+
+ if (legacyPackageTag) return legacyPackageTagId;
+
+ await savedObjectTagClient.create(
+ {
+ name: pkgTitle,
+ description: '',
+ color: TAG_COLOR,
+ },
+ { id: packageTagId, overwrite: true, refresh: false }
+ );
+
+ return packageTagId;
}
diff --git a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts
index 4ecec17560731..78683ecd07e0a 100644
--- a/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts
+++ b/x-pack/plugins/fleet/server/services/epm/packages/_install_package.ts
@@ -133,6 +133,7 @@ export async function _installPackage({
paths,
installedPkg,
logger,
+ spaceId,
})
);
// Necessary to avoid async promise rejection warning
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_container.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_container.tsx
new file mode 100644
index 0000000000000..036d22d8b7c5f
--- /dev/null
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_container.tsx
@@ -0,0 +1,39 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import React from 'react';
+import { EuiSpacer } from '@elastic/eui';
+
+import { i18n } from '@kbn/i18n';
+import { InfraLoadingPanel } from '../../../../components/loading';
+import { useMetricsDataViewContext } from '../hooks/use_data_view';
+import { UnifiedSearchBar } from './unified_search_bar';
+import { HostsTable } from './hosts_table';
+
+export const HostContainer = () => {
+ const { metricsDataView, isDataViewLoading, hasFailedLoadingDataView } =
+ useMetricsDataViewContext();
+
+ if (isDataViewLoading) {
+ return (
+
+ );
+ }
+
+ return hasFailedLoadingDataView || !metricsDataView ? null : (
+ <>
+
+
+
+ >
+ );
+};
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_table.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_table.tsx
index d045c594f0ee6..759c65ca84b2e 100644
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_table.tsx
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/hosts_table.tsx
@@ -7,16 +7,86 @@
import React from 'react';
import { EuiInMemoryTable } from '@elastic/eui';
-import type { SnapshotNode } from '../../../../../common/http_api';
+import { i18n } from '@kbn/i18n';
import { HostsTableColumns } from './hosts_table_columns';
+import { NoData } from '../../../../components/empty_states';
+import { InfraLoadingPanel } from '../../../../components/loading';
import { useHostTable } from '../hooks/use_host_table';
+import { useSnapshot } from '../../inventory_view/hooks/use_snaphot';
+import type { SnapshotMetricType } from '../../../../../common/inventory_models/types';
+import type { InfraTimerangeInput } from '../../../../../common/http_api';
+import { useUnifiedSearchContext } from '../hooks/use_unified_search';
+import { useSourceContext } from '../../../../containers/metrics_source';
-interface Props {
- nodes: SnapshotNode[];
-}
+const HOST_METRICS: Array<{ type: SnapshotMetricType }> = [
+ { type: 'rx' },
+ { type: 'tx' },
+ { type: 'memory' },
+ { type: 'cpuCores' },
+ { type: 'memoryTotal' },
+];
+
+export const HostsTable = () => {
+ const { sourceId } = useSourceContext();
+ const { esQuery, dateRangeTimestamp } = useUnifiedSearchContext();
+
+ const timeRange: InfraTimerangeInput = {
+ from: dateRangeTimestamp.from,
+ to: dateRangeTimestamp.to,
+ interval: '1m',
+ ignoreLookback: true,
+ };
+
+ // Snapshot endpoint internally uses the indices stored in source.configuration.metricAlias.
+ // For the Unified Search, we create a data view, which for now will be built off of source.configuration.metricAlias too
+ // if we introduce data view selection, we'll have to change this hook and the endpoint to accept a new parameter for the indices
+ const { loading, nodes, reload } = useSnapshot(
+ esQuery && JSON.stringify(esQuery),
+ HOST_METRICS,
+ [],
+ 'host',
+ sourceId,
+ dateRangeTimestamp.to,
+ '',
+ '',
+ true,
+ timeRange
+ );
-export const HostsTable: React.FunctionComponent = ({ nodes }) => {
const items = useHostTable(nodes);
+ const noData = items.length === 0;
- return ;
+ return (
+ <>
+ {loading ? (
+
+ ) : noData ? (
+
+ {
+ reload();
+ }}
+ testString="noMetricsDataPrompt"
+ />
+
+ ) : (
+
+ )}
+ >
+ );
};
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/unified_search_bar.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/unified_search_bar.tsx
new file mode 100644
index 0000000000000..ec9879579908e
--- /dev/null
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/unified_search_bar.tsx
@@ -0,0 +1,77 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import { useKibana } from '@kbn/kibana-react-plugin/public';
+import type { Filter, Query, TimeRange } from '@kbn/es-query';
+import type { DataView } from '@kbn/data-views-plugin/public';
+import type { SavedQuery } from '@kbn/data-plugin/public';
+import type { InfraClientStartDeps } from '../../../../types';
+import { useUnifiedSearchContext } from '../hooks/use_unified_search';
+
+interface Props {
+ dataView: DataView;
+}
+
+export const UnifiedSearchBar = ({ dataView }: Props) => {
+ const {
+ services: { unifiedSearch },
+ } = useKibana();
+ const {
+ unifiedSearchDateRange,
+ unifiedSearchQuery,
+ submitFilterChange,
+ saveQuery,
+ clearSavedQUery,
+ } = useUnifiedSearchContext();
+
+ const { SearchBar } = unifiedSearch.ui;
+
+ const onFilterChange = (filters: Filter[]) => {
+ onQueryChange({ filters });
+ };
+
+ const onQuerySubmit = (payload: { dateRange: TimeRange; query?: Query }) => {
+ onQueryChange({ payload });
+ };
+
+ const onClearSavedQuery = () => {
+ clearSavedQUery();
+ };
+
+ const onQuerySave = (savedQuery: SavedQuery) => {
+ saveQuery(savedQuery);
+ };
+
+ const onQueryChange = ({
+ payload,
+ filters,
+ }: {
+ payload?: { dateRange: TimeRange; query?: Query };
+ filters?: Filter[];
+ }) => {
+ submitFilterChange(payload?.query, payload?.dateRange, filters);
+ };
+
+ return (
+
+ );
+};
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.test.ts b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.test.ts
new file mode 100644
index 0000000000000..2a2bb57b102ff
--- /dev/null
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.test.ts
@@ -0,0 +1,85 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { useDataView } from './use_data_view';
+import { renderHook } from '@testing-library/react-hooks';
+import { KibanaReactContextValue, useKibana } from '@kbn/kibana-react-plugin/public';
+import { coreMock, notificationServiceMock } from '@kbn/core/public/mocks';
+import type { DataView } from '@kbn/data-views-plugin/public';
+import { DataViewsServicePublic } from '@kbn/data-views-plugin/public/types';
+import { InfraClientStartDeps } from '../../../../types';
+import { CoreStart } from '@kbn/core/public';
+
+jest.mock('@kbn/i18n');
+jest.mock('@kbn/kibana-react-plugin/public');
+
+let dataViewMock: jest.Mocked;
+const useKibanaMock = useKibana as jest.MockedFunction;
+const notificationMock = notificationServiceMock.createStartContract();
+const prop = { metricAlias: 'test' };
+
+const mockUseKibana = () => {
+ useKibanaMock.mockReturnValue({
+ services: {
+ ...coreMock.createStart(),
+ notifications: notificationMock,
+ dataViews: dataViewMock,
+ } as Partial & Partial,
+ } as unknown as KibanaReactContextValue & Partial>);
+};
+
+const mockDataView = {
+ id: 'mock-id',
+ title: 'mock-title',
+ timeFieldName: 'mock-time-field-name',
+ isPersisted: () => false,
+ getName: () => 'mock-data-view',
+ toSpec: () => ({}),
+} as jest.Mocked;
+
+describe('useHostTable hook', () => {
+ beforeEach(() => {
+ dataViewMock = {
+ createAndSave: jest.fn(),
+ find: jest.fn(),
+ } as Partial as jest.Mocked;
+
+ mockUseKibana();
+ });
+
+ it('should find an existing Data view', async () => {
+ dataViewMock.find.mockReturnValue(Promise.resolve([mockDataView]));
+ const { result, waitForNextUpdate } = renderHook(() => useDataView(prop));
+
+ await waitForNextUpdate();
+ expect(result.current.isDataViewLoading).toEqual(false);
+ expect(result.current.hasFailedLoadingDataView).toEqual(false);
+ expect(result.current.metricsDataView).toEqual(mockDataView);
+ });
+
+ it('should create a new Data view', async () => {
+ dataViewMock.find.mockReturnValue(Promise.resolve([]));
+ dataViewMock.createAndSave.mockReturnValue(Promise.resolve(mockDataView));
+ const { result, waitForNextUpdate } = renderHook(() => useDataView(prop));
+
+ await waitForNextUpdate();
+ expect(result.current.isDataViewLoading).toEqual(false);
+ expect(result.current.hasFailedLoadingDataView).toEqual(false);
+ expect(result.current.metricsDataView).toEqual(mockDataView);
+ });
+
+ it('should display a toast when it fails to load the data view', async () => {
+ dataViewMock.find.mockReturnValue(Promise.reject());
+ const { result, waitForNextUpdate } = renderHook(() => useDataView(prop));
+
+ await waitForNextUpdate();
+ expect(result.current.isDataViewLoading).toEqual(false);
+ expect(result.current.hasFailedLoadingDataView).toEqual(true);
+ expect(result.current.metricsDataView).toBeUndefined();
+ expect(notificationMock.toasts.addDanger).toBeCalledTimes(1);
+ });
+});
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.ts b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.ts
index b60b2aa89db62..f927afa72890c 100644
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.ts
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.ts
@@ -5,7 +5,8 @@
* 2.0.
*/
-import { useCallback, useState, useEffect } from 'react';
+import { i18n } from '@kbn/i18n';
+import { useCallback, useState, useEffect, useMemo } from 'react';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import createContainer from 'constate';
import type { DataView } from '@kbn/data-views-plugin/public';
@@ -15,7 +16,7 @@ import { useTrackedPromise } from '../../../../utils/use_tracked_promise';
export const useDataView = ({ metricAlias }: { metricAlias: string }) => {
const [metricsDataView, setMetricsDataView] = useState();
const {
- services: { dataViews },
+ services: { dataViews, notifications },
} = useKibana();
const [createDataViewRequest, createDataView] = useTrackedPromise(
@@ -33,7 +34,7 @@ export const useDataView = ({ metricAlias }: { metricAlias: string }) => {
const [getDataViewRequest, getDataView] = useTrackedPromise(
{
- createPromise: (indexPattern: string): Promise => {
+ createPromise: (_indexPattern: string): Promise => {
return dataViews.find(metricAlias, 1);
},
onResolve: (response: DataView[]) => {
@@ -58,17 +59,36 @@ export const useDataView = ({ metricAlias }: { metricAlias: string }) => {
}
}, [metricAlias, createDataView, getDataView]);
- const hasFailedFetchingDataView = getDataViewRequest.state === 'rejected';
- const hasFailedCreatingDataView = createDataViewRequest.state === 'rejected';
+ const isDataViewLoading = useMemo(
+ () => getDataViewRequest.state === 'pending' || createDataViewRequest.state === 'pending',
+ [getDataViewRequest.state, createDataViewRequest.state]
+ );
+
+ const hasFailedLoadingDataView = useMemo(
+ () => getDataViewRequest.state === 'rejected' || createDataViewRequest.state === 'rejected',
+ [getDataViewRequest.state, createDataViewRequest.state]
+ );
useEffect(() => {
loadDataView();
}, [metricAlias, loadDataView]);
+ useEffect(() => {
+ if (hasFailedLoadingDataView && notifications) {
+ notifications.toasts.addDanger(
+ i18n.translate('xpack.infra.hostsTable.errorOnCreateOrLoadDataview', {
+ defaultMessage:
+ 'There was an error trying to load or create the Data View: {metricAlias}',
+ values: { metricAlias },
+ })
+ );
+ }
+ }, [hasFailedLoadingDataView, notifications, metricAlias]);
+
return {
metricsDataView,
- hasFailedCreatingDataView,
- hasFailedFetchingDataView,
+ isDataViewLoading,
+ hasFailedLoadingDataView,
};
};
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_unified_search.ts b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_unified_search.ts
new file mode 100644
index 0000000000000..4b3d4e7a47df6
--- /dev/null
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_unified_search.ts
@@ -0,0 +1,105 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+import { useKibana } from '@kbn/kibana-react-plugin/public';
+import createContainer from 'constate';
+import { useCallback, useReducer } from 'react';
+import { buildEsQuery, Filter, Query, TimeRange } from '@kbn/es-query';
+import DateMath from '@kbn/datemath';
+import type { SavedQuery } from '@kbn/data-plugin/public';
+import type { InfraClientStartDeps } from '../../../../types';
+import { useMetricsDataViewContext } from './use_data_view';
+import { useKibanaTimefilterTime } from '../../../../hooks/use_kibana_timefilter_time';
+
+const DEFAULT_FROM_MINUTES_VALUE = 15;
+
+export const useUnifiedSearch = () => {
+ const [, forceUpdate] = useReducer((x: number) => x + 1, 0);
+
+ const { metricsDataView } = useMetricsDataViewContext();
+ const { services } = useKibana();
+ const {
+ data: { query: queryManager },
+ } = services;
+
+ const [getTime, setTime] = useKibanaTimefilterTime({
+ from: `now-${DEFAULT_FROM_MINUTES_VALUE}m`,
+ to: 'now',
+ });
+ const { queryString, filterManager } = queryManager;
+
+ const currentDate = new Date();
+ const fromTS =
+ DateMath.parse(getTime().from)?.valueOf() ??
+ new Date(currentDate.getMinutes() - DEFAULT_FROM_MINUTES_VALUE).getTime();
+ const toTS = DateMath.parse(getTime().to)?.valueOf() ?? currentDate.getTime();
+
+ const currentTimeRange = {
+ from: fromTS,
+ to: toTS,
+ };
+
+ const submitFilterChange = useCallback(
+ (query?: Query, dateRange?: TimeRange, filters?: Filter[]) => {
+ if (filters) {
+ filterManager.setFilters(filters);
+ }
+
+ setTime({
+ ...getTime(),
+ ...dateRange,
+ });
+
+ queryString.setQuery({ ...queryString.getQuery(), ...query });
+ // Unified search holds the all state, we need to force the hook to rerender so that it can return the most recent values
+ // This can be removed once we get the state from the URL
+ forceUpdate();
+ },
+ [filterManager, queryString, getTime, setTime]
+ );
+
+ const saveQuery = useCallback(
+ (newSavedQuery: SavedQuery) => {
+ const savedQueryFilters = newSavedQuery.attributes.filters ?? [];
+ const globalFilters = filterManager.getGlobalFilters();
+ filterManager.setFilters([...savedQueryFilters, ...globalFilters]);
+
+ // Unified search holds the all state, we need to force the hook to rerender so that it can return the most recent values
+ // This can be removed once we get the state from the URL
+ forceUpdate();
+ },
+ [filterManager]
+ );
+
+ const clearSavedQUery = useCallback(() => {
+ filterManager.setFilters(filterManager.getGlobalFilters());
+
+ // Unified search holds the all state, we need to force the hook to rerender so that it can return the most recent values
+ // This can be removed once we get the state from the URL
+ forceUpdate();
+ }, [filterManager]);
+
+ const buildQuery = useCallback(() => {
+ if (!metricsDataView) {
+ return null;
+ }
+ return buildEsQuery(metricsDataView, queryString.getQuery(), filterManager.getFilters());
+ }, [filterManager, metricsDataView, queryString]);
+
+ return {
+ dateRangeTimestamp: currentTimeRange,
+ esQuery: buildQuery(),
+ submitFilterChange,
+ saveQuery,
+ clearSavedQUery,
+ unifiedSearchQuery: queryString.getQuery() as Query,
+ unifiedSearchDateRange: getTime(),
+ unifiedSearchFilters: filterManager.getFilters(),
+ };
+};
+
+export const UnifiedSearch = createContainer(useUnifiedSearch);
+export const [UnifiedSearchProvider, useUnifiedSearchContext] = UnifiedSearch;
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/hosts_content.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/hosts_content.tsx
deleted file mode 100644
index 5ab4a062d7fc9..0000000000000
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/hosts_content.tsx
+++ /dev/null
@@ -1,120 +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 { Query, TimeRange } from '@kbn/es-query';
-import { i18n } from '@kbn/i18n';
-import React, { useState, useCallback } from 'react';
-import { SearchBar } from '@kbn/unified-search-plugin/public';
-import { EuiSpacer } from '@elastic/eui';
-import { NoData } from '../../../components/empty_states';
-import { InfraLoadingPanel } from '../../../components/loading';
-import { useMetricsDataViewContext } from './hooks/use_data_view';
-import { HostsTable } from './components/hosts_table';
-import { useSourceContext } from '../../../containers/metrics_source';
-import { useSnapshot } from '../inventory_view/hooks/use_snaphot';
-import type { SnapshotMetricType } from '../../../../common/inventory_models/types';
-
-export const HostsContent: React.FunctionComponent = () => {
- const { source, sourceId } = useSourceContext();
- const [dateRange, setDateRange] = useState({ from: 'now-15m', to: 'now' });
- const [query, setQuery] = useState({ query: '', language: 'kuery' });
- const { metricsDataView, hasFailedCreatingDataView, hasFailedFetchingDataView } =
- useMetricsDataViewContext();
- // needed to refresh the lens table when filters havent changed
-
- const onQuerySubmit = useCallback(
- (payload: { dateRange: TimeRange; query?: Query }) => {
- setDateRange(payload.dateRange);
- if (payload.query) {
- setQuery(payload.query);
- }
- },
- [setDateRange, setQuery]
- );
-
- const hostMetrics: Array<{ type: SnapshotMetricType }> = [
- { type: 'rx' },
- { type: 'tx' },
- { type: 'memory' },
- { type: 'cpuCores' },
- { type: 'memoryTotal' },
- ];
-
- const { loading, nodes, reload } = useSnapshot(
- '', // use the unified search query, supported type?
- hostMetrics,
- [],
- 'host',
- sourceId,
- 1666710279338, // currentTime. need to add support for TimeRange?
- '',
- '',
- true,
- {
- from: 1666710279338, // dynamic time range needs to be supported
- interval: '1m',
- lookbackSize: 5,
- to: 1666711479338,
- }
- );
-
- const noData = !loading && nodes && nodes.length === 0;
-
- return (
-
- {metricsDataView && !loading ? (
- noData ? (
-
{
- reload();
- }}
- testString="noMetricsDataPrompt"
- />
- ) : (
- <>
-
-
-
- >
- )
- ) : hasFailedCreatingDataView || hasFailedFetchingDataView ? (
-
-
There was an error trying to load or create the Data View:
- {source?.configuration.metricAlias}
-
- ) : (
-
- )}
-
- );
-};
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx
index a5dfd7f2ddd0f..3321be0af193c 100644
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/index.tsx
@@ -9,16 +9,16 @@ import { EuiErrorBoundary } from '@elastic/eui';
import React from 'react';
import { useTrackPageview } from '@kbn/observability-plugin/public';
import { APP_WRAPPER_CLASS } from '@kbn/core/public';
-
import { SourceErrorPage } from '../../../components/source_error_page';
import { SourceLoadingPage } from '../../../components/source_loading_page';
import { useSourceContext } from '../../../containers/metrics_source';
import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs';
import { MetricsPageTemplate } from '../page_template';
import { hostsTitle } from '../../../translations';
-import { HostsContent } from './hosts_content';
import { MetricsDataViewProvider } from './hooks/use_data_view';
import { fullHeightContentStyles } from '../../../page_template.styles';
+import { UnifiedSearchProvider } from './hooks/use_unified_search';
+import { HostContainer } from './components/hosts_container';
export const HostsPage = () => {
const {
@@ -56,7 +56,9 @@ export const HostsPage = () => {
}}
>
-
+
+
+
diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
index 64d389a1c0bf7..55b847d33f87d 100644
--- a/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
+++ b/x-pack/plugins/infra/server/lib/adapters/framework/adapter_types.ts
@@ -22,16 +22,18 @@ import { SpacesPluginSetup } from '@kbn/spaces-plugin/server';
import { PluginSetupContract as AlertingPluginContract } from '@kbn/alerting-plugin/server';
import { MlPluginSetup } from '@kbn/ml-plugin/server';
import { RuleRegistryPluginSetupContract } from '@kbn/rule-registry-plugin/server';
+import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server';
export interface InfraServerPluginSetupDeps {
+ alerting: AlertingPluginContract;
data: DataPluginSetup;
home: HomeServerPluginSetup;
+ features: FeaturesPluginSetup;
+ ruleRegistry: RuleRegistryPluginSetupContract;
+ observability: ObservabilityPluginSetup;
spaces: SpacesPluginSetup;
usageCollection: UsageCollectionSetup;
visTypeTimeseries: VisTypeTimeseriesSetup;
- features: FeaturesPluginSetup;
- alerting: AlertingPluginContract;
- ruleRegistry: RuleRegistryPluginSetupContract;
ml?: MlPluginSetup;
}
diff --git a/x-pack/plugins/infra/server/lib/alerting/common/messages.ts b/x-pack/plugins/infra/server/lib/alerting/common/messages.ts
index 80dae7ffac959..644c31813deae 100644
--- a/x-pack/plugins/infra/server/lib/alerting/common/messages.ts
+++ b/x-pack/plugins/infra/server/lib/alerting/common/messages.ts
@@ -169,6 +169,14 @@ export const alertStateActionVariableDescription = i18n.translate(
}
);
+export const alertDetailUrlActionVariableDescription = i18n.translate(
+ 'xpack.infra.metrics.alerting.alertDetailUrlActionVariableDescription',
+ {
+ defaultMessage:
+ 'Link to the view within Elastic that shows further details and context surrounding this alert',
+ }
+);
+
export const reasonActionVariableDescription = i18n.translate(
'xpack.infra.metrics.alerting.reasonActionVariableDescription',
{
@@ -211,7 +219,7 @@ export const viewInAppUrlActionVariableDescription = i18n.translate(
'xpack.infra.metrics.alerting.viewInAppUrlActionVariableDescription',
{
defaultMessage:
- 'Link to the view or feature within Elastic that can be used to investigate the alert and its context further',
+ 'Link to the view or feature within Elastic that can assist with further investigation',
}
);
diff --git a/x-pack/plugins/infra/server/lib/alerting/common/utils.ts b/x-pack/plugins/infra/server/lib/alerting/common/utils.ts
index 2618af72168cd..ced80c75a3ef1 100644
--- a/x-pack/plugins/infra/server/lib/alerting/common/utils.ts
+++ b/x-pack/plugins/infra/server/lib/alerting/common/utils.ts
@@ -9,8 +9,11 @@ import { isEmpty, isError } from 'lodash';
import { schema } from '@kbn/config-schema';
import { Logger, LogMeta } from '@kbn/logging';
import type { IBasePath } from '@kbn/core/server';
+import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
+import { ObservabilityConfig } from '@kbn/observability-plugin/server';
import { ALERT_RULE_PARAMETERS, TIMESTAMP } from '@kbn/rule-data-utils';
import { parseTechnicalFields } from '@kbn/rule-registry-plugin/common/parse_technical_fields';
+import { LINK_TO_METRICS_EXPLORER } from '../../../../common/alerting/metrics';
import { getInventoryViewInAppUrl } from '../../../../common/alerting/metrics/alert_link';
import {
AlertExecutionDetails,
@@ -83,18 +86,30 @@ export const createScopedLogger = (
};
};
-export const getViewInAppUrl = (basePath: IBasePath, relativeViewInAppUrl: string) =>
- basePath.publicBaseUrl
- ? new URL(basePath.prepend(relativeViewInAppUrl), basePath.publicBaseUrl).toString()
- : relativeViewInAppUrl;
+export const getAlertDetailsPageEnabledForApp = (
+ config: ObservabilityConfig['unsafe']['alertDetails'] | null,
+ appName: keyof ObservabilityConfig['unsafe']['alertDetails']
+): boolean => {
+ if (!config) return false;
-export const getViewInAppUrlInventory = (
- criteria: InventoryMetricConditions[],
- nodeType: string,
- timestamp: string,
- basePath: IBasePath
-) => {
+ return config[appName].enabled;
+};
+
+export const getViewInInventoryAppUrl = ({
+ basePath,
+ criteria,
+ nodeType,
+ spaceId,
+ timestamp,
+}: {
+ basePath: IBasePath;
+ criteria: InventoryMetricConditions[];
+ nodeType: string;
+ spaceId: string;
+ timestamp: string;
+}) => {
const { metric, customMetric } = criteria[0];
+
const fields = {
[`${ALERT_RULE_PARAMETERS}.criteria.metric`]: [metric],
[`${ALERT_RULE_PARAMETERS}.criteria.customMetric.id`]: [customMetric?.id],
@@ -104,6 +119,18 @@ export const getViewInAppUrlInventory = (
[TIMESTAMP]: timestamp,
};
- const relativeViewInAppUrl = getInventoryViewInAppUrl(parseTechnicalFields(fields, true));
- return getViewInAppUrl(basePath, relativeViewInAppUrl);
+ return addSpaceIdToPath(
+ basePath.publicBaseUrl,
+ spaceId,
+ getInventoryViewInAppUrl(parseTechnicalFields(fields, true))
+ );
};
+
+export const getViewInMetricsAppUrl = (basePath: IBasePath, spaceId: string) =>
+ addSpaceIdToPath(basePath.publicBaseUrl, spaceId, LINK_TO_METRICS_EXPLORER);
+
+export const getAlertDetailsUrl = (
+ basePath: IBasePath,
+ spaceId: string,
+ alertUuid: string | null
+) => addSpaceIdToPath(basePath.publicBaseUrl, spaceId, `/app/observability/alerts/${alertUuid}`);
diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts
index 2e51d2e8291b5..20b804a2cc7db 100644
--- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts
+++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts
@@ -30,7 +30,12 @@ import {
buildNoDataAlertReason,
stateToAlertMessage,
} from '../common/messages';
-import { createScopedLogger, getViewInAppUrlInventory } from '../common/utils';
+import {
+ createScopedLogger,
+ getAlertDetailsUrl,
+ getViewInInventoryAppUrl,
+ UNGROUPED_FACTORY_KEY,
+} from '../common/utils';
import { evaluateCondition, ConditionResult } from './evaluate_condition';
type InventoryMetricThresholdAllowedActionGroups = ActionGroupIdsOf<
@@ -61,12 +66,18 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
InventoryMetricThresholdAlertState,
InventoryMetricThresholdAlertContext,
InventoryMetricThresholdAllowedActionGroups
- >(async ({ services, params, alertId, executionId, startedAt }) => {
+ >(async ({ services, params, alertId, executionId, spaceId, startedAt }) => {
const startTime = Date.now();
+
const { criteria, filterQuery, sourceId = 'default', nodeType, alertOnNoData } = params;
+
if (criteria.length === 0) throw new Error('Cannot execute an alert with 0 conditions');
+
const logger = createScopedLogger(libs.logger, 'inventoryRule', { alertId, executionId });
- const { alertWithLifecycle, savedObjectsClient, getAlertStartedDate } = services;
+
+ const esClient = services.scopedClusterClient.asCurrentUser;
+
+ const { alertWithLifecycle, savedObjectsClient, getAlertStartedDate, getAlertUuid } = services;
const alertFactory: InventoryMetricThresholdAlertFactory = (id, reason, additionalContext) =>
alertWithLifecycle({
id,
@@ -85,23 +96,28 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
logger.error(e.message);
const actionGroupId = FIRED_ACTIONS.id; // Change this to an Error action group when able
const reason = buildInvalidQueryAlertReason(params.filterQueryText);
- const alert = alertFactory('*', reason);
- const indexedStartedDate = getAlertStartedDate('*') ?? startedAt.toISOString();
- const viewInAppUrl = getViewInAppUrlInventory(
- criteria,
- nodeType,
- indexedStartedDate,
- libs.basePath
- );
+ const alert = alertFactory(UNGROUPED_FACTORY_KEY, reason);
+ const indexedStartedDate =
+ getAlertStartedDate(UNGROUPED_FACTORY_KEY) ?? startedAt.toISOString();
+ const alertUuid = getAlertUuid(UNGROUPED_FACTORY_KEY);
+
alert.scheduleActions(actionGroupId, {
- group: '*',
+ alertDetailsUrl: getAlertDetailsUrl(libs.basePath, spaceId, alertUuid),
alertState: stateToAlertMessage[AlertStates.ERROR],
+ group: UNGROUPED_FACTORY_KEY,
+ metric: mapToConditionsLookup(criteria, (c) => c.metric),
reason,
timestamp: startedAt.toISOString(),
- viewInAppUrl,
value: null,
- metric: mapToConditionsLookup(criteria, (c) => c.metric),
+ viewInAppUrl: getViewInInventoryAppUrl({
+ basePath: libs.basePath,
+ criteria,
+ nodeType,
+ timestamp: indexedStartedDate,
+ spaceId,
+ }),
});
+
return {};
}
}
@@ -109,7 +125,7 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
const [, , { logViews }] = await libs.getStartServices();
const logQueryFields: LogQueryFields | undefined = await logViews
- .getClient(savedObjectsClient, services.scopedClusterClient.asCurrentUser)
+ .getClient(savedObjectsClient, esClient)
.getResolvedLogView(sourceId)
.then(
({ indices }) => ({ indexPattern: indices }),
@@ -120,18 +136,19 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
const results = await Promise.all(
criteria.map((condition) =>
evaluateCondition({
- condition,
- nodeType,
- source,
- logQueryFields,
- esClient: services.scopedClusterClient.asCurrentUser,
compositeSize,
- filterQuery,
+ condition,
+ esClient,
executionTimestamp: startedAt,
+ filterQuery,
logger,
+ logQueryFields,
+ nodeType,
+ source,
})
)
);
+
let scheduledActionsCount = 0;
const inventoryItems = Object.keys(first(results)!);
for (const group of inventoryItems) {
@@ -190,25 +207,28 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
const alert = alertFactory(group, reason, additionalContext);
const indexedStartedDate = getAlertStartedDate(group) ?? startedAt.toISOString();
- const viewInAppUrl = getViewInAppUrlInventory(
- criteria,
- nodeType,
- indexedStartedDate,
- libs.basePath
- );
+ const alertUuid = getAlertUuid(group);
+
scheduledActionsCount++;
const context = {
- group,
+ alertDetailsUrl: getAlertDetailsUrl(libs.basePath, spaceId, alertUuid),
alertState: stateToAlertMessage[nextState],
+ group,
reason,
+ metric: mapToConditionsLookup(criteria, (c) => c.metric),
timestamp: startedAt.toISOString(),
- viewInAppUrl,
+ threshold: mapToConditionsLookup(criteria, (c) => c.threshold),
value: mapToConditionsLookup(results, (result) =>
formatMetric(result[group].metric, result[group].currentValue)
),
- threshold: mapToConditionsLookup(criteria, (c) => c.threshold),
- metric: mapToConditionsLookup(criteria, (c) => c.metric),
+ viewInAppUrl: getViewInInventoryAppUrl({
+ basePath: libs.basePath,
+ criteria,
+ nodeType,
+ timestamp: indexedStartedDate,
+ spaceId,
+ }),
...additionalContext,
};
alert.scheduleActions(actionGroupId, context);
@@ -217,24 +237,27 @@ export const createInventoryMetricThresholdExecutor = (libs: InfraBackendLibs) =
const { getRecoveredAlerts } = services.alertFactory.done();
const recoveredAlerts = getRecoveredAlerts();
+
for (const alert of recoveredAlerts) {
const recoveredAlertId = alert.getId();
const indexedStartedDate = getAlertStartedDate(recoveredAlertId) ?? startedAt.toISOString();
- const viewInAppUrl = getViewInAppUrlInventory(
- criteria,
- nodeType,
- indexedStartedDate,
- libs.basePath
- );
- const context = {
- group: recoveredAlertId,
+ const alertUuid = getAlertUuid(recoveredAlertId);
+
+ alert.setContext({
+ alertDetailsUrl: getAlertDetailsUrl(libs.basePath, spaceId, alertUuid),
alertState: stateToAlertMessage[AlertStates.OK],
- timestamp: startedAt.toISOString(),
- viewInAppUrl,
- threshold: mapToConditionsLookup(criteria, (c) => c.threshold),
+ group: recoveredAlertId,
metric: mapToConditionsLookup(criteria, (c) => c.metric),
- };
- alert.setContext(context);
+ threshold: mapToConditionsLookup(criteria, (c) => c.threshold),
+ timestamp: startedAt.toISOString(),
+ viewInAppUrl: getViewInInventoryAppUrl({
+ basePath: libs.basePath,
+ criteria,
+ nodeType,
+ timestamp: indexedStartedDate,
+ spaceId,
+ }),
+ });
}
const stopTime = Date.now();
diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts
index b3b1f5ba21c65..030628f59ad38 100644
--- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts
+++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts
@@ -24,6 +24,7 @@ import {
} from '../../../../common/inventory_models/types';
import { InfraBackendLibs } from '../../infra_types';
import {
+ alertDetailUrlActionVariableDescription,
alertStateActionVariableDescription,
cloudActionVariableDescription,
containerActionVariableDescription,
@@ -39,7 +40,11 @@ import {
valueActionVariableDescription,
viewInAppUrlActionVariableDescription,
} from '../common/messages';
-import { oneOfLiterals, validateIsStringElasticsearchJSONFilter } from '../common/utils';
+import {
+ getAlertDetailsPageEnabledForApp,
+ oneOfLiterals,
+ validateIsStringElasticsearchJSONFilter,
+} from '../common/utils';
import {
createInventoryMetricThresholdExecutor,
FIRED_ACTIONS,
@@ -72,6 +77,8 @@ export async function registerMetricInventoryThresholdRuleType(
alertingPlugin: PluginSetupContract,
libs: InfraBackendLibs
) {
+ const config = libs.getAlertDetailsConfig();
+
alertingPlugin.registerType({
id: METRIC_INVENTORY_THRESHOLD_ALERT_TYPE_ID,
name: i18n.translate('xpack.infra.metrics.inventory.alertName', {
@@ -102,6 +109,9 @@ export async function registerMetricInventoryThresholdRuleType(
context: [
{ name: 'group', description: groupActionVariableDescription },
{ name: 'alertState', description: alertStateActionVariableDescription },
+ ...(getAlertDetailsPageEnabledForApp(config, 'metrics')
+ ? [{ name: 'alertDetailsUrl', description: alertDetailUrlActionVariableDescription }]
+ : []),
{ name: 'reason', description: reasonActionVariableDescription },
{ name: 'timestamp', description: timestampActionVariableDescription },
{ name: 'value', description: valueActionVariableDescription },
diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts
index 14b5fe8e75614..200ad68aa81d1 100644
--- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts
+++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts
@@ -26,8 +26,12 @@ import {
// buildRecoveredAlertReason,
stateToAlertMessage,
} from '../common/messages';
-import { UNGROUPED_FACTORY_KEY, getViewInAppUrl, createScopedLogger } from '../common/utils';
-import { LINK_TO_METRICS_EXPLORER } from '../../../../common/alerting/metrics';
+import {
+ createScopedLogger,
+ getAlertDetailsUrl,
+ getViewInMetricsAppUrl,
+ UNGROUPED_FACTORY_KEY,
+} from '../common/utils';
import { EvaluatedRuleParams, evaluateRule } from './lib/evaluate_rule';
@@ -67,11 +71,16 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) =>
MetricThresholdAllowedActionGroups
>(async function (options) {
const startTime = Date.now();
- const { services, params, state, startedAt, alertId, executionId } = options;
+
+ const { services, params, state, startedAt, alertId, executionId, spaceId } = options;
+
const { criteria } = params;
if (criteria.length === 0) throw new Error('Cannot execute an alert with 0 conditions');
+
const logger = createScopedLogger(libs.logger, 'metricThresholdRule', { alertId, executionId });
- const { alertWithLifecycle, savedObjectsClient } = services;
+
+ const { alertWithLifecycle, savedObjectsClient, getAlertUuid } = services;
+
const alertFactory: MetricThresholdAlertFactory = (id, reason) =>
alertWithLifecycle({
id,
@@ -100,15 +109,19 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) =>
const actionGroupId = FIRED_ACTIONS.id; // Change this to an Error action group when able
const reason = buildInvalidQueryAlertReason(params.filterQueryText);
const alert = alertFactory(UNGROUPED_FACTORY_KEY, reason);
+ const alertUuid = getAlertUuid(UNGROUPED_FACTORY_KEY);
+
alert.scheduleActions(actionGroupId, {
- group: UNGROUPED_FACTORY_KEY,
+ alertDetailsUrl: getAlertDetailsUrl(libs.basePath, spaceId, alertUuid),
alertState: stateToAlertMessage[AlertStates.ERROR],
+ group: UNGROUPED_FACTORY_KEY,
+ metric: mapToConditionsLookup(criteria, (c) => c.metric),
reason,
- viewInAppUrl: getViewInAppUrl(libs.basePath, LINK_TO_METRICS_EXPLORER),
timestamp,
value: null,
- metric: mapToConditionsLookup(criteria, (c) => c.metric),
+ viewInAppUrl: getViewInMetricsAppUrl(libs.basePath, spaceId),
});
+
return {
lastRunTimestamp: startedAt.valueOf(),
missingGroups: [],
@@ -157,6 +170,7 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) =>
const hasGroups = !isEqual(groups, [UNGROUPED_FACTORY_KEY]);
let scheduledActionsCount = 0;
+ // The key of `groups` is the alert instance ID.
for (const group of groups) {
// AND logic; all criteria must be across the threshold
const shouldAlertFire = alertResults.every((result) => result[group]?.shouldFire);
@@ -227,40 +241,45 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs) =>
? WARNING_ACTIONS.id
: FIRED_ACTIONS.id;
const alert = alertFactory(`${group}`, reason);
+ const alertUuid = getAlertUuid(group);
scheduledActionsCount++;
+
alert.scheduleActions(actionGroupId, {
- group,
+ alertDetailsUrl: getAlertDetailsUrl(libs.basePath, spaceId, alertUuid),
alertState: stateToAlertMessage[nextState],
+ group,
+ metric: mapToConditionsLookup(criteria, (c) => c.metric),
reason,
- viewInAppUrl: getViewInAppUrl(libs.basePath, LINK_TO_METRICS_EXPLORER),
+ threshold: mapToConditionsLookup(
+ alertResults,
+ (result) => formatAlertResult(result[group]).threshold
+ ),
timestamp,
value: mapToConditionsLookup(
alertResults,
(result) => formatAlertResult(result[group]).currentValue
),
- threshold: mapToConditionsLookup(
- alertResults,
- (result) => formatAlertResult(result[group]).threshold
- ),
- metric: mapToConditionsLookup(criteria, (c) => c.metric),
+ viewInAppUrl: getViewInMetricsAppUrl(libs.basePath, spaceId),
});
}
}
const { getRecoveredAlerts } = services.alertFactory.done();
const recoveredAlerts = getRecoveredAlerts();
+
for (const alert of recoveredAlerts) {
const recoveredAlertId = alert.getId();
- const viewInAppUrl = getViewInAppUrl(libs.basePath, LINK_TO_METRICS_EXPLORER);
- const context = {
- group: recoveredAlertId,
+ const alertUuid = getAlertUuid(recoveredAlertId);
+
+ alert.setContext({
+ alertDetailsUrl: getAlertDetailsUrl(libs.basePath, spaceId, alertUuid),
alertState: stateToAlertMessage[AlertStates.OK],
+ group: recoveredAlertId,
+ metric: mapToConditionsLookup(criteria, (c) => c.metric),
timestamp: startedAt.toISOString(),
- viewInAppUrl,
threshold: mapToConditionsLookup(criteria, (c) => c.threshold),
- metric: mapToConditionsLookup(criteria, (c) => c.metric),
- };
- alert.setContext(context);
+ viewInAppUrl: getViewInMetricsAppUrl(libs.basePath, spaceId),
+ });
}
const stopTime = Date.now();
diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts
index 0ebb427819f74..6538fb25b6c8c 100644
--- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts
+++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/register_metric_threshold_rule_type.ts
@@ -13,6 +13,7 @@ import { Comparator, METRIC_THRESHOLD_ALERT_TYPE_ID } from '../../../../common/a
import { METRIC_EXPLORER_AGGREGATIONS } from '../../../../common/http_api';
import { InfraBackendLibs } from '../../infra_types';
import {
+ alertDetailUrlActionVariableDescription,
alertStateActionVariableDescription,
groupActionVariableDescription,
metricActionVariableDescription,
@@ -22,7 +23,11 @@ import {
valueActionVariableDescription,
viewInAppUrlActionVariableDescription,
} from '../common/messages';
-import { oneOfLiterals, validateIsStringElasticsearchJSONFilter } from '../common/utils';
+import {
+ getAlertDetailsPageEnabledForApp,
+ oneOfLiterals,
+ validateIsStringElasticsearchJSONFilter,
+} from '../common/utils';
import {
createMetricThresholdExecutor,
FIRED_ACTIONS,
@@ -41,6 +46,8 @@ export async function registerMetricThresholdRuleType(
alertingPlugin: PluginSetupContract,
libs: InfraBackendLibs
) {
+ const config = libs.getAlertDetailsConfig();
+
const baseCriterion = {
threshold: schema.arrayOf(schema.number()),
comparator: oneOfLiterals(Object.values(Comparator)),
@@ -93,6 +100,9 @@ export async function registerMetricThresholdRuleType(
actionVariables: {
context: [
{ name: 'group', description: groupActionVariableDescription },
+ ...(getAlertDetailsPageEnabledForApp(config, 'metrics')
+ ? [{ name: 'alertDetailsUrl', description: alertDetailUrlActionVariableDescription }]
+ : []),
{ name: 'alertState', description: alertStateActionVariableDescription },
{ name: 'reason', description: reasonActionVariableDescription },
{ name: 'timestamp', description: timestampActionVariableDescription },
diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts
index 37e59700b0488..3d3c7a17cd1dd 100644
--- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts
+++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/test_mocks.ts
@@ -4,10 +4,6 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-import * as utils from '../common/utils';
-jest
- .spyOn(utils, 'getViewInAppUrl')
- .mockReturnValue('http://localhost:5601/eyg/app/metrics/explorer');
const bucketsA = (from: number) => [
{
diff --git a/x-pack/plugins/infra/server/lib/infra_types.ts b/x-pack/plugins/infra/server/lib/infra_types.ts
index a4636daa7986e..4801fb49651f6 100644
--- a/x-pack/plugins/infra/server/lib/infra_types.ts
+++ b/x-pack/plugins/infra/server/lib/infra_types.ts
@@ -8,6 +8,7 @@
import { Logger } from '@kbn/logging';
import type { IBasePath } from '@kbn/core/server';
import { handleEsError } from '@kbn/es-ui-shared-plugin/server';
+import { ObservabilityConfig } from '@kbn/observability-plugin/server';
import { RulesServiceSetup } from '../services/rules';
import { InfraConfig, InfraPluginStartServicesAccessor } from '../types';
import { KibanaFramework } from './adapters/framework/kibana_framework_adapter';
@@ -24,14 +25,15 @@ export interface InfraDomainLibs {
}
export interface InfraBackendLibs extends InfraDomainLibs {
+ basePath: IBasePath;
configuration: InfraConfig;
framework: KibanaFramework;
- sources: InfraSources;
- sourceStatus: InfraSourceStatus;
- handleEsError: typeof handleEsError;
logsRules: RulesServiceSetup;
metricsRules: RulesServiceSetup;
+ sources: InfraSources;
+ sourceStatus: InfraSourceStatus;
+ getAlertDetailsConfig: () => ObservabilityConfig['unsafe']['alertDetails'];
getStartServices: InfraPluginStartServicesAccessor;
+ handleEsError: typeof handleEsError;
logger: Logger;
- basePath: IBasePath;
}
diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts
index bfd7113ec4dc0..a7fa9ceacd3c9 100644
--- a/x-pack/plugins/infra/server/plugin.ts
+++ b/x-pack/plugins/infra/server/plugin.ts
@@ -170,6 +170,7 @@ export class InfraServerPlugin
logsRules: this.logsRules.setup(core, plugins),
metricsRules: this.metricsRules.setup(core, plugins),
getStartServices: () => core.getStartServices(),
+ getAlertDetailsConfig: () => plugins.observability.getAlertDetailsConfig(),
logger: this.logger,
basePath: core.http.basePath,
};
diff --git a/x-pack/plugins/lens/public/datasources/form_based/field_item.tsx b/x-pack/plugins/lens/public/datasources/form_based/field_item.tsx
index 5ebfecc4cc95a..e2ee0559b3808 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/field_item.tsx
+++ b/x-pack/plugins/lens/public/datasources/form_based/field_item.tsx
@@ -190,6 +190,9 @@ export const InnerFieldItem = function InnerFieldItem(props: FieldItemProps) {
initialFocus=".lnsFieldItem__fieldPanel"
className="lnsFieldItem__popoverAnchor"
data-test-subj="lnsFieldListPanelField"
+ panelProps={{
+ 'data-test-subj': 'lnsFieldListPanelFieldContent',
+ }}
container={document.querySelector('.application') || undefined}
button={
{
- if (params?.noDataFound) {
+ if (params.reason === 'no-data') {
// TODO: should we replace this with a default message "Analysis is not available for this field?"
const isUsingSampling = core.uiSettings.get('lens:useFieldExistenceSampling');
return (
- <>
-
- {isUsingSampling
- ? i18n.translate('xpack.lens.indexPattern.fieldStatsSamplingNoData', {
- defaultMessage:
- 'Lens is unable to create visualizations with this field because it does not contain data in the first 500 documents that match your filters. To create a visualization, drag and drop a different field.',
- })
- : i18n.translate('xpack.lens.indexPattern.fieldStatsNoData', {
- defaultMessage:
- 'Lens is unable to create visualizations with this field because it does not contain data. To create a visualization, drag and drop a different field.',
- })}
-
- >
+
+ {isUsingSampling
+ ? i18n.translate('xpack.lens.indexPattern.fieldStatsSamplingNoData', {
+ defaultMessage:
+ 'Lens is unable to create visualizations with this field because it does not contain data in the first 500 documents that match your filters. To create a visualization, drag and drop a different field.',
+ })
+ : i18n.translate('xpack.lens.indexPattern.fieldStatsNoData', {
+ defaultMessage:
+ 'Lens is unable to create visualizations with this field because it does not contain data. To create a visualization, drag and drop a different field.',
+ })}
+
+ );
+ }
+ if (params.reason === 'unsupported') {
+ return (
+
+ {params.element}
+
);
}
-
return params.element;
}}
/>
diff --git a/x-pack/plugins/lens/public/datasources/form_based/fields_accordion.tsx b/x-pack/plugins/lens/public/datasources/form_based/fields_accordion.tsx
index 105c9583e300d..d6b4c73b51082 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/fields_accordion.tsx
+++ b/x-pack/plugins/lens/public/datasources/form_based/fields_accordion.tsx
@@ -169,14 +169,18 @@ export const FieldsAccordion = memo(function InnerFieldsAccordion({
}
if (hasLoaded) {
return (
-
+
{fieldsCount}
);
}
return ;
- }, [showExistenceFetchError, showExistenceFetchTimeout, hasLoaded, isFiltered, fieldsCount]);
+ }, [showExistenceFetchError, showExistenceFetchTimeout, hasLoaded, isFiltered, id, fieldsCount]);
return (
-1 ? samplingIndex : samplingValue.length - 1;
return (
+
+
+
+
+
+ ),
+ }}
+ />
+
+ >
+ }
label={
<>
{i18n.translate('xpack.lens.xyChart.randomSampling.label', {
- defaultMessage: 'Sampling',
+ defaultMessage: 'Random sampling',
})}{' '}
>
}
>
- {
- setState({
- ...state,
- layers: {
- ...state.layers,
- [layerId]: {
- ...state.layers[layerId],
- sampling: samplingValue[Number(e.currentTarget.value)],
- },
- },
- });
- }}
- showInput={false}
- showRange={false}
- showTicks
- step={1}
- min={0}
- max={samplingValue.length - 1}
- ticks={samplingValue.map((v, i) => ({ label: `${v}`, value: i }))}
- />
+
+
+
+
+
+
+
+ {
+ setState({
+ ...state,
+ layers: {
+ ...state.layers,
+ [layerId]: {
+ ...state.layers[layerId],
+ sampling: samplingValue[Number(e.currentTarget.value)],
+ },
+ },
+ });
+ }}
+ showInput={false}
+ showRange={false}
+ showTicks
+ step={1}
+ min={0}
+ max={samplingValue.length - 1}
+ ticks={samplingValue.map((v, i) => ({ label: `${v * 100}%`, value: i }))}
+ />
+
+
+
+
+
+
+
);
}
diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.test.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.test.ts
index 4c1ba662d1861..a80c039064afd 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.test.ts
+++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.test.ts
@@ -103,4 +103,54 @@ describe('createFormulaPublicApi', () => {
{ indexPattern: {} }
);
});
+
+ test('should pass over advanced parameters as global params for formula', () => {
+ const baseLayer = getBaseLayer();
+
+ publicApiHelper.insertOrReplaceFormulaColumn(
+ 'col',
+ {
+ formula: 'count()',
+ timeScale: 'd',
+ filter: { query: 'myField: *', language: 'kuery' },
+ reducedTimeRange: '30s',
+ },
+ baseLayer,
+ dataView
+ );
+
+ expect(insertOrReplaceFormulaColumn).toHaveBeenCalledWith(
+ 'col',
+ {
+ customLabel: false,
+ dataType: 'number',
+ isBucketed: false,
+ label: 'count()',
+ operationType: 'formula',
+ params: { formula: 'count()', format: undefined },
+ filter: {
+ language: 'kuery',
+ query: 'myField: *',
+ },
+ timeScale: 'd',
+ reducedTimeRange: '30s',
+ references: [],
+ },
+ {
+ columnOrder: ['col1'],
+ columns: {
+ col1: {
+ dataType: 'date',
+ isBucketed: true,
+ label: '@timestamp',
+ operationType: 'date_histogram',
+ params: { interval: 'auto' },
+ scale: 'interval',
+ },
+ },
+ indexPatternId: undefined,
+ },
+ { indexPattern: {} }
+ );
+ });
});
diff --git a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.ts b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.ts
index ab17fd81e84ef..56469d61ad8f3 100644
--- a/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.ts
+++ b/x-pack/plugins/lens/public/datasources/form_based/operations/definitions/formula/formula_public_api.ts
@@ -10,6 +10,7 @@ import { Query } from '@kbn/es-query';
import { convertDataViewIntoLensIndexPattern } from '../../../../../data_views_service/loader';
import type { IndexPattern } from '../../../../../types';
import type { PersistedIndexPatternLayer } from '../../../types';
+import type { TimeScaleUnit } from '../../../../../../common/expressions';
import { insertOrReplaceFormulaColumn } from './parse';
@@ -33,6 +34,8 @@ export interface FormulaPublicApi {
formula: string;
label?: string;
filter?: Query;
+ reducedTimeRange?: string;
+ timeScale?: TimeScaleUnit;
format?: {
id: string;
params?: {
@@ -60,7 +63,12 @@ export const createFormulaPublicApi = (): FormulaPublicApi => {
};
return {
- insertOrReplaceFormulaColumn: (id, { formula, label, format, filter }, layer, dataView) => {
+ insertOrReplaceFormulaColumn: (
+ id,
+ { formula, label, format, filter, reducedTimeRange, timeScale },
+ layer,
+ dataView
+ ) => {
const indexPattern = getCachedLensIndexPattern(dataView);
return insertOrReplaceFormulaColumn(
@@ -73,6 +81,8 @@ export const createFormulaPublicApi = (): FormulaPublicApi => {
references: [],
isBucketed: false,
filter,
+ reducedTimeRange,
+ timeScale,
params: {
formula,
format,
diff --git a/x-pack/plugins/lens/public/datasources/text_based/fields_accordion.tsx b/x-pack/plugins/lens/public/datasources/text_based/fields_accordion.tsx
index 23f71e991bc82..d02fd98bc9c87 100644
--- a/x-pack/plugins/lens/public/datasources/text_based/fields_accordion.tsx
+++ b/x-pack/plugins/lens/public/datasources/text_based/fields_accordion.tsx
@@ -49,14 +49,18 @@ export const FieldsAccordion = memo(function InnerFieldsAccordion({
const extraAction = useMemo(() => {
if (hasLoaded) {
return (
-
+
{fields.length}
);
}
return ;
- }, [fields.length, hasLoaded, isFiltered]);
+ }, [fields.length, hasLoaded, id, isFiltered]);
return (
<>
diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/_layer_toc.scss b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/_layer_toc.scss
index 868c120c31691..a3a03097acb06 100644
--- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/_layer_toc.scss
+++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/_layer_toc.scss
@@ -6,6 +6,10 @@
cursor: alias !important;
}
+.mapLayerToc-droppable-isCombining {
+ background-color: $euiColorEmptyShade !important;
+}
+
.mapLayerToc-droppable-isDragging * {
cursor: ns-resize !important;
}
\ No newline at end of file
diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/layer_toc.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/layer_toc.tsx
index f152d1686b3bd..54a5d13e7702d 100644
--- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/layer_toc.tsx
+++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/layer_toc.tsx
@@ -244,6 +244,10 @@ export class LayerTOC extends Component {
dragHandleProps={draggableProvided.dragHandleProps}
isDragging={draggableSnapshot.isDragging}
isDraggingOver={droppableSnapshot.isDraggingOver}
+ isCombineLayer={
+ this.state.combineLayer !== null &&
+ this.state.combineLayer.getId() === layer.getId()
+ }
/>
);
}}
diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss
index 094d116b78623..959176547dfb2 100644
--- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss
+++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/_toc_entry.scss
@@ -62,6 +62,11 @@
pointer-events: none !important;
}
+.mapTocEntry-isCombineLayer {
+ transition: background-color $euiAnimSpeedExtraSlow ease;
+ background-color: transparentize($euiColorSuccess, .75);
+}
+
.mapTocEntry-isSelected {
background-color: tintOrShade($euiColorLightShade, 60%, 20%);
}
diff --git a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx
index 72eb38f07257e..012c1e97ad528 100644
--- a/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx
+++ b/x-pack/plugins/maps/public/connected_components/right_side_controls/layer_control/layer_toc/toc_entry/toc_entry.tsx
@@ -49,6 +49,7 @@ export interface OwnProps {
dragHandleProps?: DraggableProvidedDragHandleProps;
isDragging?: boolean;
isDraggingOver?: boolean;
+ isCombineLayer?: boolean;
}
type Props = ReduxStateProps & ReduxDispatchProps & OwnProps;
@@ -314,6 +315,7 @@ export class TOCEntry extends Component {
const classes = classNames('mapTocEntry', {
'mapTocEntry-isDragging': this.props.isDragging,
'mapTocEntry-isDraggingOver': this.props.isDraggingOver,
+ 'mapTocEntry-isCombineLayer': this.props.isCombineLayer,
'mapTocEntry-isSelected':
this.props.layer.isPreviewLayer() ||
(this.props.selectedLayer && this.props.selectedLayer.getId() === this.props.layer.getId()),
diff --git a/x-pack/plugins/observability/server/plugin.ts b/x-pack/plugins/observability/server/plugin.ts
index ff5fd246bea1b..dd2a07f848db3 100644
--- a/x-pack/plugins/observability/server/plugin.ts
+++ b/x-pack/plugins/observability/server/plugin.ts
@@ -157,6 +157,9 @@ export class ObservabilityPlugin implements Plugin {
});
return {
+ getAlertDetailsConfig() {
+ return config.unsafe.alertDetails;
+ },
getScopedAnnotationsClient: async (...args: Parameters) => {
const api = await annotationsApiPromise;
return api?.getScopedAnnotationsClient(...args);
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 160e06d03e92a..615201fe44d99 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
@@ -68,7 +68,8 @@ export interface LifecycleAlertServices<
ActionGroupIds extends string = never
> {
alertWithLifecycle: LifecycleAlertService;
- getAlertStartedDate: (alertId: string) => string | null;
+ getAlertStartedDate: (alertInstanceId: string) => string | null;
+ getAlertUuid: (alertInstanceId: string) => string | null;
}
export type LifecycleRuleExecutor<
@@ -88,6 +89,12 @@ export type LifecycleRuleExecutor<
>
) => Promise;
+/*
+ `alertId` will at some point be renamed to `ruleId` as that more
+ accurately describes the meaning of the variable.
+ See https://github.com/elastic/kibana/issues/100115
+*/
+
const trackedAlertStateRt = rt.type({
alertId: rt.string,
alertUuid: rt.string,
@@ -159,6 +166,8 @@ export const createLifecycleExecutor =
const currentAlerts: Record = {};
+ const newAlertUuids: Record = {};
+
const lifecycleAlertServices: LifecycleAlertServices<
InstanceState,
InstanceContext,
@@ -169,6 +178,15 @@ export const createLifecycleExecutor =
return alertFactory.create(id);
},
getAlertStartedDate: (alertId: string) => state.trackedAlerts[alertId]?.started ?? null,
+ getAlertUuid: (alertId: string) => {
+ if (!state.trackedAlerts[alertId]) {
+ const alertUuid = v4();
+ newAlertUuids[alertId] = alertUuid;
+ return alertUuid;
+ }
+
+ return state.trackedAlerts[alertId].alertUuid;
+ },
};
const nextWrappedState = await wrappedExecutor({
@@ -203,9 +221,9 @@ export const createLifecycleExecutor =
commonRuleFields
);
result.forEach((hit) => {
- const alertId = hit._source ? hit._source[ALERT_INSTANCE_ID] : void 0;
- if (alertId && hit._source) {
- trackedAlertsDataMap[alertId] = {
+ const alertInstanceId = hit._source ? hit._source[ALERT_INSTANCE_ID] : void 0;
+ if (alertInstanceId && hit._source) {
+ trackedAlertsDataMap[alertInstanceId] = {
indexName: hit._index,
fields: hit._source,
};
@@ -226,10 +244,12 @@ export const createLifecycleExecutor =
const isRecovered = !currentAlerts[alertId];
const isActive = !isRecovered;
- const { alertUuid, started } = state.trackedAlerts[alertId] ?? {
- alertUuid: v4(),
- started: commonRuleFields[TIMESTAMP],
- };
+ const { alertUuid, started } = !isNew
+ ? state.trackedAlerts[alertId]
+ : {
+ alertUuid: newAlertUuids[alertId] || v4(),
+ started: commonRuleFields[TIMESTAMP],
+ };
const event: ParsedTechnicalFields & ParsedExperimentalFields = {
...alertData?.fields,
@@ -249,8 +269,8 @@ export const createLifecycleExecutor =
[ALERT_WORKFLOW_STATUS]: alertData?.fields[ALERT_WORKFLOW_STATUS] ?? 'open',
[EVENT_KIND]: 'signal',
[EVENT_ACTION]: isNew ? 'open' : isActive ? 'active' : 'close',
- [VERSION]: ruleDataClient.kibanaVersion,
[TAGS]: options.tags,
+ [VERSION]: ruleDataClient.kibanaVersion,
...(isRecovered ? { [ALERT_END]: commonRuleFields[TIMESTAMP] } : {}),
};
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 f71c7391cec77..132eb096e0aaa 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
@@ -40,6 +40,11 @@ function createRule(shouldWriteAlerts: boolean = true) {
name: 'warning',
},
],
+ actionVariables: {
+ context: [],
+ params: [],
+ state: [],
+ },
defaultActionGroupId: 'warning',
executor: async ({ services }) => {
nextAlerts.forEach((alert) => {
@@ -48,17 +53,17 @@ function createRule(shouldWriteAlerts: boolean = true) {
nextAlerts = [];
},
id: 'ruleTypeId',
- minimumLicenseRequired: 'basic',
isExportable: true,
+ minimumLicenseRequired: 'basic',
name: 'ruleTypeName',
producer: 'producer',
- actionVariables: {
- context: [],
- params: [],
- state: [],
- },
validate: {
- params: schema.object({}, { unknowns: 'allow' }),
+ params: schema.object(
+ {},
+ {
+ unknowns: 'allow',
+ }
+ ),
},
});
@@ -92,10 +97,12 @@ function createRule(shouldWriteAlerts: boolean = true) {
state = ((await type.executor({
alertId: 'alertId',
createdBy: 'createdBy',
+ executionId: 'b33f65d7-6e8b-4aae-8d20-c93613dec9f9',
+ logger: loggerMock.create(),
name: 'name',
+ namespace: 'namespace',
params: {},
previousStartedAt,
- startedAt,
rule: {
actions: [],
consumer: 'consumer',
@@ -118,20 +125,18 @@ function createRule(shouldWriteAlerts: boolean = true) {
services: {
alertFactory,
savedObjectsClient: {} as any,
- uiSettingsClient: {} as any,
scopedClusterClient: {} as any,
- shouldWriteAlerts: () => shouldWriteAlerts,
- shouldStopExecution: () => false,
search: {} as any,
searchSourceClient: {} as ISearchStartSearchSource,
+ shouldStopExecution: () => false,
+ shouldWriteAlerts: () => shouldWriteAlerts,
+ uiSettingsClient: {} as any,
},
spaceId: 'spaceId',
+ startedAt,
state,
tags: ['tags'],
updatedBy: 'updatedBy',
- namespace: 'namespace',
- executionId: 'b33f65d7-6e8b-4aae-8d20-c93613dec9f9',
- logger: loggerMock.create(),
})) ?? {}) as Record;
previousStartedAt = startedAt;
diff --git a/x-pack/plugins/rule_registry/server/utils/lifecycle_alert_services.mock.ts b/x-pack/plugins/rule_registry/server/utils/lifecycle_alert_services.mock.ts
index 5465e7a7922c5..a383110394da7 100644
--- a/x-pack/plugins/rule_registry/server/utils/lifecycle_alert_services.mock.ts
+++ b/x-pack/plugins/rule_registry/server/utils/lifecycle_alert_services.mock.ts
@@ -36,4 +36,5 @@ export const createLifecycleAlertServicesMock = <
): LifecycleAlertServices => ({
alertWithLifecycle: ({ id }) => alertServices.alertFactory.create(id),
getAlertStartedDate: jest.fn((id: string) => null),
+ getAlertUuid: jest.fn((id: string) => null),
});
diff --git a/x-pack/plugins/security_solution/common/endpoint/constants.ts b/x-pack/plugins/security_solution/common/endpoint/constants.ts
index 3aa4fe007a959..078adada6d2b6 100644
--- a/x-pack/plugins/security_solution/common/endpoint/constants.ts
+++ b/x-pack/plugins/security_solution/common/endpoint/constants.ts
@@ -42,8 +42,8 @@ export const policyIndexPattern = 'metrics-endpoint.policy-*';
export const telemetryIndexPattern = 'metrics-endpoint.telemetry-*';
// File storage indexes supporting endpoint Upload/download
-export const FILE_STORAGE_METADATA_INDEX = '.fleet-files';
-export const FILE_STORAGE_DATA_INDEX = '.fleet-file_data';
+export const FILE_STORAGE_METADATA_INDEX = '.fleet-endpoint-files';
+export const FILE_STORAGE_DATA_INDEX = '.fleet-endpoint-file-data';
// Endpoint API routes
export const BASE_ENDPOINT_ROUTE = '/api/endpoint';
@@ -73,6 +73,7 @@ export const GET_FILE_ROUTE = `${BASE_ENDPOINT_ACTION_ROUTE}/get_file`;
export const ENDPOINT_ACTION_LOG_ROUTE = `${BASE_ENDPOINT_ROUTE}/action_log/{agent_id}`;
export const ACTION_STATUS_ROUTE = `${BASE_ENDPOINT_ROUTE}/action_status`;
export const ACTION_DETAILS_ROUTE = `${BASE_ENDPOINT_ACTION_ROUTE}/{action_id}`;
+export const ACTION_AGENT_FILE_INFO_ROUTE = `${BASE_ENDPOINT_ACTION_ROUTE}/{action_id}/{agent_id}/file`;
export const ACTION_AGENT_FILE_DOWNLOAD_ROUTE = `${BASE_ENDPOINT_ACTION_ROUTE}/{action_id}/{agent_id}/file/download`;
export const ENDPOINTS_ACTION_LIST_ROUTE = `${BASE_ENDPOINT_ROUTE}/action`;
diff --git a/x-pack/plugins/security_solution/common/endpoint/data_generators/base_data_generator.ts b/x-pack/plugins/security_solution/common/endpoint/data_generators/base_data_generator.ts
index 868129f3a6737..01ecc95524b27 100644
--- a/x-pack/plugins/security_solution/common/endpoint/data_generators/base_data_generator.ts
+++ b/x-pack/plugins/security_solution/common/endpoint/data_generators/base_data_generator.ts
@@ -68,6 +68,41 @@ const USERS = [
'Genevieve',
];
+const toEsSearchHit = (
+ hitSource: T,
+ index: string = 'some-index'
+): estypes.SearchHit => {
+ return {
+ _index: index,
+ _id: '123',
+ _score: 1.0,
+ _source: hitSource,
+ };
+};
+
+const toEsSearchResponse = (
+ hitsSource: Array>
+): estypes.SearchResponse => {
+ return {
+ took: 3,
+ timed_out: false,
+ _shards: {
+ total: 2,
+ successful: 2,
+ skipped: 0,
+ failed: 0,
+ },
+ hits: {
+ total: {
+ value: hitsSource.length,
+ relation: 'eq',
+ },
+ max_score: 0,
+ hits: hitsSource,
+ },
+ };
+};
+
/**
* A generic base class to assist in creating domain specific data generators. It includes
* several general purpose random data generators for use within the class and exposes one
@@ -193,12 +228,17 @@ export class BaseDataGenerator {
hitSource: T,
index: string = 'some-index'
): estypes.SearchHit {
- return {
- _index: index,
- _id: this.seededUUIDv4(),
- _score: 1.0,
- _source: hitSource,
- };
+ const hit = toEsSearchHit(hitSource, index);
+ hit._id = this.seededUUIDv4();
+
+ return hit;
+ }
+
+ static toEsSearchHit(
+ hitSource: T,
+ index: string = 'some-index'
+ ): estypes.SearchHit {
+ return toEsSearchHit(hitSource, index);
}
/**
@@ -209,23 +249,12 @@ export class BaseDataGenerator {
toEsSearchResponse(
hitsSource: Array>
): estypes.SearchResponse {
- return {
- took: 3,
- timed_out: false,
- _shards: {
- total: 2,
- successful: 2,
- skipped: 0,
- failed: 0,
- },
- hits: {
- total: {
- value: hitsSource.length,
- relation: 'eq',
- },
- max_score: 0,
- hits: hitsSource,
- },
- };
+ return toEsSearchResponse(hitsSource);
+ }
+
+ static toEsSearchResponse(
+ hitsSource: Array>
+ ): estypes.SearchResponse {
+ return toEsSearchResponse(hitsSource);
}
}
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 e9531e48d0784..f8af9d8005893 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
@@ -88,7 +88,7 @@ export class EndpointActionGenerator extends BaseDataGenerator {
output = {
type: 'json',
content: {
- code: 'ra_get-file_success',
+ code: 'ra_get-file_success_done',
path: '/some/path/bad_file.txt',
size: 1234,
zip_size: 123,
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 cb9a1d98eb326..310fbcbea326b 100644
--- a/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts
+++ b/x-pack/plugins/security_solution/common/endpoint/schema/actions.ts
@@ -139,3 +139,13 @@ export const EndpointActionFileDownloadSchema = {
export type EndpointActionFileDownloadParams = TypeOf<
typeof EndpointActionFileDownloadSchema.params
>;
+
+/** Schema that validates the file info API */
+export const EndpointActionFileInfoSchema = {
+ params: schema.object({
+ action_id: schema.string({ minLength: 1 }),
+ agent_id: schema.string({ minLength: 1 }),
+ }),
+};
+
+export type EndpointActionFileInfoParams = TypeOf;
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 2d455bb6a839f..8ac8745a5d35b 100644
--- a/x-pack/plugins/security_solution/common/endpoint/types/actions.ts
+++ b/x-pack/plugins/security_solution/common/endpoint/types/actions.ts
@@ -6,6 +6,7 @@
*/
import type { TypeOf } from '@kbn/config-schema';
+import type { FileJSON } from '@kbn/files-plugin/common';
import type {
ActionStatusRequestSchema,
NoParametersRequestSchema,
@@ -360,3 +361,12 @@ export interface ActionListApiResponse {
statuses: ResponseActionStatus[] | undefined;
total: number;
}
+
+export type UploadedFileInfo = Pick<
+ FileJSON,
+ 'name' | 'id' | 'mimeType' | 'size' | 'status' | 'created'
+>;
+
+export interface ActionFileInfoApiResponse {
+ data: UploadedFileInfo;
+}
diff --git a/x-pack/plugins/security_solution/common/endpoint/types/file_storage.ts b/x-pack/plugins/security_solution/common/endpoint/types/file_storage.ts
deleted file mode 100644
index 9ed8065197921..0000000000000
--- a/x-pack/plugins/security_solution/common/endpoint/types/file_storage.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-/**
- * The Metadata information about a file that was uploaded by Endpoint
- * as a result of a `get-file` response action
- */
-export interface UploadedFile {
- file: {
- /** The chunk size used for each chunk in this file */
- ChunkSize?: number;
- /**
- * - `AWAITING_UPLOAD`: file metadata has been created. File is ready to be uploaded.
- * - `UPLOADING`: file contents are being uploaded.
- * - `READY`: file has been uploaded, successfully, without errors.
- * - `UPLOAD_ERROR`: an error happened while the file was being uploaded, file contents
- * are most likely corrupted.
- * - `DELETED`: file is deleted. Files can be marked as deleted before the actual deletion
- * of the contents and metadata happens. Deleted files should be treated as if they don’t
- * exist. Only files in READY state can transition into DELETED state.
- */
- Status: 'AWAITING_UPLOAD' | 'UPLOADING' | 'READY' | 'UPLOAD_ERROR' | 'DELETED';
- /** File extension (if any) */
- extension?: string;
- hash?: {
- md5?: string;
- sha1?: string;
- sha256?: string;
- sha384?: string;
- sha512?: string;
- ssdeep?: string;
- tlsh?: string;
- };
- mime_type?: string;
- mode?: string;
- /** File name */
- name: string;
- /** The full path to the file on the host machine */
- path: string;
- /** The total size in bytes */
- size: number;
- created?: string;
- type: string;
- };
-}
diff --git a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/integration_tests/get_file_action.test.tsx b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/integration_tests/get_file_action.test.tsx
index 2f8b84c81e038..d69771446038f 100644
--- a/x-pack/plugins/security_solution/public/management/components/endpoint_responder/integration_tests/get_file_action.test.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/endpoint_responder/integration_tests/get_file_action.test.tsx
@@ -22,6 +22,7 @@ import { GET_FILE_ROUTE } from '../../../../../common/endpoint/constants';
import { getEndpointAuthzInitialStateMock } from '../../../../../common/endpoint/service/authz/mocks';
import type { EndpointPrivileges } from '../../../../../common/endpoint/types';
import { INSUFFICIENT_PRIVILEGES_FOR_COMMAND } from '../../../../common/translations';
+import type { HttpFetchOptionsWithPath } from '@kbn/core-http-browser';
jest.mock('../../../../common/components/user_privileges');
@@ -128,6 +129,19 @@ describe('When using get-file action from response actions console', () => {
});
it('should display download link once action completes', async () => {
+ const actionDetailsApiResponseMock: ReturnType =
+ {
+ data: {
+ ...apiMocks.responseProvider.actionDetails({
+ path: '/1',
+ } as HttpFetchOptionsWithPath).data,
+
+ completedAt: new Date().toISOString(),
+ command: 'get-file',
+ },
+ };
+ apiMocks.responseProvider.actionDetails.mockReturnValue(actionDetailsApiResponseMock);
+
await render();
enterConsoleCommand(renderResult, 'get-file --path="one/two"');
@@ -135,8 +149,10 @@ describe('When using get-file action from response actions console', () => {
expect(apiMocks.responseProvider.actionDetails).toHaveBeenCalled();
});
- expect(renderResult.getByTestId('getFileSuccess').textContent).toEqual(
- 'File retrieved from the host.Click here to download(ZIP file passcode: elastic)'
- );
+ await waitFor(() => {
+ expect(renderResult.getByTestId('getFileSuccess').textContent).toEqual(
+ 'File retrieved from the host.Click here to download(ZIP file passcode: elastic)'
+ );
+ });
});
});
diff --git a/x-pack/plugins/security_solution/public/management/components/response_action_file_download_link/response_action_file_download_link.test.tsx b/x-pack/plugins/security_solution/public/management/components/response_action_file_download_link/response_action_file_download_link.test.tsx
new file mode 100644
index 0000000000000..c243687b67378
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/management/components/response_action_file_download_link/response_action_file_download_link.test.tsx
@@ -0,0 +1,185 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license 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 { AppContextTestRender } from '../../../common/mock/endpoint';
+import { createAppRootMockRenderer } from '../../../common/mock/endpoint';
+import type {
+ ActionDetails,
+ ResponseActionGetFileOutputContent,
+ ResponseActionGetFileParameters,
+} from '../../../../common/endpoint/types';
+import React from 'react';
+import type { ResponseActionFileDownloadLinkProps } from './response_action_file_download_link';
+import { EndpointActionGenerator } from '../../../../common/endpoint/data_generators/endpoint_action_generator';
+import {
+ FILE_NO_LONGER_AVAILABLE_MESSAGE,
+ ResponseActionFileDownloadLink,
+} from './response_action_file_download_link';
+import { responseActionsHttpMocks } from '../../mocks/response_actions_http_mocks';
+import { useUserPrivileges as _useUserPrivileges } from '../../../common/components/user_privileges';
+import { getDeferred } from '../../mocks/utils';
+import { waitFor } from '@testing-library/react';
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+
+jest.mock('../../../common/components/user_privileges');
+
+describe('When using the `ResponseActionFileDownloadLink` component', () => {
+ const useUserPrivilegesMock = _useUserPrivileges as jest.Mock<
+ ReturnType
+ >;
+
+ let render: () => ReturnType;
+ let renderResult: ReturnType;
+ let renderProps: ResponseActionFileDownloadLinkProps;
+ let apiMocks: ReturnType;
+
+ beforeEach(() => {
+ const appTestContext = createAppRootMockRenderer();
+
+ apiMocks = responseActionsHttpMocks(appTestContext.coreStart.http);
+
+ renderProps = {
+ action: new EndpointActionGenerator('seed').generateActionDetails<
+ ResponseActionGetFileOutputContent,
+ ResponseActionGetFileParameters
+ >({ command: 'get-file', completedAt: new Date().toISOString() }),
+ 'data-test-subj': 'test',
+ };
+
+ render = () => {
+ renderResult = appTestContext.render();
+ return renderResult;
+ };
+ });
+
+ it('should show download button if file is available', () => {
+ render();
+
+ expect(renderResult.getByTestId('test-downloadButton')).not.toBeNull();
+ expect(renderResult.getByTestId('test-passcodeMessage')).toHaveTextContent(
+ '(ZIP file passcode: elastic)'
+ );
+ });
+
+ it('should display custom button label', () => {
+ renderProps.buttonTitle = 'hello';
+ render();
+
+ expect(renderResult.getByTestId('test-downloadButton')).toHaveTextContent('hello');
+ });
+
+ it('should show loading indicator while calling file info api', async () => {
+ const deferred = getDeferred();
+
+ apiMocks.responseProvider.fileInfo.mockDelay.mockReturnValue(deferred.promise);
+ (renderProps.action as ActionDetails).completedAt = '2021-04-15T16:08:47.449Z';
+
+ render();
+
+ expect(renderResult.getByTestId('test-loading')).not.toBeNull();
+
+ // Release the `file info` api
+ deferred.resolve();
+
+ await waitFor(() => {
+ expect(apiMocks.responseProvider.fileInfo).toHaveBeenCalledWith({
+ path: '/api/endpoint/action/123/agent-a/file',
+ });
+ });
+
+ expect(renderResult.getByTestId('test-downloadButton')).not.toBeNull();
+ });
+
+ it('should show file no longer available message if status is DELETED', async () => {
+ const fileInfoApiResponseMock = apiMocks.responseProvider.fileInfo();
+
+ fileInfoApiResponseMock.data.status = 'DELETED';
+ apiMocks.responseProvider.fileInfo.mockReturnValue(fileInfoApiResponseMock);
+
+ (renderProps.action as ActionDetails).completedAt = '2021-04-15T16:08:47.449Z';
+
+ render();
+
+ await waitFor(() => {
+ expect(renderResult.getByTestId('test-fileNoLongerAvailable')).toHaveTextContent(
+ FILE_NO_LONGER_AVAILABLE_MESSAGE
+ );
+ });
+ });
+
+ it('should show file no longer available message if file info api returns 404', async () => {
+ const error = { message: 'not found', response: { status: 404 } } as IHttpFetchError;
+
+ (renderProps.action as ActionDetails).completedAt = '2021-04-15T16:08:47.449Z';
+ apiMocks.responseProvider.fileInfo.mockImplementation(() => {
+ throw error;
+ });
+
+ render();
+
+ await waitFor(() => {
+ expect(renderResult.getByTestId('test-fileNoLongerAvailable')).toHaveTextContent(
+ FILE_NO_LONGER_AVAILABLE_MESSAGE
+ );
+ });
+ });
+
+ it('should show file info API error if one was encountered', async () => {
+ const error = { message: 'server error', response: { status: 500 } } as IHttpFetchError;
+
+ (renderProps.action as ActionDetails).completedAt = '2021-04-15T16:08:47.449Z';
+ apiMocks.responseProvider.fileInfo.mockImplementation(() => {
+ throw error;
+ });
+
+ render();
+
+ await waitFor(() => {
+ expect(renderResult.getByTestId('test-apiError')).toHaveTextContent('server error');
+ });
+ });
+
+ it('should show nothing if user does not have authz', () => {
+ const privileges = useUserPrivilegesMock();
+
+ useUserPrivilegesMock.mockImplementationOnce(() => {
+ return {
+ ...privileges,
+ endpointPrivileges: {
+ ...privileges.endpointPrivileges,
+ canWriteFileOperations: false,
+ },
+ };
+ });
+
+ render();
+
+ expect(apiMocks.responseProvider.fileInfo).not.toHaveBeenCalled();
+ expect(renderResult.container.children.length).toBe(0);
+ });
+
+ it('should show nothing if action is not complete', () => {
+ const action = renderProps.action as ActionDetails;
+ action.completedAt = undefined;
+ action.isCompleted = false;
+
+ render();
+
+ expect(apiMocks.responseProvider.fileInfo).not.toHaveBeenCalled();
+ expect(renderResult.container.children.length).toBe(0);
+ });
+
+ it('should show nothing if action was not successful', () => {
+ const action = renderProps.action as ActionDetails;
+ action.wasSuccessful = false;
+
+ render();
+
+ expect(apiMocks.responseProvider.fileInfo).not.toHaveBeenCalled();
+ expect(renderResult.container.children.length).toBe(0);
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/management/components/response_action_file_download_link/response_action_file_download_link.tsx b/x-pack/plugins/security_solution/public/management/components/response_action_file_download_link/response_action_file_download_link.tsx
index 6c01b2284e997..e873a4ce253f7 100644
--- a/x-pack/plugins/security_solution/public/management/components/response_action_file_download_link/response_action_file_download_link.tsx
+++ b/x-pack/plugins/security_solution/public/management/components/response_action_file_download_link/response_action_file_download_link.tsx
@@ -6,15 +6,19 @@
*/
import type { CSSProperties } from 'react';
-import React, { memo } from 'react';
-import { EuiButtonEmpty, EuiText } from '@elastic/eui';
+import React, { memo, useMemo } from 'react';
+import { EuiButtonEmpty, EuiLoadingContent, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
+import moment from 'moment';
+import { resolvePathVariables } from '../../../common/utils/resolve_path_variables';
+import { FormattedError } from '../formatted_error';
+import { useGetFileInfo } from '../../hooks/endpoint/use_get_file_info';
import { useUserPrivileges } from '../../../common/components/user_privileges';
import { useTestIdGenerator } from '../../hooks/use_test_id_generator';
import type { MaybeImmutable } from '../../../../common/endpoint/types';
-import { getHostActionFileDownloadUrl } from '../../services/response_actions/get_host_action_file_download_url';
import type { ActionDetails } from '../../../../common/endpoint/types/actions';
+import { ACTION_AGENT_FILE_DOWNLOAD_ROUTE } from '../../../../common/endpoint/constants';
const STYLE_INHERIT_FONT_FAMILY = Object.freeze({
fontFamily: 'inherit',
@@ -25,8 +29,15 @@ const DEFAULT_BUTTON_TITLE = i18n.translate(
{ defaultMessage: 'Click here to download' }
);
+export const FILE_NO_LONGER_AVAILABLE_MESSAGE = i18n.translate(
+ 'xpack.securitySolution.responseActionFileDownloadLink.fileNoLongerAvailable',
+ { defaultMessage: 'File is no longer available for download.' }
+);
+
export interface ResponseActionFileDownloadLinkProps {
action: MaybeImmutable;
+ /** If left undefined, the first agent that the action was sent to will be used */
+ agentId?: string;
buttonTitle?: string;
'data-test-subj'?: string;
}
@@ -38,18 +49,57 @@ export interface ResponseActionFileDownloadLinkProps {
* NOTE: Currently displays only the link for the first host in the Action
*/
export const ResponseActionFileDownloadLink = memo(
- ({ action, buttonTitle = DEFAULT_BUTTON_TITLE, 'data-test-subj': dataTestSubj }) => {
+ ({ action, agentId, buttonTitle = DEFAULT_BUTTON_TITLE, 'data-test-subj': dataTestSubj }) => {
const getTestId = useTestIdGenerator(dataTestSubj);
const { canWriteFileOperations } = useUserPrivileges().endpointPrivileges;
- if (!canWriteFileOperations) {
+ // We don't need to call the file info API every time, especially if this component is used from the
+ // console, where the link is displayed within a short time. So we only do the API call if the
+ // action was completed more than 2 days ago.
+ const checkIfStillAvailable = useMemo(() => {
+ return (
+ action.isCompleted && action.wasSuccessful && moment().diff(action.completedAt, 'days') > 2
+ );
+ }, [action.completedAt, action.isCompleted, action.wasSuccessful]);
+
+ const downloadUrl = useMemo(() => {
+ return resolvePathVariables(ACTION_AGENT_FILE_DOWNLOAD_ROUTE, {
+ action_id: action.id,
+ agent_id: agentId ?? action.agents[0],
+ });
+ }, [action.agents, action.id, agentId]);
+
+ const {
+ isFetching,
+ data: fileInfo,
+ error,
+ } = useGetFileInfo(action, undefined, {
+ enabled: canWriteFileOperations && checkIfStillAvailable,
+ });
+
+ if (!canWriteFileOperations || !action.isCompleted || !action.wasSuccessful) {
return null;
}
+ if (isFetching) {
+ return ;
+ }
+
+ // Check if file is no longer available
+ if ((error && error?.response?.status === 404) || fileInfo?.data.status === 'DELETED') {
+ return (
+
+ {FILE_NO_LONGER_AVAILABLE_MESSAGE}
+
+ );
+ } else if (error) {
+ return ;
+ }
+
return (
<>
{
+ const actualReactQueryModule = jest.requireActual('@tanstack/react-query');
+
+ return {
+ ...actualReactQueryModule,
+ useQuery: jest.fn((...args) => actualReactQueryModule.useQuery(...args)),
+ };
+});
+
+describe('When using the `useGetFileInfo()` hook', () => {
+ let renderReactQueryHook: ReactQueryHookRenderer<
+ Parameters,
+ ReturnType
+ >;
+ let http: AppContextTestRender['coreStart']['http'];
+ let apiMocks: ReturnType;
+ let actionDetailsMock: ActionDetails;
+
+ beforeEach(() => {
+ const testContext = createAppRootMockRenderer();
+
+ renderReactQueryHook = testContext.renderReactQueryHook as typeof renderReactQueryHook;
+ http = testContext.coreStart.http;
+
+ apiMocks = responseActionsHttpMocks(http);
+
+ actionDetailsMock = new EndpointActionGenerator('seed').generateActionDetails<
+ ResponseActionGetFileOutputContent,
+ ResponseActionGetFileParameters
+ >({
+ command: 'get-file',
+ });
+ });
+
+ it('should call the correct API', async () => {
+ await renderReactQueryHook(() => useGetFileInfo(actionDetailsMock));
+
+ expect(apiMocks.responseProvider.fileInfo).toHaveBeenCalledWith({
+ path: resolvePathVariables(ACTION_AGENT_FILE_INFO_ROUTE, {
+ action_id: '123',
+ agent_id: 'agent-a',
+ }),
+ });
+ });
+
+ it('should allow specific agent id to be set on input', async () => {
+ await renderReactQueryHook(() => useGetFileInfo(actionDetailsMock, 'abc'));
+
+ expect(apiMocks.responseProvider.fileInfo).toHaveBeenCalledWith({
+ path: resolvePathVariables(ACTION_AGENT_FILE_INFO_ROUTE, {
+ action_id: '123',
+ agent_id: 'abc',
+ }),
+ });
+ });
+
+ it('should allow custom options ot be used', async () => {
+ await renderReactQueryHook(() =>
+ useGetFileInfo(actionDetailsMock, undefined, {
+ queryKey: ['a', 'b'],
+ enabled: true,
+ retry: false,
+ })
+ );
+
+ expect(useQueryMock).toHaveBeenCalledWith(
+ expect.objectContaining({
+ queryKey: ['a', 'b'],
+ enabled: true,
+ retry: false,
+ })
+ );
+ });
+});
diff --git a/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_file_info.ts b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_file_info.ts
new file mode 100644
index 0000000000000..c4c2905bfd1f8
--- /dev/null
+++ b/x-pack/plugins/security_solution/public/management/hooks/endpoint/use_get_file_info.ts
@@ -0,0 +1,45 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { UseQueryOptions, UseQueryResult } from '@tanstack/react-query';
+import type { IHttpFetchError } from '@kbn/core-http-browser';
+import { useQuery } from '@tanstack/react-query';
+import { resolvePathVariables } from '../../../common/utils/resolve_path_variables';
+import { useHttp } from '../../../common/lib/kibana/hooks';
+import type {
+ ActionDetails,
+ ActionFileInfoApiResponse,
+ MaybeImmutable,
+} from '../../../../common/endpoint/types';
+import { ACTION_AGENT_FILE_INFO_ROUTE } from '../../../../common/endpoint/constants';
+
+/**
+ * Retrieves information about a file that was uploaded by the endpoint as a result of a `get-file` action
+ * @param action
+ * @param [agentId] If left undefined, the first agent that the action was sent to will be used
+ * @param [options]
+ */
+export const useGetFileInfo = (
+ action: MaybeImmutable,
+ agentId?: string,
+ options: UseQueryOptions = {}
+): UseQueryResult => {
+ const http = useHttp();
+
+ return useQuery({
+ queryKey: ['get-action-file-info', action.id, agentId ?? action.agents[0]],
+ ...options,
+ queryFn: () => {
+ const apiUrl = resolvePathVariables(ACTION_AGENT_FILE_INFO_ROUTE, {
+ action_id: action.id,
+ agent_id: agentId ?? action.agents[0],
+ });
+
+ return http.get(apiUrl);
+ },
+ });
+};
diff --git a/x-pack/plugins/security_solution/public/management/mocks/response_actions_http_mocks.ts b/x-pack/plugins/security_solution/public/management/mocks/response_actions_http_mocks.ts
index bc23427631fb9..52aa80b35586b 100644
--- a/x-pack/plugins/security_solution/public/management/mocks/response_actions_http_mocks.ts
+++ b/x-pack/plugins/security_solution/public/management/mocks/response_actions_http_mocks.ts
@@ -17,6 +17,7 @@ import {
KILL_PROCESS_ROUTE,
SUSPEND_PROCESS_ROUTE,
GET_FILE_ROUTE,
+ ACTION_AGENT_FILE_INFO_ROUTE,
} from '../../../common/endpoint/constants';
import type { ResponseProvidersInterface } from '../../common/mock/endpoint/http_handler_mock_factory';
import { httpHandlerMockFactory } from '../../common/mock/endpoint/http_handler_mock_factory';
@@ -29,6 +30,7 @@ import type {
GetProcessesActionOutputContent,
ResponseActionGetFileOutputContent,
ResponseActionGetFileParameters,
+ ActionFileInfoApiResponse,
} from '../../../common/endpoint/types';
export type ResponseActionsHttpMocksInterface = ResponseProvidersInterface<{
@@ -49,6 +51,8 @@ export type ResponseActionsHttpMocksInterface = ResponseProvidersInterface<{
processes: () => ActionDetailsApiResponse;
getFile: () => ActionDetailsApiResponse;
+
+ fileInfo: () => ActionFileInfoApiResponse;
}>;
export const responseActionsHttpMocks = httpHandlerMockFactory([
@@ -175,4 +179,21 @@ export const responseActionsHttpMocks = httpHandlerMockFactory {
+ return {
+ data: {
+ created: '2022-10-10T14:57:30.682Z',
+ id: '123',
+ mimeType: 'text/plain',
+ name: 'test.txt',
+ size: 1234,
+ status: 'READY',
+ },
+ };
+ },
+ },
]);
diff --git a/x-pack/plugins/security_solution/public/management/services/response_actions/get_host_action_file_download_url.ts b/x-pack/plugins/security_solution/public/management/services/response_actions/get_host_action_file_download_url.ts
deleted file mode 100644
index 5061c6cd36457..0000000000000
--- a/x-pack/plugins/security_solution/public/management/services/response_actions/get_host_action_file_download_url.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import { resolvePathVariables } from '../../../common/utils/resolve_path_variables';
-import { ACTION_AGENT_FILE_DOWNLOAD_ROUTE } from '../../../../common/endpoint/constants';
-import type { ActionDetails, MaybeImmutable } from '../../../../common/endpoint/types';
-
-/**
- * get the download URL for a `get-file` action
- * @param action
- * @param agentId
- */
-export const getHostActionFileDownloadUrl = (
- action: MaybeImmutable,
- agentId?: string
-): string => {
- return resolvePathVariables(ACTION_AGENT_FILE_DOWNLOAD_ROUTE, {
- action_id: action.id,
- agent_id: agentId ?? action.agents[0],
- });
-};
diff --git a/x-pack/plugins/security_solution/scripts/endpoint/agent_emulator/services/endpoint_response_actions.ts b/x-pack/plugins/security_solution/scripts/endpoint/agent_emulator/services/endpoint_response_actions.ts
index 8daeae3a28767..e778a94e90ac9 100644
--- a/x-pack/plugins/security_solution/scripts/endpoint/agent_emulator/services/endpoint_response_actions.ts
+++ b/x-pack/plugins/security_solution/scripts/endpoint/agent_emulator/services/endpoint_response_actions.ts
@@ -9,8 +9,8 @@ import type { KbnClient } from '@kbn/test';
import type { Client } from '@elastic/elasticsearch';
import { AGENT_ACTIONS_RESULTS_INDEX } from '@kbn/fleet-plugin/common';
import * as cborx from 'cbor-x';
+import { basename } from 'path';
import { getFileDownloadId } from '../../../../common/endpoint/service/response_actions/get_file_download_id';
-import type { UploadedFile } from '../../../../common/endpoint/types/file_storage';
import { checkInFleetAgent } from '../../common/fleet_services';
import { sendEndpointMetadataUpdate } from '../../common/endpoint_metadata_services';
import { FleetActionGenerator } from '../../../../common/endpoint/data_generators/fleet_action_generator';
@@ -181,22 +181,45 @@ export const sendEndpointActionResponse = async (
// For `get-file`, upload a file to ES
if (action.command === 'get-file' && !endpointResponse.error) {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ const filePath = (
+ action as ActionDetails
+ )?.parameters?.path!;
+
+ const fileName = basename(filePath.replace(/\\/g, '/'));
+
// Index the file's metadata
- const fileMeta = await esClient.index({
+ const fileMeta = await esClient.index({
index: FILE_STORAGE_METADATA_INDEX,
id: getFileDownloadId(action, action.agents[0]),
body: {
+ action_id: action.id,
+ agent_id: action.agents[0],
+ contents: [
+ {
+ hash: {
+ sha256: '8d61673c9d782297b3c774ded4e3d88f31a8869a8f25cf5cdd402ba6822d1d28',
+ },
+ name: fileName ?? 'bad_file.txt',
+ path: filePath,
+ size: 4,
+ type: 'file',
+ },
+ ],
file: {
- created: new Date().toISOString(),
- extension: 'zip',
- path: '/some/path/bad_file.txt',
- type: 'file',
- size: 221,
- name: 'bad_file.txt.zip',
+ attributes: ['archive', 'compressed'],
+ ChunkSize: 4194304,
+ Compression: 'deflate',
+ hash: {
+ sha256: '8d61673c9d782297b3c774ded4e3d88f31a8869a8f25cf5cdd402ba6822d1d28',
+ },
mime_type: 'application/zip',
+ name: 'upload.zip',
+ size: 125,
Status: 'READY',
- ChunkSize: 4194304,
+ type: 'file',
},
+ source: 'endpoint',
},
refresh: 'wait_for',
});
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/file_info_handler.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/file_info_handler.test.ts
new file mode 100644
index 0000000000000..fa3c7e392d91e
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/file_info_handler.test.ts
@@ -0,0 +1,141 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { getActionDetailsById as _getActionDetailsById } from '../../services';
+import type { HttpApiTestSetupMock } from '../../mocks';
+import { createHttpApiTestSetupMock } from '../../mocks';
+import type { EndpointActionFileDownloadParams } from '../../../../common/endpoint/schema/actions';
+import { getActionFileInfoRouteHandler, registerActionFileInfoRoute } from './file_info_handler';
+import { ACTION_AGENT_FILE_INFO_ROUTE } from '../../../../common/endpoint/constants';
+import { EndpointAuthorizationError, NotFoundError } from '../../errors';
+import type { ActionDetails } from '../../../../common/endpoint/types';
+import { EndpointActionGenerator } from '../../../../common/endpoint/data_generators/endpoint_action_generator';
+import { getFileInfo as _getFileInfo } from '../../services/actions/action_files';
+import { CustomHttpRequestError } from '../../../utils/custom_http_request_error';
+
+jest.mock('../../services');
+jest.mock('../../services/actions/action_files');
+
+describe('Response Action file info API', () => {
+ const getActionDetailsById = _getActionDetailsById as jest.Mock;
+ const getFileInfo = _getFileInfo as jest.Mock;
+
+ let apiTestSetup: HttpApiTestSetupMock;
+ let httpRequestMock: ReturnType<
+ HttpApiTestSetupMock['createRequestMock']
+ >;
+ let httpHandlerContextMock: HttpApiTestSetupMock['httpHandlerContextMock'];
+ let httpResponseMock: HttpApiTestSetupMock['httpResponseMock'];
+
+ beforeEach(() => {
+ apiTestSetup = createHttpApiTestSetupMock();
+
+ ({ httpHandlerContextMock, httpResponseMock } = apiTestSetup);
+ httpRequestMock = apiTestSetup.createRequestMock({
+ params: { action_id: '111', agent_id: '222' },
+ });
+ });
+
+ describe('#registerActionFileInfoRoute()', () => {
+ beforeEach(() => {
+ registerActionFileInfoRoute(apiTestSetup.routerMock, apiTestSetup.endpointAppContextMock);
+ });
+
+ it('should register the route', () => {
+ expect(
+ apiTestSetup.getRegisteredRouteHandler('get', ACTION_AGENT_FILE_INFO_ROUTE)
+ ).toBeDefined();
+ });
+
+ it('should error if user has no authz to api', async () => {
+ const authz = (await httpHandlerContextMock.securitySolution).endpointAuthz;
+ authz.canWriteFileOperations = false;
+
+ await apiTestSetup.getRegisteredRouteHandler('get', ACTION_AGENT_FILE_INFO_ROUTE)(
+ httpHandlerContextMock,
+ httpRequestMock,
+ httpResponseMock
+ );
+
+ expect(httpResponseMock.forbidden).toHaveBeenCalledWith({
+ body: expect.any(EndpointAuthorizationError),
+ });
+ });
+ });
+
+ describe('Route handler', () => {
+ let fileInfoHandler: ReturnType;
+ let esClientMock: ReturnType;
+ let action: ActionDetails;
+
+ beforeEach(() => {
+ esClientMock = apiTestSetup.getEsClientMock();
+ action = new EndpointActionGenerator().generateActionDetails({
+ id: '111',
+ agents: ['222'],
+ });
+ fileInfoHandler = getActionFileInfoRouteHandler(apiTestSetup.endpointAppContextMock);
+
+ getActionDetailsById.mockImplementation(async () => {
+ return action;
+ });
+
+ getFileInfo.mockImplementation(async () => {
+ return {
+ created: '2022-10-10T14:57:30.682Z',
+ id: '123',
+ mimeType: 'text/plain',
+ name: 'test.txt',
+ size: 1234,
+ status: 'READY',
+ };
+ });
+ });
+
+ it('should error if action ID is invalid', async () => {
+ getActionDetailsById.mockImplementationOnce(async () => {
+ throw new NotFoundError('not found');
+ });
+ await fileInfoHandler(httpHandlerContextMock, httpRequestMock, httpResponseMock);
+
+ expect(httpResponseMock.notFound).toHaveBeenCalled();
+ });
+
+ it('should error if agent id is not in the action', async () => {
+ action.agents = ['333'];
+ await fileInfoHandler(httpHandlerContextMock, httpRequestMock, httpResponseMock);
+
+ expect(httpResponseMock.customError).toHaveBeenCalledWith({
+ statusCode: 400,
+ body: expect.any(CustomHttpRequestError),
+ });
+ });
+
+ it('should retrieve the file info with correct file id', async () => {
+ await fileInfoHandler(httpHandlerContextMock, httpRequestMock, httpResponseMock);
+
+ expect(getFileInfo).toHaveBeenCalledWith(esClientMock, expect.anything(), '111.222');
+ });
+
+ it('should respond with expected output', async () => {
+ await fileInfoHandler(httpHandlerContextMock, httpRequestMock, httpResponseMock);
+
+ expect(httpResponseMock.ok).toHaveBeenCalledWith({
+ body: {
+ data: {
+ created: '2022-10-10T14:57:30.682Z',
+ id: '123',
+ mimeType: 'text/plain',
+ name: 'test.txt',
+ size: 1234,
+ status: 'READY',
+ },
+ },
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/file_info_handler.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/file_info_handler.ts
new file mode 100644
index 0000000000000..e8290d1c3d3b1
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/file_info_handler.ts
@@ -0,0 +1,76 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { RequestHandler } from '@kbn/core/server';
+import { getFileInfo } from '../../services/actions/action_files';
+import { getActionDetailsById } from '../../services';
+import { ACTION_AGENT_FILE_INFO_ROUTE } from '../../../../common/endpoint/constants';
+import type { EndpointAppContext } from '../../types';
+import type { EndpointActionFileInfoParams } from '../../../../common/endpoint/schema/actions';
+import type {
+ SecuritySolutionRequestHandlerContext,
+ SecuritySolutionPluginRouter,
+} from '../../../types';
+import { EndpointActionFileInfoSchema } from '../../../../common/endpoint/schema/actions';
+import { withEndpointAuthz } from '../with_endpoint_authz';
+import { CustomHttpRequestError } from '../../../utils/custom_http_request_error';
+import { getFileDownloadId } from '../../../../common/endpoint/service/response_actions/get_file_download_id';
+import { errorHandler } from '../error_handler';
+
+export const getActionFileInfoRouteHandler = (
+ endpointContext: EndpointAppContext
+): RequestHandler<
+ EndpointActionFileInfoParams,
+ unknown,
+ unknown,
+ SecuritySolutionRequestHandlerContext
+> => {
+ const logger = endpointContext.logFactory.get('actionFileInfo');
+
+ return async (context, req, res) => {
+ const { action_id: actionId, agent_id: agentId } = req.params;
+ const esClient = (await context.core).elasticsearch.client.asInternalUser;
+ const endpointMetadataService = endpointContext.service.getEndpointMetadataService();
+
+ try {
+ // Ensure action id is valid and that it was sent to the Agent ID requested.
+ const actionDetails = await getActionDetailsById(esClient, endpointMetadataService, actionId);
+
+ if (!actionDetails.agents.includes(agentId)) {
+ throw new CustomHttpRequestError(`Action was not sent to agent id [${agentId}]`, 400);
+ }
+
+ const fileId = getFileDownloadId(actionDetails, agentId);
+
+ return res.ok({
+ body: {
+ data: await getFileInfo(esClient, logger, fileId),
+ },
+ });
+ } catch (error) {
+ return errorHandler(logger, res, error);
+ }
+ };
+};
+
+export const registerActionFileInfoRoute = (
+ router: SecuritySolutionPluginRouter,
+ endpointContext: EndpointAppContext
+) => {
+ router.get(
+ {
+ path: ACTION_AGENT_FILE_INFO_ROUTE,
+ validate: EndpointActionFileInfoSchema,
+ options: { authRequired: true, tags: ['access:securitySolution'] },
+ },
+ withEndpointAuthz(
+ { all: ['canWriteFileOperations'] },
+ endpointContext.logFactory.get('actionFileInfo'),
+ getActionFileInfoRouteHandler(endpointContext)
+ )
+ );
+};
diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/actions/index.ts b/x-pack/plugins/security_solution/server/endpoint/routes/actions/index.ts
index a801360772b28..e5b3e90de8878 100644
--- a/x-pack/plugins/security_solution/server/endpoint/routes/actions/index.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/routes/actions/index.ts
@@ -5,6 +5,7 @@
* 2.0.
*/
+import { registerActionFileInfoRoute } from './file_info_handler';
import { registerActionFileDownloadRoutes } from './file_download_handler';
import { registerActionDetailsRoutes } from './details';
import type { SecuritySolutionPluginRouter } from '../../../types';
@@ -26,4 +27,5 @@ export function registerActionRoutes(
registerActionDetailsRoutes(router, endpointContext);
registerActionFileDownloadRoutes(router, endpointContext);
registerResponseActionRoutes(router, endpointContext);
+ registerActionFileInfoRoute(router, endpointContext);
}
diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_files.test.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_files.test.ts
index 288c8ba043693..ffbe39f0435a5 100644
--- a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_files.test.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_files.test.ts
@@ -10,27 +10,30 @@ import { elasticsearchServiceMock, loggingSystemMock } from '@kbn/core/server/mo
import type { Logger } from '@kbn/core/server';
import { createEsFileClient as _createEsFileClient } from '@kbn/files-plugin/server';
import { createFileClientMock } from '@kbn/files-plugin/server/mocks';
-import { getFileDownloadStream } from './action_files';
+import { getFileDownloadStream, getFileInfo } from './action_files';
import type { DiagnosticResult } from '@elastic/elasticsearch';
import { errors } from '@elastic/elasticsearch';
import { NotFoundError } from '../../errors';
+import { FILE_STORAGE_DATA_INDEX } from '../../../../common/endpoint/constants';
+import { BaseDataGenerator } from '../../../../common/endpoint/data_generators/base_data_generator';
+import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
jest.mock('@kbn/files-plugin/server');
const createEsFileClient = _createEsFileClient as jest.Mock;
describe('Action Files service', () => {
- describe('#getFileDownloadStream()', () => {
- let loggerMock: Logger;
- let esClientMock: ElasticsearchClientMock;
- let fileClientMock: ReturnType;
+ let loggerMock: Logger;
+ let esClientMock: ElasticsearchClientMock;
+ let fileClientMock: ReturnType;
- beforeEach(() => {
- loggerMock = loggingSystemMock.create().get('mock');
- esClientMock = elasticsearchServiceMock.createElasticsearchClient();
- fileClientMock = createFileClientMock();
- createEsFileClient.mockReturnValue(fileClientMock);
- });
+ beforeEach(() => {
+ loggerMock = loggingSystemMock.create().get('mock');
+ esClientMock = elasticsearchServiceMock.createElasticsearchClient();
+ fileClientMock = createFileClientMock();
+ createEsFileClient.mockReturnValue(fileClientMock);
+ });
+ describe('#getFileDownloadStream()', () => {
it('should return expected output', async () => {
await expect(getFileDownloadStream(esClientMock, loggerMock, '123')).resolves.toEqual({
stream: expect.anything(),
@@ -51,4 +54,62 @@ describe('Action Files service', () => {
);
});
});
+
+ describe('#getFileInfo()', () => {
+ let fileChunksEsResponseMock: estypes.SearchResponse;
+
+ beforeEach(() => {
+ fileChunksEsResponseMock = BaseDataGenerator.toEsSearchResponse([
+ BaseDataGenerator.toEsSearchHit({}),
+ ]);
+
+ esClientMock.search.mockImplementation(async (searchRequest) => {
+ if (searchRequest && searchRequest.index === FILE_STORAGE_DATA_INDEX) {
+ return fileChunksEsResponseMock;
+ }
+
+ return BaseDataGenerator.toEsSearchResponse([]);
+ });
+ });
+
+ it('should return expected output', async () => {
+ await expect(getFileInfo(esClientMock, loggerMock, '123')).resolves.toEqual({
+ created: '2022-10-10T14:57:30.682Z',
+ id: '123',
+ mimeType: 'text/plain',
+ name: 'test.txt',
+ size: 1234,
+ status: 'READY',
+ });
+ });
+
+ it('should check if file has chunks if status is `READY`', async () => {
+ fileChunksEsResponseMock = BaseDataGenerator.toEsSearchResponse([]);
+
+ await expect(getFileInfo(esClientMock, loggerMock, '123')).resolves.toEqual({
+ created: '2022-10-10T14:57:30.682Z',
+ id: '123',
+ mimeType: 'text/plain',
+ name: 'test.txt',
+ size: 1234,
+ status: 'DELETED',
+ });
+
+ expect(loggerMock.debug).toHaveBeenCalledWith(
+ 'File with id [123] has no data chunks. Status will be adjusted to DELETED'
+ );
+ });
+
+ it('should return a `NotFoundError` if file id is not found', async () => {
+ fileClientMock.get.mockRejectedValue(
+ new errors.ResponseError({
+ statusCode: 404,
+ } as DiagnosticResult)
+ );
+
+ await expect(getFileInfo(esClientMock, loggerMock, '123')).rejects.toBeInstanceOf(
+ NotFoundError
+ );
+ });
+ });
});
diff --git a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_files.ts b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_files.ts
index 5db82681c3572..cb161ac189d59 100644
--- a/x-pack/plugins/security_solution/server/endpoint/services/actions/action_files.ts
+++ b/x-pack/plugins/security_solution/server/endpoint/services/actions/action_files.ts
@@ -7,8 +7,11 @@
import type { ElasticsearchClient, Logger } from '@kbn/core/server';
import type { Readable } from 'stream';
+import type { FileClient } from '@kbn/files-plugin/server';
import { createEsFileClient } from '@kbn/files-plugin/server';
import { errors } from '@elastic/elasticsearch';
+import type { SearchTotalHits } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
+import type { UploadedFileInfo } from '../../../../common/endpoint/types';
import { NotFoundError } from '../../errors';
import {
FILE_STORAGE_DATA_INDEX,
@@ -16,6 +19,32 @@ import {
} from '../../../../common/endpoint/constants';
import { EndpointError } from '../../../../common/endpoint/errors';
+const getFileClient = (esClient: ElasticsearchClient, logger: Logger): FileClient => {
+ return createEsFileClient({
+ metadataIndex: FILE_STORAGE_METADATA_INDEX,
+ blobStorageIndex: FILE_STORAGE_DATA_INDEX,
+ elasticsearchClient: esClient,
+ logger,
+ });
+};
+
+const getFileRetrievalError = (
+ error: Error | errors.ResponseError,
+ fileId: string
+): EndpointError => {
+ if (error instanceof errors.ResponseError) {
+ const statusCode = error.statusCode;
+
+ // 404 will be returned if file id is not found -or- index does not exist yet.
+ // Using the `NotFoundError` error class will result in the API returning a 404
+ if (statusCode === 404) {
+ return new NotFoundError(`File with id [${fileId}] not found`, error);
+ }
+ }
+
+ return new EndpointError(`Failed to get file using id [${fileId}]: ${error.message}`, error);
+};
+
/**
* Returns a NodeJS `Readable` data stream to a file
* @param esClient
@@ -27,14 +56,8 @@ export const getFileDownloadStream = async (
logger: Logger,
fileId: string
): Promise<{ stream: Readable; fileName: string; mimeType?: string }> => {
- const fileClient = createEsFileClient({
- metadataIndex: FILE_STORAGE_METADATA_INDEX,
- blobStorageIndex: FILE_STORAGE_DATA_INDEX,
- elasticsearchClient: esClient,
- logger,
- });
-
try {
+ const fileClient = getFileClient(esClient, logger);
const file = await fileClient.get({ id: fileId });
const { name: fileName, mimeType } = file.data;
@@ -44,16 +67,69 @@ export const getFileDownloadStream = async (
mimeType,
};
} catch (error) {
- if (error instanceof errors.ResponseError) {
- const statusCode = error.statusCode;
+ throw getFileRetrievalError(error, fileId);
+ }
+};
- // 404 will be returned if file id is not found -or- index does not exist yet.
- // Using the `NotFoundError` error class will result in the API returning a 404
- if (statusCode === 404) {
- throw new NotFoundError(`File with id [${fileId}] not found`, error);
+/**
+ * Retrieve information about a file
+ *
+ * @param esClient
+ * @param logger
+ * @param fileId
+ */
+export const getFileInfo = async (
+ esClient: ElasticsearchClient,
+ logger: Logger,
+ fileId: string
+): Promise => {
+ try {
+ const fileClient = getFileClient(esClient, logger);
+ const file = await fileClient.get({ id: fileId });
+ const { name, id, mimeType, size, status, created } = file.data;
+ let fileHasChunks: boolean = true;
+
+ if (status === 'READY') {
+ fileHasChunks = await doesFileHaveChunks(esClient, fileId);
+
+ if (!fileHasChunks) {
+ logger.debug(
+ `File with id [${fileId}] has no data chunks. Status will be adjusted to DELETED`
+ );
}
}
- throw new EndpointError(`Failed to get file using id [${fileId}]: ${error.message}`, error);
+ // TODO: add `ttl` to the return payload by retrieving the value from ILM?
+
+ return {
+ name,
+ id,
+ mimeType,
+ size,
+ created,
+ status: fileHasChunks ? status : 'DELETED',
+ };
+ } catch (error) {
+ throw getFileRetrievalError(error, fileId);
}
};
+
+const doesFileHaveChunks = async (
+ esClient: ElasticsearchClient,
+ fileId: string
+): Promise => {
+ const chunks = await esClient.search({
+ index: FILE_STORAGE_DATA_INDEX,
+ body: {
+ query: {
+ term: {
+ 'bid.keyword': fileId,
+ },
+ },
+ // Setting `_source` to false - we don't need the actual document to be returned
+ _source: false,
+ },
+ });
+
+ return Boolean((chunks.hits?.total as SearchTotalHits)?.value);
+};
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 377c9bc3caf74..920540fd30082 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
@@ -444,7 +444,7 @@ describe('When using Actions service utilities', () => {
outputs: {
'456': {
content: {
- code: 'ra_get-file_success',
+ code: 'ra_get-file_success_done',
path: '/some/path/bad_file.txt',
size: 1234,
zip_size: 123,
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/guided_onborading_sample_rule.json b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/guided_onborading_sample_rule.json
new file mode 100644
index 0000000000000..7c8258984e306
--- /dev/null
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/guided_onborading_sample_rule.json
@@ -0,0 +1,60 @@
+{
+ "author": [
+ "Elastic"
+ ],
+ "description": "This rule helps you test and practice using alerts with Elastic Security as you get set up. It\u2019s not a sign of threat activity.",
+ "enabled": false,
+ "false_positives": [
+ "This rule is not looking for threat activity. Disable the rule if you're already familiar with alerts."
+ ],
+ "from": "now-24h",
+ "index": [
+ "apm-*-transaction*",
+ "auditbeat-*",
+ "endgame-*",
+ "filebeat-*",
+ "logs-*",
+ "packetbeat-*",
+ "traces-apm*",
+ "winlogbeat-*",
+ "-*elastic-cloud-logs-*"
+ ],
+ "interval": "24h",
+ "language": "kuery",
+ "license": "Elastic License v2",
+ "max_signals": 1,
+ "name": "My First Alert",
+ "note": " \nThis is a test alert.\n\nThis alert does not show threat activity. Elastic created this alert to help you understand how alerts work.\n\nFor normal rules, the Investigation Guide will help analysts investigate alerts.\n\nThis alert will show once every 24 hours for each host. It is safe to disable this rule.\n",
+ "query": "event.kind:\"event\"\n",
+ "references": [
+ "https://www.elastic.co/guide/en/security/current/prebuilt-rules.html"
+ ],
+ "required_fields": [
+ {
+ "ecs": true,
+ "name": "event.kind",
+ "type": "keyword"
+ }
+ ],
+ "risk_score": 21,
+ "rule_id": "a198fbbd-9413-45ec-a269-47ae4ccf59ce",
+ "severity": "low",
+ "tags": [
+ "Elastic",
+ "Example",
+ "Guided Onboarding",
+ "Network",
+ "APM",
+ "Windows",
+ "Elastic Endgame"
+ ],
+ "threshold": {
+ "field": [
+ "host.name"
+ ],
+ "value": 1
+ },
+ "timestamp_override": "event.ingested",
+ "type": "threshold",
+ "version": 1
+}
diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/index.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/index.ts
index 97878f9eb2e0b..5d2cbf2aa963f 100644
--- a/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/index.ts
+++ b/x-pack/plugins/security_solution/server/lib/detection_engine/prebuilt_rules/content/prepackaged_rules/index.ts
@@ -10,713 +10,713 @@
// - detection-rules repo using CLI command build-release
// Do not hand edit. Run script/command to regenerate package information instead
-import rule1 from './credential_access_access_to_browser_credentials_procargs.json';
-import rule2 from './defense_evasion_tcc_bypass_mounted_apfs_access.json';
-import rule3 from './persistence_enable_root_account.json';
-import rule4 from './defense_evasion_unload_endpointsecurity_kext.json';
-import rule5 from './persistence_account_creation_hide_at_logon.json';
-import rule6 from './persistence_creation_hidden_login_item_osascript.json';
-import rule7 from './persistence_evasion_hidden_launch_agent_deamon_creation.json';
-import rule8 from './privilege_escalation_local_user_added_to_admin.json';
-import rule9 from './credential_access_keychain_pwd_retrieval_security_cmd.json';
-import rule10 from './credential_access_systemkey_dumping.json';
-import rule11 from './execution_defense_evasion_electron_app_childproc_node_js.json';
-import rule12 from './execution_revershell_via_shell_cmd.json';
-import rule13 from './persistence_defense_evasion_hidden_launch_agent_deamon_logonitem_process.json';
-import rule14 from './privilege_escalation_persistence_phantom_dll.json';
-import rule15 from './defense_evasion_privilege_escalation_privacy_pref_sshd_fulldiskaccess.json';
-import rule16 from './lateral_movement_credential_access_kerberos_bifrostconsole.json';
-import rule17 from './lateral_movement_vpn_connection_attempt.json';
-import rule18 from './apm_403_response_to_a_post.json';
-import rule19 from './apm_405_response_method_not_allowed.json';
-import rule20 from './apm_sqlmap_user_agent.json';
-import rule21 from './command_and_control_linux_iodine_activity.json';
-import rule22 from './command_and_control_nat_traversal_port_activity.json';
-import rule23 from './command_and_control_port_26_activity.json';
-import rule24 from './command_and_control_rdp_remote_desktop_protocol_from_the_internet.json';
-import rule25 from './command_and_control_telnet_port_activity.json';
-import rule26 from './command_and_control_vnc_virtual_network_computing_from_the_internet.json';
-import rule27 from './command_and_control_vnc_virtual_network_computing_to_the_internet.json';
-import rule28 from './credential_access_endgame_cred_dumping_detected.json';
-import rule29 from './credential_access_endgame_cred_dumping_prevented.json';
-import rule30 from './defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json';
-import rule31 from './defense_evasion_clearing_windows_event_logs.json';
-import rule32 from './defense_evasion_delete_volume_usn_journal_with_fsutil.json';
-import rule33 from './defense_evasion_disable_windows_firewall_rules_with_netsh.json';
-import rule34 from './defense_evasion_misc_lolbin_connecting_to_the_internet.json';
-import rule35 from './defense_evasion_msbuild_making_network_connections.json';
-import rule36 from './defense_evasion_suspicious_certutil_commands.json';
-import rule37 from './defense_evasion_unusual_network_connection_via_rundll32.json';
-import rule38 from './defense_evasion_unusual_process_network_connection.json';
-import rule39 from './defense_evasion_via_filter_manager.json';
-import rule40 from './discovery_linux_hping_activity.json';
-import rule41 from './discovery_linux_nping_activity.json';
-import rule42 from './discovery_whoami_command_activity.json';
-import rule43 from './endgame_adversary_behavior_detected.json';
-import rule44 from './endgame_malware_detected.json';
-import rule45 from './endgame_malware_prevented.json';
-import rule46 from './endgame_ransomware_detected.json';
-import rule47 from './endgame_ransomware_prevented.json';
-import rule48 from './execution_command_prompt_connecting_to_the_internet.json';
-import rule49 from './execution_command_shell_started_by_svchost.json';
-import rule50 from './execution_endgame_exploit_detected.json';
-import rule51 from './execution_endgame_exploit_prevented.json';
-import rule52 from './execution_html_help_executable_program_connecting_to_the_internet.json';
-import rule53 from './execution_linux_netcat_network_connection.json';
-import rule54 from './execution_psexec_lateral_movement_command.json';
-import rule55 from './execution_register_server_program_connecting_to_the_internet.json';
-import rule56 from './execution_via_compiled_html_file.json';
-import rule57 from './impact_deleting_backup_catalogs_with_wbadmin.json';
-import rule58 from './impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json';
-import rule59 from './impact_volume_shadow_copy_deletion_via_wmic.json';
-import rule60 from './initial_access_rpc_remote_procedure_call_from_the_internet.json';
-import rule61 from './initial_access_rpc_remote_procedure_call_to_the_internet.json';
-import rule62 from './initial_access_script_executing_powershell.json';
-import rule63 from './initial_access_smb_windows_file_sharing_activity_to_the_internet.json';
-import rule64 from './initial_access_suspicious_ms_office_child_process.json';
-import rule65 from './initial_access_suspicious_ms_outlook_child_process.json';
-import rule66 from './lateral_movement_direct_outbound_smb_connection.json';
-import rule67 from './lateral_movement_service_control_spawned_script_int.json';
-import rule68 from './persistence_adobe_hijack_persistence.json';
-import rule69 from './persistence_local_scheduled_task_creation.json';
-import rule70 from './persistence_priv_escalation_via_accessibility_features.json';
-import rule71 from './persistence_shell_activity_by_web_server.json';
-import rule72 from './persistence_system_shells_via_services.json';
-import rule73 from './persistence_user_account_creation.json';
-import rule74 from './persistence_via_application_shimming.json';
-import rule75 from './privilege_escalation_endgame_cred_manipulation_detected.json';
-import rule76 from './privilege_escalation_endgame_cred_manipulation_prevented.json';
-import rule77 from './privilege_escalation_endgame_permission_theft_detected.json';
-import rule78 from './privilege_escalation_endgame_permission_theft_prevented.json';
-import rule79 from './privilege_escalation_endgame_process_injection_detected.json';
-import rule80 from './privilege_escalation_endgame_process_injection_prevented.json';
-import rule81 from './privilege_escalation_unusual_parentchild_relationship.json';
-import rule82 from './impact_modification_of_boot_config.json';
-import rule83 from './privilege_escalation_uac_bypass_event_viewer.json';
-import rule84 from './defense_evasion_msxsl_network.json';
-import rule85 from './discovery_command_system_account.json';
-import rule86 from './command_and_control_certutil_network_connection.json';
-import rule87 from './defense_evasion_cve_2020_0601.json';
-import rule88 from './command_and_control_ml_packetbeat_dns_tunneling.json';
-import rule89 from './command_and_control_ml_packetbeat_rare_dns_question.json';
-import rule90 from './command_and_control_ml_packetbeat_rare_urls.json';
-import rule91 from './command_and_control_ml_packetbeat_rare_user_agent.json';
-import rule92 from './credential_access_credential_dumping_msbuild.json';
-import rule93 from './credential_access_ml_suspicious_login_activity.json';
-import rule94 from './defense_evasion_execution_msbuild_started_by_office_app.json';
-import rule95 from './defense_evasion_execution_msbuild_started_by_script.json';
-import rule96 from './defense_evasion_execution_msbuild_started_by_system_process.json';
-import rule97 from './defense_evasion_execution_msbuild_started_renamed.json';
-import rule98 from './defense_evasion_execution_msbuild_started_unusal_process.json';
-import rule99 from './defense_evasion_injection_msbuild.json';
-import rule100 from './execution_ml_windows_anomalous_script.json';
-import rule101 from './initial_access_ml_linux_anomalous_user_name.json';
-import rule102 from './initial_access_ml_windows_anomalous_user_name.json';
-import rule103 from './initial_access_ml_windows_rare_user_type10_remote_login.json';
-import rule104 from './ml_linux_anomalous_network_activity.json';
-import rule105 from './ml_linux_anomalous_network_port_activity.json';
-import rule106 from './ml_packetbeat_rare_server_domain.json';
-import rule107 from './ml_windows_anomalous_network_activity.json';
-import rule108 from './persistence_ml_linux_anomalous_process_all_hosts.json';
-import rule109 from './persistence_ml_rare_process_by_host_linux.json';
-import rule110 from './persistence_ml_rare_process_by_host_windows.json';
-import rule111 from './persistence_ml_windows_anomalous_path_activity.json';
-import rule112 from './persistence_ml_windows_anomalous_process_all_hosts.json';
-import rule113 from './persistence_ml_windows_anomalous_process_creation.json';
-import rule114 from './persistence_ml_windows_anomalous_service.json';
-import rule115 from './privilege_escalation_ml_windows_rare_user_runas_event.json';
-import rule116 from './execution_suspicious_pdf_reader.json';
-import rule117 from './privilege_escalation_sudoers_file_mod.json';
-import rule118 from './defense_evasion_iis_httplogging_disabled.json';
-import rule119 from './execution_python_tty_shell.json';
-import rule120 from './execution_perl_tty_shell.json';
-import rule121 from './defense_evasion_base16_or_base32_encoding_or_decoding_activity.json';
-import rule122 from './defense_evasion_file_mod_writable_dir.json';
-import rule123 from './defense_evasion_disable_selinux_attempt.json';
-import rule124 from './discovery_kernel_module_enumeration.json';
-import rule125 from './lateral_movement_telnet_network_activity_external.json';
-import rule126 from './lateral_movement_telnet_network_activity_internal.json';
-import rule127 from './privilege_escalation_setuid_setgid_bit_set_via_chmod.json';
-import rule128 from './defense_evasion_kernel_module_removal.json';
-import rule129 from './defense_evasion_attempt_to_disable_syslog_service.json';
-import rule130 from './defense_evasion_file_deletion_via_shred.json';
-import rule131 from './discovery_virtual_machine_fingerprinting.json';
-import rule132 from './defense_evasion_hidden_file_dir_tmp.json';
-import rule133 from './defense_evasion_deletion_of_bash_command_line_history.json';
-import rule134 from './impact_cloudwatch_log_group_deletion.json';
-import rule135 from './impact_cloudwatch_log_stream_deletion.json';
-import rule136 from './impact_rds_instance_cluster_stoppage.json';
-import rule137 from './persistence_attempt_to_deactivate_mfa_for_okta_user_account.json';
-import rule138 from './persistence_rds_cluster_creation.json';
-import rule139 from './credential_access_attempted_bypass_of_okta_mfa.json';
-import rule140 from './defense_evasion_okta_attempt_to_deactivate_okta_policy.json';
-import rule141 from './defense_evasion_okta_attempt_to_deactivate_okta_policy_rule.json';
-import rule142 from './defense_evasion_okta_attempt_to_modify_okta_network_zone.json';
-import rule143 from './defense_evasion_okta_attempt_to_modify_okta_policy.json';
-import rule144 from './defense_evasion_okta_attempt_to_modify_okta_policy_rule.json';
-import rule145 from './defense_evasion_waf_acl_deletion.json';
-import rule146 from './impact_attempt_to_revoke_okta_api_token.json';
-import rule147 from './impact_iam_group_deletion.json';
-import rule148 from './impact_possible_okta_dos_attack.json';
-import rule149 from './impact_rds_instance_cluster_deletion.json';
-import rule150 from './initial_access_suspicious_activity_reported_by_okta_user.json';
-import rule151 from './okta_threat_detected_by_okta_threatinsight.json';
-import rule152 from './persistence_administrator_privileges_assigned_to_okta_group.json';
-import rule153 from './persistence_attempt_to_create_okta_api_token.json';
-import rule154 from './persistence_attempt_to_reset_mfa_factors_for_okta_user_account.json';
-import rule155 from './defense_evasion_cloudtrail_logging_deleted.json';
-import rule156 from './defense_evasion_ec2_network_acl_deletion.json';
-import rule157 from './impact_iam_deactivate_mfa_device.json';
-import rule158 from './defense_evasion_s3_bucket_configuration_deletion.json';
-import rule159 from './defense_evasion_guardduty_detector_deletion.json';
-import rule160 from './defense_evasion_okta_attempt_to_delete_okta_policy.json';
-import rule161 from './credential_access_iam_user_addition_to_group.json';
-import rule162 from './persistence_ec2_network_acl_creation.json';
-import rule163 from './impact_ec2_disable_ebs_encryption.json';
-import rule164 from './persistence_iam_group_creation.json';
-import rule165 from './defense_evasion_waf_rule_or_rule_group_deletion.json';
-import rule166 from './collection_cloudtrail_logging_created.json';
-import rule167 from './defense_evasion_cloudtrail_logging_suspended.json';
-import rule168 from './impact_cloudtrail_logging_updated.json';
-import rule169 from './initial_access_console_login_root.json';
-import rule170 from './defense_evasion_cloudwatch_alarm_deletion.json';
-import rule171 from './defense_evasion_ec2_flow_log_deletion.json';
-import rule172 from './defense_evasion_configuration_recorder_stopped.json';
-import rule173 from './exfiltration_ec2_snapshot_change_activity.json';
-import rule174 from './defense_evasion_config_service_rule_deletion.json';
-import rule175 from './persistence_okta_attempt_to_modify_or_delete_application_sign_on_policy.json';
-import rule176 from './command_and_control_download_rar_powershell_from_internet.json';
-import rule177 from './initial_access_password_recovery.json';
-import rule178 from './command_and_control_cobalt_strike_beacon.json';
-import rule179 from './command_and_control_fin7_c2_behavior.json';
-import rule180 from './command_and_control_halfbaked_beacon.json';
-import rule181 from './credential_access_secretsmanager_getsecretvalue.json';
-import rule182 from './initial_access_via_system_manager.json';
-import rule183 from './privilege_escalation_root_login_without_mfa.json';
-import rule184 from './privilege_escalation_updateassumerolepolicy.json';
-import rule185 from './impact_hosts_file_modified.json';
-import rule186 from './elastic_endpoint_security.json';
-import rule187 from './external_alerts.json';
-import rule188 from './ml_cloudtrail_error_message_spike.json';
-import rule189 from './ml_cloudtrail_rare_error_code.json';
-import rule190 from './ml_cloudtrail_rare_method_by_city.json';
-import rule191 from './ml_cloudtrail_rare_method_by_country.json';
-import rule192 from './ml_cloudtrail_rare_method_by_user.json';
-import rule193 from './credential_access_aws_iam_assume_role_brute_force.json';
-import rule194 from './credential_access_okta_brute_force_or_password_spraying.json';
-import rule195 from './initial_access_unusual_dns_service_children.json';
-import rule196 from './initial_access_unusual_dns_service_file_writes.json';
-import rule197 from './lateral_movement_dns_server_overflow.json';
-import rule198 from './credential_access_root_console_failure_brute_force.json';
-import rule199 from './initial_access_unsecure_elasticsearch_node.json';
-import rule200 from './impact_virtual_network_device_modified.json';
-import rule201 from './credential_access_domain_backup_dpapi_private_keys.json';
-import rule202 from './persistence_gpo_schtask_service_creation.json';
-import rule203 from './credential_access_credentials_keychains.json';
-import rule204 from './credential_access_kerberosdump_kcc.json';
-import rule205 from './defense_evasion_attempt_del_quarantine_attrib.json';
-import rule206 from './execution_suspicious_psexesvc.json';
-import rule207 from './execution_via_xp_cmdshell_mssql_stored_procedure.json';
-import rule208 from './privilege_escalation_printspooler_service_suspicious_file.json';
-import rule209 from './privilege_escalation_printspooler_suspicious_spl_file.json';
-import rule210 from './defense_evasion_azure_diagnostic_settings_deletion.json';
-import rule211 from './execution_command_virtual_machine.json';
-import rule212 from './execution_via_hidden_shell_conhost.json';
-import rule213 from './impact_resource_group_deletion.json';
-import rule214 from './persistence_via_telemetrycontroller_scheduledtask_hijack.json';
-import rule215 from './persistence_via_update_orchestrator_service_hijack.json';
-import rule216 from './collection_update_event_hub_auth_rule.json';
-import rule217 from './credential_access_iis_apppoolsa_pwd_appcmd.json';
-import rule218 from './credential_access_iis_connectionstrings_dumping.json';
-import rule219 from './defense_evasion_event_hub_deletion.json';
-import rule220 from './defense_evasion_firewall_policy_deletion.json';
-import rule221 from './defense_evasion_sdelete_like_filename_rename.json';
-import rule222 from './lateral_movement_remote_ssh_login_enabled.json';
-import rule223 from './persistence_azure_automation_account_created.json';
-import rule224 from './persistence_azure_automation_runbook_created_or_modified.json';
-import rule225 from './persistence_azure_automation_webhook_created.json';
-import rule226 from './privilege_escalation_uac_bypass_diskcleanup_hijack.json';
-import rule227 from './credential_access_attempts_to_brute_force_okta_user_account.json';
-import rule228 from './credential_access_storage_account_key_regenerated.json';
-import rule229 from './defense_evasion_suspicious_okta_user_password_reset_or_unlock_attempts.json';
-import rule230 from './defense_evasion_system_critical_proc_abnormal_file_activity.json';
-import rule231 from './defense_evasion_unusual_system_vp_child_program.json';
-import rule232 from './discovery_blob_container_access_mod.json';
-import rule233 from './persistence_mfa_disabled_for_azure_user.json';
-import rule234 from './persistence_user_added_as_owner_for_azure_application.json';
-import rule235 from './persistence_user_added_as_owner_for_azure_service_principal.json';
-import rule236 from './defense_evasion_dotnet_compiler_parent_process.json';
-import rule237 from './defense_evasion_suspicious_managedcode_host_process.json';
-import rule238 from './execution_command_shell_started_by_unusual_process.json';
-import rule239 from './defense_evasion_masquerading_as_elastic_endpoint_process.json';
-import rule240 from './defense_evasion_masquerading_suspicious_werfault_childproc.json';
-import rule241 from './defense_evasion_masquerading_werfault.json';
-import rule242 from './credential_access_bruteforce_admin_account.json';
-import rule243 from './credential_access_bruteforce_multiple_logon_failure_followed_by_success.json';
-import rule244 from './credential_access_bruteforce_multiple_logon_failure_same_srcip.json';
-import rule245 from './credential_access_key_vault_modified.json';
-import rule246 from './credential_access_mimikatz_memssp_default_logs.json';
-import rule247 from './defense_evasion_network_watcher_deletion.json';
-import rule248 from './initial_access_external_guest_user_invite.json';
-import rule249 from './defense_evasion_azure_automation_runbook_deleted.json';
-import rule250 from './defense_evasion_masquerading_renamed_autoit.json';
-import rule251 from './initial_access_consent_grant_attack_via_azure_registered_application.json';
-import rule252 from './persistence_azure_conditional_access_policy_modified.json';
-import rule253 from './persistence_azure_privileged_identity_management_role_modified.json';
-import rule254 from './command_and_control_teamviewer_remote_file_copy.json';
-import rule255 from './defense_evasion_installutil_beacon.json';
-import rule256 from './defense_evasion_mshta_beacon.json';
-import rule257 from './defense_evasion_network_connection_from_windows_binary.json';
-import rule258 from './defense_evasion_rundll32_no_arguments.json';
-import rule259 from './defense_evasion_suspicious_scrobj_load.json';
-import rule260 from './defense_evasion_suspicious_wmi_script.json';
-import rule261 from './execution_ms_office_written_file.json';
-import rule262 from './execution_pdf_written_file.json';
-import rule263 from './lateral_movement_cmd_service.json';
-import rule264 from './persistence_app_compat_shim.json';
-import rule265 from './command_and_control_remote_file_copy_desktopimgdownldr.json';
-import rule266 from './command_and_control_remote_file_copy_mpcmdrun.json';
-import rule267 from './defense_evasion_execution_suspicious_explorer_winword.json';
-import rule268 from './defense_evasion_suspicious_zoom_child_process.json';
-import rule269 from './discovery_ml_linux_system_information_discovery.json';
-import rule270 from './discovery_ml_linux_system_network_configuration_discovery.json';
-import rule271 from './discovery_ml_linux_system_network_connection_discovery.json';
-import rule272 from './discovery_ml_linux_system_process_discovery.json';
-import rule273 from './discovery_ml_linux_system_user_discovery.json';
-import rule274 from './privilege_escalation_ml_linux_anomalous_sudo_activity.json';
-import rule275 from './resource_development_ml_linux_anomalous_compiler_activity.json';
-import rule276 from './discovery_post_exploitation_external_ip_lookup.json';
-import rule277 from './initial_access_zoom_meeting_with_no_passcode.json';
-import rule278 from './defense_evasion_gcp_logging_sink_deletion.json';
-import rule279 from './defense_evasion_gcp_pub_sub_topic_deletion.json';
-import rule280 from './defense_evasion_gcp_firewall_rule_created.json';
-import rule281 from './defense_evasion_gcp_firewall_rule_deleted.json';
-import rule282 from './defense_evasion_gcp_firewall_rule_modified.json';
-import rule283 from './defense_evasion_gcp_logging_bucket_deletion.json';
-import rule284 from './defense_evasion_gcp_storage_bucket_permissions_modified.json';
-import rule285 from './impact_gcp_storage_bucket_deleted.json';
-import rule286 from './initial_access_gcp_iam_custom_role_creation.json';
-import rule287 from './persistence_gcp_iam_service_account_key_deletion.json';
-import rule288 from './persistence_gcp_key_created_for_service_account.json';
-import rule289 from './credential_access_ml_linux_anomalous_metadata_process.json';
-import rule290 from './credential_access_ml_linux_anomalous_metadata_user.json';
-import rule291 from './credential_access_ml_windows_anomalous_metadata_process.json';
-import rule292 from './credential_access_ml_windows_anomalous_metadata_user.json';
-import rule293 from './defense_evasion_gcp_storage_bucket_configuration_modified.json';
-import rule294 from './defense_evasion_gcp_virtual_private_cloud_network_deleted.json';
-import rule295 from './defense_evasion_gcp_virtual_private_cloud_route_created.json';
-import rule296 from './defense_evasion_gcp_virtual_private_cloud_route_deleted.json';
-import rule297 from './exfiltration_gcp_logging_sink_modification.json';
-import rule298 from './impact_gcp_iam_role_deletion.json';
-import rule299 from './impact_gcp_service_account_deleted.json';
-import rule300 from './impact_gcp_service_account_disabled.json';
-import rule301 from './persistence_gcp_service_account_created.json';
-import rule302 from './collection_gcp_pub_sub_subscription_creation.json';
-import rule303 from './collection_gcp_pub_sub_topic_creation.json';
-import rule304 from './defense_evasion_gcp_pub_sub_subscription_deletion.json';
-import rule305 from './persistence_azure_pim_user_added_global_admin.json';
-import rule306 from './command_and_control_cobalt_strike_default_teamserver_cert.json';
-import rule307 from './defense_evasion_enable_inbound_rdp_with_netsh.json';
-import rule308 from './defense_evasion_execution_lolbas_wuauclt.json';
-import rule309 from './privilege_escalation_unusual_svchost_childproc_childless.json';
-import rule310 from './command_and_control_rdp_tunnel_plink.json';
-import rule311 from './privilege_escalation_uac_bypass_winfw_mmc_hijack.json';
-import rule312 from './discovery_privileged_localgroup_membership.json';
-import rule313 from './persistence_ms_office_addins_file.json';
-import rule314 from './discovery_adfind_command_activity.json';
-import rule315 from './discovery_security_software_wmic.json';
-import rule316 from './execution_command_shell_via_rundll32.json';
-import rule317 from './execution_suspicious_cmd_wmi.json';
-import rule318 from './lateral_movement_via_startup_folder_rdp_smb.json';
-import rule319 from './privilege_escalation_uac_bypass_com_interface_icmluautil.json';
-import rule320 from './privilege_escalation_uac_bypass_mock_windir.json';
-import rule321 from './defense_evasion_potential_processherpaderping.json';
-import rule322 from './privilege_escalation_uac_bypass_dll_sideloading.json';
-import rule323 from './execution_shared_modules_local_sxs_dll.json';
-import rule324 from './privilege_escalation_uac_bypass_com_clipup.json';
-import rule325 from './initial_access_via_explorer_suspicious_child_parent_args.json';
-import rule326 from './defense_evasion_from_unusual_directory.json';
-import rule327 from './execution_from_unusual_path_cmdline.json';
-import rule328 from './credential_access_kerberoasting_unusual_process.json';
-import rule329 from './discovery_peripheral_device.json';
-import rule330 from './lateral_movement_mount_hidden_or_webdav_share_net.json';
-import rule331 from './defense_evasion_deleting_websvr_access_logs.json';
-import rule332 from './defense_evasion_log_files_deleted.json';
-import rule333 from './defense_evasion_timestomp_touch.json';
-import rule334 from './lateral_movement_dcom_hta.json';
-import rule335 from './lateral_movement_execution_via_file_shares_sequence.json';
-import rule336 from './privilege_escalation_uac_bypass_com_ieinstal.json';
-import rule337 from './command_and_control_common_webservices.json';
-import rule338 from './command_and_control_encrypted_channel_freesslcert.json';
-import rule339 from './defense_evasion_process_termination_followed_by_deletion.json';
-import rule340 from './lateral_movement_remote_file_copy_hidden_share.json';
-import rule341 from './defense_evasion_attempt_to_deactivate_okta_network_zone.json';
-import rule342 from './defense_evasion_attempt_to_delete_okta_network_zone.json';
-import rule343 from './defense_evasion_okta_attempt_to_delete_okta_policy_rule.json';
-import rule344 from './impact_okta_attempt_to_deactivate_okta_application.json';
-import rule345 from './impact_okta_attempt_to_delete_okta_application.json';
-import rule346 from './impact_okta_attempt_to_modify_okta_application.json';
-import rule347 from './lateral_movement_dcom_mmc20.json';
-import rule348 from './lateral_movement_dcom_shellwindow_shellbrowserwindow.json';
-import rule349 from './persistence_administrator_role_assigned_to_okta_user.json';
-import rule350 from './lateral_movement_executable_tool_transfer_smb.json';
-import rule351 from './command_and_control_dns_tunneling_nslookup.json';
-import rule352 from './lateral_movement_execution_from_tsclient_mup.json';
-import rule353 from './lateral_movement_rdp_sharprdp_target.json';
-import rule354 from './defense_evasion_clearing_windows_security_logs.json';
-import rule355 from './persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json';
-import rule356 from './defense_evasion_suspicious_short_program_name.json';
-import rule357 from './lateral_movement_incoming_wmi.json';
-import rule358 from './persistence_via_hidden_run_key_valuename.json';
-import rule359 from './credential_access_potential_macos_ssh_bruteforce.json';
-import rule360 from './credential_access_promt_for_pwd_via_osascript.json';
-import rule361 from './lateral_movement_remote_services.json';
-import rule362 from './defense_evasion_domain_added_to_google_workspace_trusted_domains.json';
-import rule363 from './execution_suspicious_image_load_wmi_ms_office.json';
-import rule364 from './execution_suspicious_powershell_imgload.json';
-import rule365 from './impact_google_workspace_admin_role_deletion.json';
-import rule366 from './impact_google_workspace_mfa_enforcement_disabled.json';
-import rule367 from './persistence_application_added_to_google_workspace_domain.json';
-import rule368 from './persistence_evasion_registry_ifeo_injection.json';
-import rule369 from './persistence_google_workspace_admin_role_assigned_to_user.json';
-import rule370 from './persistence_google_workspace_custom_admin_role_created.json';
-import rule371 from './persistence_google_workspace_policy_modified.json';
-import rule372 from './persistence_google_workspace_role_modified.json';
-import rule373 from './persistence_mfa_disabled_for_google_workspace_organization.json';
-import rule374 from './persistence_suspicious_image_load_scheduled_task_ms_office.json';
-import rule375 from './defense_evasion_masquerading_trusted_directory.json';
-import rule376 from './exfiltration_microsoft_365_exchange_transport_rule_creation.json';
-import rule377 from './initial_access_microsoft_365_exchange_safelinks_disabled.json';
-import rule378 from './persistence_appcertdlls_registry.json';
-import rule379 from './persistence_appinitdlls_registry.json';
-import rule380 from './persistence_microsoft_365_exchange_dkim_signing_config_disabled.json';
-import rule381 from './persistence_registry_uncommon.json';
-import rule382 from './persistence_run_key_and_startup_broad.json';
-import rule383 from './persistence_services_registry.json';
-import rule384 from './persistence_startup_folder_file_written_by_suspicious_process.json';
-import rule385 from './persistence_startup_folder_scripts.json';
-import rule386 from './persistence_suspicious_com_hijack_registry.json';
-import rule387 from './persistence_via_lsa_security_support_provider_registry.json';
-import rule388 from './defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json';
-import rule389 from './defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json';
-import rule390 from './defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json';
-import rule391 from './exfiltration_microsoft_365_exchange_transport_rule_mod.json';
-import rule392 from './initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json';
-import rule393 from './initial_access_microsoft_365_exchange_anti_phish_rule_mod.json';
-import rule394 from './lateral_movement_suspicious_rdp_client_imageload.json';
-import rule395 from './persistence_runtime_run_key_startup_susp_procs.json';
-import rule396 from './persistence_suspicious_scheduled_task_runtime.json';
-import rule397 from './defense_evasion_microsoft_365_exchange_dlp_policy_removed.json';
-import rule398 from './lateral_movement_scheduled_task_target.json';
-import rule399 from './persistence_microsoft_365_exchange_management_role_assignment.json';
-import rule400 from './persistence_microsoft_365_teams_guest_access_enabled.json';
-import rule401 from './credential_access_dump_registry_hives.json';
-import rule402 from './defense_evasion_scheduledjobs_at_protocol_enabled.json';
-import rule403 from './persistence_ms_outlook_vba_template.json';
-import rule404 from './persistence_suspicious_service_created_registry.json';
-import rule405 from './privilege_escalation_named_pipe_impersonation.json';
-import rule406 from './credential_access_cmdline_dump_tool.json';
-import rule407 from './credential_access_copy_ntds_sam_volshadowcp_cmdline.json';
-import rule408 from './credential_access_lsass_memdump_file_created.json';
-import rule409 from './lateral_movement_incoming_winrm_shell_execution.json';
-import rule410 from './lateral_movement_powershell_remoting_target.json';
-import rule411 from './command_and_control_port_forwarding_added_registry.json';
-import rule412 from './defense_evasion_hide_encoded_executable_registry.json';
-import rule413 from './lateral_movement_rdp_enabled_registry.json';
-import rule414 from './privilege_escalation_printspooler_registry_copyfiles.json';
-import rule415 from './privilege_escalation_rogue_windir_environment_var.json';
-import rule416 from './initial_access_scripts_process_started_via_wmi.json';
-import rule417 from './command_and_control_iexplore_via_com.json';
-import rule418 from './command_and_control_remote_file_copy_scripts.json';
-import rule419 from './persistence_local_scheduled_task_scripting.json';
-import rule420 from './persistence_startup_folder_file_written_by_unsigned_process.json';
-import rule421 from './command_and_control_remote_file_copy_powershell.json';
-import rule422 from './credential_access_microsoft_365_brute_force_user_account_attempt.json';
-import rule423 from './persistence_microsoft_365_teams_custom_app_interaction_allowed.json';
-import rule424 from './persistence_microsoft_365_teams_external_access_enabled.json';
-import rule425 from './credential_access_microsoft_365_potential_password_spraying_attack.json';
-import rule426 from './impact_stop_process_service_threshold.json';
-import rule427 from './collection_winrar_encryption.json';
-import rule428 from './defense_evasion_unusual_dir_ads.json';
-import rule429 from './discovery_admin_recon.json';
-import rule430 from './discovery_net_view.json';
-import rule431 from './discovery_remote_system_discovery_commands_windows.json';
-import rule432 from './persistence_via_windows_management_instrumentation_event_subscription.json';
-import rule433 from './credential_access_mimikatz_powershell_module.json';
-import rule434 from './execution_scripting_osascript_exec_followed_by_netcon.json';
-import rule435 from './execution_shell_execution_via_apple_scripting.json';
-import rule436 from './persistence_creation_change_launch_agents_file.json';
-import rule437 from './persistence_creation_modif_launch_deamon_sequence.json';
-import rule438 from './persistence_folder_action_scripts_runtime.json';
-import rule439 from './persistence_login_logout_hooks_defaults.json';
-import rule440 from './privilege_escalation_explicit_creds_via_scripting.json';
-import rule441 from './command_and_control_sunburst_c2_activity_detected.json';
-import rule442 from './defense_evasion_azure_application_credential_modification.json';
-import rule443 from './defense_evasion_azure_service_principal_addition.json';
-import rule444 from './defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json';
-import rule445 from './execution_apt_solarwinds_backdoor_child_cmd_powershell.json';
-import rule446 from './execution_apt_solarwinds_backdoor_unusual_child_processes.json';
-import rule447 from './initial_access_azure_active_directory_powershell_signin.json';
-import rule448 from './collection_email_powershell_exchange_mailbox.json';
-import rule449 from './execution_scheduled_task_powershell_source.json';
-import rule450 from './persistence_powershell_exch_mailbox_activesync_add_device.json';
-import rule451 from './persistence_docker_shortcuts_plist_modification.json';
-import rule452 from './persistence_evasion_hidden_local_account_creation.json';
-import rule453 from './persistence_finder_sync_plugin_pluginkit.json';
-import rule454 from './discovery_security_software_grep.json';
-import rule455 from './credential_access_cookies_chromium_browsers_debugging.json';
-import rule456 from './credential_access_ssh_backdoor_log.json';
-import rule457 from './persistence_credential_access_modify_auth_module_or_config.json';
-import rule458 from './persistence_credential_access_modify_ssh_binaries.json';
-import rule459 from './credential_access_collection_sensitive_files.json';
-import rule460 from './persistence_ssh_authorized_keys_modification.json';
-import rule461 from './defense_evasion_defender_disabled_via_registry.json';
-import rule462 from './defense_evasion_privacy_controls_tcc_database_modification.json';
-import rule463 from './execution_initial_access_suspicious_browser_childproc.json';
-import rule464 from './execution_script_via_automator_workflows.json';
-import rule465 from './persistence_modification_sublime_app_plugin_or_script.json';
-import rule466 from './privilege_escalation_applescript_with_admin_privs.json';
-import rule467 from './credential_access_dumping_keychain_security.json';
-import rule468 from './initial_access_azure_active_directory_high_risk_signin.json';
-import rule469 from './initial_access_suspicious_mac_ms_office_child_process.json';
-import rule470 from './credential_access_mitm_localhost_webproxy.json';
-import rule471 from './persistence_kde_autostart_modification.json';
-import rule472 from './persistence_user_account_added_to_privileged_group_ad.json';
-import rule473 from './defense_evasion_attempt_to_disable_gatekeeper.json';
-import rule474 from './defense_evasion_sandboxed_office_app_suspicious_zip_file.json';
-import rule475 from './persistence_emond_rules_file_creation.json';
-import rule476 from './persistence_emond_rules_process_execution.json';
-import rule477 from './discovery_users_domain_built_in_commands.json';
-import rule478 from './execution_pentest_eggshell_remote_admin_tool.json';
-import rule479 from './defense_evasion_install_root_certificate.json';
-import rule480 from './persistence_credential_access_authorization_plugin_creation.json';
-import rule481 from './persistence_directory_services_plugins_modification.json';
-import rule482 from './defense_evasion_modify_environment_launchctl.json';
-import rule483 from './defense_evasion_safari_config_change.json';
-import rule484 from './defense_evasion_apple_softupdates_modification.json';
-import rule485 from './credential_access_mod_wdigest_security_provider.json';
-import rule486 from './credential_access_saved_creds_vaultcmd.json';
-import rule487 from './defense_evasion_file_creation_mult_extension.json';
-import rule488 from './execution_enumeration_via_wmiprvse.json';
-import rule489 from './execution_suspicious_jar_child_process.json';
-import rule490 from './persistence_shell_profile_modification.json';
-import rule491 from './persistence_suspicious_calendar_modification.json';
-import rule492 from './persistence_time_provider_mod.json';
-import rule493 from './privilege_escalation_exploit_adobe_acrobat_updater.json';
-import rule494 from './defense_evasion_sip_provider_mod.json';
-import rule495 from './execution_com_object_xwizard.json';
-import rule496 from './privilege_escalation_disable_uac_registry.json';
-import rule497 from './defense_evasion_unusual_ads_file_creation.json';
-import rule498 from './persistence_loginwindow_plist_modification.json';
-import rule499 from './persistence_periodic_tasks_file_mdofiy.json';
-import rule500 from './persistence_via_atom_init_file_modification.json';
-import rule501 from './privilege_escalation_lsa_auth_package.json';
-import rule502 from './privilege_escalation_port_monitor_print_pocessor_abuse.json';
-import rule503 from './credential_access_dumping_hashes_bi_cmds.json';
-import rule504 from './lateral_movement_mounting_smb_share.json';
-import rule505 from './privilege_escalation_echo_nopasswd_sudoers.json';
-import rule506 from './privilege_escalation_ld_preload_shared_object_modif.json';
-import rule507 from './privilege_escalation_root_crontab_filemod.json';
-import rule508 from './defense_evasion_create_mod_root_certificate.json';
-import rule509 from './privilege_escalation_sudo_buffer_overflow.json';
-import rule510 from './execution_installer_package_spawned_network_event.json';
-import rule511 from './initial_access_suspicious_ms_exchange_files.json';
-import rule512 from './initial_access_suspicious_ms_exchange_process.json';
-import rule513 from './initial_access_suspicious_ms_exchange_worker_child_process.json';
-import rule514 from './persistence_evasion_registry_startup_shell_folder_modified.json';
-import rule515 from './persistence_local_scheduled_job_creation.json';
-import rule516 from './persistence_via_wmi_stdregprov_run_services.json';
-import rule517 from './credential_access_persistence_network_logon_provider_modification.json';
-import rule518 from './lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json';
-import rule519 from './collection_microsoft_365_new_inbox_rule.json';
-import rule520 from './ml_high_count_network_denies.json';
-import rule521 from './ml_high_count_network_events.json';
-import rule522 from './ml_rare_destination_country.json';
-import rule523 from './ml_spike_in_traffic_to_a_country.json';
-import rule524 from './command_and_control_tunneling_via_earthworm.json';
-import rule525 from './lateral_movement_evasion_rdp_shadowing.json';
-import rule526 from './threat_intel_fleet_integrations.json';
-import rule527 from './exfiltration_ec2_vm_export_failure.json';
-import rule528 from './exfiltration_ec2_full_network_packet_capture_detected.json';
-import rule529 from './impact_azure_service_principal_credentials_added.json';
-import rule530 from './persistence_ec2_security_group_configuration_change_detection.json';
-import rule531 from './defense_evasion_disabling_windows_logs.json';
-import rule532 from './persistence_route_53_domain_transfer_lock_disabled.json';
-import rule533 from './persistence_route_53_domain_transferred_to_another_account.json';
-import rule534 from './initial_access_okta_user_attempted_unauthorized_access.json';
-import rule535 from './credential_access_user_excessive_sso_logon_errors.json';
-import rule536 from './persistence_exchange_suspicious_mailbox_right_delegation.json';
-import rule537 from './privilege_escalation_new_or_modified_federation_domain.json';
-import rule538 from './privilege_escalation_sts_assumerole_usage.json';
-import rule539 from './privilege_escalation_sts_getsessiontoken_abuse.json';
-import rule540 from './defense_evasion_suspicious_execution_from_mounted_device.json';
-import rule541 from './defense_evasion_unusual_network_connection_via_dllhost.json';
-import rule542 from './defense_evasion_amsienable_key_mod.json';
-import rule543 from './impact_rds_group_deletion.json';
-import rule544 from './persistence_rds_group_creation.json';
-import rule545 from './persistence_route_table_created.json';
-import rule546 from './persistence_route_table_modified_or_deleted.json';
-import rule547 from './exfiltration_rds_snapshot_export.json';
-import rule548 from './persistence_rds_instance_creation.json';
-import rule549 from './privilege_escalation_gcp_kubernetes_rolebindings_created_or_patched.json';
-import rule550 from './credential_access_ml_auth_spike_in_failed_logon_events.json';
-import rule551 from './credential_access_ml_auth_spike_in_logon_events.json';
-import rule552 from './credential_access_ml_auth_spike_in_logon_events_from_a_source_ip.json';
-import rule553 from './initial_access_ml_auth_rare_hour_for_a_user_to_logon.json';
-import rule554 from './initial_access_ml_auth_rare_source_ip_for_a_user.json';
-import rule555 from './initial_access_ml_auth_rare_user_logon.json';
-import rule556 from './privilege_escalation_cyberarkpas_error_audit_event_promotion.json';
-import rule557 from './privilege_escalation_cyberarkpas_recommended_events_to_monitor_promotion.json';
-import rule558 from './defense_evasion_kubernetes_events_deleted.json';
-import rule559 from './impact_kubernetes_pod_deleted.json';
-import rule560 from './exfiltration_rds_snapshot_restored.json';
-import rule561 from './privilege_escalation_printspooler_suspicious_file_deletion.json';
-import rule562 from './privilege_escalation_unusual_printspooler_childprocess.json';
-import rule563 from './defense_evasion_disabling_windows_defender_powershell.json';
-import rule564 from './defense_evasion_enable_network_discovery_with_netsh.json';
-import rule565 from './defense_evasion_execution_windefend_unusual_path.json';
-import rule566 from './defense_evasion_agent_spoofing_mismatched_id.json';
-import rule567 from './defense_evasion_agent_spoofing_multiple_hosts.json';
-import rule568 from './defense_evasion_parent_process_pid_spoofing.json';
-import rule569 from './impact_microsoft_365_potential_ransomware_activity.json';
-import rule570 from './impact_microsoft_365_unusual_volume_of_file_deletion.json';
-import rule571 from './initial_access_microsoft_365_user_restricted_from_sending_email.json';
-import rule572 from './defense_evasion_elasticache_security_group_creation.json';
-import rule573 from './defense_evasion_elasticache_security_group_modified_or_deleted.json';
-import rule574 from './impact_volume_shadow_copy_deletion_via_powershell.json';
-import rule575 from './persistence_route_53_hosted_zone_associated_with_a_vpc.json';
-import rule576 from './defense_evasion_defender_exclusion_via_powershell.json';
-import rule577 from './defense_evasion_dns_over_https_enabled.json';
-import rule578 from './defense_evasion_frontdoor_firewall_policy_deletion.json';
-import rule579 from './credential_access_azure_full_network_packet_capture_detected.json';
-import rule580 from './persistence_webshell_detection.json';
-import rule581 from './defense_evasion_suppression_rule_created.json';
-import rule582 from './impact_efs_filesystem_or_mount_deleted.json';
-import rule583 from './defense_evasion_execution_control_panel_suspicious_args.json';
-import rule584 from './defense_evasion_azure_blob_permissions_modified.json';
-import rule585 from './privilege_escalation_aws_suspicious_saml_activity.json';
-import rule586 from './credential_access_potential_lsa_memdump_via_mirrordump.json';
-import rule587 from './discovery_virtual_machine_fingerprinting_grep.json';
-import rule588 from './impact_backup_file_deletion.json';
-import rule589 from './credential_access_posh_minidump.json';
-import rule590 from './persistence_screensaver_engine_unexpected_child_process.json';
-import rule591 from './persistence_screensaver_plist_file_modification.json';
-import rule592 from './credential_access_suspicious_lsass_access_memdump.json';
-import rule593 from './defense_evasion_suspicious_process_access_direct_syscall.json';
-import rule594 from './discovery_posh_suspicious_api_functions.json';
-import rule595 from './privilege_escalation_via_rogue_named_pipe.json';
-import rule596 from './credential_access_suspicious_lsass_access_via_snapshot.json';
-import rule597 from './defense_evasion_posh_process_injection.json';
-import rule598 from './collection_posh_keylogger.json';
-import rule599 from './defense_evasion_posh_assembly_load.json';
-import rule600 from './defense_evasion_powershell_windows_firewall_disabled.json';
-import rule601 from './execution_posh_portable_executable.json';
-import rule602 from './execution_posh_psreflect.json';
-import rule603 from './credential_access_suspicious_comsvcs_imageload.json';
-import rule604 from './impact_aws_eventbridge_rule_disabled_or_deleted.json';
-import rule605 from './defense_evasion_microsoft_defender_tampering.json';
-import rule606 from './initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json';
-import rule607 from './persistence_remote_password_reset.json';
-import rule608 from './privilege_escalation_azure_kubernetes_rolebinding_created.json';
-import rule609 from './collection_posh_audio_capture.json';
-import rule610 from './collection_posh_screen_grabber.json';
-import rule611 from './defense_evasion_posh_compressed.json';
-import rule612 from './defense_evasion_suspicious_process_creation_calltrace.json';
-import rule613 from './privilege_escalation_group_policy_iniscript.json';
-import rule614 from './privilege_escalation_group_policy_privileged_groups.json';
-import rule615 from './privilege_escalation_group_policy_scheduled_task.json';
-import rule616 from './defense_evasion_clearing_windows_console_history.json';
-import rule617 from './threat_intel_filebeat8x.json';
-import rule618 from './privilege_escalation_installertakeover.json';
-import rule619 from './credential_access_via_snapshot_lsass_clone_creation.json';
-import rule620 from './persistence_via_bits_job_notify_command.json';
-import rule621 from './execution_suspicious_java_netcon_childproc.json';
-import rule622 from './privilege_escalation_samaccountname_spoofing_attack.json';
-import rule623 from './credential_access_symbolic_link_to_shadow_copy_created.json';
-import rule624 from './credential_access_mfa_push_brute_force.json';
-import rule625 from './persistence_azure_global_administrator_role_assigned.json';
-import rule626 from './persistence_microsoft_365_global_administrator_role_assign.json';
-import rule627 from './lateral_movement_malware_uploaded_onedrive.json';
-import rule628 from './lateral_movement_malware_uploaded_sharepoint.json';
-import rule629 from './defense_evasion_ms_office_suspicious_regmod.json';
-import rule630 from './initial_access_o365_user_reported_phish_malware.json';
-import rule631 from './defense_evasion_microsoft_365_mailboxauditbypassassociation.json';
-import rule632 from './credential_access_disable_kerberos_preauth.json';
-import rule633 from './credential_access_posh_request_ticket.json';
-import rule634 from './credential_access_shadow_credentials.json';
-import rule635 from './privilege_escalation_pkexec_envar_hijack.json';
-import rule636 from './credential_access_seenabledelegationprivilege_assigned_to_user.json';
-import rule637 from './persistence_msds_alloweddelegateto_krbtgt.json';
-import rule638 from './defense_evasion_disable_posh_scriptblocklogging.json';
-import rule639 from './persistence_ad_adminsdholder.json';
-import rule640 from './privilege_escalation_windows_service_via_unusual_client.json';
-import rule641 from './credential_access_dcsync_replication_rights.json';
-import rule642 from './credential_access_lsass_memdump_handle_access.json';
-import rule643 from './credential_access_moving_registry_hive_via_smb.json';
-import rule644 from './credential_access_suspicious_winreg_access_via_sebackup_priv.json';
-import rule645 from './credential_access_spn_attribute_modified.json';
-import rule646 from './persistence_dontexpirepasswd_account.json';
-import rule647 from './persistence_sdprop_exclusion_dsheuristics.json';
-import rule648 from './credential_access_remote_sam_secretsdump.json';
-import rule649 from './defense_evasion_workfolders_control_execution.json';
-import rule650 from './credential_access_user_impersonation_access.json';
-import rule651 from './persistence_redshift_instance_creation.json';
-import rule652 from './persistence_crontab_creation.json';
-import rule653 from './privilege_escalation_krbrelayup_service_creation.json';
-import rule654 from './credential_access_relay_ntlm_auth_via_http_spoolss.json';
-import rule655 from './execution_shell_evasion_linux_binary.json';
-import rule656 from './execution_process_started_in_shared_memory_directory.json';
-import rule657 from './execution_abnormal_process_id_file_created.json';
-import rule658 from './execution_process_started_from_process_id_file.json';
-import rule659 from './privilege_escalation_suspicious_dnshostname_update.json';
-import rule660 from './command_and_control_connection_attempt_by_non_ssh_root_session.json';
-import rule661 from './execution_user_exec_to_pod.json';
-import rule662 from './defense_evasion_elastic_agent_service_terminated.json';
-import rule663 from './defense_evasion_proxy_execution_via_msdt.json';
-import rule664 from './discovery_enumerating_domain_trusts_via_nltest.json';
-import rule665 from './credential_access_lsass_handle_via_malseclogon.json';
-import rule666 from './discovery_suspicious_self_subject_review.json';
-import rule667 from './initial_access_evasion_suspicious_htm_file_creation.json';
-import rule668 from './persistence_exposed_service_created_with_type_nodeport.json';
-import rule669 from './privilege_escalation_pod_created_with_hostipc.json';
-import rule670 from './privilege_escalation_pod_created_with_hostnetwork.json';
-import rule671 from './privilege_escalation_pod_created_with_hostpid.json';
-import rule672 from './privilege_escalation_privileged_pod_created.json';
-import rule673 from './execution_tc_bpf_filter.json';
-import rule674 from './persistence_insmod_kernel_module_load.json';
-import rule675 from './privilege_escalation_pod_created_with_sensitive_hospath_volume.json';
-import rule676 from './persistence_dynamic_linker_backup.json';
-import rule677 from './defense_evasion_hidden_shared_object.json';
-import rule678 from './defense_evasion_chattr_immutable_file.json';
-import rule679 from './persistence_chkconfig_service_add.json';
-import rule680 from './persistence_etc_file_creation.json';
-import rule681 from './impact_process_kill_threshold.json';
-import rule682 from './discovery_posh_invoke_sharefinder.json';
-import rule683 from './privilege_escalation_posh_token_impersonation.json';
-import rule684 from './collection_google_drive_ownership_transferred_via_google_workspace.json';
-import rule685 from './persistence_google_workspace_user_group_access_modified_to_allow_external_access.json';
-import rule686 from './defense_evasion_application_removed_from_blocklist_in_google_workspace.json';
-import rule687 from './defense_evasion_google_workspace_restrictions_for_google_marketplace_changed_to_allow_any_app.json';
-import rule688 from './persistence_google_workspace_2sv_policy_disabled.json';
-import rule689 from './credential_access_generic_localdumps.json';
-import rule690 from './defense_evasion_persistence_temp_scheduled_task.json';
-import rule691 from './lateral_movement_remote_task_creation_winlog.json';
-import rule692 from './persistence_scheduled_task_creation_winlog.json';
-import rule693 from './persistence_scheduled_task_updated.json';
-import rule694 from './credential_access_saved_creds_vault_winlog.json';
-import rule695 from './privilege_escalation_create_process_as_different_user.json';
-import rule696 from './privilege_escalation_unshare_namesapce_manipulation.json';
-import rule697 from './privilege_escalation_shadow_file_read.json';
-import rule698 from './defense_evasion_google_workspace_bitlocker_setting_disabled.json';
-import rule699 from './persistence_google_workspace_user_organizational_unit_changed.json';
-import rule700 from './collection_google_workspace_custom_gmail_route_created_or_modified.json';
-import rule701 from './discovery_denied_service_account_request.json';
-import rule702 from './initial_access_anonymous_request_authorized.json';
-import rule703 from './privilege_escalation_suspicious_assignment_of_controller_service_account.json';
-import rule704 from './credential_access_bruteforce_passowrd_guessing.json';
-import rule705 from './credential_access_potential_linux_ssh_bruteforce.json';
-import rule706 from './credential_access_potential_linux_ssh_bruteforce_root.json';
-
+import rule1 from './apm_403_response_to_a_post.json';
+import rule2 from './apm_405_response_method_not_allowed.json';
+import rule3 from './apm_sqlmap_user_agent.json';
+import rule4 from './collection_cloudtrail_logging_created.json';
+import rule5 from './collection_email_powershell_exchange_mailbox.json';
+import rule6 from './collection_gcp_pub_sub_subscription_creation.json';
+import rule7 from './collection_gcp_pub_sub_topic_creation.json';
+import rule8 from './collection_google_drive_ownership_transferred_via_google_workspace.json';
+import rule9 from './collection_google_workspace_custom_gmail_route_created_or_modified.json';
+import rule10 from './collection_microsoft_365_new_inbox_rule.json';
+import rule11 from './collection_posh_audio_capture.json';
+import rule12 from './collection_posh_keylogger.json';
+import rule13 from './collection_posh_screen_grabber.json';
+import rule14 from './collection_update_event_hub_auth_rule.json';
+import rule15 from './collection_winrar_encryption.json';
+import rule16 from './command_and_control_certutil_network_connection.json';
+import rule17 from './command_and_control_cobalt_strike_beacon.json';
+import rule18 from './command_and_control_cobalt_strike_default_teamserver_cert.json';
+import rule19 from './command_and_control_common_webservices.json';
+import rule20 from './command_and_control_connection_attempt_by_non_ssh_root_session.json';
+import rule21 from './command_and_control_dns_tunneling_nslookup.json';
+import rule22 from './command_and_control_download_rar_powershell_from_internet.json';
+import rule23 from './command_and_control_encrypted_channel_freesslcert.json';
+import rule24 from './command_and_control_fin7_c2_behavior.json';
+import rule25 from './command_and_control_halfbaked_beacon.json';
+import rule26 from './command_and_control_iexplore_via_com.json';
+import rule27 from './command_and_control_linux_iodine_activity.json';
+import rule28 from './command_and_control_ml_packetbeat_dns_tunneling.json';
+import rule29 from './command_and_control_ml_packetbeat_rare_dns_question.json';
+import rule30 from './command_and_control_ml_packetbeat_rare_urls.json';
+import rule31 from './command_and_control_ml_packetbeat_rare_user_agent.json';
+import rule32 from './command_and_control_nat_traversal_port_activity.json';
+import rule33 from './command_and_control_port_26_activity.json';
+import rule34 from './command_and_control_port_forwarding_added_registry.json';
+import rule35 from './command_and_control_rdp_remote_desktop_protocol_from_the_internet.json';
+import rule36 from './command_and_control_rdp_tunnel_plink.json';
+import rule37 from './command_and_control_remote_file_copy_desktopimgdownldr.json';
+import rule38 from './command_and_control_remote_file_copy_mpcmdrun.json';
+import rule39 from './command_and_control_remote_file_copy_powershell.json';
+import rule40 from './command_and_control_remote_file_copy_scripts.json';
+import rule41 from './command_and_control_sunburst_c2_activity_detected.json';
+import rule42 from './command_and_control_teamviewer_remote_file_copy.json';
+import rule43 from './command_and_control_telnet_port_activity.json';
+import rule44 from './command_and_control_tunneling_via_earthworm.json';
+import rule45 from './command_and_control_vnc_virtual_network_computing_from_the_internet.json';
+import rule46 from './command_and_control_vnc_virtual_network_computing_to_the_internet.json';
+import rule47 from './credential_access_access_to_browser_credentials_procargs.json';
+import rule48 from './credential_access_attempted_bypass_of_okta_mfa.json';
+import rule49 from './credential_access_attempts_to_brute_force_okta_user_account.json';
+import rule50 from './credential_access_aws_iam_assume_role_brute_force.json';
+import rule51 from './credential_access_azure_full_network_packet_capture_detected.json';
+import rule52 from './credential_access_bruteforce_admin_account.json';
+import rule53 from './credential_access_bruteforce_multiple_logon_failure_followed_by_success.json';
+import rule54 from './credential_access_bruteforce_multiple_logon_failure_same_srcip.json';
+import rule55 from './credential_access_bruteforce_passowrd_guessing.json';
+import rule56 from './credential_access_cmdline_dump_tool.json';
+import rule57 from './credential_access_collection_sensitive_files.json';
+import rule58 from './credential_access_cookies_chromium_browsers_debugging.json';
+import rule59 from './credential_access_copy_ntds_sam_volshadowcp_cmdline.json';
+import rule60 from './credential_access_credential_dumping_msbuild.json';
+import rule61 from './credential_access_credentials_keychains.json';
+import rule62 from './credential_access_dcsync_replication_rights.json';
+import rule63 from './credential_access_disable_kerberos_preauth.json';
+import rule64 from './credential_access_domain_backup_dpapi_private_keys.json';
+import rule65 from './credential_access_dump_registry_hives.json';
+import rule66 from './credential_access_dumping_hashes_bi_cmds.json';
+import rule67 from './credential_access_dumping_keychain_security.json';
+import rule68 from './credential_access_endgame_cred_dumping_detected.json';
+import rule69 from './credential_access_endgame_cred_dumping_prevented.json';
+import rule70 from './credential_access_generic_localdumps.json';
+import rule71 from './credential_access_iam_user_addition_to_group.json';
+import rule72 from './credential_access_iis_apppoolsa_pwd_appcmd.json';
+import rule73 from './credential_access_iis_connectionstrings_dumping.json';
+import rule74 from './credential_access_kerberoasting_unusual_process.json';
+import rule75 from './credential_access_kerberosdump_kcc.json';
+import rule76 from './credential_access_key_vault_modified.json';
+import rule77 from './credential_access_keychain_pwd_retrieval_security_cmd.json';
+import rule78 from './credential_access_lsass_handle_via_malseclogon.json';
+import rule79 from './credential_access_lsass_memdump_file_created.json';
+import rule80 from './credential_access_lsass_memdump_handle_access.json';
+import rule81 from './credential_access_mfa_push_brute_force.json';
+import rule82 from './credential_access_microsoft_365_brute_force_user_account_attempt.json';
+import rule83 from './credential_access_microsoft_365_potential_password_spraying_attack.json';
+import rule84 from './credential_access_mimikatz_memssp_default_logs.json';
+import rule85 from './credential_access_mimikatz_powershell_module.json';
+import rule86 from './credential_access_mitm_localhost_webproxy.json';
+import rule87 from './credential_access_ml_auth_spike_in_failed_logon_events.json';
+import rule88 from './credential_access_ml_auth_spike_in_logon_events.json';
+import rule89 from './credential_access_ml_auth_spike_in_logon_events_from_a_source_ip.json';
+import rule90 from './credential_access_ml_linux_anomalous_metadata_process.json';
+import rule91 from './credential_access_ml_linux_anomalous_metadata_user.json';
+import rule92 from './credential_access_ml_suspicious_login_activity.json';
+import rule93 from './credential_access_ml_windows_anomalous_metadata_process.json';
+import rule94 from './credential_access_ml_windows_anomalous_metadata_user.json';
+import rule95 from './credential_access_mod_wdigest_security_provider.json';
+import rule96 from './credential_access_moving_registry_hive_via_smb.json';
+import rule97 from './credential_access_okta_brute_force_or_password_spraying.json';
+import rule98 from './credential_access_persistence_network_logon_provider_modification.json';
+import rule99 from './credential_access_posh_minidump.json';
+import rule100 from './credential_access_posh_request_ticket.json';
+import rule101 from './credential_access_potential_linux_ssh_bruteforce.json';
+import rule102 from './credential_access_potential_linux_ssh_bruteforce_root.json';
+import rule103 from './credential_access_potential_lsa_memdump_via_mirrordump.json';
+import rule104 from './credential_access_potential_macos_ssh_bruteforce.json';
+import rule105 from './credential_access_promt_for_pwd_via_osascript.json';
+import rule106 from './credential_access_relay_ntlm_auth_via_http_spoolss.json';
+import rule107 from './credential_access_remote_sam_secretsdump.json';
+import rule108 from './credential_access_root_console_failure_brute_force.json';
+import rule109 from './credential_access_saved_creds_vault_winlog.json';
+import rule110 from './credential_access_saved_creds_vaultcmd.json';
+import rule111 from './credential_access_secretsmanager_getsecretvalue.json';
+import rule112 from './credential_access_seenabledelegationprivilege_assigned_to_user.json';
+import rule113 from './credential_access_shadow_credentials.json';
+import rule114 from './credential_access_spn_attribute_modified.json';
+import rule115 from './credential_access_ssh_backdoor_log.json';
+import rule116 from './credential_access_storage_account_key_regenerated.json';
+import rule117 from './credential_access_suspicious_comsvcs_imageload.json';
+import rule118 from './credential_access_suspicious_lsass_access_memdump.json';
+import rule119 from './credential_access_suspicious_lsass_access_via_snapshot.json';
+import rule120 from './credential_access_suspicious_winreg_access_via_sebackup_priv.json';
+import rule121 from './credential_access_symbolic_link_to_shadow_copy_created.json';
+import rule122 from './credential_access_systemkey_dumping.json';
+import rule123 from './credential_access_user_excessive_sso_logon_errors.json';
+import rule124 from './credential_access_user_impersonation_access.json';
+import rule125 from './credential_access_via_snapshot_lsass_clone_creation.json';
+import rule126 from './defense_evasion_adding_the_hidden_file_attribute_with_via_attribexe.json';
+import rule127 from './defense_evasion_agent_spoofing_mismatched_id.json';
+import rule128 from './defense_evasion_agent_spoofing_multiple_hosts.json';
+import rule129 from './defense_evasion_amsienable_key_mod.json';
+import rule130 from './defense_evasion_apple_softupdates_modification.json';
+import rule131 from './defense_evasion_application_removed_from_blocklist_in_google_workspace.json';
+import rule132 from './defense_evasion_attempt_del_quarantine_attrib.json';
+import rule133 from './defense_evasion_attempt_to_deactivate_okta_network_zone.json';
+import rule134 from './defense_evasion_attempt_to_delete_okta_network_zone.json';
+import rule135 from './defense_evasion_attempt_to_disable_gatekeeper.json';
+import rule136 from './defense_evasion_attempt_to_disable_syslog_service.json';
+import rule137 from './defense_evasion_azure_application_credential_modification.json';
+import rule138 from './defense_evasion_azure_automation_runbook_deleted.json';
+import rule139 from './defense_evasion_azure_blob_permissions_modified.json';
+import rule140 from './defense_evasion_azure_diagnostic_settings_deletion.json';
+import rule141 from './defense_evasion_azure_service_principal_addition.json';
+import rule142 from './defense_evasion_base16_or_base32_encoding_or_decoding_activity.json';
+import rule143 from './defense_evasion_chattr_immutable_file.json';
+import rule144 from './defense_evasion_clearing_windows_console_history.json';
+import rule145 from './defense_evasion_clearing_windows_event_logs.json';
+import rule146 from './defense_evasion_clearing_windows_security_logs.json';
+import rule147 from './defense_evasion_cloudtrail_logging_deleted.json';
+import rule148 from './defense_evasion_cloudtrail_logging_suspended.json';
+import rule149 from './defense_evasion_cloudwatch_alarm_deletion.json';
+import rule150 from './defense_evasion_config_service_rule_deletion.json';
+import rule151 from './defense_evasion_configuration_recorder_stopped.json';
+import rule152 from './defense_evasion_create_mod_root_certificate.json';
+import rule153 from './defense_evasion_cve_2020_0601.json';
+import rule154 from './defense_evasion_defender_disabled_via_registry.json';
+import rule155 from './defense_evasion_defender_exclusion_via_powershell.json';
+import rule156 from './defense_evasion_delete_volume_usn_journal_with_fsutil.json';
+import rule157 from './defense_evasion_deleting_websvr_access_logs.json';
+import rule158 from './defense_evasion_deletion_of_bash_command_line_history.json';
+import rule159 from './defense_evasion_disable_posh_scriptblocklogging.json';
+import rule160 from './defense_evasion_disable_selinux_attempt.json';
+import rule161 from './defense_evasion_disable_windows_firewall_rules_with_netsh.json';
+import rule162 from './defense_evasion_disabling_windows_defender_powershell.json';
+import rule163 from './defense_evasion_disabling_windows_logs.json';
+import rule164 from './defense_evasion_dns_over_https_enabled.json';
+import rule165 from './defense_evasion_domain_added_to_google_workspace_trusted_domains.json';
+import rule166 from './defense_evasion_dotnet_compiler_parent_process.json';
+import rule167 from './defense_evasion_ec2_flow_log_deletion.json';
+import rule168 from './defense_evasion_ec2_network_acl_deletion.json';
+import rule169 from './defense_evasion_elastic_agent_service_terminated.json';
+import rule170 from './defense_evasion_elasticache_security_group_creation.json';
+import rule171 from './defense_evasion_elasticache_security_group_modified_or_deleted.json';
+import rule172 from './defense_evasion_enable_inbound_rdp_with_netsh.json';
+import rule173 from './defense_evasion_enable_network_discovery_with_netsh.json';
+import rule174 from './defense_evasion_event_hub_deletion.json';
+import rule175 from './defense_evasion_execution_control_panel_suspicious_args.json';
+import rule176 from './defense_evasion_execution_lolbas_wuauclt.json';
+import rule177 from './defense_evasion_execution_msbuild_started_by_office_app.json';
+import rule178 from './defense_evasion_execution_msbuild_started_by_script.json';
+import rule179 from './defense_evasion_execution_msbuild_started_by_system_process.json';
+import rule180 from './defense_evasion_execution_msbuild_started_renamed.json';
+import rule181 from './defense_evasion_execution_msbuild_started_unusal_process.json';
+import rule182 from './defense_evasion_execution_suspicious_explorer_winword.json';
+import rule183 from './defense_evasion_execution_windefend_unusual_path.json';
+import rule184 from './defense_evasion_file_creation_mult_extension.json';
+import rule185 from './defense_evasion_file_deletion_via_shred.json';
+import rule186 from './defense_evasion_file_mod_writable_dir.json';
+import rule187 from './defense_evasion_firewall_policy_deletion.json';
+import rule188 from './defense_evasion_from_unusual_directory.json';
+import rule189 from './defense_evasion_frontdoor_firewall_policy_deletion.json';
+import rule190 from './defense_evasion_gcp_firewall_rule_created.json';
+import rule191 from './defense_evasion_gcp_firewall_rule_deleted.json';
+import rule192 from './defense_evasion_gcp_firewall_rule_modified.json';
+import rule193 from './defense_evasion_gcp_logging_bucket_deletion.json';
+import rule194 from './defense_evasion_gcp_logging_sink_deletion.json';
+import rule195 from './defense_evasion_gcp_pub_sub_subscription_deletion.json';
+import rule196 from './defense_evasion_gcp_pub_sub_topic_deletion.json';
+import rule197 from './defense_evasion_gcp_storage_bucket_configuration_modified.json';
+import rule198 from './defense_evasion_gcp_storage_bucket_permissions_modified.json';
+import rule199 from './defense_evasion_gcp_virtual_private_cloud_network_deleted.json';
+import rule200 from './defense_evasion_gcp_virtual_private_cloud_route_created.json';
+import rule201 from './defense_evasion_gcp_virtual_private_cloud_route_deleted.json';
+import rule202 from './defense_evasion_google_workspace_bitlocker_setting_disabled.json';
+import rule203 from './defense_evasion_google_workspace_restrictions_for_google_marketplace_changed_to_allow_any_app.json';
+import rule204 from './defense_evasion_guardduty_detector_deletion.json';
+import rule205 from './defense_evasion_hidden_file_dir_tmp.json';
+import rule206 from './defense_evasion_hidden_shared_object.json';
+import rule207 from './defense_evasion_hide_encoded_executable_registry.json';
+import rule208 from './defense_evasion_iis_httplogging_disabled.json';
+import rule209 from './defense_evasion_injection_msbuild.json';
+import rule210 from './defense_evasion_install_root_certificate.json';
+import rule211 from './defense_evasion_installutil_beacon.json';
+import rule212 from './defense_evasion_kernel_module_removal.json';
+import rule213 from './defense_evasion_kubernetes_events_deleted.json';
+import rule214 from './defense_evasion_log_files_deleted.json';
+import rule215 from './defense_evasion_masquerading_as_elastic_endpoint_process.json';
+import rule216 from './defense_evasion_masquerading_renamed_autoit.json';
+import rule217 from './defense_evasion_masquerading_suspicious_werfault_childproc.json';
+import rule218 from './defense_evasion_masquerading_trusted_directory.json';
+import rule219 from './defense_evasion_masquerading_werfault.json';
+import rule220 from './defense_evasion_microsoft_365_exchange_dlp_policy_removed.json';
+import rule221 from './defense_evasion_microsoft_365_exchange_malware_filter_policy_deletion.json';
+import rule222 from './defense_evasion_microsoft_365_exchange_malware_filter_rule_mod.json';
+import rule223 from './defense_evasion_microsoft_365_exchange_safe_attach_rule_disabled.json';
+import rule224 from './defense_evasion_microsoft_365_mailboxauditbypassassociation.json';
+import rule225 from './defense_evasion_microsoft_defender_tampering.json';
+import rule226 from './defense_evasion_misc_lolbin_connecting_to_the_internet.json';
+import rule227 from './defense_evasion_modify_environment_launchctl.json';
+import rule228 from './defense_evasion_ms_office_suspicious_regmod.json';
+import rule229 from './defense_evasion_msbuild_making_network_connections.json';
+import rule230 from './defense_evasion_mshta_beacon.json';
+import rule231 from './defense_evasion_msxsl_network.json';
+import rule232 from './defense_evasion_network_connection_from_windows_binary.json';
+import rule233 from './defense_evasion_network_watcher_deletion.json';
+import rule234 from './defense_evasion_okta_attempt_to_deactivate_okta_policy.json';
+import rule235 from './defense_evasion_okta_attempt_to_deactivate_okta_policy_rule.json';
+import rule236 from './defense_evasion_okta_attempt_to_delete_okta_policy.json';
+import rule237 from './defense_evasion_okta_attempt_to_delete_okta_policy_rule.json';
+import rule238 from './defense_evasion_okta_attempt_to_modify_okta_network_zone.json';
+import rule239 from './defense_evasion_okta_attempt_to_modify_okta_policy.json';
+import rule240 from './defense_evasion_okta_attempt_to_modify_okta_policy_rule.json';
+import rule241 from './defense_evasion_parent_process_pid_spoofing.json';
+import rule242 from './defense_evasion_persistence_temp_scheduled_task.json';
+import rule243 from './defense_evasion_posh_assembly_load.json';
+import rule244 from './defense_evasion_posh_compressed.json';
+import rule245 from './defense_evasion_posh_process_injection.json';
+import rule246 from './defense_evasion_potential_processherpaderping.json';
+import rule247 from './defense_evasion_powershell_windows_firewall_disabled.json';
+import rule248 from './defense_evasion_privacy_controls_tcc_database_modification.json';
+import rule249 from './defense_evasion_privilege_escalation_privacy_pref_sshd_fulldiskaccess.json';
+import rule250 from './defense_evasion_process_termination_followed_by_deletion.json';
+import rule251 from './defense_evasion_proxy_execution_via_msdt.json';
+import rule252 from './defense_evasion_rundll32_no_arguments.json';
+import rule253 from './defense_evasion_s3_bucket_configuration_deletion.json';
+import rule254 from './defense_evasion_safari_config_change.json';
+import rule255 from './defense_evasion_sandboxed_office_app_suspicious_zip_file.json';
+import rule256 from './defense_evasion_scheduledjobs_at_protocol_enabled.json';
+import rule257 from './defense_evasion_sdelete_like_filename_rename.json';
+import rule258 from './defense_evasion_sip_provider_mod.json';
+import rule259 from './defense_evasion_solarwinds_backdoor_service_disabled_via_registry.json';
+import rule260 from './defense_evasion_suppression_rule_created.json';
+import rule261 from './defense_evasion_suspicious_certutil_commands.json';
+import rule262 from './defense_evasion_suspicious_execution_from_mounted_device.json';
+import rule263 from './defense_evasion_suspicious_managedcode_host_process.json';
+import rule264 from './defense_evasion_suspicious_okta_user_password_reset_or_unlock_attempts.json';
+import rule265 from './defense_evasion_suspicious_process_access_direct_syscall.json';
+import rule266 from './defense_evasion_suspicious_process_creation_calltrace.json';
+import rule267 from './defense_evasion_suspicious_scrobj_load.json';
+import rule268 from './defense_evasion_suspicious_short_program_name.json';
+import rule269 from './defense_evasion_suspicious_wmi_script.json';
+import rule270 from './defense_evasion_suspicious_zoom_child_process.json';
+import rule271 from './defense_evasion_system_critical_proc_abnormal_file_activity.json';
+import rule272 from './defense_evasion_tcc_bypass_mounted_apfs_access.json';
+import rule273 from './defense_evasion_timestomp_touch.json';
+import rule274 from './defense_evasion_unload_endpointsecurity_kext.json';
+import rule275 from './defense_evasion_unusual_ads_file_creation.json';
+import rule276 from './defense_evasion_unusual_dir_ads.json';
+import rule277 from './defense_evasion_unusual_network_connection_via_dllhost.json';
+import rule278 from './defense_evasion_unusual_network_connection_via_rundll32.json';
+import rule279 from './defense_evasion_unusual_process_network_connection.json';
+import rule280 from './defense_evasion_unusual_system_vp_child_program.json';
+import rule281 from './defense_evasion_via_filter_manager.json';
+import rule282 from './defense_evasion_waf_acl_deletion.json';
+import rule283 from './defense_evasion_waf_rule_or_rule_group_deletion.json';
+import rule284 from './defense_evasion_workfolders_control_execution.json';
+import rule285 from './discovery_adfind_command_activity.json';
+import rule286 from './discovery_admin_recon.json';
+import rule287 from './discovery_blob_container_access_mod.json';
+import rule288 from './discovery_command_system_account.json';
+import rule289 from './discovery_denied_service_account_request.json';
+import rule290 from './discovery_enumerating_domain_trusts_via_nltest.json';
+import rule291 from './discovery_kernel_module_enumeration.json';
+import rule292 from './discovery_linux_hping_activity.json';
+import rule293 from './discovery_linux_nping_activity.json';
+import rule294 from './discovery_ml_linux_system_information_discovery.json';
+import rule295 from './discovery_ml_linux_system_network_configuration_discovery.json';
+import rule296 from './discovery_ml_linux_system_network_connection_discovery.json';
+import rule297 from './discovery_ml_linux_system_process_discovery.json';
+import rule298 from './discovery_ml_linux_system_user_discovery.json';
+import rule299 from './discovery_net_view.json';
+import rule300 from './discovery_peripheral_device.json';
+import rule301 from './discovery_posh_invoke_sharefinder.json';
+import rule302 from './discovery_posh_suspicious_api_functions.json';
+import rule303 from './discovery_post_exploitation_external_ip_lookup.json';
+import rule304 from './discovery_privileged_localgroup_membership.json';
+import rule305 from './discovery_remote_system_discovery_commands_windows.json';
+import rule306 from './discovery_security_software_grep.json';
+import rule307 from './discovery_security_software_wmic.json';
+import rule308 from './discovery_suspicious_self_subject_review.json';
+import rule309 from './discovery_users_domain_built_in_commands.json';
+import rule310 from './discovery_virtual_machine_fingerprinting.json';
+import rule311 from './discovery_virtual_machine_fingerprinting_grep.json';
+import rule312 from './discovery_whoami_command_activity.json';
+import rule313 from './elastic_endpoint_security.json';
+import rule314 from './endgame_adversary_behavior_detected.json';
+import rule315 from './endgame_malware_detected.json';
+import rule316 from './endgame_malware_prevented.json';
+import rule317 from './endgame_ransomware_detected.json';
+import rule318 from './endgame_ransomware_prevented.json';
+import rule319 from './execution_abnormal_process_id_file_created.json';
+import rule320 from './execution_apt_solarwinds_backdoor_child_cmd_powershell.json';
+import rule321 from './execution_apt_solarwinds_backdoor_unusual_child_processes.json';
+import rule322 from './execution_com_object_xwizard.json';
+import rule323 from './execution_command_prompt_connecting_to_the_internet.json';
+import rule324 from './execution_command_shell_started_by_svchost.json';
+import rule325 from './execution_command_shell_started_by_unusual_process.json';
+import rule326 from './execution_command_shell_via_rundll32.json';
+import rule327 from './execution_command_virtual_machine.json';
+import rule328 from './execution_defense_evasion_electron_app_childproc_node_js.json';
+import rule329 from './execution_endgame_exploit_detected.json';
+import rule330 from './execution_endgame_exploit_prevented.json';
+import rule331 from './execution_enumeration_via_wmiprvse.json';
+import rule332 from './execution_from_unusual_path_cmdline.json';
+import rule333 from './execution_html_help_executable_program_connecting_to_the_internet.json';
+import rule334 from './execution_initial_access_suspicious_browser_childproc.json';
+import rule335 from './execution_installer_package_spawned_network_event.json';
+import rule336 from './execution_linux_netcat_network_connection.json';
+import rule337 from './execution_ml_windows_anomalous_script.json';
+import rule338 from './execution_ms_office_written_file.json';
+import rule339 from './execution_pdf_written_file.json';
+import rule340 from './execution_pentest_eggshell_remote_admin_tool.json';
+import rule341 from './execution_perl_tty_shell.json';
+import rule342 from './execution_posh_portable_executable.json';
+import rule343 from './execution_posh_psreflect.json';
+import rule344 from './execution_process_started_from_process_id_file.json';
+import rule345 from './execution_process_started_in_shared_memory_directory.json';
+import rule346 from './execution_psexec_lateral_movement_command.json';
+import rule347 from './execution_python_tty_shell.json';
+import rule348 from './execution_register_server_program_connecting_to_the_internet.json';
+import rule349 from './execution_revershell_via_shell_cmd.json';
+import rule350 from './execution_scheduled_task_powershell_source.json';
+import rule351 from './execution_script_via_automator_workflows.json';
+import rule352 from './execution_scripting_osascript_exec_followed_by_netcon.json';
+import rule353 from './execution_shared_modules_local_sxs_dll.json';
+import rule354 from './execution_shell_evasion_linux_binary.json';
+import rule355 from './execution_shell_execution_via_apple_scripting.json';
+import rule356 from './execution_suspicious_cmd_wmi.json';
+import rule357 from './execution_suspicious_image_load_wmi_ms_office.json';
+import rule358 from './execution_suspicious_jar_child_process.json';
+import rule359 from './execution_suspicious_java_netcon_childproc.json';
+import rule360 from './execution_suspicious_pdf_reader.json';
+import rule361 from './execution_suspicious_powershell_imgload.json';
+import rule362 from './execution_suspicious_psexesvc.json';
+import rule363 from './execution_tc_bpf_filter.json';
+import rule364 from './execution_user_exec_to_pod.json';
+import rule365 from './execution_via_compiled_html_file.json';
+import rule366 from './execution_via_hidden_shell_conhost.json';
+import rule367 from './execution_via_xp_cmdshell_mssql_stored_procedure.json';
+import rule368 from './exfiltration_ec2_full_network_packet_capture_detected.json';
+import rule369 from './exfiltration_ec2_snapshot_change_activity.json';
+import rule370 from './exfiltration_ec2_vm_export_failure.json';
+import rule371 from './exfiltration_gcp_logging_sink_modification.json';
+import rule372 from './exfiltration_microsoft_365_exchange_transport_rule_creation.json';
+import rule373 from './exfiltration_microsoft_365_exchange_transport_rule_mod.json';
+import rule374 from './exfiltration_rds_snapshot_export.json';
+import rule375 from './exfiltration_rds_snapshot_restored.json';
+import rule376 from './external_alerts.json';
+import rule377 from './guided_onborading_sample_rule.json';
+import rule378 from './impact_attempt_to_revoke_okta_api_token.json';
+import rule379 from './impact_aws_eventbridge_rule_disabled_or_deleted.json';
+import rule380 from './impact_azure_service_principal_credentials_added.json';
+import rule381 from './impact_backup_file_deletion.json';
+import rule382 from './impact_cloudtrail_logging_updated.json';
+import rule383 from './impact_cloudwatch_log_group_deletion.json';
+import rule384 from './impact_cloudwatch_log_stream_deletion.json';
+import rule385 from './impact_deleting_backup_catalogs_with_wbadmin.json';
+import rule386 from './impact_ec2_disable_ebs_encryption.json';
+import rule387 from './impact_efs_filesystem_or_mount_deleted.json';
+import rule388 from './impact_gcp_iam_role_deletion.json';
+import rule389 from './impact_gcp_service_account_deleted.json';
+import rule390 from './impact_gcp_service_account_disabled.json';
+import rule391 from './impact_gcp_storage_bucket_deleted.json';
+import rule392 from './impact_google_workspace_admin_role_deletion.json';
+import rule393 from './impact_google_workspace_mfa_enforcement_disabled.json';
+import rule394 from './impact_hosts_file_modified.json';
+import rule395 from './impact_iam_deactivate_mfa_device.json';
+import rule396 from './impact_iam_group_deletion.json';
+import rule397 from './impact_kubernetes_pod_deleted.json';
+import rule398 from './impact_microsoft_365_potential_ransomware_activity.json';
+import rule399 from './impact_microsoft_365_unusual_volume_of_file_deletion.json';
+import rule400 from './impact_modification_of_boot_config.json';
+import rule401 from './impact_okta_attempt_to_deactivate_okta_application.json';
+import rule402 from './impact_okta_attempt_to_delete_okta_application.json';
+import rule403 from './impact_okta_attempt_to_modify_okta_application.json';
+import rule404 from './impact_possible_okta_dos_attack.json';
+import rule405 from './impact_process_kill_threshold.json';
+import rule406 from './impact_rds_group_deletion.json';
+import rule407 from './impact_rds_instance_cluster_deletion.json';
+import rule408 from './impact_rds_instance_cluster_stoppage.json';
+import rule409 from './impact_resource_group_deletion.json';
+import rule410 from './impact_stop_process_service_threshold.json';
+import rule411 from './impact_virtual_network_device_modified.json';
+import rule412 from './impact_volume_shadow_copy_deletion_or_resized_via_vssadmin.json';
+import rule413 from './impact_volume_shadow_copy_deletion_via_powershell.json';
+import rule414 from './impact_volume_shadow_copy_deletion_via_wmic.json';
+import rule415 from './initial_access_anonymous_request_authorized.json';
+import rule416 from './initial_access_azure_active_directory_high_risk_signin.json';
+import rule417 from './initial_access_azure_active_directory_high_risk_signin_atrisk_or_confirmed.json';
+import rule418 from './initial_access_azure_active_directory_powershell_signin.json';
+import rule419 from './initial_access_consent_grant_attack_via_azure_registered_application.json';
+import rule420 from './initial_access_console_login_root.json';
+import rule421 from './initial_access_evasion_suspicious_htm_file_creation.json';
+import rule422 from './initial_access_external_guest_user_invite.json';
+import rule423 from './initial_access_gcp_iam_custom_role_creation.json';
+import rule424 from './initial_access_microsoft_365_exchange_anti_phish_policy_deletion.json';
+import rule425 from './initial_access_microsoft_365_exchange_anti_phish_rule_mod.json';
+import rule426 from './initial_access_microsoft_365_exchange_safelinks_disabled.json';
+import rule427 from './initial_access_microsoft_365_user_restricted_from_sending_email.json';
+import rule428 from './initial_access_ml_auth_rare_hour_for_a_user_to_logon.json';
+import rule429 from './initial_access_ml_auth_rare_source_ip_for_a_user.json';
+import rule430 from './initial_access_ml_auth_rare_user_logon.json';
+import rule431 from './initial_access_ml_linux_anomalous_user_name.json';
+import rule432 from './initial_access_ml_windows_anomalous_user_name.json';
+import rule433 from './initial_access_ml_windows_rare_user_type10_remote_login.json';
+import rule434 from './initial_access_o365_user_reported_phish_malware.json';
+import rule435 from './initial_access_okta_user_attempted_unauthorized_access.json';
+import rule436 from './initial_access_password_recovery.json';
+import rule437 from './initial_access_rpc_remote_procedure_call_from_the_internet.json';
+import rule438 from './initial_access_rpc_remote_procedure_call_to_the_internet.json';
+import rule439 from './initial_access_script_executing_powershell.json';
+import rule440 from './initial_access_scripts_process_started_via_wmi.json';
+import rule441 from './initial_access_smb_windows_file_sharing_activity_to_the_internet.json';
+import rule442 from './initial_access_suspicious_activity_reported_by_okta_user.json';
+import rule443 from './initial_access_suspicious_mac_ms_office_child_process.json';
+import rule444 from './initial_access_suspicious_ms_exchange_files.json';
+import rule445 from './initial_access_suspicious_ms_exchange_process.json';
+import rule446 from './initial_access_suspicious_ms_exchange_worker_child_process.json';
+import rule447 from './initial_access_suspicious_ms_office_child_process.json';
+import rule448 from './initial_access_suspicious_ms_outlook_child_process.json';
+import rule449 from './initial_access_unsecure_elasticsearch_node.json';
+import rule450 from './initial_access_unusual_dns_service_children.json';
+import rule451 from './initial_access_unusual_dns_service_file_writes.json';
+import rule452 from './initial_access_via_explorer_suspicious_child_parent_args.json';
+import rule453 from './initial_access_via_system_manager.json';
+import rule454 from './initial_access_zoom_meeting_with_no_passcode.json';
+import rule455 from './lateral_movement_cmd_service.json';
+import rule456 from './lateral_movement_credential_access_kerberos_bifrostconsole.json';
+import rule457 from './lateral_movement_dcom_hta.json';
+import rule458 from './lateral_movement_dcom_mmc20.json';
+import rule459 from './lateral_movement_dcom_shellwindow_shellbrowserwindow.json';
+import rule460 from './lateral_movement_defense_evasion_lanman_nullsessionpipe_modification.json';
+import rule461 from './lateral_movement_direct_outbound_smb_connection.json';
+import rule462 from './lateral_movement_dns_server_overflow.json';
+import rule463 from './lateral_movement_evasion_rdp_shadowing.json';
+import rule464 from './lateral_movement_executable_tool_transfer_smb.json';
+import rule465 from './lateral_movement_execution_from_tsclient_mup.json';
+import rule466 from './lateral_movement_execution_via_file_shares_sequence.json';
+import rule467 from './lateral_movement_incoming_winrm_shell_execution.json';
+import rule468 from './lateral_movement_incoming_wmi.json';
+import rule469 from './lateral_movement_malware_uploaded_onedrive.json';
+import rule470 from './lateral_movement_malware_uploaded_sharepoint.json';
+import rule471 from './lateral_movement_mount_hidden_or_webdav_share_net.json';
+import rule472 from './lateral_movement_mounting_smb_share.json';
+import rule473 from './lateral_movement_powershell_remoting_target.json';
+import rule474 from './lateral_movement_rdp_enabled_registry.json';
+import rule475 from './lateral_movement_rdp_sharprdp_target.json';
+import rule476 from './lateral_movement_remote_file_copy_hidden_share.json';
+import rule477 from './lateral_movement_remote_services.json';
+import rule478 from './lateral_movement_remote_ssh_login_enabled.json';
+import rule479 from './lateral_movement_remote_task_creation_winlog.json';
+import rule480 from './lateral_movement_scheduled_task_target.json';
+import rule481 from './lateral_movement_service_control_spawned_script_int.json';
+import rule482 from './lateral_movement_suspicious_rdp_client_imageload.json';
+import rule483 from './lateral_movement_telnet_network_activity_external.json';
+import rule484 from './lateral_movement_telnet_network_activity_internal.json';
+import rule485 from './lateral_movement_via_startup_folder_rdp_smb.json';
+import rule486 from './lateral_movement_vpn_connection_attempt.json';
+import rule487 from './ml_cloudtrail_error_message_spike.json';
+import rule488 from './ml_cloudtrail_rare_error_code.json';
+import rule489 from './ml_cloudtrail_rare_method_by_city.json';
+import rule490 from './ml_cloudtrail_rare_method_by_country.json';
+import rule491 from './ml_cloudtrail_rare_method_by_user.json';
+import rule492 from './ml_high_count_network_denies.json';
+import rule493 from './ml_high_count_network_events.json';
+import rule494 from './ml_linux_anomalous_network_activity.json';
+import rule495 from './ml_linux_anomalous_network_port_activity.json';
+import rule496 from './ml_packetbeat_rare_server_domain.json';
+import rule497 from './ml_rare_destination_country.json';
+import rule498 from './ml_spike_in_traffic_to_a_country.json';
+import rule499 from './ml_windows_anomalous_network_activity.json';
+import rule500 from './okta_threat_detected_by_okta_threatinsight.json';
+import rule501 from './persistence_account_creation_hide_at_logon.json';
+import rule502 from './persistence_ad_adminsdholder.json';
+import rule503 from './persistence_administrator_privileges_assigned_to_okta_group.json';
+import rule504 from './persistence_administrator_role_assigned_to_okta_user.json';
+import rule505 from './persistence_adobe_hijack_persistence.json';
+import rule506 from './persistence_app_compat_shim.json';
+import rule507 from './persistence_appcertdlls_registry.json';
+import rule508 from './persistence_appinitdlls_registry.json';
+import rule509 from './persistence_application_added_to_google_workspace_domain.json';
+import rule510 from './persistence_attempt_to_create_okta_api_token.json';
+import rule511 from './persistence_attempt_to_deactivate_mfa_for_okta_user_account.json';
+import rule512 from './persistence_attempt_to_reset_mfa_factors_for_okta_user_account.json';
+import rule513 from './persistence_azure_automation_account_created.json';
+import rule514 from './persistence_azure_automation_runbook_created_or_modified.json';
+import rule515 from './persistence_azure_automation_webhook_created.json';
+import rule516 from './persistence_azure_conditional_access_policy_modified.json';
+import rule517 from './persistence_azure_global_administrator_role_assigned.json';
+import rule518 from './persistence_azure_pim_user_added_global_admin.json';
+import rule519 from './persistence_azure_privileged_identity_management_role_modified.json';
+import rule520 from './persistence_chkconfig_service_add.json';
+import rule521 from './persistence_creation_change_launch_agents_file.json';
+import rule522 from './persistence_creation_hidden_login_item_osascript.json';
+import rule523 from './persistence_creation_modif_launch_deamon_sequence.json';
+import rule524 from './persistence_credential_access_authorization_plugin_creation.json';
+import rule525 from './persistence_credential_access_modify_auth_module_or_config.json';
+import rule526 from './persistence_credential_access_modify_ssh_binaries.json';
+import rule527 from './persistence_crontab_creation.json';
+import rule528 from './persistence_defense_evasion_hidden_launch_agent_deamon_logonitem_process.json';
+import rule529 from './persistence_directory_services_plugins_modification.json';
+import rule530 from './persistence_docker_shortcuts_plist_modification.json';
+import rule531 from './persistence_dontexpirepasswd_account.json';
+import rule532 from './persistence_dynamic_linker_backup.json';
+import rule533 from './persistence_ec2_network_acl_creation.json';
+import rule534 from './persistence_ec2_security_group_configuration_change_detection.json';
+import rule535 from './persistence_emond_rules_file_creation.json';
+import rule536 from './persistence_emond_rules_process_execution.json';
+import rule537 from './persistence_enable_root_account.json';
+import rule538 from './persistence_etc_file_creation.json';
+import rule539 from './persistence_evasion_hidden_launch_agent_deamon_creation.json';
+import rule540 from './persistence_evasion_hidden_local_account_creation.json';
+import rule541 from './persistence_evasion_registry_ifeo_injection.json';
+import rule542 from './persistence_evasion_registry_startup_shell_folder_modified.json';
+import rule543 from './persistence_exchange_suspicious_mailbox_right_delegation.json';
+import rule544 from './persistence_exposed_service_created_with_type_nodeport.json';
+import rule545 from './persistence_finder_sync_plugin_pluginkit.json';
+import rule546 from './persistence_folder_action_scripts_runtime.json';
+import rule547 from './persistence_gcp_iam_service_account_key_deletion.json';
+import rule548 from './persistence_gcp_key_created_for_service_account.json';
+import rule549 from './persistence_gcp_service_account_created.json';
+import rule550 from './persistence_google_workspace_2sv_policy_disabled.json';
+import rule551 from './persistence_google_workspace_admin_role_assigned_to_user.json';
+import rule552 from './persistence_google_workspace_api_access_granted_via_domain_wide_delegation_of_authority.json';
+import rule553 from './persistence_google_workspace_custom_admin_role_created.json';
+import rule554 from './persistence_google_workspace_policy_modified.json';
+import rule555 from './persistence_google_workspace_role_modified.json';
+import rule556 from './persistence_google_workspace_user_group_access_modified_to_allow_external_access.json';
+import rule557 from './persistence_google_workspace_user_organizational_unit_changed.json';
+import rule558 from './persistence_gpo_schtask_service_creation.json';
+import rule559 from './persistence_iam_group_creation.json';
+import rule560 from './persistence_insmod_kernel_module_load.json';
+import rule561 from './persistence_kde_autostart_modification.json';
+import rule562 from './persistence_local_scheduled_job_creation.json';
+import rule563 from './persistence_local_scheduled_task_creation.json';
+import rule564 from './persistence_local_scheduled_task_scripting.json';
+import rule565 from './persistence_login_logout_hooks_defaults.json';
+import rule566 from './persistence_loginwindow_plist_modification.json';
+import rule567 from './persistence_mfa_disabled_for_azure_user.json';
+import rule568 from './persistence_mfa_disabled_for_google_workspace_organization.json';
+import rule569 from './persistence_microsoft_365_exchange_dkim_signing_config_disabled.json';
+import rule570 from './persistence_microsoft_365_exchange_management_role_assignment.json';
+import rule571 from './persistence_microsoft_365_global_administrator_role_assign.json';
+import rule572 from './persistence_microsoft_365_teams_custom_app_interaction_allowed.json';
+import rule573 from './persistence_microsoft_365_teams_external_access_enabled.json';
+import rule574 from './persistence_microsoft_365_teams_guest_access_enabled.json';
+import rule575 from './persistence_ml_linux_anomalous_process_all_hosts.json';
+import rule576 from './persistence_ml_rare_process_by_host_linux.json';
+import rule577 from './persistence_ml_rare_process_by_host_windows.json';
+import rule578 from './persistence_ml_windows_anomalous_path_activity.json';
+import rule579 from './persistence_ml_windows_anomalous_process_all_hosts.json';
+import rule580 from './persistence_ml_windows_anomalous_process_creation.json';
+import rule581 from './persistence_ml_windows_anomalous_service.json';
+import rule582 from './persistence_modification_sublime_app_plugin_or_script.json';
+import rule583 from './persistence_ms_office_addins_file.json';
+import rule584 from './persistence_ms_outlook_vba_template.json';
+import rule585 from './persistence_msds_alloweddelegateto_krbtgt.json';
+import rule586 from './persistence_okta_attempt_to_modify_or_delete_application_sign_on_policy.json';
+import rule587 from './persistence_periodic_tasks_file_mdofiy.json';
+import rule588 from './persistence_powershell_exch_mailbox_activesync_add_device.json';
+import rule589 from './persistence_priv_escalation_via_accessibility_features.json';
+import rule590 from './persistence_rds_cluster_creation.json';
+import rule591 from './persistence_rds_group_creation.json';
+import rule592 from './persistence_rds_instance_creation.json';
+import rule593 from './persistence_redshift_instance_creation.json';
+import rule594 from './persistence_registry_uncommon.json';
+import rule595 from './persistence_remote_password_reset.json';
+import rule596 from './persistence_route_53_domain_transfer_lock_disabled.json';
+import rule597 from './persistence_route_53_domain_transferred_to_another_account.json';
+import rule598 from './persistence_route_53_hosted_zone_associated_with_a_vpc.json';
+import rule599 from './persistence_route_table_created.json';
+import rule600 from './persistence_route_table_modified_or_deleted.json';
+import rule601 from './persistence_run_key_and_startup_broad.json';
+import rule602 from './persistence_runtime_run_key_startup_susp_procs.json';
+import rule603 from './persistence_scheduled_task_creation_winlog.json';
+import rule604 from './persistence_scheduled_task_updated.json';
+import rule605 from './persistence_screensaver_engine_unexpected_child_process.json';
+import rule606 from './persistence_screensaver_plist_file_modification.json';
+import rule607 from './persistence_sdprop_exclusion_dsheuristics.json';
+import rule608 from './persistence_services_registry.json';
+import rule609 from './persistence_shell_activity_by_web_server.json';
+import rule610 from './persistence_shell_profile_modification.json';
+import rule611 from './persistence_ssh_authorized_keys_modification.json';
+import rule612 from './persistence_startup_folder_file_written_by_suspicious_process.json';
+import rule613 from './persistence_startup_folder_file_written_by_unsigned_process.json';
+import rule614 from './persistence_startup_folder_scripts.json';
+import rule615 from './persistence_suspicious_calendar_modification.json';
+import rule616 from './persistence_suspicious_com_hijack_registry.json';
+import rule617 from './persistence_suspicious_image_load_scheduled_task_ms_office.json';
+import rule618 from './persistence_suspicious_scheduled_task_runtime.json';
+import rule619 from './persistence_suspicious_service_created_registry.json';
+import rule620 from './persistence_system_shells_via_services.json';
+import rule621 from './persistence_time_provider_mod.json';
+import rule622 from './persistence_user_account_added_to_privileged_group_ad.json';
+import rule623 from './persistence_user_account_creation.json';
+import rule624 from './persistence_user_added_as_owner_for_azure_application.json';
+import rule625 from './persistence_user_added_as_owner_for_azure_service_principal.json';
+import rule626 from './persistence_via_application_shimming.json';
+import rule627 from './persistence_via_atom_init_file_modification.json';
+import rule628 from './persistence_via_bits_job_notify_command.json';
+import rule629 from './persistence_via_hidden_run_key_valuename.json';
+import rule630 from './persistence_via_lsa_security_support_provider_registry.json';
+import rule631 from './persistence_via_telemetrycontroller_scheduledtask_hijack.json';
+import rule632 from './persistence_via_update_orchestrator_service_hijack.json';
+import rule633 from './persistence_via_windows_management_instrumentation_event_subscription.json';
+import rule634 from './persistence_via_wmi_stdregprov_run_services.json';
+import rule635 from './persistence_webshell_detection.json';
+import rule636 from './privilege_escalation_applescript_with_admin_privs.json';
+import rule637 from './privilege_escalation_aws_suspicious_saml_activity.json';
+import rule638 from './privilege_escalation_azure_kubernetes_rolebinding_created.json';
+import rule639 from './privilege_escalation_create_process_as_different_user.json';
+import rule640 from './privilege_escalation_cyberarkpas_error_audit_event_promotion.json';
+import rule641 from './privilege_escalation_cyberarkpas_recommended_events_to_monitor_promotion.json';
+import rule642 from './privilege_escalation_disable_uac_registry.json';
+import rule643 from './privilege_escalation_echo_nopasswd_sudoers.json';
+import rule644 from './privilege_escalation_endgame_cred_manipulation_detected.json';
+import rule645 from './privilege_escalation_endgame_cred_manipulation_prevented.json';
+import rule646 from './privilege_escalation_endgame_permission_theft_detected.json';
+import rule647 from './privilege_escalation_endgame_permission_theft_prevented.json';
+import rule648 from './privilege_escalation_endgame_process_injection_detected.json';
+import rule649 from './privilege_escalation_endgame_process_injection_prevented.json';
+import rule650 from './privilege_escalation_explicit_creds_via_scripting.json';
+import rule651 from './privilege_escalation_exploit_adobe_acrobat_updater.json';
+import rule652 from './privilege_escalation_gcp_kubernetes_rolebindings_created_or_patched.json';
+import rule653 from './privilege_escalation_group_policy_iniscript.json';
+import rule654 from './privilege_escalation_group_policy_privileged_groups.json';
+import rule655 from './privilege_escalation_group_policy_scheduled_task.json';
+import rule656 from './privilege_escalation_installertakeover.json';
+import rule657 from './privilege_escalation_krbrelayup_service_creation.json';
+import rule658 from './privilege_escalation_ld_preload_shared_object_modif.json';
+import rule659 from './privilege_escalation_local_user_added_to_admin.json';
+import rule660 from './privilege_escalation_lsa_auth_package.json';
+import rule661 from './privilege_escalation_ml_linux_anomalous_sudo_activity.json';
+import rule662 from './privilege_escalation_ml_windows_rare_user_runas_event.json';
+import rule663 from './privilege_escalation_named_pipe_impersonation.json';
+import rule664 from './privilege_escalation_new_or_modified_federation_domain.json';
+import rule665 from './privilege_escalation_persistence_phantom_dll.json';
+import rule666 from './privilege_escalation_pkexec_envar_hijack.json';
+import rule667 from './privilege_escalation_pod_created_with_hostipc.json';
+import rule668 from './privilege_escalation_pod_created_with_hostnetwork.json';
+import rule669 from './privilege_escalation_pod_created_with_hostpid.json';
+import rule670 from './privilege_escalation_pod_created_with_sensitive_hospath_volume.json';
+import rule671 from './privilege_escalation_port_monitor_print_pocessor_abuse.json';
+import rule672 from './privilege_escalation_posh_token_impersonation.json';
+import rule673 from './privilege_escalation_printspooler_registry_copyfiles.json';
+import rule674 from './privilege_escalation_printspooler_service_suspicious_file.json';
+import rule675 from './privilege_escalation_printspooler_suspicious_file_deletion.json';
+import rule676 from './privilege_escalation_printspooler_suspicious_spl_file.json';
+import rule677 from './privilege_escalation_privileged_pod_created.json';
+import rule678 from './privilege_escalation_rogue_windir_environment_var.json';
+import rule679 from './privilege_escalation_root_crontab_filemod.json';
+import rule680 from './privilege_escalation_root_login_without_mfa.json';
+import rule681 from './privilege_escalation_samaccountname_spoofing_attack.json';
+import rule682 from './privilege_escalation_setuid_setgid_bit_set_via_chmod.json';
+import rule683 from './privilege_escalation_shadow_file_read.json';
+import rule684 from './privilege_escalation_sts_assumerole_usage.json';
+import rule685 from './privilege_escalation_sts_getsessiontoken_abuse.json';
+import rule686 from './privilege_escalation_sudo_buffer_overflow.json';
+import rule687 from './privilege_escalation_sudoers_file_mod.json';
+import rule688 from './privilege_escalation_suspicious_assignment_of_controller_service_account.json';
+import rule689 from './privilege_escalation_suspicious_dnshostname_update.json';
+import rule690 from './privilege_escalation_uac_bypass_com_clipup.json';
+import rule691 from './privilege_escalation_uac_bypass_com_ieinstal.json';
+import rule692 from './privilege_escalation_uac_bypass_com_interface_icmluautil.json';
+import rule693 from './privilege_escalation_uac_bypass_diskcleanup_hijack.json';
+import rule694 from './privilege_escalation_uac_bypass_dll_sideloading.json';
+import rule695 from './privilege_escalation_uac_bypass_event_viewer.json';
+import rule696 from './privilege_escalation_uac_bypass_mock_windir.json';
+import rule697 from './privilege_escalation_uac_bypass_winfw_mmc_hijack.json';
+import rule698 from './privilege_escalation_unshare_namesapce_manipulation.json';
+import rule699 from './privilege_escalation_unusual_parentchild_relationship.json';
+import rule700 from './privilege_escalation_unusual_printspooler_childprocess.json';
+import rule701 from './privilege_escalation_unusual_svchost_childproc_childless.json';
+import rule702 from './privilege_escalation_updateassumerolepolicy.json';
+import rule703 from './privilege_escalation_via_rogue_named_pipe.json';
+import rule704 from './privilege_escalation_windows_service_via_unusual_client.json';
+import rule705 from './resource_development_ml_linux_anomalous_compiler_activity.json';
+import rule706 from './threat_intel_filebeat8x.json';
+import rule707 from './threat_intel_fleet_integrations.json';
export const rawRules = [
rule1,
rule2,
@@ -1424,4 +1424,5 @@ export const rawRules = [
rule704,
rule705,
rule706,
+ rule707,
];
diff --git a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/event_filter_validator.ts b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/event_filter_validator.ts
index 7759caa20e1f9..2ff4a663560b7 100644
--- a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/event_filter_validator.ts
+++ b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/event_filter_validator.ts
@@ -48,8 +48,16 @@ export class EventFilterValidator extends BaseValidator {
return item.listId === ENDPOINT_EVENT_FILTERS_LIST_ID;
}
+ protected async validateHasWritePrivilege(): Promise {
+ return super.validateHasPrivilege('canWriteEventFilters');
+ }
+
+ protected async validateHasReadPrivilege(): Promise {
+ return super.validateHasPrivilege('canReadEventFilters');
+ }
+
async validatePreCreateItem(item: CreateExceptionListItemOptions) {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasWritePrivilege();
await this.validateEventFilterData(item);
// user can always create a global entry so additional checks not needed
@@ -67,7 +75,7 @@ export class EventFilterValidator extends BaseValidator {
): Promise {
const updatedItem = _updatedItem as ExceptionItemLikeOptions;
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasWritePrivilege();
await this.validateEventFilterData(updatedItem);
try {
@@ -96,27 +104,27 @@ export class EventFilterValidator extends BaseValidator {
}
async validatePreGetOneItem(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasReadPrivilege();
}
async validatePreSummary(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasReadPrivilege();
}
async validatePreDeleteItem(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasWritePrivilege();
}
async validatePreExport(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasWritePrivilege();
}
async validatePreSingleListFind(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasReadPrivilege();
}
async validatePreMultiListFind(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasReadPrivilege();
}
async validatePreImport(): Promise {
diff --git a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/host_isolation_exceptions_validator.ts b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/host_isolation_exceptions_validator.ts
index 39e86e7104fae..01809c2c28f68 100644
--- a/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/host_isolation_exceptions_validator.ts
+++ b/x-pack/plugins/security_solution/server/lists_integration/endpoint/validators/host_isolation_exceptions_validator.ts
@@ -60,9 +60,18 @@ export class HostIsolationExceptionsValidator extends BaseValidator {
return item.listId === ENDPOINT_HOST_ISOLATION_EXCEPTIONS_LIST_ID;
}
+ protected async validateHasWritePrivilege(): Promise {
+ return super.validateHasPrivilege('canWriteHostIsolationExceptions');
+ }
+
+ protected async validateHasReadPrivilege(): Promise {
+ return super.validateHasPrivilege('canReadHostIsolationExceptions');
+ }
+
async validatePreCreateItem(
item: CreateExceptionListItemOptions
): Promise {
+ await this.validateHasWritePrivilege();
await this.validateCanIsolateHosts();
await this.validateHostIsolationData(item);
await this.validateByPolicyItem(item);
@@ -75,6 +84,7 @@ export class HostIsolationExceptionsValidator extends BaseValidator {
): Promise {
const updatedItem = _updatedItem as ExceptionItemLikeOptions;
+ await this.validateHasWritePrivilege();
await this.validateCanIsolateHosts();
await this.validateHostIsolationData(updatedItem);
await this.validateByPolicyItem(updatedItem);
@@ -83,27 +93,27 @@ export class HostIsolationExceptionsValidator extends BaseValidator {
}
async validatePreGetOneItem(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasReadPrivilege();
}
async validatePreSummary(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasReadPrivilege();
}
async validatePreDeleteItem(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasWritePrivilege();
}
async validatePreExport(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasWritePrivilege();
}
async validatePreSingleListFind(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasReadPrivilege();
}
async validatePreMultiListFind(): Promise {
- await this.validateCanManageEndpointArtifacts();
+ await this.validateHasReadPrivilege();
}
async validatePreImport(): Promise {
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index 5d28e32be187e..3ebe3a63523d2 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -6860,7 +6860,6 @@
"xpack.apm.tutorial.config_otel.description3": "La liste exhaustive des variables d'environnement, les paramètres de ligne de commande et les extraits de code de configuration (conformes à la spécification OpenTelemetry) se trouvent dans le {otelInstrumentationGuide}. Certains clients OpenTelemetry instables peuvent ne pas prendre en charge toutes les fonctionnalités et nécessitent peut-être d'autres mécanismes de configuration.",
"xpack.apm.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment": "Définir l'URL personnalisée du serveur APM (par défaut : {defaultApmServerUrl})",
"xpack.apm.tutorial.djangoClient.configure.textPost": "Consultez la [documentation]({documentationLink}) pour une utilisation avancée.",
- "xpack.apm.tutorial.dotNetClient.configureAgent.textPost": "Si vous ne transférez pas une instance \"IConfiguration\" à l'agent (par ex., pour les applications non ASP.NET Core) vous pouvez également configurer l'agent par le biais de variables d'environnement. \n Consultez [the documentation]({documentationLink}) pour une utilisation avancée.",
"xpack.apm.tutorial.dotNetClient.download.textPre": "Ajoutez le(s) package(s) d'agent depuis [NuGet]({allNuGetPackagesLink}) à votre application .NET. Plusieurs packages NuGet sont disponibles pour différents cas d'utilisation. \n\nPour une application ASP.NET Core avec Entity Framework Core, téléchargez le package [Elastic.Apm.NetCoreAll]({netCoreAllApmPackageLink}). Ce package ajoutera automatiquement chaque composant d'agent à votre application. \n\n Si vous souhaitez minimiser les dépendances, vous pouvez utiliser le package [Elastic.Apm.AspNetCore]({aspNetCorePackageLink}) uniquement pour le monitoring d'ASP.NET Core ou le package [Elastic.Apm.EfCore]({efCorePackageLink}) uniquement pour le monitoring d'Entity Framework Core. \n\n Si vous souhaitez seulement utiliser l'API d'agent publique pour l'instrumentation manuelle, utilisez le package [Elastic.Apm]({elasticApmPackageLink}).",
"xpack.apm.tutorial.downloadServerRpm": "Vous cherchez les packages 32 bits ? Consultez la [Download page]({downloadPageLink}).",
"xpack.apm.tutorial.downloadServerTitle": "Vous cherchez les packages 32 bits ? Consultez la [Download page]({downloadPageLink}).",
@@ -15596,15 +15595,15 @@
"xpack.infra.homePage.noMetricsIndicesInstructionsActionLabel": "Voir les instructions de configuration",
"xpack.infra.homePage.settingsTabTitle": "Paramètres",
"xpack.infra.homePage.toolbar.kqlSearchFieldPlaceholder": "Rechercher des données d'infrastructure… (par exemple host.name:host-1)",
+ "xpack.infra.hostsTable.averageMemoryTotalColumnHeader": "Total de la mémoire (moy.)",
+ "xpack.infra.hostsTable.averageMemoryUsageColumnHeader": "Utilisation de la mémoire (moy.)",
+ "xpack.infra.hostsTable.averageRxColumnHeader": "",
+ "xpack.infra.hostsTable.averageTxColumnHeader": "",
+ "xpack.infra.hostsTable.diskLatencyColumnHeader": "",
"xpack.infra.hostsTable.nameColumnHeader": "Nom",
- "xpack.infra.hostsTable.operatingSystemColumnHeader": "Système d'exploitation",
"xpack.infra.hostsTable.numberOfCpusColumnHeader": "Nombre de processeurs",
- "xpack.infra.hostsTable.diskLatencyColumnHeader": "",
- "xpack.infra.hostsTable.averageTxColumnHeader": "",
- "xpack.infra.hostsTable.averageRxColumnHeader": "",
- "xpack.infra.hostsTable.averageMemoryTotalColumnHeader": "Total de la mémoire (moy.)",
+ "xpack.infra.hostsTable.operatingSystemColumnHeader": "Système d'exploitation",
"xpack.infra.hostsTable.servicesOnHostColumnHeader": "",
- "xpack.infra.hostsTable.averageMemoryUsageColumnHeader": "Utilisation de la mémoire (moy.)",
"xpack.infra.infra.nodeDetails.apmTabLabel": "APM",
"xpack.infra.infra.nodeDetails.createAlertLink": "Créer une règle d'inventaire",
"xpack.infra.infra.nodeDetails.openAsPage": "Ouvrir en tant que page",
@@ -33706,4 +33705,4 @@
"xpack.painlessLab.title": "Painless Lab",
"xpack.painlessLab.walkthroughButtonLabel": "Présentation"
}
-}
+}
\ No newline at end of file
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 4c173784e59f8..a74277d17862a 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -6848,7 +6848,6 @@
"xpack.apm.tutorial.config_otel.description3": "環境変数、コマンドラインパラメーター、構成コードスニペット(OpenTelemetry仕様に準拠)の網羅的な一覧は、{otelInstrumentationGuide}をご覧ください。一部の不安定なOpenTelemetryクライアントでは、一部の機能がサポートされておらず、別の構成メカニズムが必要になる場合があります。",
"xpack.apm.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment": "カスタム APM Server URL(デフォルト:{defaultApmServerUrl})を設定します",
"xpack.apm.tutorial.djangoClient.configure.textPost": "高度な用途に関しては [ドキュメンテーション]({documentationLink})をご覧ください。",
- "xpack.apm.tutorial.dotNetClient.configureAgent.textPost": "エージェントに「IConfiguration」インスタンスが渡されていない場合、(例:非 ASP.NET Core アプリケーションの場合)、エージェントを環境変数で構成することもできます。\n 高度な用途に関しては [ドキュメンテーション]({documentationLink})をご覧ください。",
"xpack.apm.tutorial.dotNetClient.download.textPre": "[NuGet]({allNuGetPackagesLink})から .NET アプリケーションにエージェントパッケージを追加してください。用途の異なる複数の NuGet パッケージがあります。\n\nEntity Framework Core の ASP.NET Core アプリケーションの場合は、[Elastic.Apm.NetCoreAll]({netCoreAllApmPackageLink})パッケージをダウンロードしてください。このパッケージは、自動的にすべてのエージェントコンポーネントをアプリケーションに追加します。\n\n 依存性を最低限に抑えたい場合、ASP.NET Coreの監視のみに[Elastic.Apm.AspNetCore]({aspNetCorePackageLink})パッケージ、またはEntity Framework Coreの監視のみに[Elastic.Apm.EfCore]({efCorePackageLink})パッケージを使用することができます。\n\n 手動インストルメンテーションのみにパブリック Agent API を使用する場合は、[Elastic.Apm]({elasticApmPackageLink})パッケージを使用してください。",
"xpack.apm.tutorial.downloadServerRpm": "32 ビットパッケージをお探しですか?[ダウンロードページ]({downloadPageLink})をご覧ください。",
"xpack.apm.tutorial.downloadServerTitle": "32 ビットパッケージをお探しですか?[ダウンロードページ]({downloadPageLink})をご覧ください。",
@@ -15581,15 +15580,15 @@
"xpack.infra.homePage.noMetricsIndicesInstructionsActionLabel": "セットアップの手順を表示",
"xpack.infra.homePage.settingsTabTitle": "設定",
"xpack.infra.homePage.toolbar.kqlSearchFieldPlaceholder": "インフラストラクチャデータを検索…(例:host.name:host-1)",
- "xpack.infra.hostsTable.nameColumnHeader": "名前",
- "xpack.infra.hostsTable.operatingSystemColumnHeader": "オペレーティングシステム",
- "xpack.infra.hostsTable.numberOfCpusColumnHeader": "CPU数",
- "xpack.infra.hostsTable.diskLatencyColumnHeader": "",
+ "xpack.infra.hostsTable.averageMemoryTotalColumnHeader": "メモリ合計 (平均) ",
+ "xpack.infra.hostsTable.averageMemoryUsageColumnHeader": "メモリー使用状況(平均)",
"xpack.infra.hostsTable.averageTxColumnHeader": "",
"xpack.infra.hostsTable.averageRxColumnHeader": "",
- "xpack.infra.hostsTable.averageMemoryTotalColumnHeader": "メモリ合計 (平均) ",
+ "xpack.infra.hostsTable.diskLatencyColumnHeader": "",
+ "xpack.infra.hostsTable.nameColumnHeader": "名前",
+ "xpack.infra.hostsTable.numberOfCpusColumnHeader": "CPU数",
+ "xpack.infra.hostsTable.operatingSystemColumnHeader": "オペレーティングシステム",
"xpack.infra.hostsTable.servicesOnHostColumnHeader": "",
- "xpack.infra.hostsTable.averageMemoryUsageColumnHeader": "メモリー使用状況(平均)",
"xpack.infra.infra.nodeDetails.apmTabLabel": "APM",
"xpack.infra.infra.nodeDetails.createAlertLink": "インベントリルールの作成",
"xpack.infra.infra.nodeDetails.openAsPage": "ページとして開く",
@@ -33680,4 +33679,4 @@
"xpack.painlessLab.title": "Painless Lab",
"xpack.painlessLab.walkthroughButtonLabel": "実地検証"
}
-}
+}
\ No newline at end of file
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index f985f05cc2dc5..6127534e13b93 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -6864,7 +6864,6 @@
"xpack.apm.tutorial.config_otel.description3": "{otelInstrumentationGuide}中提供了环境变量、命令行参数和配置代码片段(根据 OpenTelemetry 规范)的详细列表。某些不稳定的 OpenTelemetry 客户端可能不支持所有功能,并可能需要备选配置机制。",
"xpack.apm.tutorial.djangoClient.configure.commands.setCustomApmServerUrlComment": "设置定制 APM Server URL(默认值:{defaultApmServerUrl})",
"xpack.apm.tutorial.djangoClient.configure.textPost": "有关高级用法,请参阅[文档]({documentationLink})。",
- "xpack.apm.tutorial.dotNetClient.configureAgent.textPost": "如果您未将 `IConfiguration` 实例传递给代理(例如非 ASP.NET Core 应用程序), 您还可以通过环境变量配置代理。\n 有关高级用法,请参阅[文档]({documentationLink})。",
"xpack.apm.tutorial.dotNetClient.download.textPre": "将来自 [NuGet]({allNuGetPackagesLink}) 的代理软件包添加到 .NET 应用程序。有多个 NuGet 软件包可用于不同的用例。\n\n对于具有 Entity Framework Core 的 ASP.NET Core 应用程序,请下载 [Elastic.Apm.NetCoreAll]({netCoreAllApmPackageLink}) 软件包。此软件包将自动将每个 代理组件添加到您的应用程序。\n\n 如果您希望最大程度减少依存关系,您可以将 [Elastic.Apm.AspNetCore]({aspNetCorePackageLink}) 软件包仅用于 ASP.NET Core 监测,或将 [Elastic.Apm.EfCore]({efCorePackageLink}) 软件包仅用于 Entity Framework Core 监测。\n\n 如果 仅希望将公共代理 API 用于手动检测,请使用 [Elastic.Apm]({elasticApmPackageLink}) 软件包。",
"xpack.apm.tutorial.downloadServerRpm": "寻找 32 位软件包?请参阅[下载页面]({downloadPageLink})。",
"xpack.apm.tutorial.downloadServerTitle": "寻找 32 位软件包?请参阅[下载页面]({downloadPageLink})。",
@@ -15602,15 +15601,15 @@
"xpack.infra.homePage.noMetricsIndicesInstructionsActionLabel": "查看设置说明",
"xpack.infra.homePage.settingsTabTitle": "设置",
"xpack.infra.homePage.toolbar.kqlSearchFieldPlaceholder": "搜索基础设施数据……(例如 host.name:host-1)",
+ "xpack.infra.hostsTable.averageMemoryTotalColumnHeader": "内存合计 (平均值)",
+ "xpack.infra.hostsTable.averageMemoryUsageColumnHeader": "内存使用率(平均值)",
+ "xpack.infra.hostsTable.averageRxColumnHeader": "",
+ "xpack.infra.hostsTable.averageTxColumnHeader": "",
+ "xpack.infra.hostsTable.diskLatencyColumnHeader": "",
"xpack.infra.hostsTable.nameColumnHeader": "名称",
- "xpack.infra.hostsTable.operatingSystemColumnHeader": "操作系统",
"xpack.infra.hostsTable.numberOfCpusColumnHeader": "# 个 CPU",
- "xpack.infra.hostsTable.diskLatencyColumnHeader": "",
- "xpack.infra.hostsTable.averageTxColumnHeader": "",
- "xpack.infra.hostsTable.averageRxColumnHeader": "",
- "xpack.infra.hostsTable.averageMemoryTotalColumnHeader": "内存合计 (平均值)",
+ "xpack.infra.hostsTable.operatingSystemColumnHeader": "操作系统",
"xpack.infra.hostsTable.servicesOnHostColumnHeader": "",
- "xpack.infra.hostsTable.averageMemoryUsageColumnHeader": "内存使用率(平均值)",
"xpack.infra.infra.nodeDetails.apmTabLabel": "APM",
"xpack.infra.infra.nodeDetails.createAlertLink": "创建库存规则",
"xpack.infra.infra.nodeDetails.openAsPage": "以页面形式打开",
@@ -33717,4 +33716,4 @@
"xpack.painlessLab.title": "Painless 实验室",
"xpack.painlessLab.walkthroughButtonLabel": "指导"
}
-}
+}
\ No newline at end of file
diff --git a/x-pack/test/apm_api_integration/tests/storage_explorer/storage_details.spec.ts b/x-pack/test/apm_api_integration/tests/storage_explorer/storage_details.spec.ts
index 35bfca8b8c821..260c22eb68775 100644
--- a/x-pack/test/apm_api_integration/tests/storage_explorer/storage_details.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/storage_explorer/storage_details.spec.ts
@@ -70,8 +70,9 @@ export default function ApiTest({ getService }: FtrProviderContext) {
}
);
- registry.when('Storage details', { config: 'basic', archives: [] }, () => {
- describe('when data is loaded', () => {
+ // FLAKY: https://github.com/elastic/kibana/issues/144025
+ registry.when.skip('Storage details', { config: 'basic', archives: [] }, () => {
+ describe.skip('when data is loaded', () => {
before(async () => {
const serviceGo = apm
.service({ name: serviceName, environment: 'production', agentName: 'go' })
diff --git a/x-pack/test/fleet_api_integration/apis/epm/index.js b/x-pack/test/fleet_api_integration/apis/epm/index.js
index 137d7d59d8bfa..48af135f15ae2 100644
--- a/x-pack/test/fleet_api_integration/apis/epm/index.js
+++ b/x-pack/test/fleet_api_integration/apis/epm/index.js
@@ -23,6 +23,7 @@ export default function loadTests({ loadTestFile }) {
loadTestFile(require.resolve('./install_remove_kbn_assets_in_space'));
loadTestFile(require.resolve('./install_remove_multiple'));
loadTestFile(require.resolve('./install_update'));
+ loadTestFile(require.resolve('./install_tag_assets'));
loadTestFile(require.resolve('./bulk_upgrade'));
loadTestFile(require.resolve('./update_assets'));
loadTestFile(require.resolve('./data_stream'));
diff --git a/x-pack/test/fleet_api_integration/apis/epm/install_tag_assets.ts b/x-pack/test/fleet_api_integration/apis/epm/install_tag_assets.ts
new file mode 100644
index 0000000000000..7458912207a38
--- /dev/null
+++ b/x-pack/test/fleet_api_integration/apis/epm/install_tag_assets.ts
@@ -0,0 +1,154 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license 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';
+const testSpaceId = 'fleet_test_space';
+
+export default function (providerContext: FtrProviderContext) {
+ const { getService } = providerContext;
+ const kibanaServer = getService('kibanaServer');
+ const supertest = getService('supertest');
+ const dockerServers = getService('dockerServers');
+ const server = dockerServers.get('registry');
+ const pkgName = 'only_dashboard';
+ const pkgVersion = '0.1.0';
+
+ const uninstallPackage = async (pkg: string, version: string) => {
+ await supertest.delete(`/api/fleet/epm/packages/${pkg}/${version}`).set('kbn-xsrf', 'xxxx');
+ };
+
+ const installPackageInSpace = async (pkg: string, version: string, spaceId: string) => {
+ await supertest
+ .post(`/s/${spaceId}/api/fleet/epm/packages/${pkg}/${version}`)
+ .set('kbn-xsrf', 'xxxx')
+ .send({ force: true })
+ .expect(200);
+ };
+ const createSpace = async (spaceId: string) => {
+ await supertest
+ .post(`/api/spaces/space`)
+ .set('kbn-xsrf', 'xxxx')
+ .send({
+ name: spaceId,
+ id: spaceId,
+ initials: 's',
+ color: '#D6BF57',
+ disabledFeatures: [],
+ imageUrl: '',
+ })
+ .expect(200);
+ };
+
+ const getTag = async (id: string, space?: string) =>
+ kibanaServer.savedObjects
+ .get({
+ type: 'tag',
+ id,
+ ...(space && { space }),
+ })
+ .catch(() => {});
+
+ const deleteTag = async (id: string) =>
+ kibanaServer.savedObjects
+ .delete({
+ type: 'tag',
+ id,
+ })
+ .catch(() => {});
+
+ const deleteSpace = async (spaceId: string) => {
+ await supertest.delete(`/api/spaces/space/${spaceId}`).set('kbn-xsrf', 'xxxx').send();
+ };
+ describe('asset tagging', () => {
+ skipIfNoDockerRegistry(providerContext);
+ setupFleetAndAgents(providerContext);
+ before(async () => {
+ await createSpace(testSpaceId);
+ });
+
+ after(async () => {
+ await deleteSpace(testSpaceId);
+ });
+ describe('creates correct tags when installing a package in non default space after installing in default space', async () => {
+ before(async () => {
+ if (!server.enabled) return;
+ await installPackageInSpace('all_assets', pkgVersion, 'default');
+ await installPackageInSpace(pkgName, pkgVersion, testSpaceId);
+ });
+ after(async () => {
+ if (!server.enabled) return;
+ await uninstallPackage('all_assets', pkgVersion);
+ await uninstallPackage(pkgName, pkgVersion);
+ });
+
+ it('Should create managed tag saved objects', async () => {
+ const defaultTag = await getTag('fleet-managed-default');
+ expect(defaultTag).not.equal(undefined);
+
+ const spaceTag = await getTag('fleet-managed-fleet_test_space', testSpaceId);
+ expect(spaceTag).not.equal(undefined);
+ });
+ it('Should create package tag saved objects', async () => {
+ const defaultTag = await getTag(`fleet-pkg-all_assets-default`);
+ expect(defaultTag).not.equal(undefined);
+
+ const spaceTag = await getTag(`fleet-pkg-${pkgName}-fleet_test_space`, testSpaceId);
+ expect(spaceTag).not.equal(undefined);
+ });
+ });
+
+ describe('Handles presence of legacy tags', async () => {
+ before(async () => {
+ if (!server.enabled) return;
+
+ // first clean up any existing tag saved objects as they arent cleaned on uninstall
+ await deleteTag('fleet-managed-default');
+ await deleteTag(`fleet-pkg-${pkgName}-default`);
+
+ // now create the legacy tags
+ await kibanaServer.savedObjects.create({
+ type: 'tag',
+ id: 'managed',
+ overwrite: false,
+ attributes: {
+ name: 'managed',
+ description: '',
+ color: '#FFFFFF',
+ },
+ });
+ await kibanaServer.savedObjects.create({
+ type: 'tag',
+ id: pkgName,
+ overwrite: false,
+ attributes: {
+ name: pkgName,
+ description: '',
+ color: '#FFFFFF',
+ },
+ });
+
+ await installPackageInSpace(pkgName, pkgVersion, 'default');
+ });
+ after(async () => {
+ if (!server.enabled) return;
+ await uninstallPackage(pkgName, pkgVersion);
+ await deleteTag('managed');
+ await deleteTag('tag');
+ });
+
+ it('Should not create space aware tag saved objects if legacy tags exist', async () => {
+ const managedTag = await getTag('fleet-managed-default');
+ expect(managedTag).equal(undefined);
+
+ const pkgTag = await getTag(`fleet-pkg-${pkgName}-default`);
+ expect(pkgTag).equal(undefined);
+ });
+ });
+ });
+}
diff --git a/x-pack/test/functional/apps/lens/group1/fields_list.ts b/x-pack/test/functional/apps/lens/group1/fields_list.ts
new file mode 100644
index 0000000000000..3d571483bf9ac
--- /dev/null
+++ b/x-pack/test/functional/apps/lens/group1/fields_list.ts
@@ -0,0 +1,233 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ getService, getPageObjects }: FtrProviderContext) {
+ const PageObjects = getPageObjects(['visualize', 'lens', 'common', 'header']);
+ const find = getService('find');
+ const log = getService('log');
+ const testSubjects = getService('testSubjects');
+ const filterBar = getService('filterBar');
+ const fieldEditor = getService('fieldEditor');
+ const retry = getService('retry');
+
+ describe('lens fields list tests', () => {
+ for (const datasourceType of ['form-based', 'ad-hoc', 'ad-hoc-no-timefield']) {
+ describe(`${datasourceType} datasource`, () => {
+ before(async () => {
+ await PageObjects.visualize.navigateToNewVisualization();
+ await PageObjects.visualize.clickVisType('lens');
+
+ if (datasourceType !== 'form-based') {
+ await PageObjects.lens.createAdHocDataView(
+ '*stash*',
+ datasourceType !== 'ad-hoc-no-timefield'
+ );
+ retry.try(async () => {
+ const selectedPattern = await PageObjects.lens.getDataPanelIndexPattern();
+ expect(selectedPattern).to.eql('*stash*');
+ });
+ }
+
+ if (datasourceType !== 'ad-hoc-no-timefield') {
+ await PageObjects.lens.goToTimeRange();
+ }
+
+ await retry.try(async () => {
+ await PageObjects.lens.clickAddField();
+ await fieldEditor.setName('runtime_string');
+ await fieldEditor.enableValue();
+ await fieldEditor.typeScript("emit('abc')");
+ await fieldEditor.save();
+ await PageObjects.header.waitUntilLoadingHasFinished();
+ });
+ });
+
+ it('should show all fields as available', async () => {
+ expect(
+ await (await testSubjects.find('lnsIndexPatternAvailableFields-count')).getVisibleText()
+ ).to.eql(53);
+ });
+
+ it('should show a histogram and top values popover for numeric field', async () => {
+ const [fieldId] = await PageObjects.lens.findFieldIdsByType('number');
+ await log.debug(`Opening field stats for ${fieldId}`);
+ await testSubjects.click(fieldId);
+ // check for popover
+ await testSubjects.exists('lnsFieldListPanel-title');
+ // check for top values chart
+ await testSubjects.existOrFail('lnsFieldListPanel-topValues');
+ const topValuesRows = await testSubjects.findAll('lnsFieldListPanel-topValues-bucket');
+ expect(topValuesRows.length).to.eql(11);
+ // check for the Other entry
+ expect(await topValuesRows[10].getVisibleText()).to.eql('Other\n96.7%');
+ // switch to date histogram
+ await testSubjects.click('lnsFieldListPanel-buttonGroup-distributionButton');
+ // check for date histogram chart
+ expect(
+ await find.existsByCssSelector(
+ '[data-test-subj="lnsFieldListPanelFieldContent"] .echChart'
+ )
+ ).to.eql(true);
+ });
+
+ it('should show a top values popover for a keyword field', async () => {
+ const [fieldId] = await PageObjects.lens.findFieldIdsByType('string');
+ await log.debug(`Opening field stats for ${fieldId}`);
+ await testSubjects.click(fieldId);
+ // check for popover
+ await testSubjects.exists('lnsFieldListPanel-title');
+ // check for top values chart
+ await testSubjects.existOrFail('lnsFieldListPanel-topValues');
+ const topValuesRows = await testSubjects.findAll('lnsFieldListPanel-topValues-bucket');
+ expect(topValuesRows.length).to.eql(11);
+ // check for the Other entry
+ expect(await topValuesRows[10].getVisibleText()).to.eql('Other\n99.9%');
+ // check no date histogram
+ expect(
+ await find.existsByCssSelector(
+ '[data-test-subj="lnsFieldListPanelFieldContent"] .echChart'
+ )
+ ).to.eql(false);
+ });
+
+ it('should show a date histogram popover for a date field', async () => {
+ const [fieldId] = await PageObjects.lens.findFieldIdsByType('date');
+ await log.debug(`Opening field stats for ${fieldId}`);
+ await testSubjects.click(fieldId);
+ // check for popover
+ await testSubjects.exists('lnsFieldListPanel-title');
+ // check for date histogram chart
+ expect(
+ await find.existsByCssSelector(
+ '[data-test-subj="lnsFieldListPanelFieldContent"] .echChart'
+ )
+ ).to.eql(true);
+ // check no top values chart
+ await testSubjects.missingOrFail('lnsFieldListPanel-buttonGroup-topValuesButton');
+ });
+
+ it('should show a placeholder message about geo points field', async () => {
+ const [fieldId] = await PageObjects.lens.findFieldIdsByType('geo_point');
+ await log.debug(`Opening field stats for ${fieldId}`);
+ await testSubjects.click(fieldId);
+ const message = await testSubjects.getVisibleText('lnsFieldListPanel-missingFieldStats');
+ expect(message).to.eql('Analysis is not available for this field.');
+ });
+
+ it('should show stats for a numeric runtime field', async () => {
+ await PageObjects.lens.searchField('runtime');
+ await PageObjects.lens.waitForField('runtime_number');
+ const [fieldId] = await PageObjects.lens.findFieldIdsByType('number');
+ await log.debug(`Opening field stats for ${fieldId}`);
+ await testSubjects.click(fieldId);
+ // check for popover
+ await testSubjects.exists('lnsFieldListPanel-title');
+ // check for top values chart
+ await testSubjects.existOrFail('lnsFieldListPanel-topValues');
+ // check values
+ const topValuesRows = await testSubjects.findAll('lnsFieldListPanel-topValues-bucket');
+ expect(topValuesRows.length).to.eql(11);
+ // check for the Other entry
+ expect(await topValuesRows[10].getVisibleText()).to.eql('Other\n96.7%');
+ // switch to date histogram
+ await testSubjects.click('lnsFieldListPanel-buttonGroup-distributionButton');
+ // check for date histogram chart
+ expect(
+ await find.existsByCssSelector(
+ '[data-test-subj="lnsFieldListPanelFieldContent"] .echChart'
+ )
+ ).to.eql(true);
+ });
+
+ it('should show stats for a keyword runtime field', async () => {
+ await PageObjects.lens.searchField('runtime');
+ await PageObjects.lens.waitForField('runtime_string');
+ const [fieldId] = await PageObjects.lens.findFieldIdsByType('string');
+ await log.debug(`Opening field stats for ${fieldId}`);
+ await testSubjects.click(fieldId);
+ // check for popover
+ await testSubjects.exists('lnsFieldListPanel-title');
+ // check for top values chart
+ await testSubjects.existOrFail('lnsFieldListPanel-topValues');
+ // check no date histogram
+ expect(
+ await find.existsByCssSelector(
+ '[data-test-subj="lnsFieldListPanelFieldContent"] .echChart'
+ )
+ ).to.eql(false);
+ await PageObjects.lens.searchField('');
+ });
+
+ it('should change popover content if user defines a filter that affects field values', async () => {
+ // check the current records count for stats
+ const [fieldId] = await PageObjects.lens.findFieldIdsByType('string');
+ await log.debug(`Opening field stats for ${fieldId}`);
+ await testSubjects.click(fieldId);
+ const valuesCount = parseInt(
+ (await testSubjects.getVisibleText('lnsFieldListPanel-statsFooter'))
+ .replaceAll(/(Calculated from | records\.)/g, '')
+ .replace(',', ''),
+ 10
+ );
+ // define a filter
+ await filterBar.addFilter('geo.src', 'is', 'CN');
+ await retry.waitFor('Wait for the filter to take effect', async () => {
+ await testSubjects.click(fieldId);
+ // check for top values chart has changed compared to the previous test
+ const newValuesCount = parseInt(
+ (await testSubjects.getVisibleText('lnsFieldListPanel-statsFooter'))
+ .replaceAll(/(Calculated from | records\.)/g, '')
+ .replace(',', ''),
+ 10
+ );
+ return newValuesCount < valuesCount;
+ });
+ });
+
+ // One Fields cap's limitation is to not know when an index has no fields based on filters
+ it('should detect fields have no data in popup if filter excludes them', async () => {
+ await filterBar.removeAllFilters();
+ await filterBar.addFilter('bytes', 'is', '-1');
+ // check via popup fields have no data
+ const [fieldId] = await PageObjects.lens.findFieldIdsByType('string');
+ await log.debug(`Opening field stats for ${fieldId}`);
+ await retry.try(async () => {
+ await testSubjects.click(fieldId);
+ expect(await testSubjects.find('lnsFieldListPanel-missingFieldStats')).to.be.ok();
+ // close the popover
+ await testSubjects.click(fieldId);
+ });
+ });
+
+ if (datasourceType !== 'ad-hoc-no-timefield') {
+ it('should move some fields as empty when the time range excludes them', async () => {
+ // remove the filter
+ await filterBar.removeAllFilters();
+ // tweak the time range to 17 Sept 2015 to 18 Sept 2015
+ await PageObjects.lens.goToTimeRange(
+ 'Sep 17, 2015 @ 06:31:44.000',
+ 'Sep 18, 2015 @ 06:31:44.000'
+ );
+ // check all fields are empty now
+ expect(
+ await (await testSubjects.find('lnsIndexPatternEmptyFields-count')).getVisibleText()
+ ).to.eql(52);
+ // check avaialble count is 0
+ expect(
+ await (
+ await testSubjects.find('lnsIndexPatternAvailableFields-count')
+ ).getVisibleText()
+ ).to.eql(1);
+ });
+ }
+ });
+ }
+ });
+}
diff --git a/x-pack/test/functional/apps/lens/group1/index.ts b/x-pack/test/functional/apps/lens/group1/index.ts
index 47f08a59e7341..302289319adbf 100644
--- a/x-pack/test/functional/apps/lens/group1/index.ts
+++ b/x-pack/test/functional/apps/lens/group1/index.ts
@@ -79,6 +79,7 @@ export default ({ getService, loadTestFile, getPageObjects }: FtrProviderContext
loadTestFile(require.resolve('./table_dashboard'));
loadTestFile(require.resolve('./table'));
loadTestFile(require.resolve('./text_based_languages'));
+ loadTestFile(require.resolve('./fields_list'));
loadTestFile(require.resolve('./layer_actions'));
}
});
diff --git a/x-pack/test/functional/page_objects/lens_page.ts b/x-pack/test/functional/page_objects/lens_page.ts
index 8dd95aa107929..c814b5b161fcd 100644
--- a/x-pack/test/functional/page_objects/lens_page.ts
+++ b/x-pack/test/functional/page_objects/lens_page.ts
@@ -1335,9 +1335,9 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
await testSubjects.click('indexPattern-add-field');
},
- async createAdHocDataView(name: string) {
+ async createAdHocDataView(name: string, hasTimeField?: boolean) {
await testSubjects.click('lns-dataView-switch-link');
- await PageObjects.unifiedSearch.createNewDataView(name, true);
+ await PageObjects.unifiedSearch.createNewDataView(name, true, hasTimeField);
},
async switchToTextBasedLanguage(language: string) {
@@ -1638,5 +1638,17 @@ export function LensPageProvider({ getService, getPageObjects }: FtrProviderCont
})
);
},
+
+ async findFieldIdsByType(
+ type: 'string' | 'number' | 'date' | 'geo_point' | 'ip_range',
+ group: 'available' | 'empty' | 'meta' = 'available'
+ ) {
+ const groupCapitalized = `${group[0].toUpperCase()}${group.slice(1).toLowerCase()}`;
+ const allFieldsForType = await find.allByCssSelector(
+ `[data-test-subj="lnsIndexPattern${groupCapitalized}Fields"] .lnsFieldItem--${type}`
+ );
+ // map to testSubjId
+ return Promise.all(allFieldsForType.map((el) => el.getAttribute('data-test-subj')));
+ },
});
}
diff --git a/yarn.lock b/yarn.lock
index 554c99f5ce852..9ed18bf2180b0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3117,6 +3117,18 @@
version "0.0.0"
uid ""
+"@kbn/core-lifecycle-server-internal@link:bazel-bin/packages/core/lifecycle/core-lifecycle-server-internal":
+ version "0.0.0"
+ uid ""
+
+"@kbn/core-lifecycle-server-mocks@link:bazel-bin/packages/core/lifecycle/core-lifecycle-server-mocks":
+ version "0.0.0"
+ uid ""
+
+"@kbn/core-lifecycle-server@link:bazel-bin/packages/core/lifecycle/core-lifecycle-server":
+ version "0.0.0"
+ uid ""
+
"@kbn/core-logging-server-internal@link:bazel-bin/packages/core/logging/core-logging-server-internal":
version "0.0.0"
uid ""
@@ -3209,6 +3221,18 @@
version "0.0.0"
uid ""
+"@kbn/core-plugins-server-internal@link:bazel-bin/packages/core/plugins/core-plugins-server-internal":
+ version "0.0.0"
+ uid ""
+
+"@kbn/core-plugins-server-mocks@link:bazel-bin/packages/core/plugins/core-plugins-server-mocks":
+ version "0.0.0"
+ uid ""
+
+"@kbn/core-plugins-server@link:bazel-bin/packages/core/plugins/core-plugins-server":
+ version "0.0.0"
+ uid ""
+
"@kbn/core-preboot-server-internal@link:bazel-bin/packages/core/preboot/core-preboot-server-internal":
version "0.0.0"
uid ""
@@ -7326,6 +7350,18 @@
version "0.0.0"
uid ""
+"@types/kbn__core-lifecycle-server-internal@link:bazel-bin/packages/core/lifecycle/core-lifecycle-server-internal/npm_module_types":
+ version "0.0.0"
+ uid ""
+
+"@types/kbn__core-lifecycle-server-mocks@link:bazel-bin/packages/core/lifecycle/core-lifecycle-server-mocks/npm_module_types":
+ version "0.0.0"
+ uid ""
+
+"@types/kbn__core-lifecycle-server@link:bazel-bin/packages/core/lifecycle/core-lifecycle-server/npm_module_types":
+ version "0.0.0"
+ uid ""
+
"@types/kbn__core-logging-server-internal@link:bazel-bin/packages/core/logging/core-logging-server-internal/npm_module_types":
version "0.0.0"
uid ""
@@ -7418,6 +7454,18 @@
version "0.0.0"
uid ""
+"@types/kbn__core-plugins-server-internal@link:bazel-bin/packages/core/plugins/core-plugins-server-internal/npm_module_types":
+ version "0.0.0"
+ uid ""
+
+"@types/kbn__core-plugins-server-mocks@link:bazel-bin/packages/core/plugins/core-plugins-server-mocks/npm_module_types":
+ version "0.0.0"
+ uid ""
+
+"@types/kbn__core-plugins-server@link:bazel-bin/packages/core/plugins/core-plugins-server/npm_module_types":
+ version "0.0.0"
+ uid ""
+
"@types/kbn__core-preboot-server-internal@link:bazel-bin/packages/core/preboot/core-preboot-server-internal/npm_module_types":
version "0.0.0"
uid ""