diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index f38621c5f5d52..dfcda878c2e4e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1098,6 +1098,7 @@ x-pack/plugins/cloud_integrations/cloud_full_story/server/config.ts @elastic/kib /x-pack/plugins/security_solution/server/lib/timeline @elastic/security-threat-hunting-investigations ## Security Solution sub teams - Threat Hunting Explore +/x-pack/plugins/security_solution/common/api/risk_score @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/common/search_strategy/security_solution/hosts @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/common/search_strategy/security_solution/matrix_histogram @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/common/search_strategy/security_solution/network @elastic/security-threat-hunting-explore diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index 0c144f6323d4f..4830d43d5a5e1 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: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'actions'] --- import actionsObj from './actions.devdocs.json'; diff --git a/api_docs/advanced_settings.mdx b/api_docs/advanced_settings.mdx index ce2a0fd5f9558..cbdf72e9b3f17 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: 2023-08-07 +date: 2023-08-08 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 a74c901bf95a8..370b7d66dafcd 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: 2023-08-07 +date: 2023-08-08 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 a5a706acb4c7c..b6e940f0c1c8f 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: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 555df9a979958..f9d18e273f7c8 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: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/asset_manager.mdx b/api_docs/asset_manager.mdx index cea362fc1a3d4..f4d18f9705670 100644 --- a/api_docs/asset_manager.mdx +++ b/api_docs/asset_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/assetManager title: "assetManager" image: https://source.unsplash.com/400x175/?github description: API docs for the assetManager plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'assetManager'] --- import assetManagerObj from './asset_manager.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 3a23d057ccb70..40c84072b6875 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: 2023-08-07 +date: 2023-08-08 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 55f95bd830af2..a09991262233c 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: 2023-08-07 +date: 2023-08-08 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 1b5d94cd94d81..6015bb6745617 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: 2023-08-07 +date: 2023-08-08 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 cb04e39a209fd..5b9296c2f8cac 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: 2023-08-07 +date: 2023-08-08 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 826e12bd9e367..0386ec84baa3e 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: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.devdocs.json b/api_docs/cloud.devdocs.json index 728a017d66d72..a184e4150164f 100644 --- a/api_docs/cloud.devdocs.json +++ b/api_docs/cloud.devdocs.json @@ -85,6 +85,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "cloud", + "id": "def-public.CloudConfigType.projects_url", + "type": "string", + "tags": [], + "label": "projects_url", + "description": [], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/cloud/public/plugin.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "cloud", "id": "def-public.CloudConfigType.billing_url", @@ -369,6 +383,22 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "cloud", + "id": "def-public.CloudStart.projectsUrl", + "type": "string", + "tags": [], + "label": "projectsUrl", + "description": [ + "\nThe full URL to the serverless projects page on Elastic Cloud. Undefined if not running in Serverless." + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/cloud/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "cloud", "id": "def-public.CloudStart.elasticsearchUrl", @@ -528,6 +558,22 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "cloud", + "id": "def-public.CloudSetup.projectsUrl", + "type": "string", + "tags": [], + "label": "projectsUrl", + "description": [ + "\nThe full URL to the serverless projects page on Elastic Cloud. Undefined if not running in Serverless." + ], + "signature": [ + "string | undefined" + ], + "path": "x-pack/plugins/cloud/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "cloud", "id": "def-public.CloudSetup.profileUrl", diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index cdf3ca39c2dfd..917ce1dd5e70d 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: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 65 | 0 | 15 | 0 | +| 68 | 0 | 16 | 0 | ## Client diff --git a/api_docs/cloud_chat.mdx b/api_docs/cloud_chat.mdx index b93c01cfeb41e..2439ac29b2acd 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: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChat'] --- import cloudChatObj from './cloud_chat.devdocs.json'; diff --git a/api_docs/cloud_chat_provider.mdx b/api_docs/cloud_chat_provider.mdx index 19a89c56dacd2..09e274f8d6ac2 100644 --- a/api_docs/cloud_chat_provider.mdx +++ b/api_docs/cloud_chat_provider.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudChatProvider title: "cloudChatProvider" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudChatProvider plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudChatProvider'] --- import cloudChatProviderObj from './cloud_chat_provider.devdocs.json'; diff --git a/api_docs/cloud_data_migration.mdx b/api_docs/cloud_data_migration.mdx index 8b31aad23c101..904c4a2398b07 100644 --- a/api_docs/cloud_data_migration.mdx +++ b/api_docs/cloud_data_migration.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDataMigration title: "cloudDataMigration" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDataMigration plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDataMigration'] --- import cloudDataMigrationObj from './cloud_data_migration.devdocs.json'; diff --git a/api_docs/cloud_defend.mdx b/api_docs/cloud_defend.mdx index c700785eec027..50651cb15c6eb 100644 --- a/api_docs/cloud_defend.mdx +++ b/api_docs/cloud_defend.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudDefend title: "cloudDefend" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudDefend plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloudDefend'] --- import cloudDefendObj from './cloud_defend.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index 3221f0760a879..19630e2129c64 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: 2023-08-07 +date: 2023-08-08 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 d1011864b96b0..e5d9d6c84093e 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: 2023-08-07 +date: 2023-08-08 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 d5c35a16bff48..c26eb4445b0d2 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: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/content_management.mdx b/api_docs/content_management.mdx index f995eef2384fc..375156d7a08a5 100644 --- a/api_docs/content_management.mdx +++ b/api_docs/content_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/contentManagement title: "contentManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the contentManagement plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'contentManagement'] --- import contentManagementObj from './content_management.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 38ba3ffa03d5f..b86db1ce03475 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: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index 35731de1849ef..48852fd3e96b2 100644 --- a/api_docs/custom_integrations.mdx +++ b/api_docs/custom_integrations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/customIntegrations title: "customIntegrations" image: https://source.unsplash.com/400x175/?github description: API docs for the customIntegrations plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'customIntegrations'] --- import customIntegrationsObj from './custom_integrations.devdocs.json'; diff --git a/api_docs/dashboard.mdx b/api_docs/dashboard.mdx index dc966fef6e212..2bb3f88bcfd8e 100644 --- a/api_docs/dashboard.mdx +++ b/api_docs/dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboard title: "dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboard plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboard'] --- import dashboardObj from './dashboard.devdocs.json'; diff --git a/api_docs/dashboard_enhanced.mdx b/api_docs/dashboard_enhanced.mdx index ed1f0adc3ca58..f5efa0a0d205f 100644 --- a/api_docs/dashboard_enhanced.mdx +++ b/api_docs/dashboard_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dashboardEnhanced title: "dashboardEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the dashboardEnhanced plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.mdx b/api_docs/data.mdx index 4e4595d9035f9..ed440a37583cb 100644 --- a/api_docs/data.mdx +++ b/api_docs/data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data title: "data" image: https://source.unsplash.com/400x175/?github description: API docs for the data plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data'] --- import dataObj from './data.devdocs.json'; diff --git a/api_docs/data_query.mdx b/api_docs/data_query.mdx index 6827faeb91cea..6f4cdc678a730 100644 --- a/api_docs/data_query.mdx +++ b/api_docs/data_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-query title: "data.query" image: https://source.unsplash.com/400x175/?github description: API docs for the data.query plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.query'] --- import dataQueryObj from './data_query.devdocs.json'; diff --git a/api_docs/data_search.mdx b/api_docs/data_search.mdx index a4d9f50c0d006..2ba7fae435d5f 100644 --- a/api_docs/data_search.mdx +++ b/api_docs/data_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/data-search title: "data.search" image: https://source.unsplash.com/400x175/?github description: API docs for the data.search plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'data.search'] --- import dataSearchObj from './data_search.devdocs.json'; diff --git a/api_docs/data_view_editor.mdx b/api_docs/data_view_editor.mdx index 21d943704390a..0afb9c6cc38d6 100644 --- a/api_docs/data_view_editor.mdx +++ b/api_docs/data_view_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewEditor title: "dataViewEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewEditor plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewEditor'] --- import dataViewEditorObj from './data_view_editor.devdocs.json'; diff --git a/api_docs/data_view_field_editor.mdx b/api_docs/data_view_field_editor.mdx index 3f26559205d3f..88b56f7be7bf5 100644 --- a/api_docs/data_view_field_editor.mdx +++ b/api_docs/data_view_field_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewFieldEditor title: "dataViewFieldEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewFieldEditor plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewFieldEditor'] --- import dataViewFieldEditorObj from './data_view_field_editor.devdocs.json'; diff --git a/api_docs/data_view_management.mdx b/api_docs/data_view_management.mdx index 9c0152cca82f5..4a6c796e4e163 100644 --- a/api_docs/data_view_management.mdx +++ b/api_docs/data_view_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViewManagement title: "dataViewManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViewManagement plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViewManagement'] --- import dataViewManagementObj from './data_view_management.devdocs.json'; diff --git a/api_docs/data_views.mdx b/api_docs/data_views.mdx index 5fcfb52aac83b..939dbf86bcc32 100644 --- a/api_docs/data_views.mdx +++ b/api_docs/data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataViews title: "dataViews" image: https://source.unsplash.com/400x175/?github description: API docs for the dataViews plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataViews'] --- import dataViewsObj from './data_views.devdocs.json'; diff --git a/api_docs/data_visualizer.mdx b/api_docs/data_visualizer.mdx index 406e99d0768af..121bea50c1589 100644 --- a/api_docs/data_visualizer.mdx +++ b/api_docs/data_visualizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/dataVisualizer title: "dataVisualizer" image: https://source.unsplash.com/400x175/?github description: API docs for the dataVisualizer plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dataVisualizer'] --- import dataVisualizerObj from './data_visualizer.devdocs.json'; diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index cc74b20da38c3..acc2067839829 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByApi slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-api title: Deprecated API usage by API description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index b8f6b90a55b6a..cdf90dc6b2602 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsByPlugin slug: /kibana-dev-docs/api-meta/deprecated-api-list-by-plugin title: Deprecated API usage by plugin description: A list of deprecated APIs, which plugins are still referencing them, and when they need to be removed by. -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index 0065c2bbfbd95..585d6b75de9aa 100644 --- a/api_docs/deprecations_by_team.mdx +++ b/api_docs/deprecations_by_team.mdx @@ -7,7 +7,7 @@ id: kibDevDocsDeprecationsDueByTeam slug: /kibana-dev-docs/api-meta/deprecations-due-by-team title: Deprecated APIs due to be removed, by team description: Lists the teams that are referencing deprecated APIs with a remove by date. -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index cba0f46d085e4..8a8540fc1360f 100644 --- a/api_docs/dev_tools.mdx +++ b/api_docs/dev_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/devTools title: "devTools" image: https://source.unsplash.com/400x175/?github description: API docs for the devTools plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'devTools'] --- import devToolsObj from './dev_tools.devdocs.json'; diff --git a/api_docs/discover.mdx b/api_docs/discover.mdx index f078833af6e5a..2bd1d80e8a7b2 100644 --- a/api_docs/discover.mdx +++ b/api_docs/discover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discover title: "discover" image: https://source.unsplash.com/400x175/?github description: API docs for the discover plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discover'] --- import discoverObj from './discover.devdocs.json'; diff --git a/api_docs/discover_enhanced.mdx b/api_docs/discover_enhanced.mdx index 182d735998d2c..bd072de583e44 100644 --- a/api_docs/discover_enhanced.mdx +++ b/api_docs/discover_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/discoverEnhanced title: "discoverEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the discoverEnhanced plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/ecs_data_quality_dashboard.mdx b/api_docs/ecs_data_quality_dashboard.mdx index e0342ca566e72..7cf7dd6fd5681 100644 --- a/api_docs/ecs_data_quality_dashboard.mdx +++ b/api_docs/ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ecsDataQualityDashboard title: "ecsDataQualityDashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the ecsDataQualityDashboard plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ecsDataQualityDashboard'] --- import ecsDataQualityDashboardObj from './ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index e1659ddc7d4ac..5ca2ab1573fa9 100644 --- a/api_docs/embeddable.mdx +++ b/api_docs/embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddable title: "embeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddable plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddable'] --- import embeddableObj from './embeddable.devdocs.json'; diff --git a/api_docs/embeddable_enhanced.mdx b/api_docs/embeddable_enhanced.mdx index c183702ab5e30..9ec369a20e907 100644 --- a/api_docs/embeddable_enhanced.mdx +++ b/api_docs/embeddable_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/embeddableEnhanced title: "embeddableEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the embeddableEnhanced plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'embeddableEnhanced'] --- import embeddableEnhancedObj from './embeddable_enhanced.devdocs.json'; diff --git a/api_docs/encrypted_saved_objects.mdx b/api_docs/encrypted_saved_objects.mdx index 71994f34dee0d..fd78a0506ea65 100644 --- a/api_docs/encrypted_saved_objects.mdx +++ b/api_docs/encrypted_saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/encryptedSavedObjects title: "encryptedSavedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the encryptedSavedObjects plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'encryptedSavedObjects'] --- import encryptedSavedObjectsObj from './encrypted_saved_objects.devdocs.json'; diff --git a/api_docs/enterprise_search.mdx b/api_docs/enterprise_search.mdx index 44e075bf6556f..142741b6ca029 100644 --- a/api_docs/enterprise_search.mdx +++ b/api_docs/enterprise_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/enterpriseSearch title: "enterpriseSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the enterpriseSearch plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'enterpriseSearch'] --- import enterpriseSearchObj from './enterprise_search.devdocs.json'; diff --git a/api_docs/es_ui_shared.mdx b/api_docs/es_ui_shared.mdx index c78713974d762..f72c796652692 100644 --- a/api_docs/es_ui_shared.mdx +++ b/api_docs/es_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/esUiShared title: "esUiShared" image: https://source.unsplash.com/400x175/?github description: API docs for the esUiShared plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'esUiShared'] --- import esUiSharedObj from './es_ui_shared.devdocs.json'; diff --git a/api_docs/event_annotation.mdx b/api_docs/event_annotation.mdx index a3d826745a6d3..f50f62c4a8927 100644 --- a/api_docs/event_annotation.mdx +++ b/api_docs/event_annotation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventAnnotation title: "eventAnnotation" image: https://source.unsplash.com/400x175/?github description: API docs for the eventAnnotation plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventAnnotation'] --- import eventAnnotationObj from './event_annotation.devdocs.json'; diff --git a/api_docs/event_log.mdx b/api_docs/event_log.mdx index 62d41e5302149..e89fac58a2876 100644 --- a/api_docs/event_log.mdx +++ b/api_docs/event_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/eventLog title: "eventLog" image: https://source.unsplash.com/400x175/?github description: API docs for the eventLog plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/exploratory_view.mdx b/api_docs/exploratory_view.mdx index fe4582ac8061a..935ec02b807e9 100644 --- a/api_docs/exploratory_view.mdx +++ b/api_docs/exploratory_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/exploratoryView title: "exploratoryView" image: https://source.unsplash.com/400x175/?github description: API docs for the exploratoryView plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'exploratoryView'] --- import exploratoryViewObj from './exploratory_view.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index d249faa557bcf..e2041edf19373 100644 --- a/api_docs/expression_error.mdx +++ b/api_docs/expression_error.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionError title: "expressionError" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionError plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionError'] --- import expressionErrorObj from './expression_error.devdocs.json'; diff --git a/api_docs/expression_gauge.mdx b/api_docs/expression_gauge.mdx index 4bb9d73956019..7939c2f3076e7 100644 --- a/api_docs/expression_gauge.mdx +++ b/api_docs/expression_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionGauge title: "expressionGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionGauge plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionGauge'] --- import expressionGaugeObj from './expression_gauge.devdocs.json'; diff --git a/api_docs/expression_heatmap.mdx b/api_docs/expression_heatmap.mdx index e98a93be419a9..c6cf3ed57d316 100644 --- a/api_docs/expression_heatmap.mdx +++ b/api_docs/expression_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionHeatmap title: "expressionHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionHeatmap plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionHeatmap'] --- import expressionHeatmapObj from './expression_heatmap.devdocs.json'; diff --git a/api_docs/expression_image.mdx b/api_docs/expression_image.mdx index 1edb7360bf0c3..cd90df87cb30a 100644 --- a/api_docs/expression_image.mdx +++ b/api_docs/expression_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionImage title: "expressionImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionImage plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionImage'] --- import expressionImageObj from './expression_image.devdocs.json'; diff --git a/api_docs/expression_legacy_metric_vis.mdx b/api_docs/expression_legacy_metric_vis.mdx index 70fe703e36ecf..40193204df51f 100644 --- a/api_docs/expression_legacy_metric_vis.mdx +++ b/api_docs/expression_legacy_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionLegacyMetricVis title: "expressionLegacyMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionLegacyMetricVis plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionLegacyMetricVis'] --- import expressionLegacyMetricVisObj from './expression_legacy_metric_vis.devdocs.json'; diff --git a/api_docs/expression_metric.mdx b/api_docs/expression_metric.mdx index 4ef71c992c72f..8456e45c43aa7 100644 --- a/api_docs/expression_metric.mdx +++ b/api_docs/expression_metric.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetric title: "expressionMetric" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetric plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetric'] --- import expressionMetricObj from './expression_metric.devdocs.json'; diff --git a/api_docs/expression_metric_vis.mdx b/api_docs/expression_metric_vis.mdx index 0e7aff229a2ac..6e1c7fff5b9cb 100644 --- a/api_docs/expression_metric_vis.mdx +++ b/api_docs/expression_metric_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionMetricVis title: "expressionMetricVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionMetricVis plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionMetricVis'] --- import expressionMetricVisObj from './expression_metric_vis.devdocs.json'; diff --git a/api_docs/expression_partition_vis.mdx b/api_docs/expression_partition_vis.mdx index 522b3449dd35f..40c1ec352d684 100644 --- a/api_docs/expression_partition_vis.mdx +++ b/api_docs/expression_partition_vis.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionPartitionVis title: "expressionPartitionVis" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionPartitionVis plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionPartitionVis'] --- import expressionPartitionVisObj from './expression_partition_vis.devdocs.json'; diff --git a/api_docs/expression_repeat_image.mdx b/api_docs/expression_repeat_image.mdx index e09616800f00f..fdfc5024941dc 100644 --- a/api_docs/expression_repeat_image.mdx +++ b/api_docs/expression_repeat_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRepeatImage title: "expressionRepeatImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRepeatImage plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRepeatImage'] --- import expressionRepeatImageObj from './expression_repeat_image.devdocs.json'; diff --git a/api_docs/expression_reveal_image.mdx b/api_docs/expression_reveal_image.mdx index 0b33d89cc05c9..f12b98a3ef638 100644 --- a/api_docs/expression_reveal_image.mdx +++ b/api_docs/expression_reveal_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionRevealImage title: "expressionRevealImage" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionRevealImage plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionRevealImage'] --- import expressionRevealImageObj from './expression_reveal_image.devdocs.json'; diff --git a/api_docs/expression_shape.mdx b/api_docs/expression_shape.mdx index a92dad1497d54..0b38793ebf1d1 100644 --- a/api_docs/expression_shape.mdx +++ b/api_docs/expression_shape.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionShape title: "expressionShape" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionShape plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionShape'] --- import expressionShapeObj from './expression_shape.devdocs.json'; diff --git a/api_docs/expression_tagcloud.mdx b/api_docs/expression_tagcloud.mdx index 4b2a09dce305e..fdd5a6e7434a1 100644 --- a/api_docs/expression_tagcloud.mdx +++ b/api_docs/expression_tagcloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionTagcloud title: "expressionTagcloud" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionTagcloud plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionTagcloud'] --- import expressionTagcloudObj from './expression_tagcloud.devdocs.json'; diff --git a/api_docs/expression_x_y.mdx b/api_docs/expression_x_y.mdx index b4ba19142c62e..13291fe251db6 100644 --- a/api_docs/expression_x_y.mdx +++ b/api_docs/expression_x_y.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressionXY title: "expressionXY" image: https://source.unsplash.com/400x175/?github description: API docs for the expressionXY plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressionXY'] --- import expressionXYObj from './expression_x_y.devdocs.json'; diff --git a/api_docs/expressions.mdx b/api_docs/expressions.mdx index 490a81add6324..46144bdd70a71 100644 --- a/api_docs/expressions.mdx +++ b/api_docs/expressions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/expressions title: "expressions" image: https://source.unsplash.com/400x175/?github description: API docs for the expressions plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'expressions'] --- import expressionsObj from './expressions.devdocs.json'; diff --git a/api_docs/features.mdx b/api_docs/features.mdx index 798bd4482c030..c84e5990a374f 100644 --- a/api_docs/features.mdx +++ b/api_docs/features.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/features title: "features" image: https://source.unsplash.com/400x175/?github description: API docs for the features plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'features'] --- import featuresObj from './features.devdocs.json'; diff --git a/api_docs/field_formats.mdx b/api_docs/field_formats.mdx index 8d1e48d06ba8d..d0a6e1861cdcb 100644 --- a/api_docs/field_formats.mdx +++ b/api_docs/field_formats.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fieldFormats title: "fieldFormats" image: https://source.unsplash.com/400x175/?github description: API docs for the fieldFormats plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fieldFormats'] --- import fieldFormatsObj from './field_formats.devdocs.json'; diff --git a/api_docs/file_upload.mdx b/api_docs/file_upload.mdx index fea923ace85b8..4ad74f547420c 100644 --- a/api_docs/file_upload.mdx +++ b/api_docs/file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fileUpload title: "fileUpload" image: https://source.unsplash.com/400x175/?github description: API docs for the fileUpload plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.mdx b/api_docs/files.mdx index c8963c7cb063c..459bc877566b3 100644 --- a/api_docs/files.mdx +++ b/api_docs/files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/files title: "files" image: https://source.unsplash.com/400x175/?github description: API docs for the files plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; diff --git a/api_docs/files_management.mdx b/api_docs/files_management.mdx index 54ffadcf83b77..d7b28cd1617f8 100644 --- a/api_docs/files_management.mdx +++ b/api_docs/files_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/filesManagement title: "filesManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the filesManagement plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'filesManagement'] --- import filesManagementObj from './files_management.devdocs.json'; diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index bff412b2b54c3..a5600ae945a8e 100644 --- a/api_docs/fleet.mdx +++ b/api_docs/fleet.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/fleet title: "fleet" image: https://source.unsplash.com/400x175/?github description: API docs for the fleet plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fleet'] --- import fleetObj from './fleet.devdocs.json'; diff --git a/api_docs/global_search.mdx b/api_docs/global_search.mdx index da19543e2ec66..1bb35a9da4b34 100644 --- a/api_docs/global_search.mdx +++ b/api_docs/global_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/globalSearch title: "globalSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the globalSearch plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'globalSearch'] --- import globalSearchObj from './global_search.devdocs.json'; diff --git a/api_docs/guided_onboarding.mdx b/api_docs/guided_onboarding.mdx index 0691f6b56baba..649eab3e58dab 100644 --- a/api_docs/guided_onboarding.mdx +++ b/api_docs/guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/guidedOnboarding title: "guidedOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the guidedOnboarding plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.devdocs.json b/api_docs/home.devdocs.json index bb166c8e01d12..20a538f673ae6 100644 --- a/api_docs/home.devdocs.json +++ b/api_docs/home.devdocs.json @@ -201,7 +201,7 @@ "\nConvert instruction variant id into display text.\n" ], "signature": [ - "(id: \"ESC\" | \"OSX\" | \"DEB\" | \"RPM\" | \"DOCKER\" | \"WINDOWS\" | \"NODE\" | \"DJANGO\" | \"FLASK\" | \"RAILS\" | \"RACK\" | \"JS\" | \"GO\" | \"JAVA\" | \"DOTNET\" | \"LINUX\" | \"PHP\" | \"FLEET\" | \"OPEN_TELEMETRY\") => any" + "(id: \"ESC\" | \"OSX\" | \"DEB\" | \"RPM\" | \"DOCKER\" | \"WINDOWS\" | \"NODE\" | \"DJANGO\" | \"FLASK\" | \"RAILS\" | \"RACK\" | \"JS\" | \"GO\" | \"JAVA\" | \"DOTNET\" | \"LINUX\" | \"PHP\" | \"FLEET\" | \"OPEN_TELEMETRY\" | \"OTHER_LINUX\") => any" ], "path": "src/plugins/home/common/instruction_variant.ts", "deprecated": false, @@ -215,7 +215,7 @@ "label": "id", "description": [], "signature": [ - "\"ESC\" | \"OSX\" | \"DEB\" | \"RPM\" | \"DOCKER\" | \"WINDOWS\" | \"NODE\" | \"DJANGO\" | \"FLASK\" | \"RAILS\" | \"RACK\" | \"JS\" | \"GO\" | \"JAVA\" | \"DOTNET\" | \"LINUX\" | \"PHP\" | \"FLEET\" | \"OPEN_TELEMETRY\"" + "\"ESC\" | \"OSX\" | \"DEB\" | \"RPM\" | \"DOCKER\" | \"WINDOWS\" | \"NODE\" | \"DJANGO\" | \"FLASK\" | \"RAILS\" | \"RACK\" | \"JS\" | \"GO\" | \"JAVA\" | \"DOTNET\" | \"LINUX\" | \"PHP\" | \"FLEET\" | \"OPEN_TELEMETRY\" | \"OTHER_LINUX\"" ], "path": "src/plugins/home/common/instruction_variant.ts", "deprecated": false, @@ -1180,6 +1180,17 @@ "path": "src/plugins/home/common/instruction_variant.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "home", + "id": "def-public.INSTRUCTION_VARIANT.OTHER_LINUX", + "type": "string", + "tags": [], + "label": "OTHER_LINUX", + "description": [], + "path": "src/plugins/home/common/instruction_variant.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false @@ -2122,6 +2133,17 @@ "path": "src/plugins/home/common/instruction_variant.ts", "deprecated": false, "trackAdoption": false + }, + { + "parentPluginId": "home", + "id": "def-server.INSTRUCTION_VARIANT.OTHER_LINUX", + "type": "string", + "tags": [], + "label": "OTHER_LINUX", + "description": [], + "path": "src/plugins/home/common/instruction_variant.ts", + "deprecated": false, + "trackAdoption": false } ], "initialIsOpen": false diff --git a/api_docs/home.mdx b/api_docs/home.mdx index ea0a15fa8556f..37986e0e5531e 100644 --- a/api_docs/home.mdx +++ b/api_docs/home.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/home title: "home" image: https://source.unsplash.com/400x175/?github description: API docs for the home plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 143 | 0 | 104 | 0 | +| 145 | 0 | 106 | 0 | ## Client diff --git a/api_docs/image_embeddable.mdx b/api_docs/image_embeddable.mdx index 06ea6f1913542..84f6acf3fc8e9 100644 --- a/api_docs/image_embeddable.mdx +++ b/api_docs/image_embeddable.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/imageEmbeddable title: "imageEmbeddable" image: https://source.unsplash.com/400x175/?github description: API docs for the imageEmbeddable plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'imageEmbeddable'] --- import imageEmbeddableObj from './image_embeddable.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 9ae86e7532e20..bbac09985808e 100644 --- a/api_docs/index_lifecycle_management.mdx +++ b/api_docs/index_lifecycle_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexLifecycleManagement title: "indexLifecycleManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexLifecycleManagement plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexLifecycleManagement'] --- import indexLifecycleManagementObj from './index_lifecycle_management.devdocs.json'; diff --git a/api_docs/index_management.mdx b/api_docs/index_management.mdx index 5931f242bc59b..39520e4f5fd12 100644 --- a/api_docs/index_management.mdx +++ b/api_docs/index_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/indexManagement title: "indexManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the indexManagement plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'indexManagement'] --- import indexManagementObj from './index_management.devdocs.json'; diff --git a/api_docs/infra.mdx b/api_docs/infra.mdx index bef30bab07abc..43b6b1f6d5fec 100644 --- a/api_docs/infra.mdx +++ b/api_docs/infra.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/infra title: "infra" image: https://source.unsplash.com/400x175/?github description: API docs for the infra plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'infra'] --- import infraObj from './infra.devdocs.json'; diff --git a/api_docs/inspector.mdx b/api_docs/inspector.mdx index 0a5c3e4b51003..f8fb7c62396c0 100644 --- a/api_docs/inspector.mdx +++ b/api_docs/inspector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/inspector title: "inspector" image: https://source.unsplash.com/400x175/?github description: API docs for the inspector plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'inspector'] --- import inspectorObj from './inspector.devdocs.json'; diff --git a/api_docs/interactive_setup.mdx b/api_docs/interactive_setup.mdx index 10a3efee6b126..f24b897b682f1 100644 --- a/api_docs/interactive_setup.mdx +++ b/api_docs/interactive_setup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/interactiveSetup title: "interactiveSetup" image: https://source.unsplash.com/400x175/?github description: API docs for the interactiveSetup plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'interactiveSetup'] --- import interactiveSetupObj from './interactive_setup.devdocs.json'; diff --git a/api_docs/kbn_ace.mdx b/api_docs/kbn_ace.mdx index 02126c00f3997..66b909ccff85d 100644 --- a/api_docs/kbn_ace.mdx +++ b/api_docs/kbn_ace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ace title: "@kbn/ace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ace plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ace'] --- import kbnAceObj from './kbn_ace.devdocs.json'; diff --git a/api_docs/kbn_aiops_components.mdx b/api_docs/kbn_aiops_components.mdx index cc74978a0e2b7..e4e3eed672b02 100644 --- a/api_docs/kbn_aiops_components.mdx +++ b/api_docs/kbn_aiops_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-components title: "@kbn/aiops-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-components plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-components'] --- import kbnAiopsComponentsObj from './kbn_aiops_components.devdocs.json'; diff --git a/api_docs/kbn_aiops_utils.mdx b/api_docs/kbn_aiops_utils.mdx index c2cdf4f854037..8ab1310b76c47 100644 --- a/api_docs/kbn_aiops_utils.mdx +++ b/api_docs/kbn_aiops_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-aiops-utils title: "@kbn/aiops-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/aiops-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerting_state_types.mdx b/api_docs/kbn_alerting_state_types.mdx index c2fc0a56c7df6..748be1e48ebf4 100644 --- a/api_docs/kbn_alerting_state_types.mdx +++ b/api_docs/kbn_alerting_state_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerting-state-types title: "@kbn/alerting-state-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerting-state-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerting-state-types'] --- import kbnAlertingStateTypesObj from './kbn_alerting_state_types.devdocs.json'; diff --git a/api_docs/kbn_alerts_as_data_utils.mdx b/api_docs/kbn_alerts_as_data_utils.mdx index 2ba5da05a515b..c7101ea8fa22b 100644 --- a/api_docs/kbn_alerts_as_data_utils.mdx +++ b/api_docs/kbn_alerts_as_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-as-data-utils title: "@kbn/alerts-as-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-as-data-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-as-data-utils'] --- import kbnAlertsAsDataUtilsObj from './kbn_alerts_as_data_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts_ui_shared.mdx b/api_docs/kbn_alerts_ui_shared.mdx index d08e2ab2705d3..d3929a4dea717 100644 --- a/api_docs/kbn_alerts_ui_shared.mdx +++ b/api_docs/kbn_alerts_ui_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts-ui-shared title: "@kbn/alerts-ui-shared" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts-ui-shared plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts-ui-shared'] --- import kbnAlertsUiSharedObj from './kbn_alerts_ui_shared.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index eb936323da803..f3bf145144bb5 100644 --- a/api_docs/kbn_analytics.mdx +++ b/api_docs/kbn_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics title: "@kbn/analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics'] --- import kbnAnalyticsObj from './kbn_analytics.devdocs.json'; diff --git a/api_docs/kbn_analytics_client.mdx b/api_docs/kbn_analytics_client.mdx index 840e34d485af8..0dec0bae902c6 100644 --- a/api_docs/kbn_analytics_client.mdx +++ b/api_docs/kbn_analytics_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-client title: "@kbn/analytics-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-client plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-client'] --- import kbnAnalyticsClientObj from './kbn_analytics_client.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx index cc278cafd4911..ad3639f903acd 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-browser title: "@kbn/analytics-shippers-elastic-v3-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-browser'] --- import kbnAnalyticsShippersElasticV3BrowserObj from './kbn_analytics_shippers_elastic_v3_browser.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx index 1b2c66804ac83..579d8f9c06d06 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-common title: "@kbn/analytics-shippers-elastic-v3-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-common'] --- import kbnAnalyticsShippersElasticV3CommonObj from './kbn_analytics_shippers_elastic_v3_common.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx index d95676efe757a..ea346f0f543ae 100644 --- a/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx +++ b/api_docs/kbn_analytics_shippers_elastic_v3_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-elastic-v3-server title: "@kbn/analytics-shippers-elastic-v3-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-elastic-v3-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-elastic-v3-server'] --- import kbnAnalyticsShippersElasticV3ServerObj from './kbn_analytics_shippers_elastic_v3_server.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_fullstory.mdx b/api_docs/kbn_analytics_shippers_fullstory.mdx index ff748b34a271a..32ea46da84ad8 100644 --- a/api_docs/kbn_analytics_shippers_fullstory.mdx +++ b/api_docs/kbn_analytics_shippers_fullstory.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-fullstory title: "@kbn/analytics-shippers-fullstory" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-fullstory plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_analytics_shippers_gainsight.mdx b/api_docs/kbn_analytics_shippers_gainsight.mdx index fd7aaa58696d2..534625a620b5a 100644 --- a/api_docs/kbn_analytics_shippers_gainsight.mdx +++ b/api_docs/kbn_analytics_shippers_gainsight.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-analytics-shippers-gainsight title: "@kbn/analytics-shippers-gainsight" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/analytics-shippers-gainsight plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-gainsight'] --- import kbnAnalyticsShippersGainsightObj from './kbn_analytics_shippers_gainsight.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index b0132cdb69886..19b3c53dc1fa6 100644 --- a/api_docs/kbn_apm_config_loader.mdx +++ b/api_docs/kbn_apm_config_loader.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-config-loader title: "@kbn/apm-config-loader" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-config-loader plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-config-loader'] --- import kbnApmConfigLoaderObj from './kbn_apm_config_loader.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace.mdx b/api_docs/kbn_apm_synthtrace.mdx index cc9943b7ee22e..9082cac1d53cf 100644 --- a/api_docs/kbn_apm_synthtrace.mdx +++ b/api_docs/kbn_apm_synthtrace.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace title: "@kbn/apm-synthtrace" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_synthtrace_client.mdx b/api_docs/kbn_apm_synthtrace_client.mdx index 3d0a6bd163b6f..0793199486530 100644 --- a/api_docs/kbn_apm_synthtrace_client.mdx +++ b/api_docs/kbn_apm_synthtrace_client.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-synthtrace-client title: "@kbn/apm-synthtrace-client" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-synthtrace-client plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace-client'] --- import kbnApmSynthtraceClientObj from './kbn_apm_synthtrace_client.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index fd0c28d324e52..35fd8b188e4bb 100644 --- a/api_docs/kbn_apm_utils.mdx +++ b/api_docs/kbn_apm_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-apm-utils title: "@kbn/apm-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/apm-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-utils'] --- import kbnApmUtilsObj from './kbn_apm_utils.devdocs.json'; diff --git a/api_docs/kbn_axe_config.mdx b/api_docs/kbn_axe_config.mdx index f2aa3551bdff3..8796a2577f2e8 100644 --- a/api_docs/kbn_axe_config.mdx +++ b/api_docs/kbn_axe_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-axe-config title: "@kbn/axe-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/axe-config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_cases_components.mdx b/api_docs/kbn_cases_components.mdx index 6cb3543e896ad..60115e5095ec3 100644 --- a/api_docs/kbn_cases_components.mdx +++ b/api_docs/kbn_cases_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cases-components title: "@kbn/cases-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cases-components plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cases-components'] --- import kbnCasesComponentsObj from './kbn_cases_components.devdocs.json'; diff --git a/api_docs/kbn_cell_actions.mdx b/api_docs/kbn_cell_actions.mdx index b1bff9a8a9461..f1ea4d738f4e6 100644 --- a/api_docs/kbn_cell_actions.mdx +++ b/api_docs/kbn_cell_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cell-actions title: "@kbn/cell-actions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cell-actions plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cell-actions'] --- import kbnCellActionsObj from './kbn_cell_actions.devdocs.json'; diff --git a/api_docs/kbn_chart_expressions_common.mdx b/api_docs/kbn_chart_expressions_common.mdx index 9c9c4d94acb57..965afdd0dd7b4 100644 --- a/api_docs/kbn_chart_expressions_common.mdx +++ b/api_docs/kbn_chart_expressions_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-expressions-common title: "@kbn/chart-expressions-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-expressions-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-expressions-common'] --- import kbnChartExpressionsCommonObj from './kbn_chart_expressions_common.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index bd3112254a9f7..e23a54e6cfde5 100644 --- a/api_docs/kbn_chart_icons.mdx +++ b/api_docs/kbn_chart_icons.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-chart-icons title: "@kbn/chart-icons" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/chart-icons plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/chart-icons'] --- import kbnChartIconsObj from './kbn_chart_icons.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_core.mdx b/api_docs/kbn_ci_stats_core.mdx index 58ebbed6ccc73..bcdaad75b0888 100644 --- a/api_docs/kbn_ci_stats_core.mdx +++ b/api_docs/kbn_ci_stats_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-core title: "@kbn/ci-stats-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-core plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-core'] --- import kbnCiStatsCoreObj from './kbn_ci_stats_core.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_performance_metrics.mdx b/api_docs/kbn_ci_stats_performance_metrics.mdx index 1e8434b48c492..c9afcf2d42fe4 100644 --- a/api_docs/kbn_ci_stats_performance_metrics.mdx +++ b/api_docs/kbn_ci_stats_performance_metrics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-performance-metrics title: "@kbn/ci-stats-performance-metrics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-performance-metrics plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-performance-metrics'] --- import kbnCiStatsPerformanceMetricsObj from './kbn_ci_stats_performance_metrics.devdocs.json'; diff --git a/api_docs/kbn_ci_stats_reporter.mdx b/api_docs/kbn_ci_stats_reporter.mdx index 719735461ce66..3db876a7ee320 100644 --- a/api_docs/kbn_ci_stats_reporter.mdx +++ b/api_docs/kbn_ci_stats_reporter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ci-stats-reporter title: "@kbn/ci-stats-reporter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ci-stats-reporter plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ci-stats-reporter'] --- import kbnCiStatsReporterObj from './kbn_ci_stats_reporter.devdocs.json'; diff --git a/api_docs/kbn_cli_dev_mode.mdx b/api_docs/kbn_cli_dev_mode.mdx index b7dc9dfbe42b4..f05ae46a3609a 100644 --- a/api_docs/kbn_cli_dev_mode.mdx +++ b/api_docs/kbn_cli_dev_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cli-dev-mode title: "@kbn/cli-dev-mode" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cli-dev-mode plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_code_editor.mdx b/api_docs/kbn_code_editor.mdx index 966691e3a8b84..8bf30ebb4b9d0 100644 --- a/api_docs/kbn_code_editor.mdx +++ b/api_docs/kbn_code_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor title: "@kbn/code-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor'] --- import kbnCodeEditorObj from './kbn_code_editor.devdocs.json'; diff --git a/api_docs/kbn_code_editor_mocks.mdx b/api_docs/kbn_code_editor_mocks.mdx index 481dda09849e7..b8bf6bc9537dd 100644 --- a/api_docs/kbn_code_editor_mocks.mdx +++ b/api_docs/kbn_code_editor_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-code-editor-mocks title: "@kbn/code-editor-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/code-editor-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/code-editor-mocks'] --- import kbnCodeEditorMocksObj from './kbn_code_editor_mocks.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index 62291903364cc..33fd7a4d6418b 100644 --- a/api_docs/kbn_coloring.mdx +++ b/api_docs/kbn_coloring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-coloring title: "@kbn/coloring" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/coloring plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/coloring'] --- import kbnColoringObj from './kbn_coloring.devdocs.json'; diff --git a/api_docs/kbn_config.mdx b/api_docs/kbn_config.mdx index a1eb10c15082a..b74fada882cdd 100644 --- a/api_docs/kbn_config.mdx +++ b/api_docs/kbn_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config title: "@kbn/config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config'] --- import kbnConfigObj from './kbn_config.devdocs.json'; diff --git a/api_docs/kbn_config_mocks.mdx b/api_docs/kbn_config_mocks.mdx index 4e0e793884dda..3524e6e8d82aa 100644 --- a/api_docs/kbn_config_mocks.mdx +++ b/api_docs/kbn_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-mocks title: "@kbn/config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-mocks'] --- import kbnConfigMocksObj from './kbn_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_config_schema.mdx b/api_docs/kbn_config_schema.mdx index 16a346b8cf85f..71e8e4fea5a34 100644 --- a/api_docs/kbn_config_schema.mdx +++ b/api_docs/kbn_config_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-config-schema title: "@kbn/config-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/config-schema plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_content_editor.mdx b/api_docs/kbn_content_management_content_editor.mdx index 12b868522369e..3db5874410372 100644 --- a/api_docs/kbn_content_management_content_editor.mdx +++ b/api_docs/kbn_content_management_content_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-content-editor title: "@kbn/content-management-content-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-content-editor plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-content-editor'] --- import kbnContentManagementContentEditorObj from './kbn_content_management_content_editor.devdocs.json'; diff --git a/api_docs/kbn_content_management_tabbed_table_list_view.mdx b/api_docs/kbn_content_management_tabbed_table_list_view.mdx index 4fec0f2a9e363..74fe7e277a2ec 100644 --- a/api_docs/kbn_content_management_tabbed_table_list_view.mdx +++ b/api_docs/kbn_content_management_tabbed_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-tabbed-table-list-view title: "@kbn/content-management-tabbed-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-tabbed-table-list-view plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-tabbed-table-list-view'] --- import kbnContentManagementTabbedTableListViewObj from './kbn_content_management_tabbed_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view.mdx b/api_docs/kbn_content_management_table_list_view.mdx index 346d3acb6736b..0a393870c35cf 100644 --- a/api_docs/kbn_content_management_table_list_view.mdx +++ b/api_docs/kbn_content_management_table_list_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view title: "@kbn/content-management-table-list-view" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view'] --- import kbnContentManagementTableListViewObj from './kbn_content_management_table_list_view.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list_view_table.mdx b/api_docs/kbn_content_management_table_list_view_table.mdx index c7906a4bb7749..2560ce1238725 100644 --- a/api_docs/kbn_content_management_table_list_view_table.mdx +++ b/api_docs/kbn_content_management_table_list_view_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list-view-table title: "@kbn/content-management-table-list-view-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list-view-table plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list-view-table'] --- import kbnContentManagementTableListViewTableObj from './kbn_content_management_table_list_view_table.devdocs.json'; diff --git a/api_docs/kbn_content_management_utils.devdocs.json b/api_docs/kbn_content_management_utils.devdocs.json index e72887c5e9afa..e58246c889b47 100644 --- a/api_docs/kbn_content_management_utils.devdocs.json +++ b/api_docs/kbn_content_management_utils.devdocs.json @@ -1826,7 +1826,7 @@ "section": "def-common.UpdateIn", "text": "UpdateIn" }, - "" + ", UpdateOptions>" ], "path": "packages/kbn-content-management-utils/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_content_management_utils.mdx b/api_docs/kbn_content_management_utils.mdx index 8f6ad7a704de8..4b8b9829a1a50 100644 --- a/api_docs/kbn_content_management_utils.mdx +++ b/api_docs/kbn_content_management_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-utils title: "@kbn/content-management-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-utils'] --- import kbnContentManagementUtilsObj from './kbn_content_management_utils.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 21af9ddac1a6c..54b1c35b9669f 100644 --- a/api_docs/kbn_core_analytics_browser.mdx +++ b/api_docs/kbn_core_analytics_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser title: "@kbn/core-analytics-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser'] --- import kbnCoreAnalyticsBrowserObj from './kbn_core_analytics_browser.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_internal.mdx b/api_docs/kbn_core_analytics_browser_internal.mdx index ee6073fb845e7..56dacaceda3e6 100644 --- a/api_docs/kbn_core_analytics_browser_internal.mdx +++ b/api_docs/kbn_core_analytics_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-internal title: "@kbn/core-analytics-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-internal'] --- import kbnCoreAnalyticsBrowserInternalObj from './kbn_core_analytics_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser_mocks.mdx b/api_docs/kbn_core_analytics_browser_mocks.mdx index f2d91ebeafc81..f0bbbf320541d 100644 --- a/api_docs/kbn_core_analytics_browser_mocks.mdx +++ b/api_docs/kbn_core_analytics_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-browser-mocks title: "@kbn/core-analytics-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-browser-mocks'] --- import kbnCoreAnalyticsBrowserMocksObj from './kbn_core_analytics_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server.mdx b/api_docs/kbn_core_analytics_server.mdx index b6cf726f6f1ec..cb51ca86bda86 100644 --- a/api_docs/kbn_core_analytics_server.mdx +++ b/api_docs/kbn_core_analytics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server title: "@kbn/core-analytics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server'] --- import kbnCoreAnalyticsServerObj from './kbn_core_analytics_server.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_internal.mdx b/api_docs/kbn_core_analytics_server_internal.mdx index b4202ebe3285b..03048cb389098 100644 --- a/api_docs/kbn_core_analytics_server_internal.mdx +++ b/api_docs/kbn_core_analytics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-internal title: "@kbn/core-analytics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-internal'] --- import kbnCoreAnalyticsServerInternalObj from './kbn_core_analytics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_server_mocks.mdx b/api_docs/kbn_core_analytics_server_mocks.mdx index d91a5147dce01..8d63466db6756 100644 --- a/api_docs/kbn_core_analytics_server_mocks.mdx +++ b/api_docs/kbn_core_analytics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-analytics-server-mocks title: "@kbn/core-analytics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-analytics-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-analytics-server-mocks'] --- import kbnCoreAnalyticsServerMocksObj from './kbn_core_analytics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser.mdx b/api_docs/kbn_core_application_browser.mdx index 3e10ef105ed8f..90fab26c3bf54 100644 --- a/api_docs/kbn_core_application_browser.mdx +++ b/api_docs/kbn_core_application_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser title: "@kbn/core-application-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser'] --- import kbnCoreApplicationBrowserObj from './kbn_core_application_browser.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_internal.mdx b/api_docs/kbn_core_application_browser_internal.mdx index 3ad9bcbb680dd..e5c429b13bc13 100644 --- a/api_docs/kbn_core_application_browser_internal.mdx +++ b/api_docs/kbn_core_application_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-internal title: "@kbn/core-application-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-internal'] --- import kbnCoreApplicationBrowserInternalObj from './kbn_core_application_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_application_browser_mocks.mdx b/api_docs/kbn_core_application_browser_mocks.mdx index df8213850e061..025d1bd9e42cb 100644 --- a/api_docs/kbn_core_application_browser_mocks.mdx +++ b/api_docs/kbn_core_application_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-browser-mocks title: "@kbn/core-application-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-browser-mocks'] --- import kbnCoreApplicationBrowserMocksObj from './kbn_core_application_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_application_common.mdx b/api_docs/kbn_core_application_common.mdx index b48c7be29083f..253dcb5d92671 100644 --- a/api_docs/kbn_core_application_common.mdx +++ b/api_docs/kbn_core_application_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-application-common title: "@kbn/core-application-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-application-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-application-common'] --- import kbnCoreApplicationCommonObj from './kbn_core_application_common.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_internal.mdx b/api_docs/kbn_core_apps_browser_internal.mdx index 8f23acf336d0d..b305c86fe1c93 100644 --- a/api_docs/kbn_core_apps_browser_internal.mdx +++ b/api_docs/kbn_core_apps_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-internal title: "@kbn/core-apps-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-internal'] --- import kbnCoreAppsBrowserInternalObj from './kbn_core_apps_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_apps_browser_mocks.mdx b/api_docs/kbn_core_apps_browser_mocks.mdx index 77461372b8422..7c776934de2fc 100644 --- a/api_docs/kbn_core_apps_browser_mocks.mdx +++ b/api_docs/kbn_core_apps_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-browser-mocks title: "@kbn/core-apps-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-browser-mocks'] --- import kbnCoreAppsBrowserMocksObj from './kbn_core_apps_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_apps_server_internal.mdx b/api_docs/kbn_core_apps_server_internal.mdx index bc95a84909823..284e58f106333 100644 --- a/api_docs/kbn_core_apps_server_internal.mdx +++ b/api_docs/kbn_core_apps_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-apps-server-internal title: "@kbn/core-apps-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-apps-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-apps-server-internal'] --- import kbnCoreAppsServerInternalObj from './kbn_core_apps_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index 138025ffeb935..c017c2b09c5fc 100644 --- a/api_docs/kbn_core_base_browser_mocks.mdx +++ b/api_docs/kbn_core_base_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-browser-mocks title: "@kbn/core-base-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-browser-mocks'] --- import kbnCoreBaseBrowserMocksObj from './kbn_core_base_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_base_common.mdx b/api_docs/kbn_core_base_common.mdx index 619e8a58f0376..730462673de14 100644 --- a/api_docs/kbn_core_base_common.mdx +++ b/api_docs/kbn_core_base_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-common title: "@kbn/core-base-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-common'] --- import kbnCoreBaseCommonObj from './kbn_core_base_common.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_internal.mdx b/api_docs/kbn_core_base_server_internal.mdx index dc6d52581009a..cf5ab5cb40877 100644 --- a/api_docs/kbn_core_base_server_internal.mdx +++ b/api_docs/kbn_core_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-internal title: "@kbn/core-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-internal'] --- import kbnCoreBaseServerInternalObj from './kbn_core_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_base_server_mocks.mdx b/api_docs/kbn_core_base_server_mocks.mdx index c055cf341a639..07cbfbfb0af7e 100644 --- a/api_docs/kbn_core_base_server_mocks.mdx +++ b/api_docs/kbn_core_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-base-server-mocks title: "@kbn/core-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-base-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-base-server-mocks'] --- import kbnCoreBaseServerMocksObj from './kbn_core_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_browser_mocks.mdx b/api_docs/kbn_core_capabilities_browser_mocks.mdx index ec9ed82cca82f..98eedb888c16a 100644 --- a/api_docs/kbn_core_capabilities_browser_mocks.mdx +++ b/api_docs/kbn_core_capabilities_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-browser-mocks title: "@kbn/core-capabilities-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-browser-mocks'] --- import kbnCoreCapabilitiesBrowserMocksObj from './kbn_core_capabilities_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_common.mdx b/api_docs/kbn_core_capabilities_common.mdx index 707d3f2ea644d..8effd8f79e6e2 100644 --- a/api_docs/kbn_core_capabilities_common.mdx +++ b/api_docs/kbn_core_capabilities_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-common title: "@kbn/core-capabilities-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-common'] --- import kbnCoreCapabilitiesCommonObj from './kbn_core_capabilities_common.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server.mdx b/api_docs/kbn_core_capabilities_server.mdx index 81c54f88e2082..133401c40993b 100644 --- a/api_docs/kbn_core_capabilities_server.mdx +++ b/api_docs/kbn_core_capabilities_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server title: "@kbn/core-capabilities-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server'] --- import kbnCoreCapabilitiesServerObj from './kbn_core_capabilities_server.devdocs.json'; diff --git a/api_docs/kbn_core_capabilities_server_mocks.mdx b/api_docs/kbn_core_capabilities_server_mocks.mdx index df70490a6ef91..7b1538003a8be 100644 --- a/api_docs/kbn_core_capabilities_server_mocks.mdx +++ b/api_docs/kbn_core_capabilities_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-capabilities-server-mocks title: "@kbn/core-capabilities-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-capabilities-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-capabilities-server-mocks'] --- import kbnCoreCapabilitiesServerMocksObj from './kbn_core_capabilities_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser.mdx b/api_docs/kbn_core_chrome_browser.mdx index 5c78fbd29080d..7128a9710b907 100644 --- a/api_docs/kbn_core_chrome_browser.mdx +++ b/api_docs/kbn_core_chrome_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser title: "@kbn/core-chrome-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser'] --- import kbnCoreChromeBrowserObj from './kbn_core_chrome_browser.devdocs.json'; diff --git a/api_docs/kbn_core_chrome_browser_mocks.mdx b/api_docs/kbn_core_chrome_browser_mocks.mdx index 9e4529b9ad4a6..228624d0ecaf2 100644 --- a/api_docs/kbn_core_chrome_browser_mocks.mdx +++ b/api_docs/kbn_core_chrome_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-chrome-browser-mocks title: "@kbn/core-chrome-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-chrome-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-chrome-browser-mocks'] --- import kbnCoreChromeBrowserMocksObj from './kbn_core_chrome_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_config_server_internal.mdx b/api_docs/kbn_core_config_server_internal.mdx index f9dd854f2aa1e..4251ce1a56b61 100644 --- a/api_docs/kbn_core_config_server_internal.mdx +++ b/api_docs/kbn_core_config_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-config-server-internal title: "@kbn/core-config-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-config-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-config-server-internal'] --- import kbnCoreConfigServerInternalObj from './kbn_core_config_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser.mdx b/api_docs/kbn_core_custom_branding_browser.mdx index 03b8bcf72b3fb..670995a4a05c8 100644 --- a/api_docs/kbn_core_custom_branding_browser.mdx +++ b/api_docs/kbn_core_custom_branding_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser title: "@kbn/core-custom-branding-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser'] --- import kbnCoreCustomBrandingBrowserObj from './kbn_core_custom_branding_browser.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_internal.mdx b/api_docs/kbn_core_custom_branding_browser_internal.mdx index 83d09fbd01bbd..35e42e0ea93dc 100644 --- a/api_docs/kbn_core_custom_branding_browser_internal.mdx +++ b/api_docs/kbn_core_custom_branding_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-internal title: "@kbn/core-custom-branding-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-internal'] --- import kbnCoreCustomBrandingBrowserInternalObj from './kbn_core_custom_branding_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_browser_mocks.mdx b/api_docs/kbn_core_custom_branding_browser_mocks.mdx index a879f4b404baf..88779b741c0f6 100644 --- a/api_docs/kbn_core_custom_branding_browser_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-browser-mocks title: "@kbn/core-custom-branding-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-browser-mocks'] --- import kbnCoreCustomBrandingBrowserMocksObj from './kbn_core_custom_branding_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_common.mdx b/api_docs/kbn_core_custom_branding_common.mdx index 7cece0092a868..11415cb9894d6 100644 --- a/api_docs/kbn_core_custom_branding_common.mdx +++ b/api_docs/kbn_core_custom_branding_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-common title: "@kbn/core-custom-branding-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-common'] --- import kbnCoreCustomBrandingCommonObj from './kbn_core_custom_branding_common.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server.mdx b/api_docs/kbn_core_custom_branding_server.mdx index b17a5efd940af..c6cef5d82d103 100644 --- a/api_docs/kbn_core_custom_branding_server.mdx +++ b/api_docs/kbn_core_custom_branding_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server title: "@kbn/core-custom-branding-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server'] --- import kbnCoreCustomBrandingServerObj from './kbn_core_custom_branding_server.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_internal.mdx b/api_docs/kbn_core_custom_branding_server_internal.mdx index ff1ef553fb08b..d021591eff678 100644 --- a/api_docs/kbn_core_custom_branding_server_internal.mdx +++ b/api_docs/kbn_core_custom_branding_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-internal title: "@kbn/core-custom-branding-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-internal'] --- import kbnCoreCustomBrandingServerInternalObj from './kbn_core_custom_branding_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_custom_branding_server_mocks.mdx b/api_docs/kbn_core_custom_branding_server_mocks.mdx index 3ede907a150bd..68c2414844881 100644 --- a/api_docs/kbn_core_custom_branding_server_mocks.mdx +++ b/api_docs/kbn_core_custom_branding_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-custom-branding-server-mocks title: "@kbn/core-custom-branding-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-custom-branding-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-custom-branding-server-mocks'] --- import kbnCoreCustomBrandingServerMocksObj from './kbn_core_custom_branding_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 5ab8792f5e05e..947af0a1b0da4 100644 --- a/api_docs/kbn_core_deprecations_browser.mdx +++ b/api_docs/kbn_core_deprecations_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser title: "@kbn/core-deprecations-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser'] --- import kbnCoreDeprecationsBrowserObj from './kbn_core_deprecations_browser.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_internal.mdx b/api_docs/kbn_core_deprecations_browser_internal.mdx index 638c102a2ea24..f94179345c264 100644 --- a/api_docs/kbn_core_deprecations_browser_internal.mdx +++ b/api_docs/kbn_core_deprecations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-internal title: "@kbn/core-deprecations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-internal'] --- import kbnCoreDeprecationsBrowserInternalObj from './kbn_core_deprecations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_browser_mocks.mdx b/api_docs/kbn_core_deprecations_browser_mocks.mdx index 34c7c011b564a..1d15fcc40b881 100644 --- a/api_docs/kbn_core_deprecations_browser_mocks.mdx +++ b/api_docs/kbn_core_deprecations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-browser-mocks title: "@kbn/core-deprecations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-browser-mocks'] --- import kbnCoreDeprecationsBrowserMocksObj from './kbn_core_deprecations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_common.mdx b/api_docs/kbn_core_deprecations_common.mdx index c79bb262bb7f6..582190d70f7b8 100644 --- a/api_docs/kbn_core_deprecations_common.mdx +++ b/api_docs/kbn_core_deprecations_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-common title: "@kbn/core-deprecations-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-common'] --- import kbnCoreDeprecationsCommonObj from './kbn_core_deprecations_common.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server.mdx b/api_docs/kbn_core_deprecations_server.mdx index d83e02f40e616..5be7399218312 100644 --- a/api_docs/kbn_core_deprecations_server.mdx +++ b/api_docs/kbn_core_deprecations_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server title: "@kbn/core-deprecations-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server'] --- import kbnCoreDeprecationsServerObj from './kbn_core_deprecations_server.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_internal.mdx b/api_docs/kbn_core_deprecations_server_internal.mdx index 7cbddae397c9d..89421e8bdb148 100644 --- a/api_docs/kbn_core_deprecations_server_internal.mdx +++ b/api_docs/kbn_core_deprecations_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-internal title: "@kbn/core-deprecations-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-internal'] --- import kbnCoreDeprecationsServerInternalObj from './kbn_core_deprecations_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_deprecations_server_mocks.mdx b/api_docs/kbn_core_deprecations_server_mocks.mdx index d6381d2bbbb0d..f25e1c8a0ee66 100644 --- a/api_docs/kbn_core_deprecations_server_mocks.mdx +++ b/api_docs/kbn_core_deprecations_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-deprecations-server-mocks title: "@kbn/core-deprecations-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-deprecations-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-deprecations-server-mocks'] --- import kbnCoreDeprecationsServerMocksObj from './kbn_core_deprecations_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser.mdx b/api_docs/kbn_core_doc_links_browser.mdx index 0e2a34188d524..b81abcc8258de 100644 --- a/api_docs/kbn_core_doc_links_browser.mdx +++ b/api_docs/kbn_core_doc_links_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser title: "@kbn/core-doc-links-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser'] --- import kbnCoreDocLinksBrowserObj from './kbn_core_doc_links_browser.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_browser_mocks.mdx b/api_docs/kbn_core_doc_links_browser_mocks.mdx index bc3046980c509..735b84c1b0079 100644 --- a/api_docs/kbn_core_doc_links_browser_mocks.mdx +++ b/api_docs/kbn_core_doc_links_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-browser-mocks title: "@kbn/core-doc-links-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-browser-mocks'] --- import kbnCoreDocLinksBrowserMocksObj from './kbn_core_doc_links_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server.mdx b/api_docs/kbn_core_doc_links_server.mdx index 387581b7a7f4c..67eedbc41794e 100644 --- a/api_docs/kbn_core_doc_links_server.mdx +++ b/api_docs/kbn_core_doc_links_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server title: "@kbn/core-doc-links-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server'] --- import kbnCoreDocLinksServerObj from './kbn_core_doc_links_server.devdocs.json'; diff --git a/api_docs/kbn_core_doc_links_server_mocks.mdx b/api_docs/kbn_core_doc_links_server_mocks.mdx index 6d3f8be2203b4..b839841f35de9 100644 --- a/api_docs/kbn_core_doc_links_server_mocks.mdx +++ b/api_docs/kbn_core_doc_links_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-doc-links-server-mocks title: "@kbn/core-doc-links-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-doc-links-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-doc-links-server-mocks'] --- import kbnCoreDocLinksServerMocksObj from './kbn_core_doc_links_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx index 08583fcbaa53c..686e5e9661d4c 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-internal title: "@kbn/core-elasticsearch-client-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-internal'] --- import kbnCoreElasticsearchClientServerInternalObj from './kbn_core_elasticsearch_client_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx index 284e88616e128..24e3759ce4b8a 100644 --- a/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_client_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-client-server-mocks title: "@kbn/core-elasticsearch-client-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-client-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-client-server-mocks'] --- import kbnCoreElasticsearchClientServerMocksObj from './kbn_core_elasticsearch_client_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server.mdx b/api_docs/kbn_core_elasticsearch_server.mdx index 6430fff915def..dadbf28ea6332 100644 --- a/api_docs/kbn_core_elasticsearch_server.mdx +++ b/api_docs/kbn_core_elasticsearch_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server title: "@kbn/core-elasticsearch-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server'] --- import kbnCoreElasticsearchServerObj from './kbn_core_elasticsearch_server.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_internal.mdx b/api_docs/kbn_core_elasticsearch_server_internal.mdx index 49bb018bbdf1c..e903616263fb4 100644 --- a/api_docs/kbn_core_elasticsearch_server_internal.mdx +++ b/api_docs/kbn_core_elasticsearch_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-internal title: "@kbn/core-elasticsearch-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-internal'] --- import kbnCoreElasticsearchServerInternalObj from './kbn_core_elasticsearch_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_elasticsearch_server_mocks.mdx b/api_docs/kbn_core_elasticsearch_server_mocks.mdx index bdcf2b7a406e8..8fe13951442ca 100644 --- a/api_docs/kbn_core_elasticsearch_server_mocks.mdx +++ b/api_docs/kbn_core_elasticsearch_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-elasticsearch-server-mocks title: "@kbn/core-elasticsearch-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-elasticsearch-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-elasticsearch-server-mocks'] --- import kbnCoreElasticsearchServerMocksObj from './kbn_core_elasticsearch_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_internal.mdx b/api_docs/kbn_core_environment_server_internal.mdx index 3e8960d127bd6..1256a5eb245e7 100644 --- a/api_docs/kbn_core_environment_server_internal.mdx +++ b/api_docs/kbn_core_environment_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-internal title: "@kbn/core-environment-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-internal'] --- import kbnCoreEnvironmentServerInternalObj from './kbn_core_environment_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_environment_server_mocks.mdx b/api_docs/kbn_core_environment_server_mocks.mdx index 87d84af14577d..04ea7169eb666 100644 --- a/api_docs/kbn_core_environment_server_mocks.mdx +++ b/api_docs/kbn_core_environment_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-environment-server-mocks title: "@kbn/core-environment-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-environment-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-environment-server-mocks'] --- import kbnCoreEnvironmentServerMocksObj from './kbn_core_environment_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser.mdx b/api_docs/kbn_core_execution_context_browser.mdx index b1184b2540b57..90009c29c89cc 100644 --- a/api_docs/kbn_core_execution_context_browser.mdx +++ b/api_docs/kbn_core_execution_context_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser title: "@kbn/core-execution-context-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser'] --- import kbnCoreExecutionContextBrowserObj from './kbn_core_execution_context_browser.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_internal.mdx b/api_docs/kbn_core_execution_context_browser_internal.mdx index a80c1874dcd79..7716f62714f6b 100644 --- a/api_docs/kbn_core_execution_context_browser_internal.mdx +++ b/api_docs/kbn_core_execution_context_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-internal title: "@kbn/core-execution-context-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-internal'] --- import kbnCoreExecutionContextBrowserInternalObj from './kbn_core_execution_context_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_browser_mocks.mdx b/api_docs/kbn_core_execution_context_browser_mocks.mdx index 439540e9f90a2..f4c2a8115015b 100644 --- a/api_docs/kbn_core_execution_context_browser_mocks.mdx +++ b/api_docs/kbn_core_execution_context_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-browser-mocks title: "@kbn/core-execution-context-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-browser-mocks'] --- import kbnCoreExecutionContextBrowserMocksObj from './kbn_core_execution_context_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_common.mdx b/api_docs/kbn_core_execution_context_common.mdx index a247f0bf7b504..cb08d0340717d 100644 --- a/api_docs/kbn_core_execution_context_common.mdx +++ b/api_docs/kbn_core_execution_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-common title: "@kbn/core-execution-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-common'] --- import kbnCoreExecutionContextCommonObj from './kbn_core_execution_context_common.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server.mdx b/api_docs/kbn_core_execution_context_server.mdx index a625223d68ea0..321b72ad4e2f5 100644 --- a/api_docs/kbn_core_execution_context_server.mdx +++ b/api_docs/kbn_core_execution_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server title: "@kbn/core-execution-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server'] --- import kbnCoreExecutionContextServerObj from './kbn_core_execution_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_internal.mdx b/api_docs/kbn_core_execution_context_server_internal.mdx index 26c3d9db9514b..78bcb9afedc40 100644 --- a/api_docs/kbn_core_execution_context_server_internal.mdx +++ b/api_docs/kbn_core_execution_context_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-internal title: "@kbn/core-execution-context-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-internal'] --- import kbnCoreExecutionContextServerInternalObj from './kbn_core_execution_context_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_execution_context_server_mocks.mdx b/api_docs/kbn_core_execution_context_server_mocks.mdx index 1fc4b873a7099..d6aa6ab279e28 100644 --- a/api_docs/kbn_core_execution_context_server_mocks.mdx +++ b/api_docs/kbn_core_execution_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-execution-context-server-mocks title: "@kbn/core-execution-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-execution-context-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-execution-context-server-mocks'] --- import kbnCoreExecutionContextServerMocksObj from './kbn_core_execution_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser.mdx b/api_docs/kbn_core_fatal_errors_browser.mdx index d2bbed12bc04b..19aa36087e3fd 100644 --- a/api_docs/kbn_core_fatal_errors_browser.mdx +++ b/api_docs/kbn_core_fatal_errors_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser title: "@kbn/core-fatal-errors-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser'] --- import kbnCoreFatalErrorsBrowserObj from './kbn_core_fatal_errors_browser.devdocs.json'; diff --git a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx index 96ccd86e3749f..1d63ca16b335c 100644 --- a/api_docs/kbn_core_fatal_errors_browser_mocks.mdx +++ b/api_docs/kbn_core_fatal_errors_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-fatal-errors-browser-mocks title: "@kbn/core-fatal-errors-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-fatal-errors-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-fatal-errors-browser-mocks'] --- import kbnCoreFatalErrorsBrowserMocksObj from './kbn_core_fatal_errors_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser.mdx b/api_docs/kbn_core_http_browser.mdx index cc4cfd9bafbeb..787454514e00e 100644 --- a/api_docs/kbn_core_http_browser.mdx +++ b/api_docs/kbn_core_http_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser title: "@kbn/core-http-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser'] --- import kbnCoreHttpBrowserObj from './kbn_core_http_browser.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_internal.mdx b/api_docs/kbn_core_http_browser_internal.mdx index 3fb5265be456e..87e0876cc677d 100644 --- a/api_docs/kbn_core_http_browser_internal.mdx +++ b/api_docs/kbn_core_http_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-internal title: "@kbn/core-http-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-internal'] --- import kbnCoreHttpBrowserInternalObj from './kbn_core_http_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_browser_mocks.mdx b/api_docs/kbn_core_http_browser_mocks.mdx index e57185791f015..57abe05b1e9a3 100644 --- a/api_docs/kbn_core_http_browser_mocks.mdx +++ b/api_docs/kbn_core_http_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-browser-mocks title: "@kbn/core-http-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-browser-mocks'] --- import kbnCoreHttpBrowserMocksObj from './kbn_core_http_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_common.mdx b/api_docs/kbn_core_http_common.mdx index d858070e7fd28..6d0f2c07a925c 100644 --- a/api_docs/kbn_core_http_common.mdx +++ b/api_docs/kbn_core_http_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-common title: "@kbn/core-http-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-common'] --- import kbnCoreHttpCommonObj from './kbn_core_http_common.devdocs.json'; diff --git a/api_docs/kbn_core_http_context_server_mocks.mdx b/api_docs/kbn_core_http_context_server_mocks.mdx index 1bace87514d6d..8ee889cbcf8ad 100644 --- a/api_docs/kbn_core_http_context_server_mocks.mdx +++ b/api_docs/kbn_core_http_context_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-context-server-mocks title: "@kbn/core-http-context-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-context-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-context-server-mocks'] --- import kbnCoreHttpContextServerMocksObj from './kbn_core_http_context_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_request_handler_context_server.mdx b/api_docs/kbn_core_http_request_handler_context_server.mdx index 927519b63d640..3d3161cb7cbb3 100644 --- a/api_docs/kbn_core_http_request_handler_context_server.mdx +++ b/api_docs/kbn_core_http_request_handler_context_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-request-handler-context-server title: "@kbn/core-http-request-handler-context-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-request-handler-context-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-request-handler-context-server'] --- import kbnCoreHttpRequestHandlerContextServerObj from './kbn_core_http_request_handler_context_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server.mdx b/api_docs/kbn_core_http_resources_server.mdx index db0b3cef77e54..fa1fa17e20bb6 100644 --- a/api_docs/kbn_core_http_resources_server.mdx +++ b/api_docs/kbn_core_http_resources_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server title: "@kbn/core-http-resources-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server'] --- import kbnCoreHttpResourcesServerObj from './kbn_core_http_resources_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_internal.mdx b/api_docs/kbn_core_http_resources_server_internal.mdx index ac61647d10990..636c73bcfe78f 100644 --- a/api_docs/kbn_core_http_resources_server_internal.mdx +++ b/api_docs/kbn_core_http_resources_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-internal title: "@kbn/core-http-resources-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-internal'] --- import kbnCoreHttpResourcesServerInternalObj from './kbn_core_http_resources_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_resources_server_mocks.mdx b/api_docs/kbn_core_http_resources_server_mocks.mdx index 06f4a2f7ea688..c63fcf2523f89 100644 --- a/api_docs/kbn_core_http_resources_server_mocks.mdx +++ b/api_docs/kbn_core_http_resources_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-resources-server-mocks title: "@kbn/core-http-resources-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-resources-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-resources-server-mocks'] --- import kbnCoreHttpResourcesServerMocksObj from './kbn_core_http_resources_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index 57836e99367a1..45554c9823289 100644 --- a/api_docs/kbn_core_http_router_server_internal.mdx +++ b/api_docs/kbn_core_http_router_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-internal title: "@kbn/core-http-router-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-internal'] --- import kbnCoreHttpRouterServerInternalObj from './kbn_core_http_router_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_router_server_mocks.mdx b/api_docs/kbn_core_http_router_server_mocks.mdx index 8a1c0d60077f5..a9c57abc605a1 100644 --- a/api_docs/kbn_core_http_router_server_mocks.mdx +++ b/api_docs/kbn_core_http_router_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-router-server-mocks title: "@kbn/core-http-router-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-router-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.devdocs.json b/api_docs/kbn_core_http_server.devdocs.json index 38c38b593fd85..45aa782bcbd31 100644 --- a/api_docs/kbn_core_http_server.devdocs.json +++ b/api_docs/kbn_core_http_server.devdocs.json @@ -3375,18 +3375,6 @@ "plugin": "security", "path": "x-pack/plugins/security/server/routes/anonymous_access/get_state.ts" }, - { - "plugin": "security", - "path": "x-pack/plugins/security/server/routes/api_keys/enabled.ts" - }, - { - "plugin": "security", - "path": "x-pack/plugins/security/server/routes/api_keys/get.ts" - }, - { - "plugin": "security", - "path": "x-pack/plugins/security/server/routes/api_keys/privileges.ts" - }, { "plugin": "security", "path": "x-pack/plugins/security/server/routes/authentication/common.ts" @@ -3463,6 +3451,14 @@ "plugin": "security", "path": "x-pack/plugins/security/server/routes/views/login.ts" }, + { + "plugin": "security", + "path": "x-pack/plugins/security/server/routes/api_keys/enabled.ts" + }, + { + "plugin": "security", + "path": "x-pack/plugins/security/server/routes/api_keys/get.ts" + }, { "plugin": "monitoringCollection", "path": "x-pack/plugins/monitoring_collection/server/routes/api/v1/dynamic_route/get_metrics_by_type.ts" @@ -5807,10 +5803,6 @@ "plugin": "security", "path": "x-pack/plugins/security/server/routes/api_keys/get.test.ts" }, - { - "plugin": "security", - "path": "x-pack/plugins/security/server/routes/api_keys/privileges.test.ts" - }, { "plugin": "security", "path": "x-pack/plugins/security/server/routes/authentication/index.test.ts" @@ -6213,14 +6205,6 @@ "plugin": "security", "path": "x-pack/plugins/security/server/routes/analytics/authentication_type.ts" }, - { - "plugin": "security", - "path": "x-pack/plugins/security/server/routes/api_keys/create.ts" - }, - { - "plugin": "security", - "path": "x-pack/plugins/security/server/routes/api_keys/invalidate.ts" - }, { "plugin": "security", "path": "x-pack/plugins/security/server/routes/authentication/common.ts" @@ -6281,6 +6265,14 @@ "plugin": "security", "path": "x-pack/plugins/security/server/routes/users/enable.ts" }, + { + "plugin": "security", + "path": "x-pack/plugins/security/server/routes/api_keys/create.ts" + }, + { + "plugin": "security", + "path": "x-pack/plugins/security/server/routes/api_keys/invalidate.ts" + }, { "plugin": "encryptedSavedObjects", "path": "x-pack/plugins/encrypted_saved_objects/server/routes/key_rotation.ts" @@ -8593,11 +8585,11 @@ }, { "plugin": "security", - "path": "x-pack/plugins/security/server/routes/api_keys/update.ts" + "path": "x-pack/plugins/security/server/routes/authorization/roles/put.ts" }, { "plugin": "security", - "path": "x-pack/plugins/security/server/routes/authorization/roles/put.ts" + "path": "x-pack/plugins/security/server/routes/api_keys/update.ts" }, { "plugin": "actions", diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index 0a5ecdb4a3900..04b45513b45c5 100644 --- a/api_docs/kbn_core_http_server.mdx +++ b/api_docs/kbn_core_http_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server title: "@kbn/core-http-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server'] --- import kbnCoreHttpServerObj from './kbn_core_http_server.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_internal.mdx b/api_docs/kbn_core_http_server_internal.mdx index a1223d8a11534..df28c49f0862d 100644 --- a/api_docs/kbn_core_http_server_internal.mdx +++ b/api_docs/kbn_core_http_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-internal title: "@kbn/core-http-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-internal'] --- import kbnCoreHttpServerInternalObj from './kbn_core_http_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_http_server_mocks.mdx b/api_docs/kbn_core_http_server_mocks.mdx index 1eabe681358b8..71fd4602c628d 100644 --- a/api_docs/kbn_core_http_server_mocks.mdx +++ b/api_docs/kbn_core_http_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-http-server-mocks title: "@kbn/core-http-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-http-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-server-mocks'] --- import kbnCoreHttpServerMocksObj from './kbn_core_http_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser.mdx b/api_docs/kbn_core_i18n_browser.mdx index e0d759b5bf5d4..dedebc31e31fd 100644 --- a/api_docs/kbn_core_i18n_browser.mdx +++ b/api_docs/kbn_core_i18n_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser title: "@kbn/core-i18n-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser'] --- import kbnCoreI18nBrowserObj from './kbn_core_i18n_browser.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_browser_mocks.mdx b/api_docs/kbn_core_i18n_browser_mocks.mdx index 8d7fd45b3fbd0..d196e9513ab6c 100644 --- a/api_docs/kbn_core_i18n_browser_mocks.mdx +++ b/api_docs/kbn_core_i18n_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-browser-mocks title: "@kbn/core-i18n-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-browser-mocks'] --- import kbnCoreI18nBrowserMocksObj from './kbn_core_i18n_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server.mdx b/api_docs/kbn_core_i18n_server.mdx index 9dd2dbe97e826..a4f118dfa303d 100644 --- a/api_docs/kbn_core_i18n_server.mdx +++ b/api_docs/kbn_core_i18n_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server title: "@kbn/core-i18n-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server'] --- import kbnCoreI18nServerObj from './kbn_core_i18n_server.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_internal.mdx b/api_docs/kbn_core_i18n_server_internal.mdx index 736e80bd415e2..1c1d80320475a 100644 --- a/api_docs/kbn_core_i18n_server_internal.mdx +++ b/api_docs/kbn_core_i18n_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-internal title: "@kbn/core-i18n-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-internal'] --- import kbnCoreI18nServerInternalObj from './kbn_core_i18n_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_i18n_server_mocks.mdx b/api_docs/kbn_core_i18n_server_mocks.mdx index 8e83cb9258608..5f6215c2b0e27 100644 --- a/api_docs/kbn_core_i18n_server_mocks.mdx +++ b/api_docs/kbn_core_i18n_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-i18n-server-mocks title: "@kbn/core-i18n-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-i18n-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-i18n-server-mocks'] --- import kbnCoreI18nServerMocksObj from './kbn_core_i18n_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx index dae274d3a2dfe..5391d2f281be5 100644 --- a/api_docs/kbn_core_injected_metadata_browser_mocks.mdx +++ b/api_docs/kbn_core_injected_metadata_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser-mocks title: "@kbn/core-injected-metadata-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser-mocks'] --- import kbnCoreInjectedMetadataBrowserMocksObj from './kbn_core_injected_metadata_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_internal.mdx b/api_docs/kbn_core_integrations_browser_internal.mdx index b5d1222c2f55e..df5e3bb4349d7 100644 --- a/api_docs/kbn_core_integrations_browser_internal.mdx +++ b/api_docs/kbn_core_integrations_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-internal title: "@kbn/core-integrations-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-internal'] --- import kbnCoreIntegrationsBrowserInternalObj from './kbn_core_integrations_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_integrations_browser_mocks.mdx b/api_docs/kbn_core_integrations_browser_mocks.mdx index 9bc4d2f901cbc..56086553b00dc 100644 --- a/api_docs/kbn_core_integrations_browser_mocks.mdx +++ b/api_docs/kbn_core_integrations_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-integrations-browser-mocks title: "@kbn/core-integrations-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-integrations-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-integrations-browser-mocks'] --- import kbnCoreIntegrationsBrowserMocksObj from './kbn_core_integrations_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser.mdx b/api_docs/kbn_core_lifecycle_browser.mdx index f53d3ce0442d3..99531b81e8574 100644 --- a/api_docs/kbn_core_lifecycle_browser.mdx +++ b/api_docs/kbn_core_lifecycle_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser title: "@kbn/core-lifecycle-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser'] --- import kbnCoreLifecycleBrowserObj from './kbn_core_lifecycle_browser.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_browser_mocks.mdx b/api_docs/kbn_core_lifecycle_browser_mocks.mdx index 7b68f3084a442..2a0f438edb26b 100644 --- a/api_docs/kbn_core_lifecycle_browser_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-browser-mocks title: "@kbn/core-lifecycle-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-browser-mocks'] --- import kbnCoreLifecycleBrowserMocksObj from './kbn_core_lifecycle_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server.mdx b/api_docs/kbn_core_lifecycle_server.mdx index 2429100b85989..a02bdb3c0101e 100644 --- a/api_docs/kbn_core_lifecycle_server.mdx +++ b/api_docs/kbn_core_lifecycle_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server title: "@kbn/core-lifecycle-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server'] --- import kbnCoreLifecycleServerObj from './kbn_core_lifecycle_server.devdocs.json'; diff --git a/api_docs/kbn_core_lifecycle_server_mocks.mdx b/api_docs/kbn_core_lifecycle_server_mocks.mdx index e7641904a0df7..7d2581f42e4f6 100644 --- a/api_docs/kbn_core_lifecycle_server_mocks.mdx +++ b/api_docs/kbn_core_lifecycle_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-lifecycle-server-mocks title: "@kbn/core-lifecycle-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-lifecycle-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-lifecycle-server-mocks'] --- import kbnCoreLifecycleServerMocksObj from './kbn_core_lifecycle_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_browser_mocks.mdx b/api_docs/kbn_core_logging_browser_mocks.mdx index ff349cb04a89d..ba13559eba6bf 100644 --- a/api_docs/kbn_core_logging_browser_mocks.mdx +++ b/api_docs/kbn_core_logging_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-browser-mocks title: "@kbn/core-logging-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-browser-mocks'] --- import kbnCoreLoggingBrowserMocksObj from './kbn_core_logging_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_logging_common_internal.mdx b/api_docs/kbn_core_logging_common_internal.mdx index 4d900461c0291..29169fb4371cd 100644 --- a/api_docs/kbn_core_logging_common_internal.mdx +++ b/api_docs/kbn_core_logging_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-common-internal title: "@kbn/core-logging-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-common-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-common-internal'] --- import kbnCoreLoggingCommonInternalObj from './kbn_core_logging_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 6e030b422170c..123e3aa3e7619 100644 --- a/api_docs/kbn_core_logging_server.mdx +++ b/api_docs/kbn_core_logging_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server title: "@kbn/core-logging-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server'] --- import kbnCoreLoggingServerObj from './kbn_core_logging_server.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_internal.mdx b/api_docs/kbn_core_logging_server_internal.mdx index 24dc12db0332b..4fb6a77b9b04d 100644 --- a/api_docs/kbn_core_logging_server_internal.mdx +++ b/api_docs/kbn_core_logging_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-internal title: "@kbn/core-logging-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-internal'] --- import kbnCoreLoggingServerInternalObj from './kbn_core_logging_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_logging_server_mocks.mdx b/api_docs/kbn_core_logging_server_mocks.mdx index a82b557a1f1a7..3d86ef8947788 100644 --- a/api_docs/kbn_core_logging_server_mocks.mdx +++ b/api_docs/kbn_core_logging_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-logging-server-mocks title: "@kbn/core-logging-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-logging-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-logging-server-mocks'] --- import kbnCoreLoggingServerMocksObj from './kbn_core_logging_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_internal.mdx b/api_docs/kbn_core_metrics_collectors_server_internal.mdx index 72b65f0dfa4b4..dc7e196ccdf06 100644 --- a/api_docs/kbn_core_metrics_collectors_server_internal.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-internal title: "@kbn/core-metrics-collectors-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-internal'] --- import kbnCoreMetricsCollectorsServerInternalObj from './kbn_core_metrics_collectors_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx index 2f8824f490946..317ba2ee9e774 100644 --- a/api_docs/kbn_core_metrics_collectors_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_collectors_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-collectors-server-mocks title: "@kbn/core-metrics-collectors-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-collectors-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-collectors-server-mocks'] --- import kbnCoreMetricsCollectorsServerMocksObj from './kbn_core_metrics_collectors_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server.mdx b/api_docs/kbn_core_metrics_server.mdx index 942fbf14d559d..ace69d608a26d 100644 --- a/api_docs/kbn_core_metrics_server.mdx +++ b/api_docs/kbn_core_metrics_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server title: "@kbn/core-metrics-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server'] --- import kbnCoreMetricsServerObj from './kbn_core_metrics_server.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_internal.mdx b/api_docs/kbn_core_metrics_server_internal.mdx index be6df7cb8cf9b..751b14ef4a567 100644 --- a/api_docs/kbn_core_metrics_server_internal.mdx +++ b/api_docs/kbn_core_metrics_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-internal title: "@kbn/core-metrics-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-internal'] --- import kbnCoreMetricsServerInternalObj from './kbn_core_metrics_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_metrics_server_mocks.mdx b/api_docs/kbn_core_metrics_server_mocks.mdx index d4fc649fdc2eb..b8bc5cfc50f5b 100644 --- a/api_docs/kbn_core_metrics_server_mocks.mdx +++ b/api_docs/kbn_core_metrics_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-metrics-server-mocks title: "@kbn/core-metrics-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-metrics-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-metrics-server-mocks'] --- import kbnCoreMetricsServerMocksObj from './kbn_core_metrics_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_mount_utils_browser.mdx b/api_docs/kbn_core_mount_utils_browser.mdx index 4b00b2548c899..f558d06a364d1 100644 --- a/api_docs/kbn_core_mount_utils_browser.mdx +++ b/api_docs/kbn_core_mount_utils_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-mount-utils-browser title: "@kbn/core-mount-utils-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-mount-utils-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-mount-utils-browser'] --- import kbnCoreMountUtilsBrowserObj from './kbn_core_mount_utils_browser.devdocs.json'; diff --git a/api_docs/kbn_core_node_server.mdx b/api_docs/kbn_core_node_server.mdx index 9d70da599cfab..010eab5713a79 100644 --- a/api_docs/kbn_core_node_server.mdx +++ b/api_docs/kbn_core_node_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server title: "@kbn/core-node-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server'] --- import kbnCoreNodeServerObj from './kbn_core_node_server.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_internal.mdx b/api_docs/kbn_core_node_server_internal.mdx index 60d0a8caf0656..b142c9f37285f 100644 --- a/api_docs/kbn_core_node_server_internal.mdx +++ b/api_docs/kbn_core_node_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-internal title: "@kbn/core-node-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-internal'] --- import kbnCoreNodeServerInternalObj from './kbn_core_node_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_node_server_mocks.mdx b/api_docs/kbn_core_node_server_mocks.mdx index 050726f8b168c..6c94ef3afbb40 100644 --- a/api_docs/kbn_core_node_server_mocks.mdx +++ b/api_docs/kbn_core_node_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-node-server-mocks title: "@kbn/core-node-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-node-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-node-server-mocks'] --- import kbnCoreNodeServerMocksObj from './kbn_core_node_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser.mdx b/api_docs/kbn_core_notifications_browser.mdx index 35b2eb6697abd..c2638a4737c23 100644 --- a/api_docs/kbn_core_notifications_browser.mdx +++ b/api_docs/kbn_core_notifications_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser title: "@kbn/core-notifications-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser'] --- import kbnCoreNotificationsBrowserObj from './kbn_core_notifications_browser.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_internal.mdx b/api_docs/kbn_core_notifications_browser_internal.mdx index 4a218856ce992..0e95009b0cb85 100644 --- a/api_docs/kbn_core_notifications_browser_internal.mdx +++ b/api_docs/kbn_core_notifications_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-internal title: "@kbn/core-notifications-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-internal'] --- import kbnCoreNotificationsBrowserInternalObj from './kbn_core_notifications_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_notifications_browser_mocks.mdx b/api_docs/kbn_core_notifications_browser_mocks.mdx index 70b8eb5495ac3..a25e35d4e19ba 100644 --- a/api_docs/kbn_core_notifications_browser_mocks.mdx +++ b/api_docs/kbn_core_notifications_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-notifications-browser-mocks title: "@kbn/core-notifications-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-notifications-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-notifications-browser-mocks'] --- import kbnCoreNotificationsBrowserMocksObj from './kbn_core_notifications_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser.mdx b/api_docs/kbn_core_overlays_browser.mdx index 894be30c59744..69b5674fe89ab 100644 --- a/api_docs/kbn_core_overlays_browser.mdx +++ b/api_docs/kbn_core_overlays_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser title: "@kbn/core-overlays-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser'] --- import kbnCoreOverlaysBrowserObj from './kbn_core_overlays_browser.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_internal.mdx b/api_docs/kbn_core_overlays_browser_internal.mdx index e98985a874e8c..079aed26d91d7 100644 --- a/api_docs/kbn_core_overlays_browser_internal.mdx +++ b/api_docs/kbn_core_overlays_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-internal title: "@kbn/core-overlays-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-internal'] --- import kbnCoreOverlaysBrowserInternalObj from './kbn_core_overlays_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_overlays_browser_mocks.mdx b/api_docs/kbn_core_overlays_browser_mocks.mdx index d2fa2c9281280..b39ee812ab659 100644 --- a/api_docs/kbn_core_overlays_browser_mocks.mdx +++ b/api_docs/kbn_core_overlays_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-overlays-browser-mocks title: "@kbn/core-overlays-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-overlays-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-overlays-browser-mocks'] --- import kbnCoreOverlaysBrowserMocksObj from './kbn_core_overlays_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser.mdx b/api_docs/kbn_core_plugins_browser.mdx index 7f47c1039c9d6..916c6fafc8bd0 100644 --- a/api_docs/kbn_core_plugins_browser.mdx +++ b/api_docs/kbn_core_plugins_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser title: "@kbn/core-plugins-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser'] --- import kbnCorePluginsBrowserObj from './kbn_core_plugins_browser.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_browser_mocks.mdx b/api_docs/kbn_core_plugins_browser_mocks.mdx index da5748d5ea8aa..a6f60b7e0e965 100644 --- a/api_docs/kbn_core_plugins_browser_mocks.mdx +++ b/api_docs/kbn_core_plugins_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-browser-mocks title: "@kbn/core-plugins-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-browser-mocks'] --- import kbnCorePluginsBrowserMocksObj from './kbn_core_plugins_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server.mdx b/api_docs/kbn_core_plugins_server.mdx index 83e8074946994..c2a5349922e0d 100644 --- a/api_docs/kbn_core_plugins_server.mdx +++ b/api_docs/kbn_core_plugins_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server title: "@kbn/core-plugins-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server'] --- import kbnCorePluginsServerObj from './kbn_core_plugins_server.devdocs.json'; diff --git a/api_docs/kbn_core_plugins_server_mocks.mdx b/api_docs/kbn_core_plugins_server_mocks.mdx index b699d5a18fc3b..18f595bde6978 100644 --- a/api_docs/kbn_core_plugins_server_mocks.mdx +++ b/api_docs/kbn_core_plugins_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-plugins-server-mocks title: "@kbn/core-plugins-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-plugins-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-plugins-server-mocks'] --- import kbnCorePluginsServerMocksObj from './kbn_core_plugins_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index 9055ae02f55e3..78e0717918e17 100644 --- a/api_docs/kbn_core_preboot_server.mdx +++ b/api_docs/kbn_core_preboot_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server title: "@kbn/core-preboot-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server'] --- import kbnCorePrebootServerObj from './kbn_core_preboot_server.devdocs.json'; diff --git a/api_docs/kbn_core_preboot_server_mocks.mdx b/api_docs/kbn_core_preboot_server_mocks.mdx index cd5b4aaff1a35..86670bcafb4ae 100644 --- a/api_docs/kbn_core_preboot_server_mocks.mdx +++ b/api_docs/kbn_core_preboot_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-preboot-server-mocks title: "@kbn/core-preboot-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-preboot-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-preboot-server-mocks'] --- import kbnCorePrebootServerMocksObj from './kbn_core_preboot_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_browser_mocks.mdx b/api_docs/kbn_core_rendering_browser_mocks.mdx index c93084a00cc27..6aec9dfd84597 100644 --- a/api_docs/kbn_core_rendering_browser_mocks.mdx +++ b/api_docs/kbn_core_rendering_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-browser-mocks title: "@kbn/core-rendering-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-browser-mocks'] --- import kbnCoreRenderingBrowserMocksObj from './kbn_core_rendering_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_internal.mdx b/api_docs/kbn_core_rendering_server_internal.mdx index 5ec8429ba5358..abb1fb3e8afe6 100644 --- a/api_docs/kbn_core_rendering_server_internal.mdx +++ b/api_docs/kbn_core_rendering_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-internal title: "@kbn/core-rendering-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-internal'] --- import kbnCoreRenderingServerInternalObj from './kbn_core_rendering_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_rendering_server_mocks.mdx b/api_docs/kbn_core_rendering_server_mocks.mdx index 248c5a1377f27..ff0bc3ad493e7 100644 --- a/api_docs/kbn_core_rendering_server_mocks.mdx +++ b/api_docs/kbn_core_rendering_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-rendering-server-mocks title: "@kbn/core-rendering-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-rendering-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-rendering-server-mocks'] --- import kbnCoreRenderingServerMocksObj from './kbn_core_rendering_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_root_server_internal.mdx b/api_docs/kbn_core_root_server_internal.mdx index 4dc417f5a7d53..b38e9d98875bb 100644 --- a/api_docs/kbn_core_root_server_internal.mdx +++ b/api_docs/kbn_core_root_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-root-server-internal title: "@kbn/core-root-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-root-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-root-server-internal'] --- import kbnCoreRootServerInternalObj from './kbn_core_root_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index 0883a8154b408..a62569321db1f 100644 --- a/api_docs/kbn_core_saved_objects_api_browser.mdx +++ b/api_docs/kbn_core_saved_objects_api_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-browser title: "@kbn/core-saved-objects-api-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-browser'] --- import kbnCoreSavedObjectsApiBrowserObj from './kbn_core_saved_objects_api_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server.mdx b/api_docs/kbn_core_saved_objects_api_server.mdx index 8ccae1b8c8f0d..b4501b269354e 100644 --- a/api_docs/kbn_core_saved_objects_api_server.mdx +++ b/api_docs/kbn_core_saved_objects_api_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server title: "@kbn/core-saved-objects-api-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server'] --- import kbnCoreSavedObjectsApiServerObj from './kbn_core_saved_objects_api_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx index e8eff5f0f2ad3..95fa85cab16b5 100644 --- a/api_docs/kbn_core_saved_objects_api_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-mocks title: "@kbn/core-saved-objects-api-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-mocks'] --- import kbnCoreSavedObjectsApiServerMocksObj from './kbn_core_saved_objects_api_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_internal.mdx b/api_docs/kbn_core_saved_objects_base_server_internal.mdx index 7808916e0016e..d1e46f4c1ee5e 100644 --- a/api_docs/kbn_core_saved_objects_base_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-internal title: "@kbn/core-saved-objects-base-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-internal'] --- import kbnCoreSavedObjectsBaseServerInternalObj from './kbn_core_saved_objects_base_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx index a05db382fe8de..a987dc60dc8d8 100644 --- a/api_docs/kbn_core_saved_objects_base_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_base_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-base-server-mocks title: "@kbn/core-saved-objects-base-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-base-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-base-server-mocks'] --- import kbnCoreSavedObjectsBaseServerMocksObj from './kbn_core_saved_objects_base_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser.mdx b/api_docs/kbn_core_saved_objects_browser.mdx index 3da20bbcf7354..c493c59bc1b4a 100644 --- a/api_docs/kbn_core_saved_objects_browser.mdx +++ b/api_docs/kbn_core_saved_objects_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser title: "@kbn/core-saved-objects-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser'] --- import kbnCoreSavedObjectsBrowserObj from './kbn_core_saved_objects_browser.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_internal.mdx b/api_docs/kbn_core_saved_objects_browser_internal.mdx index fc768a7c4fa20..d6b01343a214b 100644 --- a/api_docs/kbn_core_saved_objects_browser_internal.mdx +++ b/api_docs/kbn_core_saved_objects_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-internal title: "@kbn/core-saved-objects-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-internal'] --- import kbnCoreSavedObjectsBrowserInternalObj from './kbn_core_saved_objects_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_browser_mocks.mdx b/api_docs/kbn_core_saved_objects_browser_mocks.mdx index ed47503a0dfae..99a7f0976ded9 100644 --- a/api_docs/kbn_core_saved_objects_browser_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-browser-mocks title: "@kbn/core-saved-objects-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-browser-mocks'] --- import kbnCoreSavedObjectsBrowserMocksObj from './kbn_core_saved_objects_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_common.mdx b/api_docs/kbn_core_saved_objects_common.mdx index 0770377386221..7d5ba1632a8d4 100644 --- a/api_docs/kbn_core_saved_objects_common.mdx +++ b/api_docs/kbn_core_saved_objects_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-common title: "@kbn/core-saved-objects-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-common'] --- import kbnCoreSavedObjectsCommonObj from './kbn_core_saved_objects_common.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx index 15e296e8acafb..758ebdab3d222 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-internal title: "@kbn/core-saved-objects-import-export-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-internal'] --- import kbnCoreSavedObjectsImportExportServerInternalObj from './kbn_core_saved_objects_import_export_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx index af6b3c93af036..99235c2ce242a 100644 --- a/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_import_export_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-import-export-server-mocks title: "@kbn/core-saved-objects-import-export-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-import-export-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-import-export-server-mocks'] --- import kbnCoreSavedObjectsImportExportServerMocksObj from './kbn_core_saved_objects_import_export_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx index 7335ede94d23a..845cab1c1d84b 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-internal title: "@kbn/core-saved-objects-migration-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-internal'] --- import kbnCoreSavedObjectsMigrationServerInternalObj from './kbn_core_saved_objects_migration_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx index c44e0764ba9c1..d8ae52e1c5cd1 100644 --- a/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_migration_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-migration-server-mocks title: "@kbn/core-saved-objects-migration-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-migration-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-migration-server-mocks'] --- import kbnCoreSavedObjectsMigrationServerMocksObj from './kbn_core_saved_objects_migration_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server.mdx b/api_docs/kbn_core_saved_objects_server.mdx index 7216da5906fe5..d54b0c18fa7f9 100644 --- a/api_docs/kbn_core_saved_objects_server.mdx +++ b/api_docs/kbn_core_saved_objects_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server title: "@kbn/core-saved-objects-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server'] --- import kbnCoreSavedObjectsServerObj from './kbn_core_saved_objects_server.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_internal.mdx b/api_docs/kbn_core_saved_objects_server_internal.mdx index d045972dd2212..48c029ae6a3fa 100644 --- a/api_docs/kbn_core_saved_objects_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-internal title: "@kbn/core-saved-objects-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-internal'] --- import kbnCoreSavedObjectsServerInternalObj from './kbn_core_saved_objects_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_server_mocks.mdx b/api_docs/kbn_core_saved_objects_server_mocks.mdx index d967ea230269d..7b0108f47de19 100644 --- a/api_docs/kbn_core_saved_objects_server_mocks.mdx +++ b/api_docs/kbn_core_saved_objects_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-server-mocks title: "@kbn/core-saved-objects-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-server-mocks'] --- import kbnCoreSavedObjectsServerMocksObj from './kbn_core_saved_objects_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_saved_objects_utils_server.mdx b/api_docs/kbn_core_saved_objects_utils_server.mdx index b3fca84984523..4cd54142fc9d2 100644 --- a/api_docs/kbn_core_saved_objects_utils_server.mdx +++ b/api_docs/kbn_core_saved_objects_utils_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-utils-server title: "@kbn/core-saved-objects-utils-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-utils-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-utils-server'] --- import kbnCoreSavedObjectsUtilsServerObj from './kbn_core_saved_objects_utils_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_common.mdx b/api_docs/kbn_core_status_common.mdx index 49ed62ee3c940..f1c9d87eab6cf 100644 --- a/api_docs/kbn_core_status_common.mdx +++ b/api_docs/kbn_core_status_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common title: "@kbn/core-status-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common'] --- import kbnCoreStatusCommonObj from './kbn_core_status_common.devdocs.json'; diff --git a/api_docs/kbn_core_status_common_internal.mdx b/api_docs/kbn_core_status_common_internal.mdx index 9da435a350f29..1d759a21ce701 100644 --- a/api_docs/kbn_core_status_common_internal.mdx +++ b/api_docs/kbn_core_status_common_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-common-internal title: "@kbn/core-status-common-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-common-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-common-internal'] --- import kbnCoreStatusCommonInternalObj from './kbn_core_status_common_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server.mdx b/api_docs/kbn_core_status_server.mdx index 41ada1a0f1818..e654990475f5d 100644 --- a/api_docs/kbn_core_status_server.mdx +++ b/api_docs/kbn_core_status_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server title: "@kbn/core-status-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server'] --- import kbnCoreStatusServerObj from './kbn_core_status_server.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_internal.mdx b/api_docs/kbn_core_status_server_internal.mdx index 40e49a4e6ffc3..117678763edcb 100644 --- a/api_docs/kbn_core_status_server_internal.mdx +++ b/api_docs/kbn_core_status_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-internal title: "@kbn/core-status-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-internal'] --- import kbnCoreStatusServerInternalObj from './kbn_core_status_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_status_server_mocks.mdx b/api_docs/kbn_core_status_server_mocks.mdx index 38810ad683e39..6695ef9c86476 100644 --- a/api_docs/kbn_core_status_server_mocks.mdx +++ b/api_docs/kbn_core_status_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-status-server-mocks title: "@kbn/core-status-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-status-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-status-server-mocks'] --- import kbnCoreStatusServerMocksObj from './kbn_core_status_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx index c59fd4824bddf..271a06dbd26e7 100644 --- a/api_docs/kbn_core_test_helpers_deprecations_getters.mdx +++ b/api_docs/kbn_core_test_helpers_deprecations_getters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-deprecations-getters title: "@kbn/core-test-helpers-deprecations-getters" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-deprecations-getters plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-deprecations-getters'] --- import kbnCoreTestHelpersDeprecationsGettersObj from './kbn_core_test_helpers_deprecations_getters.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx index b2f3dc18e7476..1bf1a38c714f5 100644 --- a/api_docs/kbn_core_test_helpers_http_setup_browser.mdx +++ b/api_docs/kbn_core_test_helpers_http_setup_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-http-setup-browser title: "@kbn/core-test-helpers-http-setup-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-http-setup-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-http-setup-browser'] --- import kbnCoreTestHelpersHttpSetupBrowserObj from './kbn_core_test_helpers_http_setup_browser.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_kbn_server.mdx b/api_docs/kbn_core_test_helpers_kbn_server.mdx index 6f6e2d0f5633f..56b267ba84572 100644 --- a/api_docs/kbn_core_test_helpers_kbn_server.mdx +++ b/api_docs/kbn_core_test_helpers_kbn_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-kbn-server title: "@kbn/core-test-helpers-kbn-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-kbn-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-kbn-server'] --- import kbnCoreTestHelpersKbnServerObj from './kbn_core_test_helpers_kbn_server.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx index 83d8c1444ac8d..bc776395968b5 100644 --- a/api_docs/kbn_core_test_helpers_so_type_serializer.mdx +++ b/api_docs/kbn_core_test_helpers_so_type_serializer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-so-type-serializer title: "@kbn/core-test-helpers-so-type-serializer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-so-type-serializer plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-so-type-serializer'] --- import kbnCoreTestHelpersSoTypeSerializerObj from './kbn_core_test_helpers_so_type_serializer.devdocs.json'; diff --git a/api_docs/kbn_core_test_helpers_test_utils.mdx b/api_docs/kbn_core_test_helpers_test_utils.mdx index 811c7d83c377e..c6feaf4650780 100644 --- a/api_docs/kbn_core_test_helpers_test_utils.mdx +++ b/api_docs/kbn_core_test_helpers_test_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-test-helpers-test-utils title: "@kbn/core-test-helpers-test-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-test-helpers-test-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-test-helpers-test-utils'] --- import kbnCoreTestHelpersTestUtilsObj from './kbn_core_test_helpers_test_utils.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index f177a989535d4..cdbe74136748f 100644 --- a/api_docs/kbn_core_theme_browser.mdx +++ b/api_docs/kbn_core_theme_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser title: "@kbn/core-theme-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser'] --- import kbnCoreThemeBrowserObj from './kbn_core_theme_browser.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 5d5ac993a8ca9..9ddf2c57ce822 100644 --- a/api_docs/kbn_core_theme_browser_mocks.mdx +++ b/api_docs/kbn_core_theme_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-mocks title: "@kbn/core-theme-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-mocks'] --- import kbnCoreThemeBrowserMocksObj from './kbn_core_theme_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser.mdx b/api_docs/kbn_core_ui_settings_browser.mdx index eaa17b95953db..7abf2e74bf987 100644 --- a/api_docs/kbn_core_ui_settings_browser.mdx +++ b/api_docs/kbn_core_ui_settings_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser title: "@kbn/core-ui-settings-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser'] --- import kbnCoreUiSettingsBrowserObj from './kbn_core_ui_settings_browser.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_internal.mdx b/api_docs/kbn_core_ui_settings_browser_internal.mdx index be1bab5f4dbb0..1931ac3b26fff 100644 --- a/api_docs/kbn_core_ui_settings_browser_internal.mdx +++ b/api_docs/kbn_core_ui_settings_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-internal title: "@kbn/core-ui-settings-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-internal'] --- import kbnCoreUiSettingsBrowserInternalObj from './kbn_core_ui_settings_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_browser_mocks.mdx b/api_docs/kbn_core_ui_settings_browser_mocks.mdx index cf1f5ae1043f0..532c7adad3e1c 100644 --- a/api_docs/kbn_core_ui_settings_browser_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_browser_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-browser-mocks title: "@kbn/core-ui-settings-browser-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-browser-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-browser-mocks'] --- import kbnCoreUiSettingsBrowserMocksObj from './kbn_core_ui_settings_browser_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_common.mdx b/api_docs/kbn_core_ui_settings_common.mdx index bfd270e8df76b..0ab8e28aa0df9 100644 --- a/api_docs/kbn_core_ui_settings_common.mdx +++ b/api_docs/kbn_core_ui_settings_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-common title: "@kbn/core-ui-settings-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-common'] --- import kbnCoreUiSettingsCommonObj from './kbn_core_ui_settings_common.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server.mdx b/api_docs/kbn_core_ui_settings_server.mdx index ec0c61a65bd27..7a75e89ea4150 100644 --- a/api_docs/kbn_core_ui_settings_server.mdx +++ b/api_docs/kbn_core_ui_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server title: "@kbn/core-ui-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server'] --- import kbnCoreUiSettingsServerObj from './kbn_core_ui_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_internal.mdx b/api_docs/kbn_core_ui_settings_server_internal.mdx index aa0fa15eb3c9b..c67e252addd2f 100644 --- a/api_docs/kbn_core_ui_settings_server_internal.mdx +++ b/api_docs/kbn_core_ui_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-internal title: "@kbn/core-ui-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-internal'] --- import kbnCoreUiSettingsServerInternalObj from './kbn_core_ui_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_ui_settings_server_mocks.mdx b/api_docs/kbn_core_ui_settings_server_mocks.mdx index d9f554ddddeeb..4e6b67b9852b3 100644 --- a/api_docs/kbn_core_ui_settings_server_mocks.mdx +++ b/api_docs/kbn_core_ui_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-ui-settings-server-mocks title: "@kbn/core-ui-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-ui-settings-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-ui-settings-server-mocks'] --- import kbnCoreUiSettingsServerMocksObj from './kbn_core_ui_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server.mdx b/api_docs/kbn_core_usage_data_server.mdx index f84ba34fff7e0..d4cbd84c11c56 100644 --- a/api_docs/kbn_core_usage_data_server.mdx +++ b/api_docs/kbn_core_usage_data_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server title: "@kbn/core-usage-data-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server'] --- import kbnCoreUsageDataServerObj from './kbn_core_usage_data_server.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_internal.mdx b/api_docs/kbn_core_usage_data_server_internal.mdx index 678616540e397..79c868879899d 100644 --- a/api_docs/kbn_core_usage_data_server_internal.mdx +++ b/api_docs/kbn_core_usage_data_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-internal title: "@kbn/core-usage-data-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-internal'] --- import kbnCoreUsageDataServerInternalObj from './kbn_core_usage_data_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_usage_data_server_mocks.mdx b/api_docs/kbn_core_usage_data_server_mocks.mdx index 38d6be53c777e..25757579a4fbd 100644 --- a/api_docs/kbn_core_usage_data_server_mocks.mdx +++ b/api_docs/kbn_core_usage_data_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-usage-data-server-mocks title: "@kbn/core-usage-data-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-usage-data-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-usage-data-server-mocks'] --- import kbnCoreUsageDataServerMocksObj from './kbn_core_usage_data_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server.mdx b/api_docs/kbn_core_user_settings_server.mdx index fca5fc0b07610..935179f08e439 100644 --- a/api_docs/kbn_core_user_settings_server.mdx +++ b/api_docs/kbn_core_user_settings_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server title: "@kbn/core-user-settings-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server'] --- import kbnCoreUserSettingsServerObj from './kbn_core_user_settings_server.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_internal.mdx b/api_docs/kbn_core_user_settings_server_internal.mdx index 07484ca0f7b1a..dddf1ef343884 100644 --- a/api_docs/kbn_core_user_settings_server_internal.mdx +++ b/api_docs/kbn_core_user_settings_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-internal title: "@kbn/core-user-settings-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-internal plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-internal'] --- import kbnCoreUserSettingsServerInternalObj from './kbn_core_user_settings_server_internal.devdocs.json'; diff --git a/api_docs/kbn_core_user_settings_server_mocks.mdx b/api_docs/kbn_core_user_settings_server_mocks.mdx index 1d997baa966b2..45056ff08f1af 100644 --- a/api_docs/kbn_core_user_settings_server_mocks.mdx +++ b/api_docs/kbn_core_user_settings_server_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-user-settings-server-mocks title: "@kbn/core-user-settings-server-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-user-settings-server-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-user-settings-server-mocks'] --- import kbnCoreUserSettingsServerMocksObj from './kbn_core_user_settings_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_crypto.mdx b/api_docs/kbn_crypto.mdx index d808f075556d0..cc016eec8bfc8 100644 --- a/api_docs/kbn_crypto.mdx +++ b/api_docs/kbn_crypto.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto title: "@kbn/crypto" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto'] --- import kbnCryptoObj from './kbn_crypto.devdocs.json'; diff --git a/api_docs/kbn_crypto_browser.mdx b/api_docs/kbn_crypto_browser.mdx index 7812502e1ed10..56ce772d5b1d1 100644 --- a/api_docs/kbn_crypto_browser.mdx +++ b/api_docs/kbn_crypto_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-crypto-browser title: "@kbn/crypto-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/crypto-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_cypress_config.mdx b/api_docs/kbn_cypress_config.mdx index 9149fa36981e7..4c969ab0e95fa 100644 --- a/api_docs/kbn_cypress_config.mdx +++ b/api_docs/kbn_cypress_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-cypress-config title: "@kbn/cypress-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/cypress-config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cypress-config'] --- import kbnCypressConfigObj from './kbn_cypress_config.devdocs.json'; diff --git a/api_docs/kbn_data_service.mdx b/api_docs/kbn_data_service.mdx index f5c45e8f8121a..b53458717153d 100644 --- a/api_docs/kbn_data_service.mdx +++ b/api_docs/kbn_data_service.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-data-service title: "@kbn/data-service" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/data-service plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/data-service'] --- import kbnDataServiceObj from './kbn_data_service.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index 849f0af9a5909..4a9f76a2bf852 100644 --- a/api_docs/kbn_datemath.mdx +++ b/api_docs/kbn_datemath.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-datemath title: "@kbn/datemath" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/datemath plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_analytics.mdx b/api_docs/kbn_deeplinks_analytics.mdx index fff79c4340b37..395daccf034c6 100644 --- a/api_docs/kbn_deeplinks_analytics.mdx +++ b/api_docs/kbn_deeplinks_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-analytics title: "@kbn/deeplinks-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-analytics plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-analytics'] --- import kbnDeeplinksAnalyticsObj from './kbn_deeplinks_analytics.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_devtools.mdx b/api_docs/kbn_deeplinks_devtools.mdx index 1f642a3a3451e..4f65a2c1d09d1 100644 --- a/api_docs/kbn_deeplinks_devtools.mdx +++ b/api_docs/kbn_deeplinks_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-devtools title: "@kbn/deeplinks-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-devtools plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-devtools'] --- import kbnDeeplinksDevtoolsObj from './kbn_deeplinks_devtools.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_management.mdx b/api_docs/kbn_deeplinks_management.mdx index d60ff0a50c84d..1517e4387cf9b 100644 --- a/api_docs/kbn_deeplinks_management.mdx +++ b/api_docs/kbn_deeplinks_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-management title: "@kbn/deeplinks-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-management plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-management'] --- import kbnDeeplinksManagementObj from './kbn_deeplinks_management.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_ml.mdx b/api_docs/kbn_deeplinks_ml.mdx index f89016cf340b7..3d1bc0ada81d1 100644 --- a/api_docs/kbn_deeplinks_ml.mdx +++ b/api_docs/kbn_deeplinks_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-ml title: "@kbn/deeplinks-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-ml plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-ml'] --- import kbnDeeplinksMlObj from './kbn_deeplinks_ml.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_observability.mdx b/api_docs/kbn_deeplinks_observability.mdx index d1d76275435c6..1ff762c760aa7 100644 --- a/api_docs/kbn_deeplinks_observability.mdx +++ b/api_docs/kbn_deeplinks_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-observability title: "@kbn/deeplinks-observability" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-observability plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-observability'] --- import kbnDeeplinksObservabilityObj from './kbn_deeplinks_observability.devdocs.json'; diff --git a/api_docs/kbn_deeplinks_search.mdx b/api_docs/kbn_deeplinks_search.mdx index 344dfc30878bb..e3d1e559f3f0d 100644 --- a/api_docs/kbn_deeplinks_search.mdx +++ b/api_docs/kbn_deeplinks_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-deeplinks-search title: "@kbn/deeplinks-search" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/deeplinks-search plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/deeplinks-search'] --- import kbnDeeplinksSearchObj from './kbn_deeplinks_search.devdocs.json'; diff --git a/api_docs/kbn_default_nav_analytics.mdx b/api_docs/kbn_default_nav_analytics.mdx index 84b9e8018e08f..544a84a94c069 100644 --- a/api_docs/kbn_default_nav_analytics.mdx +++ b/api_docs/kbn_default_nav_analytics.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-analytics title: "@kbn/default-nav-analytics" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-analytics plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-analytics'] --- import kbnDefaultNavAnalyticsObj from './kbn_default_nav_analytics.devdocs.json'; diff --git a/api_docs/kbn_default_nav_devtools.mdx b/api_docs/kbn_default_nav_devtools.mdx index 7af7f09d22b06..20667b6757a8d 100644 --- a/api_docs/kbn_default_nav_devtools.mdx +++ b/api_docs/kbn_default_nav_devtools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-devtools title: "@kbn/default-nav-devtools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-devtools plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-devtools'] --- import kbnDefaultNavDevtoolsObj from './kbn_default_nav_devtools.devdocs.json'; diff --git a/api_docs/kbn_default_nav_management.mdx b/api_docs/kbn_default_nav_management.mdx index 3fbae862d90c2..7c20d850bdd3d 100644 --- a/api_docs/kbn_default_nav_management.mdx +++ b/api_docs/kbn_default_nav_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-management title: "@kbn/default-nav-management" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-management plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-management'] --- import kbnDefaultNavManagementObj from './kbn_default_nav_management.devdocs.json'; diff --git a/api_docs/kbn_default_nav_ml.mdx b/api_docs/kbn_default_nav_ml.mdx index 57e461409ffae..332dab42ea5ec 100644 --- a/api_docs/kbn_default_nav_ml.mdx +++ b/api_docs/kbn_default_nav_ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-default-nav-ml title: "@kbn/default-nav-ml" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/default-nav-ml plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/default-nav-ml'] --- import kbnDefaultNavMlObj from './kbn_default_nav_ml.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index c098a6cffcff1..08a9a3fb7df56 100644 --- a/api_docs/kbn_dev_cli_errors.mdx +++ b/api_docs/kbn_dev_cli_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-errors title: "@kbn/dev-cli-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-errors plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-errors'] --- import kbnDevCliErrorsObj from './kbn_dev_cli_errors.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_runner.mdx b/api_docs/kbn_dev_cli_runner.mdx index b35d1bd05f89a..337ba8695482a 100644 --- a/api_docs/kbn_dev_cli_runner.mdx +++ b/api_docs/kbn_dev_cli_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-cli-runner title: "@kbn/dev-cli-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-cli-runner plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-cli-runner'] --- import kbnDevCliRunnerObj from './kbn_dev_cli_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_proc_runner.mdx b/api_docs/kbn_dev_proc_runner.mdx index e49cb2bc360af..7558dc4339d3f 100644 --- a/api_docs/kbn_dev_proc_runner.mdx +++ b/api_docs/kbn_dev_proc_runner.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-proc-runner title: "@kbn/dev-proc-runner" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-proc-runner plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-proc-runner'] --- import kbnDevProcRunnerObj from './kbn_dev_proc_runner.devdocs.json'; diff --git a/api_docs/kbn_dev_utils.mdx b/api_docs/kbn_dev_utils.mdx index 15b9bb29e5118..89db217814781 100644 --- a/api_docs/kbn_dev_utils.mdx +++ b/api_docs/kbn_dev_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dev-utils title: "@kbn/dev-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dev-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_discover_utils.mdx b/api_docs/kbn_discover_utils.mdx index 65cfe370e9c1f..b4fad8a137581 100644 --- a/api_docs/kbn_discover_utils.mdx +++ b/api_docs/kbn_discover_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-discover-utils title: "@kbn/discover-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/discover-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/discover-utils'] --- import kbnDiscoverUtilsObj from './kbn_discover_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index c01bc367d6f6e..5939e5a135fa4 100644 --- a/api_docs/kbn_doc_links.mdx +++ b/api_docs/kbn_doc_links.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-doc-links title: "@kbn/doc-links" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/doc-links plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/doc-links'] --- import kbnDocLinksObj from './kbn_doc_links.devdocs.json'; diff --git a/api_docs/kbn_docs_utils.mdx b/api_docs/kbn_docs_utils.mdx index 327cc31f474cf..06fbb1b04042e 100644 --- a/api_docs/kbn_docs_utils.mdx +++ b/api_docs/kbn_docs_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-docs-utils title: "@kbn/docs-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/docs-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_dom_drag_drop.mdx b/api_docs/kbn_dom_drag_drop.mdx index 8d8ddd63bcdef..9423dfb94366c 100644 --- a/api_docs/kbn_dom_drag_drop.mdx +++ b/api_docs/kbn_dom_drag_drop.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-dom-drag-drop title: "@kbn/dom-drag-drop" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/dom-drag-drop plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dom-drag-drop'] --- import kbnDomDragDropObj from './kbn_dom_drag_drop.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 90f8c163bc5e5..9fa55673ed2b0 100644 --- a/api_docs/kbn_ebt_tools.mdx +++ b/api_docs/kbn_ebt_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ebt-tools title: "@kbn/ebt-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ebt-tools plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_ecs.mdx b/api_docs/kbn_ecs.mdx index 6aeec83297161..7ba02853d106f 100644 --- a/api_docs/kbn_ecs.mdx +++ b/api_docs/kbn_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs title: "@kbn/ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs'] --- import kbnEcsObj from './kbn_ecs.devdocs.json'; diff --git a/api_docs/kbn_ecs_data_quality_dashboard.mdx b/api_docs/kbn_ecs_data_quality_dashboard.mdx index a7b8fed083067..0dbcabd54280f 100644 --- a/api_docs/kbn_ecs_data_quality_dashboard.mdx +++ b/api_docs/kbn_ecs_data_quality_dashboard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ecs-data-quality-dashboard title: "@kbn/ecs-data-quality-dashboard" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ecs-data-quality-dashboard plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ecs-data-quality-dashboard'] --- import kbnEcsDataQualityDashboardObj from './kbn_ecs_data_quality_dashboard.devdocs.json'; diff --git a/api_docs/kbn_elastic_assistant.mdx b/api_docs/kbn_elastic_assistant.mdx index a85f005858206..3d27411f79c8a 100644 --- a/api_docs/kbn_elastic_assistant.mdx +++ b/api_docs/kbn_elastic_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-elastic-assistant title: "@kbn/elastic-assistant" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/elastic-assistant plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/elastic-assistant'] --- import kbnElasticAssistantObj from './kbn_elastic_assistant.devdocs.json'; diff --git a/api_docs/kbn_es.mdx b/api_docs/kbn_es.mdx index 09fafa8af939b..265c4b5b4b2e5 100644 --- a/api_docs/kbn_es.mdx +++ b/api_docs/kbn_es.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es title: "@kbn/es" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es'] --- import kbnEsObj from './kbn_es.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index f7f7c393c0fdb..06d97ea2e6c09 100644 --- a/api_docs/kbn_es_archiver.mdx +++ b/api_docs/kbn_es_archiver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-archiver title: "@kbn/es-archiver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-archiver plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-archiver'] --- import kbnEsArchiverObj from './kbn_es_archiver.devdocs.json'; diff --git a/api_docs/kbn_es_errors.mdx b/api_docs/kbn_es_errors.mdx index ca0f8f2d1ce85..d6cef59c85df9 100644 --- a/api_docs/kbn_es_errors.mdx +++ b/api_docs/kbn_es_errors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-errors title: "@kbn/es-errors" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-errors plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-errors'] --- import kbnEsErrorsObj from './kbn_es_errors.devdocs.json'; diff --git a/api_docs/kbn_es_query.mdx b/api_docs/kbn_es_query.mdx index e887dbfbb3621..b152de1a0efad 100644 --- a/api_docs/kbn_es_query.mdx +++ b/api_docs/kbn_es_query.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-query title: "@kbn/es-query" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-query plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-query'] --- import kbnEsQueryObj from './kbn_es_query.devdocs.json'; diff --git a/api_docs/kbn_es_types.mdx b/api_docs/kbn_es_types.mdx index 21fe8e223cbc2..f5bfbca78eb95 100644 --- a/api_docs/kbn_es_types.mdx +++ b/api_docs/kbn_es_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-es-types title: "@kbn/es-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/es-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/es-types'] --- import kbnEsTypesObj from './kbn_es_types.devdocs.json'; diff --git a/api_docs/kbn_eslint_plugin_imports.mdx b/api_docs/kbn_eslint_plugin_imports.mdx index 85d78c0d4c7f6..cda3ff57e110d 100644 --- a/api_docs/kbn_eslint_plugin_imports.mdx +++ b/api_docs/kbn_eslint_plugin_imports.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-eslint-plugin-imports title: "@kbn/eslint-plugin-imports" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/eslint-plugin-imports plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_common.mdx b/api_docs/kbn_event_annotation_common.mdx index 89c11df2dc27a..4ce21cb4603ce 100644 --- a/api_docs/kbn_event_annotation_common.mdx +++ b/api_docs/kbn_event_annotation_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-common title: "@kbn/event-annotation-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-common'] --- import kbnEventAnnotationCommonObj from './kbn_event_annotation_common.devdocs.json'; diff --git a/api_docs/kbn_event_annotation_components.mdx b/api_docs/kbn_event_annotation_components.mdx index a020c57a31d0e..9cd8f7214cfa8 100644 --- a/api_docs/kbn_event_annotation_components.mdx +++ b/api_docs/kbn_event_annotation_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-event-annotation-components title: "@kbn/event-annotation-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/event-annotation-components plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/event-annotation-components'] --- import kbnEventAnnotationComponentsObj from './kbn_event_annotation_components.devdocs.json'; diff --git a/api_docs/kbn_expandable_flyout.mdx b/api_docs/kbn_expandable_flyout.mdx index 69b50a9b3222a..732812f7a79b7 100644 --- a/api_docs/kbn_expandable_flyout.mdx +++ b/api_docs/kbn_expandable_flyout.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-expandable-flyout title: "@kbn/expandable-flyout" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/expandable-flyout plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/expandable-flyout'] --- import kbnExpandableFlyoutObj from './kbn_expandable_flyout.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index d6aa6729a8a80..5bdbfb13a0efb 100644 --- a/api_docs/kbn_field_types.mdx +++ b/api_docs/kbn_field_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-field-types title: "@kbn/field-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/field-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/field-types'] --- import kbnFieldTypesObj from './kbn_field_types.devdocs.json'; diff --git a/api_docs/kbn_find_used_node_modules.mdx b/api_docs/kbn_find_used_node_modules.mdx index 0b7f47064fe0e..2c8eb05ed00fb 100644 --- a/api_docs/kbn_find_used_node_modules.mdx +++ b/api_docs/kbn_find_used_node_modules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-find-used-node-modules title: "@kbn/find-used-node-modules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/find-used-node-modules plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/find-used-node-modules'] --- import kbnFindUsedNodeModulesObj from './kbn_find_used_node_modules.devdocs.json'; diff --git a/api_docs/kbn_ftr_common_functional_services.mdx b/api_docs/kbn_ftr_common_functional_services.mdx index 923a678b2ab3f..dcd7828d8f729 100644 --- a/api_docs/kbn_ftr_common_functional_services.mdx +++ b/api_docs/kbn_ftr_common_functional_services.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ftr-common-functional-services title: "@kbn/ftr-common-functional-services" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ftr-common-functional-services plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ftr-common-functional-services'] --- import kbnFtrCommonFunctionalServicesObj from './kbn_ftr_common_functional_services.devdocs.json'; diff --git a/api_docs/kbn_generate.mdx b/api_docs/kbn_generate.mdx index 586448fcc74dc..5ab4aeed0523f 100644 --- a/api_docs/kbn_generate.mdx +++ b/api_docs/kbn_generate.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate title: "@kbn/generate" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_generate_console_definitions.mdx b/api_docs/kbn_generate_console_definitions.mdx index aa7dc4b082499..a40025b07062d 100644 --- a/api_docs/kbn_generate_console_definitions.mdx +++ b/api_docs/kbn_generate_console_definitions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-console-definitions title: "@kbn/generate-console-definitions" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-console-definitions plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-console-definitions'] --- import kbnGenerateConsoleDefinitionsObj from './kbn_generate_console_definitions.devdocs.json'; diff --git a/api_docs/kbn_generate_csv.mdx b/api_docs/kbn_generate_csv.mdx index 239e591d4020b..195dc456047cf 100644 --- a/api_docs/kbn_generate_csv.mdx +++ b/api_docs/kbn_generate_csv.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv title: "@kbn/generate-csv" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv'] --- import kbnGenerateCsvObj from './kbn_generate_csv.devdocs.json'; diff --git a/api_docs/kbn_generate_csv_types.mdx b/api_docs/kbn_generate_csv_types.mdx index 9879cb25632a7..de8d08099659f 100644 --- a/api_docs/kbn_generate_csv_types.mdx +++ b/api_docs/kbn_generate_csv_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-generate-csv-types title: "@kbn/generate-csv-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/generate-csv-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate-csv-types'] --- import kbnGenerateCsvTypesObj from './kbn_generate_csv_types.devdocs.json'; diff --git a/api_docs/kbn_guided_onboarding.mdx b/api_docs/kbn_guided_onboarding.mdx index 0962db8bb19da..e03dc06db9fa2 100644 --- a/api_docs/kbn_guided_onboarding.mdx +++ b/api_docs/kbn_guided_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-guided-onboarding title: "@kbn/guided-onboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/guided-onboarding plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/guided-onboarding'] --- import kbnGuidedOnboardingObj from './kbn_guided_onboarding.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index 014b562460932..7e1396bcb3633 100644 --- a/api_docs/kbn_handlebars.mdx +++ b/api_docs/kbn_handlebars.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-handlebars title: "@kbn/handlebars" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/handlebars plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/handlebars'] --- import kbnHandlebarsObj from './kbn_handlebars.devdocs.json'; diff --git a/api_docs/kbn_hapi_mocks.mdx b/api_docs/kbn_hapi_mocks.mdx index 8bb7a5004a495..fe31787dee3e4 100644 --- a/api_docs/kbn_hapi_mocks.mdx +++ b/api_docs/kbn_hapi_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-hapi-mocks title: "@kbn/hapi-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/hapi-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_health_gateway_server.mdx b/api_docs/kbn_health_gateway_server.mdx index 997add0894ff3..aa9e3fd4aeea1 100644 --- a/api_docs/kbn_health_gateway_server.mdx +++ b/api_docs/kbn_health_gateway_server.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-health-gateway-server title: "@kbn/health-gateway-server" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/health-gateway-server plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/health-gateway-server'] --- import kbnHealthGatewayServerObj from './kbn_health_gateway_server.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 234fe75097ed2..5f08767456ce9 100644 --- a/api_docs/kbn_home_sample_data_card.mdx +++ b/api_docs/kbn_home_sample_data_card.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-card title: "@kbn/home-sample-data-card" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-card plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-card'] --- import kbnHomeSampleDataCardObj from './kbn_home_sample_data_card.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_tab.mdx b/api_docs/kbn_home_sample_data_tab.mdx index 60f753e15335f..c58cdd56cebd3 100644 --- a/api_docs/kbn_home_sample_data_tab.mdx +++ b/api_docs/kbn_home_sample_data_tab.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-home-sample-data-tab title: "@kbn/home-sample-data-tab" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/home-sample-data-tab plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/home-sample-data-tab'] --- import kbnHomeSampleDataTabObj from './kbn_home_sample_data_tab.devdocs.json'; diff --git a/api_docs/kbn_i18n.mdx b/api_docs/kbn_i18n.mdx index 6bf353b2813a4..2f53834a6ea42 100644 --- a/api_docs/kbn_i18n.mdx +++ b/api_docs/kbn_i18n.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n title: "@kbn/i18n" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_i18n_react.mdx b/api_docs/kbn_i18n_react.mdx index bb6453416b17b..5f867be9c59b2 100644 --- a/api_docs/kbn_i18n_react.mdx +++ b/api_docs/kbn_i18n_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-i18n-react title: "@kbn/i18n-react" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/i18n-react plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n-react'] --- import kbnI18nReactObj from './kbn_i18n_react.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index 340ed7a3af679..abce71a506637 100644 --- a/api_docs/kbn_import_resolver.mdx +++ b/api_docs/kbn_import_resolver.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-import-resolver title: "@kbn/import-resolver" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/import-resolver plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_infra_forge.mdx b/api_docs/kbn_infra_forge.mdx index cbe4e23b2b357..20c0060b80444 100644 --- a/api_docs/kbn_infra_forge.mdx +++ b/api_docs/kbn_infra_forge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-infra-forge title: "@kbn/infra-forge" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/infra-forge plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/infra-forge'] --- import kbnInfraForgeObj from './kbn_infra_forge.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index f7d159aa49749..769d75499448a 100644 --- a/api_docs/kbn_interpreter.mdx +++ b/api_docs/kbn_interpreter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-interpreter title: "@kbn/interpreter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/interpreter plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/interpreter'] --- import kbnInterpreterObj from './kbn_interpreter.devdocs.json'; diff --git a/api_docs/kbn_io_ts_utils.mdx b/api_docs/kbn_io_ts_utils.mdx index d239853aa37e0..7871742ad90e1 100644 --- a/api_docs/kbn_io_ts_utils.mdx +++ b/api_docs/kbn_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-io-ts-utils title: "@kbn/io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/io-ts-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/io-ts-utils'] --- import kbnIoTsUtilsObj from './kbn_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_jest_serializers.mdx b/api_docs/kbn_jest_serializers.mdx index 6a913026d39e7..5275a27b9dc42 100644 --- a/api_docs/kbn_jest_serializers.mdx +++ b/api_docs/kbn_jest_serializers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-jest-serializers title: "@kbn/jest-serializers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/jest-serializers plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_journeys.mdx b/api_docs/kbn_journeys.mdx index 581914686fa6a..ba7fc5802fd43 100644 --- a/api_docs/kbn_journeys.mdx +++ b/api_docs/kbn_journeys.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-journeys title: "@kbn/journeys" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/journeys plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/journeys'] --- import kbnJourneysObj from './kbn_journeys.devdocs.json'; diff --git a/api_docs/kbn_json_ast.mdx b/api_docs/kbn_json_ast.mdx index 5e115e94d4e54..9d53c0f40410b 100644 --- a/api_docs/kbn_json_ast.mdx +++ b/api_docs/kbn_json_ast.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-json-ast title: "@kbn/json-ast" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/json-ast plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/json-ast'] --- import kbnJsonAstObj from './kbn_json_ast.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index 6c8f1af516b96..c81f36b2dd300 100644 --- a/api_docs/kbn_kibana_manifest_schema.mdx +++ b/api_docs/kbn_kibana_manifest_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-kibana-manifest-schema title: "@kbn/kibana-manifest-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/kibana-manifest-schema plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_language_documentation_popover.mdx b/api_docs/kbn_language_documentation_popover.mdx index 201f7ecec2f4b..d55332c57262e 100644 --- a/api_docs/kbn_language_documentation_popover.mdx +++ b/api_docs/kbn_language_documentation_popover.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-language-documentation-popover title: "@kbn/language-documentation-popover" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/language-documentation-popover plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/language-documentation-popover'] --- import kbnLanguageDocumentationPopoverObj from './kbn_language_documentation_popover.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index 18f2c79df1243..30e81fe7e6dce 100644 --- a/api_docs/kbn_logging.mdx +++ b/api_docs/kbn_logging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging title: "@kbn/logging" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging'] --- import kbnLoggingObj from './kbn_logging.devdocs.json'; diff --git a/api_docs/kbn_logging_mocks.mdx b/api_docs/kbn_logging_mocks.mdx index d8106036dde28..23defe077087c 100644 --- a/api_docs/kbn_logging_mocks.mdx +++ b/api_docs/kbn_logging_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-logging-mocks title: "@kbn/logging-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/logging-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/logging-mocks'] --- import kbnLoggingMocksObj from './kbn_logging_mocks.devdocs.json'; diff --git a/api_docs/kbn_managed_vscode_config.mdx b/api_docs/kbn_managed_vscode_config.mdx index 3564f42cc7ceb..f2c347ff0d8e2 100644 --- a/api_docs/kbn_managed_vscode_config.mdx +++ b/api_docs/kbn_managed_vscode_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-managed-vscode-config title: "@kbn/managed-vscode-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/managed-vscode-config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_management_cards_navigation.mdx b/api_docs/kbn_management_cards_navigation.mdx index c9bf3d0f4d079..7b2f34834dc06 100644 --- a/api_docs/kbn_management_cards_navigation.mdx +++ b/api_docs/kbn_management_cards_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-cards-navigation title: "@kbn/management-cards-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-cards-navigation plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-cards-navigation'] --- import kbnManagementCardsNavigationObj from './kbn_management_cards_navigation.devdocs.json'; diff --git a/api_docs/kbn_management_storybook_config.mdx b/api_docs/kbn_management_storybook_config.mdx index a392d4b164632..e1ee8679a1f9e 100644 --- a/api_docs/kbn_management_storybook_config.mdx +++ b/api_docs/kbn_management_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-management-storybook-config title: "@kbn/management-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/management-storybook-config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/management-storybook-config'] --- import kbnManagementStorybookConfigObj from './kbn_management_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index 51a0017b879cc..fe91a56bfe951 100644 --- a/api_docs/kbn_mapbox_gl.mdx +++ b/api_docs/kbn_mapbox_gl.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-mapbox-gl title: "@kbn/mapbox-gl" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/mapbox-gl plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_maps_vector_tile_utils.mdx b/api_docs/kbn_maps_vector_tile_utils.mdx index d8e4f74d314d8..6c99005c7825a 100644 --- a/api_docs/kbn_maps_vector_tile_utils.mdx +++ b/api_docs/kbn_maps_vector_tile_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-maps-vector-tile-utils title: "@kbn/maps-vector-tile-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/maps-vector-tile-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/maps-vector-tile-utils'] --- import kbnMapsVectorTileUtilsObj from './kbn_maps_vector_tile_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 766cf8e24ee9d..27d6a1535e2cd 100644 --- a/api_docs/kbn_ml_agg_utils.mdx +++ b/api_docs/kbn_ml_agg_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-agg-utils title: "@kbn/ml-agg-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-agg-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-agg-utils'] --- import kbnMlAggUtilsObj from './kbn_ml_agg_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_anomaly_utils.mdx b/api_docs/kbn_ml_anomaly_utils.mdx index e6e979f73900e..e80999e46e2cc 100644 --- a/api_docs/kbn_ml_anomaly_utils.mdx +++ b/api_docs/kbn_ml_anomaly_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-anomaly-utils title: "@kbn/ml-anomaly-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-anomaly-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-anomaly-utils'] --- import kbnMlAnomalyUtilsObj from './kbn_ml_anomaly_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_category_validator.mdx b/api_docs/kbn_ml_category_validator.mdx index 15dfd7a5bbaac..2f32314397b45 100644 --- a/api_docs/kbn_ml_category_validator.mdx +++ b/api_docs/kbn_ml_category_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-category-validator title: "@kbn/ml-category-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-category-validator plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-category-validator'] --- import kbnMlCategoryValidatorObj from './kbn_ml_category_validator.devdocs.json'; diff --git a/api_docs/kbn_ml_data_frame_analytics_utils.mdx b/api_docs/kbn_ml_data_frame_analytics_utils.mdx index 974513d76693e..046a864c1ba4a 100644 --- a/api_docs/kbn_ml_data_frame_analytics_utils.mdx +++ b/api_docs/kbn_ml_data_frame_analytics_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-frame-analytics-utils title: "@kbn/ml-data-frame-analytics-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-frame-analytics-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-frame-analytics-utils'] --- import kbnMlDataFrameAnalyticsUtilsObj from './kbn_ml_data_frame_analytics_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_data_grid.mdx b/api_docs/kbn_ml_data_grid.mdx index 6d456dfd9db4c..55bb1c3e001a9 100644 --- a/api_docs/kbn_ml_data_grid.mdx +++ b/api_docs/kbn_ml_data_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-data-grid title: "@kbn/ml-data-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-data-grid plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-data-grid'] --- import kbnMlDataGridObj from './kbn_ml_data_grid.devdocs.json'; diff --git a/api_docs/kbn_ml_date_picker.mdx b/api_docs/kbn_ml_date_picker.mdx index 0edce417c1a90..194920b61337e 100644 --- a/api_docs/kbn_ml_date_picker.mdx +++ b/api_docs/kbn_ml_date_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-picker title: "@kbn/ml-date-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-picker plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-picker'] --- import kbnMlDatePickerObj from './kbn_ml_date_picker.devdocs.json'; diff --git a/api_docs/kbn_ml_date_utils.mdx b/api_docs/kbn_ml_date_utils.mdx index 9d6a341f4d7d9..2332cec54f230 100644 --- a/api_docs/kbn_ml_date_utils.mdx +++ b/api_docs/kbn_ml_date_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-date-utils title: "@kbn/ml-date-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-date-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-date-utils'] --- import kbnMlDateUtilsObj from './kbn_ml_date_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_error_utils.mdx b/api_docs/kbn_ml_error_utils.mdx index 3a96e95f462a8..b863f9b37db68 100644 --- a/api_docs/kbn_ml_error_utils.mdx +++ b/api_docs/kbn_ml_error_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-error-utils title: "@kbn/ml-error-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-error-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-error-utils'] --- import kbnMlErrorUtilsObj from './kbn_ml_error_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_in_memory_table.mdx b/api_docs/kbn_ml_in_memory_table.mdx index b3a3a491a515e..6807a03355675 100644 --- a/api_docs/kbn_ml_in_memory_table.mdx +++ b/api_docs/kbn_ml_in_memory_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-in-memory-table title: "@kbn/ml-in-memory-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-in-memory-table plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-in-memory-table'] --- import kbnMlInMemoryTableObj from './kbn_ml_in_memory_table.devdocs.json'; diff --git a/api_docs/kbn_ml_is_defined.mdx b/api_docs/kbn_ml_is_defined.mdx index 34331174df4e8..495dd2e996efb 100644 --- a/api_docs/kbn_ml_is_defined.mdx +++ b/api_docs/kbn_ml_is_defined.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-defined title: "@kbn/ml-is-defined" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-defined plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-defined'] --- import kbnMlIsDefinedObj from './kbn_ml_is_defined.devdocs.json'; diff --git a/api_docs/kbn_ml_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index ed6fb448b23ce..ca1444af45137 100644 --- a/api_docs/kbn_ml_is_populated_object.mdx +++ b/api_docs/kbn_ml_is_populated_object.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-is-populated-object title: "@kbn/ml-is-populated-object" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-is-populated-object plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-is-populated-object'] --- import kbnMlIsPopulatedObjectObj from './kbn_ml_is_populated_object.devdocs.json'; diff --git a/api_docs/kbn_ml_kibana_theme.mdx b/api_docs/kbn_ml_kibana_theme.mdx index 5b00f4392a4ca..3b1ab520333fd 100644 --- a/api_docs/kbn_ml_kibana_theme.mdx +++ b/api_docs/kbn_ml_kibana_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-kibana-theme title: "@kbn/ml-kibana-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-kibana-theme plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-kibana-theme'] --- import kbnMlKibanaThemeObj from './kbn_ml_kibana_theme.devdocs.json'; diff --git a/api_docs/kbn_ml_local_storage.mdx b/api_docs/kbn_ml_local_storage.mdx index 4d9033abe84e1..d000fb610f36c 100644 --- a/api_docs/kbn_ml_local_storage.mdx +++ b/api_docs/kbn_ml_local_storage.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-local-storage title: "@kbn/ml-local-storage" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-local-storage plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-local-storage'] --- import kbnMlLocalStorageObj from './kbn_ml_local_storage.devdocs.json'; diff --git a/api_docs/kbn_ml_nested_property.mdx b/api_docs/kbn_ml_nested_property.mdx index 4d3cd6a8baf01..69e93bf55bcb8 100644 --- a/api_docs/kbn_ml_nested_property.mdx +++ b/api_docs/kbn_ml_nested_property.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-nested-property title: "@kbn/ml-nested-property" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-nested-property plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-nested-property'] --- import kbnMlNestedPropertyObj from './kbn_ml_nested_property.devdocs.json'; diff --git a/api_docs/kbn_ml_number_utils.mdx b/api_docs/kbn_ml_number_utils.mdx index 0758d7aae59ea..dc3aa4b33ce9c 100644 --- a/api_docs/kbn_ml_number_utils.mdx +++ b/api_docs/kbn_ml_number_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-number-utils title: "@kbn/ml-number-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-number-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-number-utils'] --- import kbnMlNumberUtilsObj from './kbn_ml_number_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_query_utils.mdx b/api_docs/kbn_ml_query_utils.mdx index ea70201b845ec..70d162bde8b08 100644 --- a/api_docs/kbn_ml_query_utils.mdx +++ b/api_docs/kbn_ml_query_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-query-utils title: "@kbn/ml-query-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-query-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-query-utils'] --- import kbnMlQueryUtilsObj from './kbn_ml_query_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_random_sampler_utils.mdx b/api_docs/kbn_ml_random_sampler_utils.mdx index 5b3219a7bb27c..ffd5f8a5881e1 100644 --- a/api_docs/kbn_ml_random_sampler_utils.mdx +++ b/api_docs/kbn_ml_random_sampler_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-random-sampler-utils title: "@kbn/ml-random-sampler-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-random-sampler-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-random-sampler-utils'] --- import kbnMlRandomSamplerUtilsObj from './kbn_ml_random_sampler_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_route_utils.mdx b/api_docs/kbn_ml_route_utils.mdx index b208d17c598fa..ff84ab0ed20d7 100644 --- a/api_docs/kbn_ml_route_utils.mdx +++ b/api_docs/kbn_ml_route_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-route-utils title: "@kbn/ml-route-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-route-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-route-utils'] --- import kbnMlRouteUtilsObj from './kbn_ml_route_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_runtime_field_utils.mdx b/api_docs/kbn_ml_runtime_field_utils.mdx index 40a18db691876..5086d30b3eb5d 100644 --- a/api_docs/kbn_ml_runtime_field_utils.mdx +++ b/api_docs/kbn_ml_runtime_field_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-runtime-field-utils title: "@kbn/ml-runtime-field-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-runtime-field-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-runtime-field-utils'] --- import kbnMlRuntimeFieldUtilsObj from './kbn_ml_runtime_field_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index e1cfba46fd3ca..42c0c41ca1e7f 100644 --- a/api_docs/kbn_ml_string_hash.mdx +++ b/api_docs/kbn_ml_string_hash.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-string-hash title: "@kbn/ml-string-hash" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-string-hash plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_ml_trained_models_utils.mdx b/api_docs/kbn_ml_trained_models_utils.mdx index 56c5439790a85..41c37b3de7060 100644 --- a/api_docs/kbn_ml_trained_models_utils.mdx +++ b/api_docs/kbn_ml_trained_models_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-trained-models-utils title: "@kbn/ml-trained-models-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-trained-models-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-trained-models-utils'] --- import kbnMlTrainedModelsUtilsObj from './kbn_ml_trained_models_utils.devdocs.json'; diff --git a/api_docs/kbn_ml_url_state.mdx b/api_docs/kbn_ml_url_state.mdx index b4fdb401c1a2f..358eadfb73659 100644 --- a/api_docs/kbn_ml_url_state.mdx +++ b/api_docs/kbn_ml_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ml-url-state title: "@kbn/ml-url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ml-url-state plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-url-state'] --- import kbnMlUrlStateObj from './kbn_ml_url_state.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 80ca6309027ca..64b83da073a33 100644 --- a/api_docs/kbn_monaco.mdx +++ b/api_docs/kbn_monaco.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-monaco title: "@kbn/monaco" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/monaco plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_object_versioning.mdx b/api_docs/kbn_object_versioning.mdx index 36b12fe47b312..4d20d05ca243f 100644 --- a/api_docs/kbn_object_versioning.mdx +++ b/api_docs/kbn_object_versioning.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-object-versioning title: "@kbn/object-versioning" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/object-versioning plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/object-versioning'] --- import kbnObjectVersioningObj from './kbn_object_versioning.devdocs.json'; diff --git a/api_docs/kbn_observability_alert_details.mdx b/api_docs/kbn_observability_alert_details.mdx index 9e1794909e35d..894950a4c61ef 100644 --- a/api_docs/kbn_observability_alert_details.mdx +++ b/api_docs/kbn_observability_alert_details.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-observability-alert-details title: "@kbn/observability-alert-details" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/observability-alert-details plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/observability-alert-details'] --- import kbnObservabilityAlertDetailsObj from './kbn_observability_alert_details.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 23c55cac99c58..6791b1d97fe5a 100644 --- a/api_docs/kbn_optimizer.mdx +++ b/api_docs/kbn_optimizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer title: "@kbn/optimizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer'] --- import kbnOptimizerObj from './kbn_optimizer.devdocs.json'; diff --git a/api_docs/kbn_optimizer_webpack_helpers.mdx b/api_docs/kbn_optimizer_webpack_helpers.mdx index b0116b1a5c736..85bf9046af977 100644 --- a/api_docs/kbn_optimizer_webpack_helpers.mdx +++ b/api_docs/kbn_optimizer_webpack_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-optimizer-webpack-helpers title: "@kbn/optimizer-webpack-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/optimizer-webpack-helpers plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_osquery_io_ts_types.mdx b/api_docs/kbn_osquery_io_ts_types.mdx index 871f75ffdc0fd..bda4fcd016615 100644 --- a/api_docs/kbn_osquery_io_ts_types.mdx +++ b/api_docs/kbn_osquery_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-osquery-io-ts-types title: "@kbn/osquery-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/osquery-io-ts-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/osquery-io-ts-types'] --- import kbnOsqueryIoTsTypesObj from './kbn_osquery_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 1e96944c6ef96..051f8d90787bf 100644 --- a/api_docs/kbn_performance_testing_dataset_extractor.mdx +++ b/api_docs/kbn_performance_testing_dataset_extractor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-performance-testing-dataset-extractor title: "@kbn/performance-testing-dataset-extractor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/performance-testing-dataset-extractor plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/performance-testing-dataset-extractor'] --- import kbnPerformanceTestingDatasetExtractorObj from './kbn_performance_testing_dataset_extractor.devdocs.json'; diff --git a/api_docs/kbn_plugin_generator.mdx b/api_docs/kbn_plugin_generator.mdx index e0b4853f59623..9efe6b300e30b 100644 --- a/api_docs/kbn_plugin_generator.mdx +++ b/api_docs/kbn_plugin_generator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-generator title: "@kbn/plugin-generator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-generator plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-generator'] --- import kbnPluginGeneratorObj from './kbn_plugin_generator.devdocs.json'; diff --git a/api_docs/kbn_plugin_helpers.mdx b/api_docs/kbn_plugin_helpers.mdx index 13005ee9745a5..431a8af99adf6 100644 --- a/api_docs/kbn_plugin_helpers.mdx +++ b/api_docs/kbn_plugin_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-plugin-helpers title: "@kbn/plugin-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/plugin-helpers plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_random_sampling.mdx b/api_docs/kbn_random_sampling.mdx index b8f46f3dfc4a4..289486f09d428 100644 --- a/api_docs/kbn_random_sampling.mdx +++ b/api_docs/kbn_random_sampling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-random-sampling title: "@kbn/random-sampling" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/random-sampling plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/random-sampling'] --- import kbnRandomSamplingObj from './kbn_random_sampling.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index a1467afabd52e..da5d240964584 100644 --- a/api_docs/kbn_react_field.mdx +++ b/api_docs/kbn_react_field.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-field title: "@kbn/react-field" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-field plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_common.mdx b/api_docs/kbn_react_kibana_context_common.mdx index fd95e0f6231b0..b23eb4928089b 100644 --- a/api_docs/kbn_react_kibana_context_common.mdx +++ b/api_docs/kbn_react_kibana_context_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-common title: "@kbn/react-kibana-context-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-common'] --- import kbnReactKibanaContextCommonObj from './kbn_react_kibana_context_common.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_render.mdx b/api_docs/kbn_react_kibana_context_render.mdx index 06a001afc507d..1af5802080806 100644 --- a/api_docs/kbn_react_kibana_context_render.mdx +++ b/api_docs/kbn_react_kibana_context_render.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-render title: "@kbn/react-kibana-context-render" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-render plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-render'] --- import kbnReactKibanaContextRenderObj from './kbn_react_kibana_context_render.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_root.mdx b/api_docs/kbn_react_kibana_context_root.mdx index fe45dc254f411..ac75bb3bdb311 100644 --- a/api_docs/kbn_react_kibana_context_root.mdx +++ b/api_docs/kbn_react_kibana_context_root.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-root title: "@kbn/react-kibana-context-root" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-root plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-root'] --- import kbnReactKibanaContextRootObj from './kbn_react_kibana_context_root.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_styled.mdx b/api_docs/kbn_react_kibana_context_styled.mdx index 87360938fc309..957713bb1a751 100644 --- a/api_docs/kbn_react_kibana_context_styled.mdx +++ b/api_docs/kbn_react_kibana_context_styled.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-styled title: "@kbn/react-kibana-context-styled" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-styled plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-styled'] --- import kbnReactKibanaContextStyledObj from './kbn_react_kibana_context_styled.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_context_theme.mdx b/api_docs/kbn_react_kibana_context_theme.mdx index bf618223267cd..e2aa061cb4bea 100644 --- a/api_docs/kbn_react_kibana_context_theme.mdx +++ b/api_docs/kbn_react_kibana_context_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-context-theme title: "@kbn/react-kibana-context-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-context-theme plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-context-theme'] --- import kbnReactKibanaContextThemeObj from './kbn_react_kibana_context_theme.devdocs.json'; diff --git a/api_docs/kbn_react_kibana_mount.mdx b/api_docs/kbn_react_kibana_mount.mdx index afdb439e1c515..c7d6c27548c55 100644 --- a/api_docs/kbn_react_kibana_mount.mdx +++ b/api_docs/kbn_react_kibana_mount.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-react-kibana-mount title: "@kbn/react-kibana-mount" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/react-kibana-mount plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-kibana-mount'] --- import kbnReactKibanaMountObj from './kbn_react_kibana_mount.devdocs.json'; diff --git a/api_docs/kbn_repo_file_maps.mdx b/api_docs/kbn_repo_file_maps.mdx index fac4ebcd8aef5..b9c9725d04ee6 100644 --- a/api_docs/kbn_repo_file_maps.mdx +++ b/api_docs/kbn_repo_file_maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-file-maps title: "@kbn/repo-file-maps" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-file-maps plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-file-maps'] --- import kbnRepoFileMapsObj from './kbn_repo_file_maps.devdocs.json'; diff --git a/api_docs/kbn_repo_linter.mdx b/api_docs/kbn_repo_linter.mdx index 4e42cdf7de723..7392e055177b3 100644 --- a/api_docs/kbn_repo_linter.mdx +++ b/api_docs/kbn_repo_linter.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-linter title: "@kbn/repo-linter" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-linter plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-linter'] --- import kbnRepoLinterObj from './kbn_repo_linter.devdocs.json'; diff --git a/api_docs/kbn_repo_path.mdx b/api_docs/kbn_repo_path.mdx index f59c4e8d269f1..62955e96811da 100644 --- a/api_docs/kbn_repo_path.mdx +++ b/api_docs/kbn_repo_path.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-path title: "@kbn/repo-path" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-path plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-path'] --- import kbnRepoPathObj from './kbn_repo_path.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 0e6236e399cf5..d7bab19e316ed 100644 --- a/api_docs/kbn_repo_source_classifier.mdx +++ b/api_docs/kbn_repo_source_classifier.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-repo-source-classifier title: "@kbn/repo-source-classifier" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/repo-source-classifier plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_reporting_common.mdx b/api_docs/kbn_reporting_common.mdx index 0f99c3f3dc30b..f2dcf6582a1a4 100644 --- a/api_docs/kbn_reporting_common.mdx +++ b/api_docs/kbn_reporting_common.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-reporting-common title: "@kbn/reporting-common" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/reporting-common plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/reporting-common'] --- import kbnReportingCommonObj from './kbn_reporting_common.devdocs.json'; diff --git a/api_docs/kbn_rison.mdx b/api_docs/kbn_rison.mdx index eae98a59ec229..d39dc1c0385ae 100644 --- a/api_docs/kbn_rison.mdx +++ b/api_docs/kbn_rison.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rison title: "@kbn/rison" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rison plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rison'] --- import kbnRisonObj from './kbn_rison.devdocs.json'; diff --git a/api_docs/kbn_rrule.mdx b/api_docs/kbn_rrule.mdx index 6614eb3aeb3e4..aa118bc496e35 100644 --- a/api_docs/kbn_rrule.mdx +++ b/api_docs/kbn_rrule.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rrule title: "@kbn/rrule" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rrule plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rrule'] --- import kbnRruleObj from './kbn_rrule.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index add74e6ad8ffd..92409aa81aa38 100644 --- a/api_docs/kbn_rule_data_utils.mdx +++ b/api_docs/kbn_rule_data_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-rule-data-utils title: "@kbn/rule-data-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/rule-data-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_saved_objects_settings.mdx b/api_docs/kbn_saved_objects_settings.mdx index cf64471ca27b5..bb0bc3382f502 100644 --- a/api_docs/kbn_saved_objects_settings.mdx +++ b/api_docs/kbn_saved_objects_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-saved-objects-settings title: "@kbn/saved-objects-settings" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/saved-objects-settings plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/saved-objects-settings'] --- import kbnSavedObjectsSettingsObj from './kbn_saved_objects_settings.devdocs.json'; diff --git a/api_docs/kbn_security_solution_navigation.mdx b/api_docs/kbn_security_solution_navigation.mdx index b184fc09deaf3..815a1197552d0 100644 --- a/api_docs/kbn_security_solution_navigation.mdx +++ b/api_docs/kbn_security_solution_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-navigation title: "@kbn/security-solution-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-navigation plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-navigation'] --- import kbnSecuritySolutionNavigationObj from './kbn_security_solution_navigation.devdocs.json'; diff --git a/api_docs/kbn_security_solution_side_nav.mdx b/api_docs/kbn_security_solution_side_nav.mdx index 0e6f40f82b35c..0a74cefaf140a 100644 --- a/api_docs/kbn_security_solution_side_nav.mdx +++ b/api_docs/kbn_security_solution_side_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-side-nav title: "@kbn/security-solution-side-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-side-nav plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-side-nav'] --- import kbnSecuritySolutionSideNavObj from './kbn_security_solution_side_nav.devdocs.json'; diff --git a/api_docs/kbn_security_solution_storybook_config.mdx b/api_docs/kbn_security_solution_storybook_config.mdx index 1f08090c34a60..ae4497a82d076 100644 --- a/api_docs/kbn_security_solution_storybook_config.mdx +++ b/api_docs/kbn_security_solution_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-security-solution-storybook-config title: "@kbn/security-solution-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/security-solution-storybook-config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/security-solution-storybook-config'] --- import kbnSecuritySolutionStorybookConfigObj from './kbn_security_solution_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index cf04e13ec9d9e..8726c38268640 100644 --- a/api_docs/kbn_securitysolution_autocomplete.mdx +++ b/api_docs/kbn_securitysolution_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-autocomplete title: "@kbn/securitysolution-autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-autocomplete plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_data_table.mdx b/api_docs/kbn_securitysolution_data_table.mdx index 5a4334e58d1c6..235ece6579de9 100644 --- a/api_docs/kbn_securitysolution_data_table.mdx +++ b/api_docs/kbn_securitysolution_data_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-data-table title: "@kbn/securitysolution-data-table" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-data-table plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-data-table'] --- import kbnSecuritysolutionDataTableObj from './kbn_securitysolution_data_table.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_ecs.mdx b/api_docs/kbn_securitysolution_ecs.mdx index 4650d5675a9cf..5589b2f530f97 100644 --- a/api_docs/kbn_securitysolution_ecs.mdx +++ b/api_docs/kbn_securitysolution_ecs.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-ecs title: "@kbn/securitysolution-ecs" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-ecs plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-ecs'] --- import kbnSecuritysolutionEcsObj from './kbn_securitysolution_ecs.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index 6c512079be686..c629a70eaeae3 100644 --- a/api_docs/kbn_securitysolution_es_utils.mdx +++ b/api_docs/kbn_securitysolution_es_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-es-utils title: "@kbn/securitysolution-es-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-es-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-es-utils'] --- import kbnSecuritysolutionEsUtilsObj from './kbn_securitysolution_es_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_exception_list_components.mdx b/api_docs/kbn_securitysolution_exception_list_components.mdx index 77e87464c2cd9..8784dae4ef7d8 100644 --- a/api_docs/kbn_securitysolution_exception_list_components.mdx +++ b/api_docs/kbn_securitysolution_exception_list_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-exception-list-components title: "@kbn/securitysolution-exception-list-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-exception-list-components plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-exception-list-components'] --- import kbnSecuritysolutionExceptionListComponentsObj from './kbn_securitysolution_exception_list_components.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_grouping.mdx b/api_docs/kbn_securitysolution_grouping.mdx index 57eed7ab46500..1435f7d61f57f 100644 --- a/api_docs/kbn_securitysolution_grouping.mdx +++ b/api_docs/kbn_securitysolution_grouping.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-grouping title: "@kbn/securitysolution-grouping" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-grouping plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-grouping'] --- import kbnSecuritysolutionGroupingObj from './kbn_securitysolution_grouping.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index f669d16c8e67c..32ca05053289c 100644 --- a/api_docs/kbn_securitysolution_hook_utils.mdx +++ b/api_docs/kbn_securitysolution_hook_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-hook-utils title: "@kbn/securitysolution-hook-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-hook-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-hook-utils'] --- import kbnSecuritysolutionHookUtilsObj from './kbn_securitysolution_hook_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx index 3f078461c87d5..22a450072fd3e 100644 --- a/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_alerting_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-alerting-types title: "@kbn/securitysolution-io-ts-alerting-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-alerting-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-alerting-types'] --- import kbnSecuritysolutionIoTsAlertingTypesObj from './kbn_securitysolution_io_ts_alerting_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_list_types.mdx b/api_docs/kbn_securitysolution_io_ts_list_types.mdx index f59600e077dfa..ebab6071e8d81 100644 --- a/api_docs/kbn_securitysolution_io_ts_list_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_list_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-list-types title: "@kbn/securitysolution-io-ts-list-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-list-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-list-types'] --- import kbnSecuritysolutionIoTsListTypesObj from './kbn_securitysolution_io_ts_list_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_types.mdx b/api_docs/kbn_securitysolution_io_ts_types.mdx index dcef4f6118565..87a6fd81b10ea 100644 --- a/api_docs/kbn_securitysolution_io_ts_types.mdx +++ b/api_docs/kbn_securitysolution_io_ts_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-types title: "@kbn/securitysolution-io-ts-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-types'] --- import kbnSecuritysolutionIoTsTypesObj from './kbn_securitysolution_io_ts_types.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_io_ts_utils.mdx b/api_docs/kbn_securitysolution_io_ts_utils.mdx index 52ce14978e053..e87c29be26fe1 100644 --- a/api_docs/kbn_securitysolution_io_ts_utils.mdx +++ b/api_docs/kbn_securitysolution_io_ts_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-io-ts-utils title: "@kbn/securitysolution-io-ts-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-io-ts-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-io-ts-utils'] --- import kbnSecuritysolutionIoTsUtilsObj from './kbn_securitysolution_io_ts_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_api.mdx b/api_docs/kbn_securitysolution_list_api.mdx index b79ba7905c55d..8d9f9842dc69f 100644 --- a/api_docs/kbn_securitysolution_list_api.mdx +++ b/api_docs/kbn_securitysolution_list_api.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-api title: "@kbn/securitysolution-list-api" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-api plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-api'] --- import kbnSecuritysolutionListApiObj from './kbn_securitysolution_list_api.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_constants.mdx b/api_docs/kbn_securitysolution_list_constants.mdx index bfa472a7df907..df6f0c1128ce5 100644 --- a/api_docs/kbn_securitysolution_list_constants.mdx +++ b/api_docs/kbn_securitysolution_list_constants.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-constants title: "@kbn/securitysolution-list-constants" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-constants plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-constants'] --- import kbnSecuritysolutionListConstantsObj from './kbn_securitysolution_list_constants.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_hooks.mdx b/api_docs/kbn_securitysolution_list_hooks.mdx index 9ffafc743f5ad..c9430b91c1899 100644 --- a/api_docs/kbn_securitysolution_list_hooks.mdx +++ b/api_docs/kbn_securitysolution_list_hooks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-hooks title: "@kbn/securitysolution-list-hooks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-hooks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-hooks'] --- import kbnSecuritysolutionListHooksObj from './kbn_securitysolution_list_hooks.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_list_utils.mdx b/api_docs/kbn_securitysolution_list_utils.mdx index 36d554892ee95..7f4b2d4750f03 100644 --- a/api_docs/kbn_securitysolution_list_utils.mdx +++ b/api_docs/kbn_securitysolution_list_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-list-utils title: "@kbn/securitysolution-list-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-list-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-list-utils'] --- import kbnSecuritysolutionListUtilsObj from './kbn_securitysolution_list_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_rules.mdx b/api_docs/kbn_securitysolution_rules.mdx index 45b6f59b77f3d..650998ba6f321 100644 --- a/api_docs/kbn_securitysolution_rules.mdx +++ b/api_docs/kbn_securitysolution_rules.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-rules title: "@kbn/securitysolution-rules" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-rules plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-rules'] --- import kbnSecuritysolutionRulesObj from './kbn_securitysolution_rules.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_t_grid.mdx b/api_docs/kbn_securitysolution_t_grid.mdx index eb45087ea98c7..6108a52fc0879 100644 --- a/api_docs/kbn_securitysolution_t_grid.mdx +++ b/api_docs/kbn_securitysolution_t_grid.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-t-grid title: "@kbn/securitysolution-t-grid" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-t-grid plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-t-grid'] --- import kbnSecuritysolutionTGridObj from './kbn_securitysolution_t_grid.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_utils.mdx b/api_docs/kbn_securitysolution_utils.mdx index e065731c99666..047a13ff0e0fd 100644 --- a/api_docs/kbn_securitysolution_utils.mdx +++ b/api_docs/kbn_securitysolution_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-securitysolution-utils title: "@kbn/securitysolution-utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/securitysolution-utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-utils'] --- import kbnSecuritysolutionUtilsObj from './kbn_securitysolution_utils.devdocs.json'; diff --git a/api_docs/kbn_server_http_tools.mdx b/api_docs/kbn_server_http_tools.mdx index 2fc6695cfc05d..88150273d7da5 100644 --- a/api_docs/kbn_server_http_tools.mdx +++ b/api_docs/kbn_server_http_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-http-tools title: "@kbn/server-http-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-http-tools plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-http-tools'] --- import kbnServerHttpToolsObj from './kbn_server_http_tools.devdocs.json'; diff --git a/api_docs/kbn_server_route_repository.mdx b/api_docs/kbn_server_route_repository.mdx index e21f1d3e76cf0..f6196c49f2940 100644 --- a/api_docs/kbn_server_route_repository.mdx +++ b/api_docs/kbn_server_route_repository.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-server-route-repository title: "@kbn/server-route-repository" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/server-route-repository plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_serverless_project_switcher.mdx b/api_docs/kbn_serverless_project_switcher.mdx index 229aea7549e26..6f280358cec5c 100644 --- a/api_docs/kbn_serverless_project_switcher.mdx +++ b/api_docs/kbn_serverless_project_switcher.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-project-switcher title: "@kbn/serverless-project-switcher" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-project-switcher plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-project-switcher'] --- import kbnServerlessProjectSwitcherObj from './kbn_serverless_project_switcher.devdocs.json'; diff --git a/api_docs/kbn_serverless_storybook_config.mdx b/api_docs/kbn_serverless_storybook_config.mdx index ad2f534d55cdd..9a18e91b6ff78 100644 --- a/api_docs/kbn_serverless_storybook_config.mdx +++ b/api_docs/kbn_serverless_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-serverless-storybook-config title: "@kbn/serverless-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/serverless-storybook-config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/serverless-storybook-config'] --- import kbnServerlessStorybookConfigObj from './kbn_serverless_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 8b101d8ad4aad..f5a753bc3aaab 100644 --- a/api_docs/kbn_shared_svg.mdx +++ b/api_docs/kbn_shared_svg.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-svg title: "@kbn/shared-svg" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-svg plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-svg'] --- import kbnSharedSvgObj from './kbn_shared_svg.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_solution.mdx b/api_docs/kbn_shared_ux_avatar_solution.mdx index 903f41df69c99..41d395bf7e246 100644 --- a/api_docs/kbn_shared_ux_avatar_solution.mdx +++ b/api_docs/kbn_shared_ux_avatar_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-solution title: "@kbn/shared-ux-avatar-solution" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-solution plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-solution'] --- import kbnSharedUxAvatarSolutionObj from './kbn_shared_ux_avatar_solution.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index bd98cfe8f14bb..4beb3231db452 100644 --- a/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx +++ b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-avatar-user-profile-components title: "@kbn/shared-ux-avatar-user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-avatar-user-profile-components plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-avatar-user-profile-components'] --- import kbnSharedUxAvatarUserProfileComponentsObj from './kbn_shared_ux_avatar_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx index 78bfbb9705fc7..919291ee2d24d 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen title: "@kbn/shared-ux-button-exit-full-screen" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen'] --- import kbnSharedUxButtonExitFullScreenObj from './kbn_shared_ux_button_exit_full_screen.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index c8aa8eb3adf26..31f67a7732224 100644 --- a/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx +++ b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-exit-full-screen-mocks title: "@kbn/shared-ux-button-exit-full-screen-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-exit-full-screen-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-exit-full-screen-mocks'] --- import kbnSharedUxButtonExitFullScreenMocksObj from './kbn_shared_ux_button_exit_full_screen_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_button_toolbar.mdx b/api_docs/kbn_shared_ux_button_toolbar.mdx index f98bae6cf376e..c7be5ae0d8d23 100644 --- a/api_docs/kbn_shared_ux_button_toolbar.mdx +++ b/api_docs/kbn_shared_ux_button_toolbar.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-button-toolbar title: "@kbn/shared-ux-button-toolbar" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-button-toolbar plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-button-toolbar'] --- import kbnSharedUxButtonToolbarObj from './kbn_shared_ux_button_toolbar.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data.mdx b/api_docs/kbn_shared_ux_card_no_data.mdx index 80e6c1c490473..4923afb2f3563 100644 --- a/api_docs/kbn_shared_ux_card_no_data.mdx +++ b/api_docs/kbn_shared_ux_card_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data title: "@kbn/shared-ux-card-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data'] --- import kbnSharedUxCardNoDataObj from './kbn_shared_ux_card_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx index 782a8a2023fd9..759df6f700995 100644 --- a/api_docs/kbn_shared_ux_card_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_card_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-card-no-data-mocks title: "@kbn/shared-ux-card-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-card-no-data-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-card-no-data-mocks'] --- import kbnSharedUxCardNoDataMocksObj from './kbn_shared_ux_card_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_chrome_navigation.mdx b/api_docs/kbn_shared_ux_chrome_navigation.mdx index 81641dcca4d25..8623b7e4f4d27 100644 --- a/api_docs/kbn_shared_ux_chrome_navigation.mdx +++ b/api_docs/kbn_shared_ux_chrome_navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-chrome-navigation title: "@kbn/shared-ux-chrome-navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-chrome-navigation plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-chrome-navigation'] --- import kbnSharedUxChromeNavigationObj from './kbn_shared_ux_chrome_navigation.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_context.mdx b/api_docs/kbn_shared_ux_file_context.mdx index dde1eb26cd967..079cd7d6a5dcb 100644 --- a/api_docs/kbn_shared_ux_file_context.mdx +++ b/api_docs/kbn_shared_ux_file_context.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-context title: "@kbn/shared-ux-file-context" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-context plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-context'] --- import kbnSharedUxFileContextObj from './kbn_shared_ux_file_context.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image.mdx b/api_docs/kbn_shared_ux_file_image.mdx index 3f8ff9a49788b..811357a139728 100644 --- a/api_docs/kbn_shared_ux_file_image.mdx +++ b/api_docs/kbn_shared_ux_file_image.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image title: "@kbn/shared-ux-file-image" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image'] --- import kbnSharedUxFileImageObj from './kbn_shared_ux_file_image.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_image_mocks.mdx b/api_docs/kbn_shared_ux_file_image_mocks.mdx index bc9bf2aeda1e1..47814b8c7eb51 100644 --- a/api_docs/kbn_shared_ux_file_image_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_image_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-image-mocks title: "@kbn/shared-ux-file-image-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-image-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-image-mocks'] --- import kbnSharedUxFileImageMocksObj from './kbn_shared_ux_file_image_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_mocks.mdx b/api_docs/kbn_shared_ux_file_mocks.mdx index 1dddded90d51c..91388199fbe63 100644 --- a/api_docs/kbn_shared_ux_file_mocks.mdx +++ b/api_docs/kbn_shared_ux_file_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-mocks title: "@kbn/shared-ux-file-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-mocks'] --- import kbnSharedUxFileMocksObj from './kbn_shared_ux_file_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_picker.mdx b/api_docs/kbn_shared_ux_file_picker.mdx index 4ca1fb06acae2..edddbc6f20c0b 100644 --- a/api_docs/kbn_shared_ux_file_picker.mdx +++ b/api_docs/kbn_shared_ux_file_picker.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-picker title: "@kbn/shared-ux-file-picker" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-picker plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-picker'] --- import kbnSharedUxFilePickerObj from './kbn_shared_ux_file_picker.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_types.mdx b/api_docs/kbn_shared_ux_file_types.mdx index 00dc008303b61..4cc3a68c3d1db 100644 --- a/api_docs/kbn_shared_ux_file_types.mdx +++ b/api_docs/kbn_shared_ux_file_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-types title: "@kbn/shared-ux-file-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-types'] --- import kbnSharedUxFileTypesObj from './kbn_shared_ux_file_types.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_upload.mdx b/api_docs/kbn_shared_ux_file_upload.mdx index 567c0e80ad420..b521456e62f20 100644 --- a/api_docs/kbn_shared_ux_file_upload.mdx +++ b/api_docs/kbn_shared_ux_file_upload.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-upload title: "@kbn/shared-ux-file-upload" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-upload plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-upload'] --- import kbnSharedUxFileUploadObj from './kbn_shared_ux_file_upload.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_file_util.mdx b/api_docs/kbn_shared_ux_file_util.mdx index 0ba8a9aec5781..e9b286aa5109f 100644 --- a/api_docs/kbn_shared_ux_file_util.mdx +++ b/api_docs/kbn_shared_ux_file_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-file-util title: "@kbn/shared-ux-file-util" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-file-util plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-file-util'] --- import kbnSharedUxFileUtilObj from './kbn_shared_ux_file_util.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app.mdx b/api_docs/kbn_shared_ux_link_redirect_app.mdx index e336fb85900fd..6451b59819e84 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app title: "@kbn/shared-ux-link-redirect-app" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app'] --- import kbnSharedUxLinkRedirectAppObj from './kbn_shared_ux_link_redirect_app.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index 35316fad9e57b..e7b3f47baf8e7 100644 --- a/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx +++ b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-link-redirect-app-mocks title: "@kbn/shared-ux-link-redirect-app-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-link-redirect-app-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-link-redirect-app-mocks'] --- import kbnSharedUxLinkRedirectAppMocksObj from './kbn_shared_ux_link_redirect_app_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown.mdx b/api_docs/kbn_shared_ux_markdown.mdx index 8b32bbf5c7312..21e9e7cf31995 100644 --- a/api_docs/kbn_shared_ux_markdown.mdx +++ b/api_docs/kbn_shared_ux_markdown.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown title: "@kbn/shared-ux-markdown" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown'] --- import kbnSharedUxMarkdownObj from './kbn_shared_ux_markdown.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_markdown_mocks.mdx b/api_docs/kbn_shared_ux_markdown_mocks.mdx index c4543b05decf2..71229302d7c5b 100644 --- a/api_docs/kbn_shared_ux_markdown_mocks.mdx +++ b/api_docs/kbn_shared_ux_markdown_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-markdown-mocks title: "@kbn/shared-ux-markdown-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-markdown-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-markdown-mocks'] --- import kbnSharedUxMarkdownMocksObj from './kbn_shared_ux_markdown_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 4f14153bf4828..90f4bd8dcad84 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data title: "@kbn/shared-ux-page-analytics-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data'] --- import kbnSharedUxPageAnalyticsNoDataObj from './kbn_shared_ux_page_analytics_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx index dbbca22ec3a28..6bb75d60c122f 100644 --- a/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_analytics_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-analytics-no-data-mocks title: "@kbn/shared-ux-page-analytics-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-analytics-no-data-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-analytics-no-data-mocks'] --- import kbnSharedUxPageAnalyticsNoDataMocksObj from './kbn_shared_ux_page_analytics_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx index 7dd432d5343a7..5578bc12670a5 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data title: "@kbn/shared-ux-page-kibana-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data'] --- import kbnSharedUxPageKibanaNoDataObj from './kbn_shared_ux_page_kibana_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx index 8c6ce2f61b880..7a25309d4728d 100644 --- a/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-no-data-mocks title: "@kbn/shared-ux-page-kibana-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-no-data-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-no-data-mocks'] --- import kbnSharedUxPageKibanaNoDataMocksObj from './kbn_shared_ux_page_kibana_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template.mdx b/api_docs/kbn_shared_ux_page_kibana_template.mdx index 24811cc9f26ae..561b6e180acac 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template title: "@kbn/shared-ux-page-kibana-template" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template'] --- import kbnSharedUxPageKibanaTemplateObj from './kbn_shared_ux_page_kibana_template.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx index f38ada3c0e4fc..6b8591b832ca7 100644 --- a/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_kibana_template_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-kibana-template-mocks title: "@kbn/shared-ux-page-kibana-template-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-kibana-template-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-kibana-template-mocks'] --- import kbnSharedUxPageKibanaTemplateMocksObj from './kbn_shared_ux_page_kibana_template_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data.mdx b/api_docs/kbn_shared_ux_page_no_data.mdx index de56bc48a2e11..77ff7acea5927 100644 --- a/api_docs/kbn_shared_ux_page_no_data.mdx +++ b/api_docs/kbn_shared_ux_page_no_data.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data title: "@kbn/shared-ux-page-no-data" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data'] --- import kbnSharedUxPageNoDataObj from './kbn_shared_ux_page_no_data.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config.mdx b/api_docs/kbn_shared_ux_page_no_data_config.mdx index 21358f9f07f90..a84303e13216c 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config title: "@kbn/shared-ux-page-no-data-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config'] --- import kbnSharedUxPageNoDataConfigObj from './kbn_shared_ux_page_no_data_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx index dfb502ee183dc..0ea4839401c00 100644 --- a/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_config_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-config-mocks title: "@kbn/shared-ux-page-no-data-config-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-config-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-config-mocks'] --- import kbnSharedUxPageNoDataConfigMocksObj from './kbn_shared_ux_page_no_data_config_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx index 1660a14287710..46a518352d9a9 100644 --- a/api_docs/kbn_shared_ux_page_no_data_mocks.mdx +++ b/api_docs/kbn_shared_ux_page_no_data_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-no-data-mocks title: "@kbn/shared-ux-page-no-data-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-no-data-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-no-data-mocks'] --- import kbnSharedUxPageNoDataMocksObj from './kbn_shared_ux_page_no_data_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_page_solution_nav.mdx b/api_docs/kbn_shared_ux_page_solution_nav.mdx index 75d71b22ef19e..c3b6c74213720 100644 --- a/api_docs/kbn_shared_ux_page_solution_nav.mdx +++ b/api_docs/kbn_shared_ux_page_solution_nav.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-page-solution-nav title: "@kbn/shared-ux-page-solution-nav" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-page-solution-nav plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-page-solution-nav'] --- import kbnSharedUxPageSolutionNavObj from './kbn_shared_ux_page_solution_nav.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx index 097c468a01852..e3edf8a67b8ea 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views title: "@kbn/shared-ux-prompt-no-data-views" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views'] --- import kbnSharedUxPromptNoDataViewsObj from './kbn_shared_ux_prompt_no_data_views.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx index 3464b83dfc1d4..42af8a9811ca5 100644 --- a/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx +++ b/api_docs/kbn_shared_ux_prompt_no_data_views_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-no-data-views-mocks title: "@kbn/shared-ux-prompt-no-data-views-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-no-data-views-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-no-data-views-mocks'] --- import kbnSharedUxPromptNoDataViewsMocksObj from './kbn_shared_ux_prompt_no_data_views_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_prompt_not_found.mdx b/api_docs/kbn_shared_ux_prompt_not_found.mdx index 6c23cc7c90c73..d5707fbb5792e 100644 --- a/api_docs/kbn_shared_ux_prompt_not_found.mdx +++ b/api_docs/kbn_shared_ux_prompt_not_found.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-prompt-not-found title: "@kbn/shared-ux-prompt-not-found" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-prompt-not-found plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-prompt-not-found'] --- import kbnSharedUxPromptNotFoundObj from './kbn_shared_ux_prompt_not_found.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router.mdx b/api_docs/kbn_shared_ux_router.mdx index d7eb0346b128b..65d2a81e0e5b3 100644 --- a/api_docs/kbn_shared_ux_router.mdx +++ b/api_docs/kbn_shared_ux_router.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router title: "@kbn/shared-ux-router" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router'] --- import kbnSharedUxRouterObj from './kbn_shared_ux_router.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_router_mocks.mdx b/api_docs/kbn_shared_ux_router_mocks.mdx index e12847aaf0b93..5964795eb49d4 100644 --- a/api_docs/kbn_shared_ux_router_mocks.mdx +++ b/api_docs/kbn_shared_ux_router_mocks.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-router-mocks title: "@kbn/shared-ux-router-mocks" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-router-mocks plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-router-mocks'] --- import kbnSharedUxRouterMocksObj from './kbn_shared_ux_router_mocks.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_config.mdx b/api_docs/kbn_shared_ux_storybook_config.mdx index c85af4a789cb2..74cbfba121c9c 100644 --- a/api_docs/kbn_shared_ux_storybook_config.mdx +++ b/api_docs/kbn_shared_ux_storybook_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-config title: "@kbn/shared-ux-storybook-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-config'] --- import kbnSharedUxStorybookConfigObj from './kbn_shared_ux_storybook_config.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_storybook_mock.mdx b/api_docs/kbn_shared_ux_storybook_mock.mdx index 5734996e01ddf..8d6ff71719424 100644 --- a/api_docs/kbn_shared_ux_storybook_mock.mdx +++ b/api_docs/kbn_shared_ux_storybook_mock.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-storybook-mock title: "@kbn/shared-ux-storybook-mock" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-storybook-mock plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-storybook-mock'] --- import kbnSharedUxStorybookMockObj from './kbn_shared_ux_storybook_mock.devdocs.json'; diff --git a/api_docs/kbn_shared_ux_utility.mdx b/api_docs/kbn_shared_ux_utility.mdx index d97efc0d809ff..ef0fe567eb189 100644 --- a/api_docs/kbn_shared_ux_utility.mdx +++ b/api_docs/kbn_shared_ux_utility.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-shared-ux-utility title: "@kbn/shared-ux-utility" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/shared-ux-utility plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_slo_schema.mdx b/api_docs/kbn_slo_schema.mdx index d7184a114169b..213dffb218e96 100644 --- a/api_docs/kbn_slo_schema.mdx +++ b/api_docs/kbn_slo_schema.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-slo-schema title: "@kbn/slo-schema" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/slo-schema plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/slo-schema'] --- import kbnSloSchemaObj from './kbn_slo_schema.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index b0b4a7230a3ef..ec092e1d0296d 100644 --- a/api_docs/kbn_some_dev_log.mdx +++ b/api_docs/kbn_some_dev_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-some-dev-log title: "@kbn/some-dev-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/some-dev-log plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 149157f05975d..c680cf30e2b20 100644 --- a/api_docs/kbn_std.mdx +++ b/api_docs/kbn_std.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-std title: "@kbn/std" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/std plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/std'] --- import kbnStdObj from './kbn_std.devdocs.json'; diff --git a/api_docs/kbn_stdio_dev_helpers.mdx b/api_docs/kbn_stdio_dev_helpers.mdx index 0d0ce51cb2b79..5d8ec59ecb184 100644 --- a/api_docs/kbn_stdio_dev_helpers.mdx +++ b/api_docs/kbn_stdio_dev_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-stdio-dev-helpers title: "@kbn/stdio-dev-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/stdio-dev-helpers plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/stdio-dev-helpers'] --- import kbnStdioDevHelpersObj from './kbn_stdio_dev_helpers.devdocs.json'; diff --git a/api_docs/kbn_storybook.mdx b/api_docs/kbn_storybook.mdx index ccec97bada45f..755ee9f447cd9 100644 --- a/api_docs/kbn_storybook.mdx +++ b/api_docs/kbn_storybook.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-storybook title: "@kbn/storybook" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/storybook plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/storybook'] --- import kbnStorybookObj from './kbn_storybook.devdocs.json'; diff --git a/api_docs/kbn_telemetry_tools.mdx b/api_docs/kbn_telemetry_tools.mdx index fd08fb176fdaa..a046a972fb1af 100644 --- a/api_docs/kbn_telemetry_tools.mdx +++ b/api_docs/kbn_telemetry_tools.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-telemetry-tools title: "@kbn/telemetry-tools" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/telemetry-tools plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/telemetry-tools'] --- import kbnTelemetryToolsObj from './kbn_telemetry_tools.devdocs.json'; diff --git a/api_docs/kbn_test.mdx b/api_docs/kbn_test.mdx index 635e912a4b350..740c3f77368e1 100644 --- a/api_docs/kbn_test.mdx +++ b/api_docs/kbn_test.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test title: "@kbn/test" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test'] --- import kbnTestObj from './kbn_test.devdocs.json'; diff --git a/api_docs/kbn_test_jest_helpers.mdx b/api_docs/kbn_test_jest_helpers.mdx index 589df797386c0..67378b52f35ad 100644 --- a/api_docs/kbn_test_jest_helpers.mdx +++ b/api_docs/kbn_test_jest_helpers.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-jest-helpers title: "@kbn/test-jest-helpers" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-jest-helpers plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-jest-helpers'] --- import kbnTestJestHelpersObj from './kbn_test_jest_helpers.devdocs.json'; diff --git a/api_docs/kbn_test_subj_selector.mdx b/api_docs/kbn_test_subj_selector.mdx index 1ae3614e977f9..c520055faac88 100644 --- a/api_docs/kbn_test_subj_selector.mdx +++ b/api_docs/kbn_test_subj_selector.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-test-subj-selector title: "@kbn/test-subj-selector" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/test-subj-selector plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_text_based_editor.mdx b/api_docs/kbn_text_based_editor.mdx index 50b97378e3b4a..da6967718d10a 100644 --- a/api_docs/kbn_text_based_editor.mdx +++ b/api_docs/kbn_text_based_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-text-based-editor title: "@kbn/text-based-editor" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/text-based-editor plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/text-based-editor'] --- import kbnTextBasedEditorObj from './kbn_text_based_editor.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 077c60514ecb0..4fbb7781ad46f 100644 --- a/api_docs/kbn_tooling_log.mdx +++ b/api_docs/kbn_tooling_log.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-tooling-log title: "@kbn/tooling-log" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/tooling-log plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_ts_projects.mdx b/api_docs/kbn_ts_projects.mdx index ca5b1aaf34c97..2c6610824c6e8 100644 --- a/api_docs/kbn_ts_projects.mdx +++ b/api_docs/kbn_ts_projects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ts-projects title: "@kbn/ts-projects" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ts-projects plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ts-projects'] --- import kbnTsProjectsObj from './kbn_ts_projects.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 0103431491652..d47a99ee54ce2 100644 --- a/api_docs/kbn_typed_react_router_config.mdx +++ b/api_docs/kbn_typed_react_router_config.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-typed-react-router-config title: "@kbn/typed-react-router-config" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/typed-react-router-config plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/typed-react-router-config'] --- import kbnTypedReactRouterConfigObj from './kbn_typed_react_router_config.devdocs.json'; diff --git a/api_docs/kbn_ui_actions_browser.mdx b/api_docs/kbn_ui_actions_browser.mdx index 7f2cf23f02ed7..35e03a3ff3065 100644 --- a/api_docs/kbn_ui_actions_browser.mdx +++ b/api_docs/kbn_ui_actions_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-actions-browser title: "@kbn/ui-actions-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-actions-browser plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-actions-browser'] --- import kbnUiActionsBrowserObj from './kbn_ui_actions_browser.devdocs.json'; diff --git a/api_docs/kbn_ui_shared_deps_src.mdx b/api_docs/kbn_ui_shared_deps_src.mdx index 441ed0de50a2f..8407eb4258544 100644 --- a/api_docs/kbn_ui_shared_deps_src.mdx +++ b/api_docs/kbn_ui_shared_deps_src.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-shared-deps-src title: "@kbn/ui-shared-deps-src" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-shared-deps-src plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-shared-deps-src'] --- import kbnUiSharedDepsSrcObj from './kbn_ui_shared_deps_src.devdocs.json'; diff --git a/api_docs/kbn_ui_theme.mdx b/api_docs/kbn_ui_theme.mdx index fbc69e15524a1..6cb41dc8c4f9c 100644 --- a/api_docs/kbn_ui_theme.mdx +++ b/api_docs/kbn_ui_theme.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-ui-theme title: "@kbn/ui-theme" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/ui-theme plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_unified_field_list.mdx b/api_docs/kbn_unified_field_list.mdx index 56fcf1c58c8e2..3b0bd687483b8 100644 --- a/api_docs/kbn_unified_field_list.mdx +++ b/api_docs/kbn_unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-unified-field-list title: "@kbn/unified-field-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/unified-field-list plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/unified-field-list'] --- import kbnUnifiedFieldListObj from './kbn_unified_field_list.devdocs.json'; diff --git a/api_docs/kbn_url_state.mdx b/api_docs/kbn_url_state.mdx index f4c570b59641a..17cf7043cdaf1 100644 --- a/api_docs/kbn_url_state.mdx +++ b/api_docs/kbn_url_state.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-url-state title: "@kbn/url-state" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/url-state plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/url-state'] --- import kbnUrlStateObj from './kbn_url_state.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index 7312250210d47..25e3e061b5b02 100644 --- a/api_docs/kbn_user_profile_components.mdx +++ b/api_docs/kbn_user_profile_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-user-profile-components title: "@kbn/user-profile-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/user-profile-components plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/user-profile-components'] --- import kbnUserProfileComponentsObj from './kbn_user_profile_components.devdocs.json'; diff --git a/api_docs/kbn_utility_types.mdx b/api_docs/kbn_utility_types.mdx index c0d1039c624cd..a5f33d9761e5e 100644 --- a/api_docs/kbn_utility_types.mdx +++ b/api_docs/kbn_utility_types.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types title: "@kbn/utility-types" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types'] --- import kbnUtilityTypesObj from './kbn_utility_types.devdocs.json'; diff --git a/api_docs/kbn_utility_types_jest.mdx b/api_docs/kbn_utility_types_jest.mdx index 049ae982f4a70..247cf97516111 100644 --- a/api_docs/kbn_utility_types_jest.mdx +++ b/api_docs/kbn_utility_types_jest.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utility-types-jest title: "@kbn/utility-types-jest" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utility-types-jest plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utility-types-jest'] --- import kbnUtilityTypesJestObj from './kbn_utility_types_jest.devdocs.json'; diff --git a/api_docs/kbn_utils.mdx b/api_docs/kbn_utils.mdx index e49faf2baed5d..4483896e948fa 100644 --- a/api_docs/kbn_utils.mdx +++ b/api_docs/kbn_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-utils title: "@kbn/utils" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/utils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_visualization_ui_components.mdx b/api_docs/kbn_visualization_ui_components.mdx index f9d4097d4c6a1..2399b8a856ad1 100644 --- a/api_docs/kbn_visualization_ui_components.mdx +++ b/api_docs/kbn_visualization_ui_components.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-visualization-ui-components title: "@kbn/visualization-ui-components" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/visualization-ui-components plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/visualization-ui-components'] --- import kbnVisualizationUiComponentsObj from './kbn_visualization_ui_components.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 97b1dbf0a4422..b9927fd6e19f7 100644 --- a/api_docs/kbn_yarn_lock_validator.mdx +++ b/api_docs/kbn_yarn_lock_validator.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-yarn-lock-validator title: "@kbn/yarn-lock-validator" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/yarn-lock-validator plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/yarn-lock-validator'] --- import kbnYarnLockValidatorObj from './kbn_yarn_lock_validator.devdocs.json'; diff --git a/api_docs/kibana_overview.mdx b/api_docs/kibana_overview.mdx index 1663b4fe1e548..6e1f9222238c7 100644 --- a/api_docs/kibana_overview.mdx +++ b/api_docs/kibana_overview.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaOverview title: "kibanaOverview" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaOverview plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaOverview'] --- import kibanaOverviewObj from './kibana_overview.devdocs.json'; diff --git a/api_docs/kibana_react.mdx b/api_docs/kibana_react.mdx index 02b0b9735d385..fd0b38bf12cb1 100644 --- a/api_docs/kibana_react.mdx +++ b/api_docs/kibana_react.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaReact title: "kibanaReact" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaReact plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaReact'] --- import kibanaReactObj from './kibana_react.devdocs.json'; diff --git a/api_docs/kibana_utils.mdx b/api_docs/kibana_utils.mdx index b1e40f56b57b5..d0010371e0fea 100644 --- a/api_docs/kibana_utils.mdx +++ b/api_docs/kibana_utils.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kibanaUtils title: "kibanaUtils" image: https://source.unsplash.com/400x175/?github description: API docs for the kibanaUtils plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kibanaUtils'] --- import kibanaUtilsObj from './kibana_utils.devdocs.json'; diff --git a/api_docs/kubernetes_security.mdx b/api_docs/kubernetes_security.mdx index 60d1133ab3c65..6f976bbdca7fa 100644 --- a/api_docs/kubernetes_security.mdx +++ b/api_docs/kubernetes_security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kubernetesSecurity title: "kubernetesSecurity" image: https://source.unsplash.com/400x175/?github description: API docs for the kubernetesSecurity plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'kubernetesSecurity'] --- import kubernetesSecurityObj from './kubernetes_security.devdocs.json'; diff --git a/api_docs/lens.mdx b/api_docs/lens.mdx index 0a04ef05428eb..e33e34a0b36be 100644 --- a/api_docs/lens.mdx +++ b/api_docs/lens.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lens title: "lens" image: https://source.unsplash.com/400x175/?github description: API docs for the lens plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lens'] --- import lensObj from './lens.devdocs.json'; diff --git a/api_docs/license_api_guard.mdx b/api_docs/license_api_guard.mdx index c20b095013fd1..0583a521ae2f9 100644 --- a/api_docs/license_api_guard.mdx +++ b/api_docs/license_api_guard.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseApiGuard title: "licenseApiGuard" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseApiGuard plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseApiGuard'] --- import licenseApiGuardObj from './license_api_guard.devdocs.json'; diff --git a/api_docs/license_management.mdx b/api_docs/license_management.mdx index 52fa06ee599ea..128e3d18314c0 100644 --- a/api_docs/license_management.mdx +++ b/api_docs/license_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licenseManagement title: "licenseManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the licenseManagement plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licenseManagement'] --- import licenseManagementObj from './license_management.devdocs.json'; diff --git a/api_docs/licensing.mdx b/api_docs/licensing.mdx index 82966dd7d72ea..98d216c70b6d6 100644 --- a/api_docs/licensing.mdx +++ b/api_docs/licensing.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/licensing title: "licensing" image: https://source.unsplash.com/400x175/?github description: API docs for the licensing plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'licensing'] --- import licensingObj from './licensing.devdocs.json'; diff --git a/api_docs/lists.mdx b/api_docs/lists.mdx index 6c72ca0d88e1c..0959f42b36730 100644 --- a/api_docs/lists.mdx +++ b/api_docs/lists.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/lists title: "lists" image: https://source.unsplash.com/400x175/?github description: API docs for the lists plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/logs_shared.mdx b/api_docs/logs_shared.mdx index fae3dda74be0d..4444e39542caf 100644 --- a/api_docs/logs_shared.mdx +++ b/api_docs/logs_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/logsShared title: "logsShared" image: https://source.unsplash.com/400x175/?github description: API docs for the logsShared plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'logsShared'] --- import logsSharedObj from './logs_shared.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 7f6db3ae56c3f..77219c568a9b9 100644 --- a/api_docs/management.mdx +++ b/api_docs/management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/management title: "management" image: https://source.unsplash.com/400x175/?github description: API docs for the management plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'management'] --- import managementObj from './management.devdocs.json'; diff --git a/api_docs/maps.mdx b/api_docs/maps.mdx index cc56d721ea1d1..2191f1726b317 100644 --- a/api_docs/maps.mdx +++ b/api_docs/maps.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/maps title: "maps" image: https://source.unsplash.com/400x175/?github description: API docs for the maps plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'maps'] --- import mapsObj from './maps.devdocs.json'; diff --git a/api_docs/maps_ems.mdx b/api_docs/maps_ems.mdx index 255625cea3f09..4a596b8f87948 100644 --- a/api_docs/maps_ems.mdx +++ b/api_docs/maps_ems.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/mapsEms title: "mapsEms" image: https://source.unsplash.com/400x175/?github description: API docs for the mapsEms plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'mapsEms'] --- import mapsEmsObj from './maps_ems.devdocs.json'; diff --git a/api_docs/ml.mdx b/api_docs/ml.mdx index 0e8536bf20d5a..aac94910e94b1 100644 --- a/api_docs/ml.mdx +++ b/api_docs/ml.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ml title: "ml" image: https://source.unsplash.com/400x175/?github description: API docs for the ml plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ml'] --- import mlObj from './ml.devdocs.json'; diff --git a/api_docs/monitoring.mdx b/api_docs/monitoring.mdx index 3868a377f4925..1ac07084a95b9 100644 --- a/api_docs/monitoring.mdx +++ b/api_docs/monitoring.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoring title: "monitoring" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoring plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoring'] --- import monitoringObj from './monitoring.devdocs.json'; diff --git a/api_docs/monitoring_collection.mdx b/api_docs/monitoring_collection.mdx index 9babfa036f670..b5e8501f6ebd4 100644 --- a/api_docs/monitoring_collection.mdx +++ b/api_docs/monitoring_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/monitoringCollection title: "monitoringCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the monitoringCollection plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'monitoringCollection'] --- import monitoringCollectionObj from './monitoring_collection.devdocs.json'; diff --git a/api_docs/navigation.mdx b/api_docs/navigation.mdx index 962510215557a..f0e8b14832169 100644 --- a/api_docs/navigation.mdx +++ b/api_docs/navigation.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/navigation title: "navigation" image: https://source.unsplash.com/400x175/?github description: API docs for the navigation plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'navigation'] --- import navigationObj from './navigation.devdocs.json'; diff --git a/api_docs/newsfeed.mdx b/api_docs/newsfeed.mdx index feb2921204586..3b494d9a2daad 100644 --- a/api_docs/newsfeed.mdx +++ b/api_docs/newsfeed.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/newsfeed title: "newsfeed" image: https://source.unsplash.com/400x175/?github description: API docs for the newsfeed plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/notifications.mdx b/api_docs/notifications.mdx index e1918927f1ed1..8ebb28a12df00 100644 --- a/api_docs/notifications.mdx +++ b/api_docs/notifications.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/notifications title: "notifications" image: https://source.unsplash.com/400x175/?github description: API docs for the notifications plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'notifications'] --- import notificationsObj from './notifications.devdocs.json'; diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index 1c11825166e1b..2187ddd6940b1 100644 --- a/api_docs/observability.mdx +++ b/api_docs/observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observability title: "observability" image: https://source.unsplash.com/400x175/?github description: API docs for the observability plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; diff --git a/api_docs/observability_a_i_assistant.mdx b/api_docs/observability_a_i_assistant.mdx index 8b19227f0eb95..f2868024f51cb 100644 --- a/api_docs/observability_a_i_assistant.mdx +++ b/api_docs/observability_a_i_assistant.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityAIAssistant title: "observabilityAIAssistant" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityAIAssistant plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityAIAssistant'] --- import observabilityAIAssistantObj from './observability_a_i_assistant.devdocs.json'; diff --git a/api_docs/observability_onboarding.mdx b/api_docs/observability_onboarding.mdx index b12e3c9a096cf..8499bbadd51b3 100644 --- a/api_docs/observability_onboarding.mdx +++ b/api_docs/observability_onboarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityOnboarding title: "observabilityOnboarding" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityOnboarding plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityOnboarding'] --- import observabilityOnboardingObj from './observability_onboarding.devdocs.json'; diff --git a/api_docs/observability_shared.mdx b/api_docs/observability_shared.mdx index 42a79000e2da4..b00388af882bc 100644 --- a/api_docs/observability_shared.mdx +++ b/api_docs/observability_shared.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/observabilityShared title: "observabilityShared" image: https://source.unsplash.com/400x175/?github description: API docs for the observabilityShared plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observabilityShared'] --- import observabilitySharedObj from './observability_shared.devdocs.json'; diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index 1c73c3d587dc3..11d520ff3b5e0 100644 --- a/api_docs/osquery.mdx +++ b/api_docs/osquery.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/osquery title: "osquery" image: https://source.unsplash.com/400x175/?github description: API docs for the osquery plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'osquery'] --- import osqueryObj from './osquery.devdocs.json'; diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 5e18c4d86509f..5836f5e27a50e 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -7,7 +7,7 @@ id: kibDevDocsPluginDirectory slug: /kibana-dev-docs/api-meta/plugin-api-directory title: Directory description: Directory of public APIs available through plugins or packages. -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 71825 | 556 | 61371 | 1470 | +| 71820 | 556 | 61367 | 1472 | ## Plugin Directory @@ -38,7 +38,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/kibana-presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Canvas application to Kibana | 9 | 0 | 8 | 3 | | | [@elastic/response-ops](https://github.com/orgs/elastic/teams/response-ops) | The Case management system in Kibana | 93 | 0 | 74 | 27 | | | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 268 | 16 | 253 | 10 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 65 | 0 | 15 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 16 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | Chat available on Elastic Cloud deployments for quicker assistance. | 3 | 0 | 2 | 0 | | | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | This plugin exists as a workaround for using `cloudChat` plugin in plugins which can't have a direct dependency on security plugin. | 5 | 0 | 5 | 0 | | | [@elastic/platform-onboarding](https://github.com/orgs/elastic/teams/platform-onboarding) | Static migration page where self-managed users can see text/copy about migrating to Elastic Cloud | 8 | 1 | 8 | 1 | @@ -102,7 +102,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | graph | [@elastic/kibana-visualizations](https://github.com/orgs/elastic/teams/kibana-visualizations) | - | 0 | 0 | 0 | 0 | | grokdebugger | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | | | [@elastic/platform-onboarding](https://github.com/orgs/elastic/teams/platform-onboarding) | Guided onboarding framework | 58 | 0 | 57 | 0 | -| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 143 | 0 | 104 | 0 | +| | [@elastic/kibana-core](https://github.com/orgs/elastic/teams/kibana-core) | - | 145 | 0 | 106 | 0 | | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | Image embeddable | 3 | 0 | 3 | 1 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 4 | 0 | 4 | 0 | | | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 177 | 0 | 172 | 3 | @@ -154,7 +154,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [@elastic/appex-sharedux](https://github.com/orgs/elastic/teams/appex-sharedux) | - | 32 | 0 | 13 | 0 | | | [@elastic/kibana-reporting-services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Kibana Screenshotting Plugin | 27 | 0 | 8 | 5 | | searchprofiler | [@elastic/platform-deployment-management](https://github.com/orgs/elastic/teams/platform-deployment-management) | - | 0 | 0 | 0 | 0 | -| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 287 | 0 | 96 | 2 | +| | [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 277 | 0 | 89 | 4 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | - | 192 | 2 | 126 | 32 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | ESS customizations for Security Solution. | 6 | 0 | 6 | 0 | | | [@elastic/security-solution](https://github.com/orgs/elastic/teams/security-solution) | Serverless customizations for security. | 6 | 0 | 6 | 0 | diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index b0ebf57c3d3ba..0fe8f9a7d353e 100644 --- a/api_docs/presentation_util.mdx +++ b/api_docs/presentation_util.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/presentationUtil title: "presentationUtil" image: https://source.unsplash.com/400x175/?github description: API docs for the presentationUtil plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'presentationUtil'] --- import presentationUtilObj from './presentation_util.devdocs.json'; diff --git a/api_docs/profiling.mdx b/api_docs/profiling.mdx index 0a4e2d900a6c9..0b39ac1b4e63c 100644 --- a/api_docs/profiling.mdx +++ b/api_docs/profiling.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/profiling title: "profiling" image: https://source.unsplash.com/400x175/?github description: API docs for the profiling plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'profiling'] --- import profilingObj from './profiling.devdocs.json'; diff --git a/api_docs/remote_clusters.mdx b/api_docs/remote_clusters.mdx index cfcbe35b4fc23..0ff4e46e2a510 100644 --- a/api_docs/remote_clusters.mdx +++ b/api_docs/remote_clusters.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/remoteClusters title: "remoteClusters" image: https://source.unsplash.com/400x175/?github description: API docs for the remoteClusters plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'remoteClusters'] --- import remoteClustersObj from './remote_clusters.devdocs.json'; diff --git a/api_docs/reporting.mdx b/api_docs/reporting.mdx index 993285d8d765d..112b4b29f3ae1 100644 --- a/api_docs/reporting.mdx +++ b/api_docs/reporting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/reporting title: "reporting" image: https://source.unsplash.com/400x175/?github description: API docs for the reporting plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'reporting'] --- import reportingObj from './reporting.devdocs.json'; diff --git a/api_docs/rollup.mdx b/api_docs/rollup.mdx index fdb4a9c879987..f8272bfef1d9f 100644 --- a/api_docs/rollup.mdx +++ b/api_docs/rollup.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/rollup title: "rollup" image: https://source.unsplash.com/400x175/?github description: API docs for the rollup plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'rollup'] --- import rollupObj from './rollup.devdocs.json'; diff --git a/api_docs/rule_registry.mdx b/api_docs/rule_registry.mdx index cf236f474c540..274209f68d7d7 100644 --- a/api_docs/rule_registry.mdx +++ b/api_docs/rule_registry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ruleRegistry title: "ruleRegistry" image: https://source.unsplash.com/400x175/?github description: API docs for the ruleRegistry plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ruleRegistry'] --- import ruleRegistryObj from './rule_registry.devdocs.json'; diff --git a/api_docs/runtime_fields.mdx b/api_docs/runtime_fields.mdx index 08b84f0e389e1..589623de8182e 100644 --- a/api_docs/runtime_fields.mdx +++ b/api_docs/runtime_fields.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/runtimeFields title: "runtimeFields" image: https://source.unsplash.com/400x175/?github description: API docs for the runtimeFields plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'runtimeFields'] --- import runtimeFieldsObj from './runtime_fields.devdocs.json'; diff --git a/api_docs/saved_objects.mdx b/api_docs/saved_objects.mdx index 939676db7d9ae..a71ec6f5e7609 100644 --- a/api_docs/saved_objects.mdx +++ b/api_docs/saved_objects.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjects title: "savedObjects" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjects plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjects'] --- import savedObjectsObj from './saved_objects.devdocs.json'; diff --git a/api_docs/saved_objects_finder.mdx b/api_docs/saved_objects_finder.mdx index e1f9be2433c19..e37e0a65e9f47 100644 --- a/api_docs/saved_objects_finder.mdx +++ b/api_docs/saved_objects_finder.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsFinder title: "savedObjectsFinder" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsFinder plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsFinder'] --- import savedObjectsFinderObj from './saved_objects_finder.devdocs.json'; diff --git a/api_docs/saved_objects_management.mdx b/api_docs/saved_objects_management.mdx index 95ff67f89f258..2af10a0ba1a5c 100644 --- a/api_docs/saved_objects_management.mdx +++ b/api_docs/saved_objects_management.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsManagement title: "savedObjectsManagement" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsManagement plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsManagement'] --- import savedObjectsManagementObj from './saved_objects_management.devdocs.json'; diff --git a/api_docs/saved_objects_tagging.mdx b/api_docs/saved_objects_tagging.mdx index 1b67d2c623e3f..9453cbd5adb2c 100644 --- a/api_docs/saved_objects_tagging.mdx +++ b/api_docs/saved_objects_tagging.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTagging title: "savedObjectsTagging" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTagging plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTagging'] --- import savedObjectsTaggingObj from './saved_objects_tagging.devdocs.json'; diff --git a/api_docs/saved_objects_tagging_oss.mdx b/api_docs/saved_objects_tagging_oss.mdx index f4bc7d3c4204d..0461d38388a45 100644 --- a/api_docs/saved_objects_tagging_oss.mdx +++ b/api_docs/saved_objects_tagging_oss.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedObjectsTaggingOss title: "savedObjectsTaggingOss" image: https://source.unsplash.com/400x175/?github description: API docs for the savedObjectsTaggingOss plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedObjectsTaggingOss'] --- import savedObjectsTaggingOssObj from './saved_objects_tagging_oss.devdocs.json'; diff --git a/api_docs/saved_search.mdx b/api_docs/saved_search.mdx index b84cfb81f65f2..e120f71b28e4b 100644 --- a/api_docs/saved_search.mdx +++ b/api_docs/saved_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/savedSearch title: "savedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the savedSearch plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'savedSearch'] --- import savedSearchObj from './saved_search.devdocs.json'; diff --git a/api_docs/screenshot_mode.mdx b/api_docs/screenshot_mode.mdx index a47227e729fec..a2d304cc86e66 100644 --- a/api_docs/screenshot_mode.mdx +++ b/api_docs/screenshot_mode.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotMode title: "screenshotMode" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotMode plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotMode'] --- import screenshotModeObj from './screenshot_mode.devdocs.json'; diff --git a/api_docs/screenshotting.mdx b/api_docs/screenshotting.mdx index f3d632c4ffb7c..6f8e21a4b85fa 100644 --- a/api_docs/screenshotting.mdx +++ b/api_docs/screenshotting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/screenshotting title: "screenshotting" image: https://source.unsplash.com/400x175/?github description: API docs for the screenshotting plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.devdocs.json b/api_docs/security.devdocs.json index c6a4112d8233f..167308664bcd8 100644 --- a/api_docs/security.devdocs.json +++ b/api_docs/security.devdocs.json @@ -2195,13 +2195,7 @@ "text": "CreateAPIKeyParams" }, ") => Promise<", - { - "pluginId": "security", - "scope": "server", - "docId": "kibSecurityPluginApi", - "section": "def-server.CreateAPIKeyResult", - "text": "CreateAPIKeyResult" - }, + "SecurityCreateApiKeyResponse", " | null>; validate: (apiKeyPrams: ", { "pluginId": "security", @@ -2210,7 +2204,7 @@ "section": "def-server.ValidateAPIKeyParams", "text": "ValidateAPIKeyParams" }, - ") => Promise; areAPIKeysEnabled: () => Promise; invalidate: (request: ", + ") => Promise; areAPIKeysEnabled: () => Promise; areCrossClusterAPIKeysEnabled: () => Promise; invalidate: (request: ", { "pluginId": "@kbn/core-http-server", "scope": "common", @@ -2242,15 +2236,7 @@ "section": "def-common.KibanaRequest", "text": "KibanaRequest" }, - ", createParams: ", - { - "pluginId": "security", - "scope": "server", - "docId": "kibSecurityPluginApi", - "section": "def-server.CreateAPIKeyParams", - "text": "CreateAPIKeyParams" - }, - ") => Promise<", + ", createParams: Readonly<{ type?: \"rest\" | undefined; metadata?: Readonly<{} & {}> | undefined; expiration?: string | undefined; } & { name: string; role_descriptors: Record>; }> | Readonly<{ type?: \"rest\" | undefined; metadata?: Readonly<{} & {}> | undefined; expiration?: string | undefined; } & { name: string; kibana_role_descriptors: Record | undefined; } & { spaces: string[] | \"*\"[]; }>[]; elasticsearch: Readonly<{ cluster?: string[] | undefined; indices?: Readonly<{ query?: string | undefined; field_security?: Record<\"grant\" | \"except\", string[]> | undefined; allow_restricted_indices?: boolean | undefined; } & { names: string[]; privileges: string[]; }>[] | undefined; remote_indices?: Readonly<{ query?: string | undefined; field_security?: Record<\"grant\" | \"except\", string[]> | undefined; allow_restricted_indices?: boolean | undefined; } & { names: string[]; privileges: string[]; clusters: string[]; }>[] | undefined; run_as?: string[] | undefined; } & {}>; }>>; }>) => Promise<", { "pluginId": "security", "scope": "server", @@ -2386,77 +2372,6 @@ ], "initialIsOpen": false }, - { - "parentPluginId": "security", - "id": "def-server.CreateAPIKeyResult", - "type": "Interface", - "tags": [], - "label": "CreateAPIKeyResult", - "description": [ - "\nThe return value when creating an API key in Elasticsearch. The API key returned by this API\ncan then be used by sending a request with a Authorization header with a value having the\nprefix ApiKey `{token}` where token is id and api_key joined by a colon `{id}:{api_key}` and\nthen encoded to base64." - ], - "path": "x-pack/plugins/security/server/authentication/api_keys/api_keys.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "security", - "id": "def-server.CreateAPIKeyResult.id", - "type": "string", - "tags": [], - "label": "id", - "description": [ - "\nUnique id for this API key" - ], - "path": "x-pack/plugins/security/server/authentication/api_keys/api_keys.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-server.CreateAPIKeyResult.name", - "type": "string", - "tags": [], - "label": "name", - "description": [ - "\nName for this API key" - ], - "path": "x-pack/plugins/security/server/authentication/api_keys/api_keys.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-server.CreateAPIKeyResult.expiration", - "type": "number", - "tags": [], - "label": "expiration", - "description": [ - "\nOptional expiration in milliseconds for this API key" - ], - "signature": [ - "number | undefined" - ], - "path": "x-pack/plugins/security/server/authentication/api_keys/api_keys.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-server.CreateAPIKeyResult.api_key", - "type": "string", - "tags": [], - "label": "api_key", - "description": [ - "\nGenerated API key" - ], - "path": "x-pack/plugins/security/server/authentication/api_keys/api_keys.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "security", "id": "def-server.GrantAPIKeyResult", @@ -3169,12 +3084,74 @@ "tags": [], "label": "CreateAPIKeyParams", "description": [ - "\nRepresents the params for creating an API key" + "\nRequest body of Kibana Create API key endpoint." ], "signature": [ - "Omit & ((Pick, \"role_descriptors\"> & { kibana_role_descriptors?: undefined; }) | (Pick, \"kibana_role_descriptors\"> & { role_descriptors?: undefined; }))" + "Readonly<{ type?: \"rest\" | undefined; metadata?: Readonly<{} & {}> | undefined; expiration?: string | undefined; } & { name: string; role_descriptors: Record>; }> | Readonly<{ type?: \"rest\" | undefined; metadata?: Readonly<{} & {}> | undefined; expiration?: string | undefined; } & { name: string; kibana_role_descriptors: Record | undefined; } & { spaces: string[] | \"*\"[]; }>[]; elasticsearch: Readonly<{ cluster?: string[] | undefined; indices?: Readonly<{ query?: string | undefined; field_security?: Record<\"grant\" | \"except\", string[]> | undefined; allow_restricted_indices?: boolean | undefined; } & { names: string[]; privileges: string[]; }>[] | undefined; remote_indices?: Readonly<{ query?: string | undefined; field_security?: Record<\"grant\" | \"except\", string[]> | undefined; allow_restricted_indices?: boolean | undefined; } & { names: string[]; privileges: string[]; clusters: string[]; }>[] | undefined; run_as?: string[] | undefined; } & {}>; }>>; }> | Readonly<{ metadata?: Readonly<{} & {}> | undefined; expiration?: string | undefined; } & { type: \"cross_cluster\"; name: string; access: Readonly<{ search?: Readonly<{} & { names: string[]; }>[] | undefined; replication?: Readonly<{} & { names: string[]; }>[] | undefined; } & {}>; }>" ], - "path": "x-pack/plugins/security/server/authentication/api_keys/api_keys.ts", + "path": "x-pack/plugins/security/server/routes/api_keys/create.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "security", + "id": "def-server.CreateAPIKeyResult", + "type": "Type", + "tags": [], + "label": "CreateAPIKeyResult", + "description": [ + "\nResponse of Kibana Create API key endpoint." + ], + "signature": [ + "SecurityCreateApiKeyResponse" + ], + "path": "x-pack/plugins/security/server/routes/api_keys/create.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "security", + "id": "def-server.CreateCrossClusterAPIKeyParams", + "type": "Type", + "tags": [], + "label": "CreateCrossClusterAPIKeyParams", + "description": [], + "signature": [ + "{ readonly metadata?: Readonly<{} & {}> | undefined; readonly expiration?: string | undefined; readonly type: \"cross_cluster\"; readonly name: string; readonly access: Readonly<{ search?: Readonly<{} & { names: string[]; }>[] | undefined; replication?: Readonly<{} & { names: string[]; }>[] | undefined; } & {}>; }" + ], + "path": "x-pack/plugins/security/server/routes/api_keys/create.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "security", + "id": "def-server.CreateRestAPIKeyParams", + "type": "Type", + "tags": [], + "label": "CreateRestAPIKeyParams", + "description": [], + "signature": [ + "{ readonly type?: \"rest\" | undefined; readonly metadata?: Readonly<{} & {}> | undefined; readonly expiration?: string | undefined; readonly name: string; readonly role_descriptors: Record>; }" + ], + "path": "x-pack/plugins/security/server/routes/api_keys/create.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, + { + "parentPluginId": "security", + "id": "def-server.CreateRestAPIKeyWithKibanaPrivilegesParams", + "type": "Type", + "tags": [], + "label": "CreateRestAPIKeyWithKibanaPrivilegesParams", + "description": [], + "signature": [ + "{ readonly type?: \"rest\" | undefined; readonly metadata?: Readonly<{} & {}> | undefined; readonly expiration?: string | undefined; readonly name: string; readonly kibana_role_descriptors: Record | undefined; } & { spaces: string[] | \"*\"[]; }>[]; elasticsearch: Readonly<{ cluster?: string[] | undefined; indices?: Readonly<{ query?: string | undefined; field_security?: Record<\"grant\" | \"except\", string[]> | undefined; allow_restricted_indices?: boolean | undefined; } & { names: string[]; privileges: string[]; }>[] | undefined; remote_indices?: Readonly<{ query?: string | undefined; field_security?: Record<\"grant\" | \"except\", string[]> | undefined; allow_restricted_indices?: boolean | undefined; } & { names: string[]; privileges: string[]; clusters: string[]; }>[] | undefined; run_as?: string[] | undefined; } & {}>; }>>; }" + ], + "path": "x-pack/plugins/security/server/routes/api_keys/create.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false @@ -3583,125 +3560,6 @@ } ], "interfaces": [ - { - "parentPluginId": "security", - "id": "def-common.ApiKey", - "type": "Interface", - "tags": [], - "label": "ApiKey", - "description": [], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false, - "children": [ - { - "parentPluginId": "security", - "id": "def-common.ApiKey.id", - "type": "string", - "tags": [], - "label": "id", - "description": [], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.ApiKey.name", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.ApiKey.username", - "type": "string", - "tags": [], - "label": "username", - "description": [], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.ApiKey.realm", - "type": "string", - "tags": [], - "label": "realm", - "description": [], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.ApiKey.creation", - "type": "number", - "tags": [], - "label": "creation", - "description": [], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.ApiKey.expiration", - "type": "number", - "tags": [], - "label": "expiration", - "description": [], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.ApiKey.invalidated", - "type": "boolean", - "tags": [], - "label": "invalidated", - "description": [], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.ApiKey.metadata", - "type": "Object", - "tags": [], - "label": "metadata", - "description": [], - "signature": [ - "{ [x: string]: any; }" - ], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false - }, - { - "parentPluginId": "security", - "id": "def-common.ApiKey.role_descriptors", - "type": "Object", - "tags": [], - "label": "role_descriptors", - "description": [], - "signature": [ - "Record | undefined" - ], - "path": "x-pack/plugins/security/common/model/api_key.ts", - "deprecated": false, - "trackAdoption": false - } - ], - "initialIsOpen": false - }, { "parentPluginId": "security", "id": "def-common.AuthenticatedUser", @@ -5311,6 +5169,25 @@ ], "enums": [], "misc": [ + { + "parentPluginId": "security", + "id": "def-common.ApiKey", + "type": "Type", + "tags": [], + "label": "ApiKey", + "description": [ + "\nInterface representing an API key the way it is returned by Elasticsearch GET endpoint." + ], + "signature": [ + "RestApiKey", + " | ", + "CrossClusterApiKey" + ], + "path": "x-pack/plugins/security/common/model/api_key.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "security", "id": "def-common.LoginLayout", diff --git a/api_docs/security.mdx b/api_docs/security.mdx index e3b9bbd0c3412..292adb907ed5c 100644 --- a/api_docs/security.mdx +++ b/api_docs/security.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/security title: "security" image: https://source.unsplash.com/400x175/?github description: API docs for the security plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; @@ -21,7 +21,7 @@ Contact [@elastic/kibana-security](https://github.com/orgs/elastic/teams/kibana- | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 287 | 0 | 96 | 2 | +| 277 | 0 | 89 | 4 | ## Client diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index fd3c697b26dbe..c64f8c3f50052 100644 --- a/api_docs/security_solution.mdx +++ b/api_docs/security_solution.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolution title: "securitySolution" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolution plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/security_solution_ess.mdx b/api_docs/security_solution_ess.mdx index c03174f4aaa57..a9739d6975107 100644 --- a/api_docs/security_solution_ess.mdx +++ b/api_docs/security_solution_ess.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionEss title: "securitySolutionEss" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionEss plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionEss'] --- import securitySolutionEssObj from './security_solution_ess.devdocs.json'; diff --git a/api_docs/security_solution_serverless.mdx b/api_docs/security_solution_serverless.mdx index d40114516bed6..ba832361ce496 100644 --- a/api_docs/security_solution_serverless.mdx +++ b/api_docs/security_solution_serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/securitySolutionServerless title: "securitySolutionServerless" image: https://source.unsplash.com/400x175/?github description: API docs for the securitySolutionServerless plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolutionServerless'] --- import securitySolutionServerlessObj from './security_solution_serverless.devdocs.json'; diff --git a/api_docs/serverless.mdx b/api_docs/serverless.mdx index 1ff15da6c5142..459fdbaba17f1 100644 --- a/api_docs/serverless.mdx +++ b/api_docs/serverless.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverless title: "serverless" image: https://source.unsplash.com/400x175/?github description: API docs for the serverless plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverless'] --- import serverlessObj from './serverless.devdocs.json'; diff --git a/api_docs/serverless_observability.mdx b/api_docs/serverless_observability.mdx index 303e3815fb425..5f07e440f3f62 100644 --- a/api_docs/serverless_observability.mdx +++ b/api_docs/serverless_observability.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessObservability title: "serverlessObservability" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessObservability plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessObservability'] --- import serverlessObservabilityObj from './serverless_observability.devdocs.json'; diff --git a/api_docs/serverless_search.mdx b/api_docs/serverless_search.mdx index a8d08963790a1..d0d3c45b346be 100644 --- a/api_docs/serverless_search.mdx +++ b/api_docs/serverless_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/serverlessSearch title: "serverlessSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the serverlessSearch plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'serverlessSearch'] --- import serverlessSearchObj from './serverless_search.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 3f9c647333d6e..36c1c386fe626 100644 --- a/api_docs/session_view.mdx +++ b/api_docs/session_view.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/sessionView title: "sessionView" image: https://source.unsplash.com/400x175/?github description: API docs for the sessionView plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'sessionView'] --- import sessionViewObj from './session_view.devdocs.json'; diff --git a/api_docs/share.mdx b/api_docs/share.mdx index 3cad3e95874b3..dd82b7a7820c6 100644 --- a/api_docs/share.mdx +++ b/api_docs/share.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/share title: "share" image: https://source.unsplash.com/400x175/?github description: API docs for the share plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'share'] --- import shareObj from './share.devdocs.json'; diff --git a/api_docs/snapshot_restore.mdx b/api_docs/snapshot_restore.mdx index a4e7f8d070fee..f8ab5e8b4628b 100644 --- a/api_docs/snapshot_restore.mdx +++ b/api_docs/snapshot_restore.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/snapshotRestore title: "snapshotRestore" image: https://source.unsplash.com/400x175/?github description: API docs for the snapshotRestore plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'snapshotRestore'] --- import snapshotRestoreObj from './snapshot_restore.devdocs.json'; diff --git a/api_docs/spaces.mdx b/api_docs/spaces.mdx index ba837c41d517f..53d46e39ab72c 100644 --- a/api_docs/spaces.mdx +++ b/api_docs/spaces.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/spaces title: "spaces" image: https://source.unsplash.com/400x175/?github description: API docs for the spaces plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 54f78158b9e9e..7e05dfd474d7a 100644 --- a/api_docs/stack_alerts.mdx +++ b/api_docs/stack_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackAlerts title: "stackAlerts" image: https://source.unsplash.com/400x175/?github description: API docs for the stackAlerts plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackAlerts'] --- import stackAlertsObj from './stack_alerts.devdocs.json'; diff --git a/api_docs/stack_connectors.mdx b/api_docs/stack_connectors.mdx index 4f3fa06d4fcb0..0bf6d4874a9a8 100644 --- a/api_docs/stack_connectors.mdx +++ b/api_docs/stack_connectors.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/stackConnectors title: "stackConnectors" image: https://source.unsplash.com/400x175/?github description: API docs for the stackConnectors plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'stackConnectors'] --- import stackConnectorsObj from './stack_connectors.devdocs.json'; diff --git a/api_docs/task_manager.mdx b/api_docs/task_manager.mdx index 9bdae4babe7ca..868d29e007c8f 100644 --- a/api_docs/task_manager.mdx +++ b/api_docs/task_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/taskManager title: "taskManager" image: https://source.unsplash.com/400x175/?github description: API docs for the taskManager plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'taskManager'] --- import taskManagerObj from './task_manager.devdocs.json'; diff --git a/api_docs/telemetry.mdx b/api_docs/telemetry.mdx index 9be29a6d912c0..746ecac6f05e1 100644 --- a/api_docs/telemetry.mdx +++ b/api_docs/telemetry.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetry title: "telemetry" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetry plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetry'] --- import telemetryObj from './telemetry.devdocs.json'; diff --git a/api_docs/telemetry_collection_manager.mdx b/api_docs/telemetry_collection_manager.mdx index 6c1fe5076d5a2..0c6166a26328a 100644 --- a/api_docs/telemetry_collection_manager.mdx +++ b/api_docs/telemetry_collection_manager.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionManager title: "telemetryCollectionManager" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionManager plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionManager'] --- import telemetryCollectionManagerObj from './telemetry_collection_manager.devdocs.json'; diff --git a/api_docs/telemetry_collection_xpack.mdx b/api_docs/telemetry_collection_xpack.mdx index 32b5b7a296350..ade3334eb49c2 100644 --- a/api_docs/telemetry_collection_xpack.mdx +++ b/api_docs/telemetry_collection_xpack.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryCollectionXpack title: "telemetryCollectionXpack" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryCollectionXpack plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryCollectionXpack'] --- import telemetryCollectionXpackObj from './telemetry_collection_xpack.devdocs.json'; diff --git a/api_docs/telemetry_management_section.mdx b/api_docs/telemetry_management_section.mdx index fb476b919a14a..b0ee09e8d8339 100644 --- a/api_docs/telemetry_management_section.mdx +++ b/api_docs/telemetry_management_section.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/telemetryManagementSection title: "telemetryManagementSection" image: https://source.unsplash.com/400x175/?github description: API docs for the telemetryManagementSection plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/text_based_languages.mdx b/api_docs/text_based_languages.mdx index 9822263677fa5..5caa041d59d6d 100644 --- a/api_docs/text_based_languages.mdx +++ b/api_docs/text_based_languages.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/textBasedLanguages title: "textBasedLanguages" image: https://source.unsplash.com/400x175/?github description: API docs for the textBasedLanguages plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'textBasedLanguages'] --- import textBasedLanguagesObj from './text_based_languages.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 96bfb59032d94..e134dec835ed6 100644 --- a/api_docs/threat_intelligence.mdx +++ b/api_docs/threat_intelligence.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/threatIntelligence title: "threatIntelligence" image: https://source.unsplash.com/400x175/?github description: API docs for the threatIntelligence plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'threatIntelligence'] --- import threatIntelligenceObj from './threat_intelligence.devdocs.json'; diff --git a/api_docs/timelines.mdx b/api_docs/timelines.mdx index 5bba8bd14ca88..a8e4b3b5a20f8 100644 --- a/api_docs/timelines.mdx +++ b/api_docs/timelines.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/timelines title: "timelines" image: https://source.unsplash.com/400x175/?github description: API docs for the timelines plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'timelines'] --- import timelinesObj from './timelines.devdocs.json'; diff --git a/api_docs/transform.mdx b/api_docs/transform.mdx index 8660890cd1239..4d0f82ab99596 100644 --- a/api_docs/transform.mdx +++ b/api_docs/transform.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/transform title: "transform" image: https://source.unsplash.com/400x175/?github description: API docs for the transform plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'transform'] --- import transformObj from './transform.devdocs.json'; diff --git a/api_docs/triggers_actions_ui.mdx b/api_docs/triggers_actions_ui.mdx index b05f786351b15..9eafa3e8da610 100644 --- a/api_docs/triggers_actions_ui.mdx +++ b/api_docs/triggers_actions_ui.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/triggersActionsUi title: "triggersActionsUi" image: https://source.unsplash.com/400x175/?github description: API docs for the triggersActionsUi plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'triggersActionsUi'] --- import triggersActionsUiObj from './triggers_actions_ui.devdocs.json'; diff --git a/api_docs/ui_actions.mdx b/api_docs/ui_actions.mdx index 756fff53153f7..01c5f50bac220 100644 --- a/api_docs/ui_actions.mdx +++ b/api_docs/ui_actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActions title: "uiActions" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActions plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActions'] --- import uiActionsObj from './ui_actions.devdocs.json'; diff --git a/api_docs/ui_actions_enhanced.mdx b/api_docs/ui_actions_enhanced.mdx index 15f42e8eea7a6..3e22d68385fce 100644 --- a/api_docs/ui_actions_enhanced.mdx +++ b/api_docs/ui_actions_enhanced.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uiActionsEnhanced title: "uiActionsEnhanced" image: https://source.unsplash.com/400x175/?github description: API docs for the uiActionsEnhanced plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_histogram.mdx b/api_docs/unified_histogram.mdx index 82290aed1524f..3da5d56294975 100644 --- a/api_docs/unified_histogram.mdx +++ b/api_docs/unified_histogram.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedHistogram title: "unifiedHistogram" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedHistogram plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedHistogram'] --- import unifiedHistogramObj from './unified_histogram.devdocs.json'; diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 11d67ea357644..03e9d55385d40 100644 --- a/api_docs/unified_search.mdx +++ b/api_docs/unified_search.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch title: "unifiedSearch" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 285170e9e6e90..153cbbc053047 100644 --- a/api_docs/unified_search_autocomplete.mdx +++ b/api_docs/unified_search_autocomplete.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedSearch-autocomplete title: "unifiedSearch.autocomplete" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedSearch.autocomplete plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; diff --git a/api_docs/uptime.mdx b/api_docs/uptime.mdx index 8315a5d3e1282..aeaf31dc6c99d 100644 --- a/api_docs/uptime.mdx +++ b/api_docs/uptime.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/uptime title: "uptime" image: https://source.unsplash.com/400x175/?github description: API docs for the uptime plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uptime'] --- import uptimeObj from './uptime.devdocs.json'; diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 7a09fbf67931a..8d3fab6cb85b4 100644 --- a/api_docs/url_forwarding.mdx +++ b/api_docs/url_forwarding.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/urlForwarding title: "urlForwarding" image: https://source.unsplash.com/400x175/?github description: API docs for the urlForwarding plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'urlForwarding'] --- import urlForwardingObj from './url_forwarding.devdocs.json'; diff --git a/api_docs/usage_collection.mdx b/api_docs/usage_collection.mdx index 7b80800b37f13..a87f8530bd772 100644 --- a/api_docs/usage_collection.mdx +++ b/api_docs/usage_collection.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/usageCollection title: "usageCollection" image: https://source.unsplash.com/400x175/?github description: API docs for the usageCollection plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'usageCollection'] --- import usageCollectionObj from './usage_collection.devdocs.json'; diff --git a/api_docs/ux.mdx b/api_docs/ux.mdx index cea049af23b5b..41ba7d449fded 100644 --- a/api_docs/ux.mdx +++ b/api_docs/ux.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/ux title: "ux" image: https://source.unsplash.com/400x175/?github description: API docs for the ux plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'ux'] --- import uxObj from './ux.devdocs.json'; diff --git a/api_docs/vis_default_editor.mdx b/api_docs/vis_default_editor.mdx index 758273df02e1d..a0b85ee1fcbae 100644 --- a/api_docs/vis_default_editor.mdx +++ b/api_docs/vis_default_editor.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visDefaultEditor title: "visDefaultEditor" image: https://source.unsplash.com/400x175/?github description: API docs for the visDefaultEditor plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visDefaultEditor'] --- import visDefaultEditorObj from './vis_default_editor.devdocs.json'; diff --git a/api_docs/vis_type_gauge.mdx b/api_docs/vis_type_gauge.mdx index 4251a59217600..cf0915fb30f3c 100644 --- a/api_docs/vis_type_gauge.mdx +++ b/api_docs/vis_type_gauge.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeGauge title: "visTypeGauge" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeGauge plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeGauge'] --- import visTypeGaugeObj from './vis_type_gauge.devdocs.json'; diff --git a/api_docs/vis_type_heatmap.mdx b/api_docs/vis_type_heatmap.mdx index eaad9c6f352d5..b474cae15bc68 100644 --- a/api_docs/vis_type_heatmap.mdx +++ b/api_docs/vis_type_heatmap.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeHeatmap title: "visTypeHeatmap" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeHeatmap plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeHeatmap'] --- import visTypeHeatmapObj from './vis_type_heatmap.devdocs.json'; diff --git a/api_docs/vis_type_pie.mdx b/api_docs/vis_type_pie.mdx index bbeb89072a2bf..5bc15be9f7c0f 100644 --- a/api_docs/vis_type_pie.mdx +++ b/api_docs/vis_type_pie.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypePie title: "visTypePie" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypePie plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypePie'] --- import visTypePieObj from './vis_type_pie.devdocs.json'; diff --git a/api_docs/vis_type_table.mdx b/api_docs/vis_type_table.mdx index f3e2400e6e0f3..7643ddfaae90e 100644 --- a/api_docs/vis_type_table.mdx +++ b/api_docs/vis_type_table.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTable title: "visTypeTable" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTable plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTable'] --- import visTypeTableObj from './vis_type_table.devdocs.json'; diff --git a/api_docs/vis_type_timelion.mdx b/api_docs/vis_type_timelion.mdx index f4fb301bb4415..d7fc9723f84a0 100644 --- a/api_docs/vis_type_timelion.mdx +++ b/api_docs/vis_type_timelion.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimelion title: "visTypeTimelion" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimelion plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimelion'] --- import visTypeTimelionObj from './vis_type_timelion.devdocs.json'; diff --git a/api_docs/vis_type_timeseries.mdx b/api_docs/vis_type_timeseries.mdx index c7e12347477dc..fe7f2cd1a24a0 100644 --- a/api_docs/vis_type_timeseries.mdx +++ b/api_docs/vis_type_timeseries.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeTimeseries title: "visTypeTimeseries" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeTimeseries plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeTimeseries'] --- import visTypeTimeseriesObj from './vis_type_timeseries.devdocs.json'; diff --git a/api_docs/vis_type_vega.mdx b/api_docs/vis_type_vega.mdx index 8adbae9dc7a4a..925862995104a 100644 --- a/api_docs/vis_type_vega.mdx +++ b/api_docs/vis_type_vega.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVega title: "visTypeVega" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVega plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVega'] --- import visTypeVegaObj from './vis_type_vega.devdocs.json'; diff --git a/api_docs/vis_type_vislib.mdx b/api_docs/vis_type_vislib.mdx index 1dbbf0fc29875..68339735ba1b9 100644 --- a/api_docs/vis_type_vislib.mdx +++ b/api_docs/vis_type_vislib.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeVislib title: "visTypeVislib" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeVislib plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeVislib'] --- import visTypeVislibObj from './vis_type_vislib.devdocs.json'; diff --git a/api_docs/vis_type_xy.mdx b/api_docs/vis_type_xy.mdx index 0ca9f2059a642..c44837021f0c4 100644 --- a/api_docs/vis_type_xy.mdx +++ b/api_docs/vis_type_xy.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visTypeXy title: "visTypeXy" image: https://source.unsplash.com/400x175/?github description: API docs for the visTypeXy plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 1e4cef6acb7ab..7b2d1ab51cdeb 100644 --- a/api_docs/visualizations.mdx +++ b/api_docs/visualizations.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/visualizations title: "visualizations" image: https://source.unsplash.com/400x175/?github description: API docs for the visualizations plugin -date: 2023-08-07 +date: 2023-08-08 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; diff --git a/config/serverless.oblt.yml b/config/serverless.oblt.yml index 1fc14186373a2..44d26351b5380 100644 --- a/config/serverless.oblt.yml +++ b/config/serverless.oblt.yml @@ -39,7 +39,6 @@ xpack.apm.featureFlags.infraUiAvailable: false xpack.apm.featureFlags.migrationToFleetAvailable: false xpack.apm.featureFlags.sourcemapApiAvailable: false xpack.apm.featureFlags.storageExplorerAvailable: false -xpack.apm.featureFlags.fastRefreshAvailable: true # Specify in telemetry the project type telemetry.labels.serverless: observability diff --git a/docs/developer/advanced/upgrading-nodejs.asciidoc b/docs/developer/advanced/upgrading-nodejs.asciidoc index c2c559c9c380e..3f27d5a62147d 100644 --- a/docs/developer/advanced/upgrading-nodejs.asciidoc +++ b/docs/developer/advanced/upgrading-nodejs.asciidoc @@ -44,15 +44,21 @@ Use best judgement when backporting. ==== Node.js patch upgrades -Typically, you want to backport Node.js *patch* upgrades to all supported release branches that run the same *major* Node.js version (which currently is all of them, but this might change in the future once Node.js v18 is released and becomes LTS): +Typically, you want to backport Node.js *patch* upgrades to all supported release branches that run the same *major* Node.js version (which currently is all of them, but this might change in the future): - - If upgrading Node.js 16, and the current release is 8.1.x, the main PR should target `main` and be backported to `7.17` and `8.1`. + - If the current release is 8.1.x, the main PR should target `main` and be backported to `7.17` and `8.1` (GitHub tag example: `backport:all-open`). ==== Node.js minor upgrades -Typically, you want to backport Node.js *minor* upgrades to the next minor {kib} release branch that runs the same *major* Node.js version: +Typically, you want to backport Node.js *minor* upgrades to the previous major {kib} release branch (if it runs the same *major* Node.js version): - - If upgrading Node.js 16, and the current release is 8.1.x, the main PR should target `main` and be backported to `7.17`, while leaving the `8.1` branch as-is. + - If the current release is 8.1.x, the main PR should target `main` and be backported to `7.17`, while leaving the `8.1` branch as-is (GitHub tag example: `auto-backport` + `v7.17.13`). + +==== Node.js major upgrades + +Typically, you want to backport Node.js *major* upgrades to the previous major {kib} release branch: + + - If the current release is 8.1.x, the main PR should target `main` and be backported to `7.17`, while leaving the `8.1` branch as-is (GitHub tag example: `auto-backport` + `v7.17.13`). === Upgrading installed Node.js version diff --git a/packages/content-management/content_editor/src/components/editor_flyout_content.tsx b/packages/content-management/content_editor/src/components/editor_flyout_content.tsx index 5bbca8363047f..a760ec5f5d1a9 100644 --- a/packages/content-management/content_editor/src/components/editor_flyout_content.tsx +++ b/packages/content-management/content_editor/src/components/editor_flyout_content.tsx @@ -126,7 +126,7 @@ export const ContentEditorFlyoutContent: FC = ({

- + {title}

diff --git a/packages/content-management/content_editor/src/components/metadata_form.tsx b/packages/content-management/content_editor/src/components/metadata_form.tsx index 5d0dfc53a681d..42e06671bc7a8 100644 --- a/packages/content-management/content_editor/src/components/metadata_form.tsx +++ b/packages/content-management/content_editor/src/components/metadata_form.tsx @@ -9,7 +9,14 @@ import React from 'react'; import type { FC } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiForm, EuiFormRow, EuiFieldText, EuiTextArea, EuiSpacer } from '@elastic/eui'; +import { + EuiForm, + EuiFormRow, + EuiFieldText, + EuiTextArea, + EuiSpacer, + EuiToolTip, +} from '@elastic/eui'; import { ContentEditorFlyoutWarningsCallOut } from './editor_flyout_warnings'; import type { MetadataFormState, Field } from './use_metadata_form'; @@ -47,6 +54,11 @@ export const MetadataForm: FC = ({ getWarnings, } = form; + const readOnlyToolTip = i18n.translate( + 'contentManagement.contentEditor.metadataForm.readOnlyToolTip', + { defaultMessage: 'To edit these details, contact your administrator for access.' } + ); + return ( @@ -59,16 +71,22 @@ export const MetadataForm: FC = ({ isInvalid={!isFormFieldValid(title)} fullWidth > - { - setTitle(e.target.value); - }} - fullWidth - data-test-subj="nameInput" - readOnly={isReadonly} - /> + + { + setTitle(e.target.value); + }} + fullWidth + data-test-subj="nameInput" + readOnly={isReadonly} + /> + @@ -84,19 +102,25 @@ export const MetadataForm: FC = ({ isInvalid={!isFormFieldValid(description)} fullWidth > - { - setDescription(e.target.value); - }} - fullWidth - data-test-subj="descriptionInput" - readOnly={isReadonly} - /> + + { + setDescription(e.target.value); + }} + fullWidth + data-test-subj="descriptionInput" + readOnly={isReadonly} + /> + - {TagList && isReadonly && ( + {TagList && isReadonly && tagsReferences.length > 0 && ( <> ({ available: (v) => (showEditActionForItem ? showEditActionForItem(v) : true), enabled: (v) => !(v as unknown as { error: string })?.error, onClick: editItem, + 'data-test-subj': `edit-action`, }); } @@ -575,9 +576,10 @@ function TableListViewTableComp({ defaultMessage: 'View details', } ), - icon: 'inspect', + icon: 'iInCircle', type: 'icon', onClick: inspectItem, + 'data-test-subj': `inspect-action`, }); } diff --git a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx index e425ef7059572..0b575e4a0f215 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/chrome_service.tsx @@ -225,6 +225,11 @@ export class ChromeService { projectNavigation.setProjectHome(homeHref); }; + const setProjectsUrl = (projectsUrl: string) => { + validateChromeStyle(); + projectNavigation.setProjectsUrl(projectsUrl); + }; + const isIE = () => { const ua = window.navigator.userAgent; const msie = ua.indexOf('MSIE '); // IE 10 or older @@ -317,6 +322,7 @@ export class ChromeService { loadingCount$={http.getLoadingCount$()} headerBanner$={headerBanner$.pipe(takeUntil(this.stop$))} homeHref$={projectNavigation.getProjectHome$()} + projectsUrl$={projectNavigation.getProjectsUrl$()} docLinks={docLinks} kibanaVersion={injectedMetadata.getKibanaVersion()} prependBasePath={http.basePath.prepend} @@ -444,6 +450,7 @@ export class ChromeService { getChromeStyle$: () => chromeStyle$.pipe(takeUntil(this.stop$)), project: { setHome: setProjectHome, + setProjectsUrl, setNavigation: setProjectNavigation, setSideNavComponent: setProjectSideNavComponent, setBreadcrumbs: setProjectBreadcrumbs, diff --git a/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.ts b/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.ts index 32f876e6b35a1..50bf609dde0da 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.ts +++ b/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/project_navigation_service.ts @@ -35,6 +35,7 @@ export class ProjectNavigationService { current: SideNavComponent | null; }>({ current: null }); private projectHome$ = new BehaviorSubject(undefined); + private projectsUrl$ = new BehaviorSubject(undefined); private projectNavigation$ = new BehaviorSubject(undefined); private activeNodes$ = new BehaviorSubject([]); private projectNavigationNavTreeFlattened: Record = {}; @@ -66,6 +67,12 @@ export class ProjectNavigationService { getProjectHome$: () => { return this.projectHome$.asObservable(); }, + setProjectsUrl: (projectsUrl: string) => { + this.projectsUrl$.next(projectsUrl); + }, + getProjectsUrl$: () => { + return this.projectsUrl$.asObservable(); + }, setProjectNavigation: (projectNavigation: ChromeProjectNavigation) => { this.projectNavigation$.next(projectNavigation); this.projectNavigationNavTreeFlattened = flattenNav(projectNavigation.navigationTree); diff --git a/packages/core/chrome/core-chrome-browser-internal/src/types.ts b/packages/core/chrome/core-chrome-browser-internal/src/types.ts index 43ae77dee434a..1eea86ad4090d 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/types.ts +++ b/packages/core/chrome/core-chrome-browser-internal/src/types.ts @@ -44,6 +44,12 @@ export interface InternalChromeStart extends ChromeStart { */ setHome(homeHref: string): void; + /** + * Sets the cloud's projects page. + * @param projectsUrl + */ + setProjectsUrl(projectsUrl: string): void; + /** * Sets the project navigation config to be used for rendering project navigation. * It is used for default project sidenav, project breadcrumbs, tracking active deep link. diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.test.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.test.tsx index 52099c100cb9a..63db10979d026 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.test.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.test.tsx @@ -28,6 +28,7 @@ describe('Header', () => { helpSupportUrl$: Rx.of('app/help'), helpMenuLinks$: Rx.of([]), homeHref$: Rx.of('app/home'), + projectsUrl$: Rx.of('/projects/'), kibanaVersion: '8.9', loadingCount$: Rx.of(0), navControlsLeft$: Rx.of([]), @@ -71,4 +72,15 @@ describe('Header', () => { await toggleNav(); await toggleNav(); }); + + it('displays the link to projects', async () => { + render( + + Hello, world! + + ); + + const projectsLink = await screen.getByTestId('projectsLink'); + expect(projectsLink).toHaveAttribute('href', '/projects/'); + }); }); diff --git a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx index 45061e193de38..8786b9223a2a9 100644 --- a/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx +++ b/packages/core/chrome/core-chrome-browser-internal/src/ui/project/header.tsx @@ -78,8 +78,8 @@ const headerStrings = { }), }, cloud: { - linkToDeployments: i18n.translate('core.ui.primaryNav.cloud.linkToDeployments', { - defaultMessage: 'My deployments', + linkToProjects: i18n.translate('core.ui.primaryNav.cloud.linkToProjects', { + defaultMessage: 'Projects', }), }, nav: { @@ -100,6 +100,7 @@ export interface Props { helpSupportUrl$: Observable; helpMenuLinks$: Observable; homeHref$: Observable; + projectsUrl$: Observable; kibanaVersion: string; application: InternalApplicationStart; loadingCount$: ReturnType; @@ -175,6 +176,7 @@ export const ProjectHeader = ({ const [isOpen, setIsOpen] = useLocalStorage(LOCAL_STORAGE_IS_OPEN_KEY, true); const toggleCollapsibleNavRef = createRef void }>(); const headerActionMenuMounter = useHeaderActionMenuMounter(observables.actionMenu$); + const projectsUrl = useObservable(observables.projectsUrl$); return ( <> @@ -233,8 +235,8 @@ export const ProjectHeader = ({ - - {headerStrings.cloud.linkToDeployments} + + {headerStrings.cloud.linkToProjects} diff --git a/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts b/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts index f1ce84f2f9be1..884426a7f037a 100644 --- a/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts +++ b/packages/core/chrome/core-chrome-browser-mocks/src/chrome_service.mock.ts @@ -69,6 +69,7 @@ const createStartContractMock = () => { setChromeStyle: jest.fn(), project: { setHome: jest.fn(), + setProjectsUrl: jest.fn(), setNavigation: jest.fn(), setSideNavComponent: jest.fn(), setBreadcrumbs: jest.fn(), diff --git a/packages/kbn-content-management-utils/src/types.ts b/packages/kbn-content-management-utils/src/types.ts index ad9f805bc0998..7dce7961290af 100644 --- a/packages/kbn-content-management-utils/src/types.ts +++ b/packages/kbn-content-management-utils/src/types.ts @@ -347,7 +347,7 @@ export interface ContentManagementCrudTypes< /** * Update item params */ - UpdateIn: UpdateIn; + UpdateIn: UpdateIn, UpdateOptions>; /** * Update item result */ diff --git a/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx b/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx index affbff3ea9b2c..4684a160881b8 100644 --- a/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx +++ b/src/plugins/chart_expressions/expression_gauge/public/components/gauge_component.tsx @@ -246,7 +246,10 @@ export const GaugeComponent: FC = memo( const onRenderChange = useCallback( (isRendered: boolean = true) => { if (isRendered) { - renderComplete(); + // this requestAnimationFrame call is a temporary fix for https://github.com/elastic/elastic-charts/issues/2124 + window.requestAnimationFrame(() => { + renderComplete(); + }); } }, [renderComplete] diff --git a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx index ab70211361e46..95856d1bae485 100644 --- a/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx +++ b/src/plugins/chart_expressions/expression_heatmap/public/components/heatmap_component.tsx @@ -196,7 +196,10 @@ export const HeatmapComponent: FC = memo( const onRenderChange = useCallback( (isRendered: boolean = true) => { if (isRendered) { - renderComplete(); + // this requestAnimationFrame call is a temporary fix for https://github.com/elastic/elastic-charts/issues/2124 + window.requestAnimationFrame(() => { + renderComplete(); + }); } }, [renderComplete] diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.test.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.test.tsx index 209608c260eca..6e96c2ab06cdf 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.test.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.test.tsx @@ -971,6 +971,11 @@ describe('MetricVisComponent', function () { }); it('should report render complete', () => { + jest.spyOn(window, 'requestAnimationFrame').mockImplementation((cb) => { + cb(0); + return 0; + }); + const renderCompleteSpy = jest.fn(); const component = shallow( { diff --git a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx index f0aa3c3e1dede..cb352fe883152 100644 --- a/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx +++ b/src/plugins/chart_expressions/expression_metric/public/components/metric_vis.tsx @@ -134,7 +134,10 @@ export const MetricVis = ({ const onRenderChange = useCallback( (isRendered) => { if (isRendered) { - renderComplete(); + // this requestAnimationFrame call is a temporary fix for https://github.com/elastic/elastic-charts/issues/2124 + window.requestAnimationFrame(() => { + renderComplete(); + }); } }, [renderComplete] diff --git a/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx b/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx index a321aaf181e2d..c151741158ac1 100644 --- a/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx +++ b/src/plugins/chart_expressions/expression_partition_vis/public/components/partition_vis_component.tsx @@ -176,8 +176,11 @@ const PartitionVisComponent = (props: PartitionVisComponentProps) => { const onRenderChange = useCallback( (isRendered: boolean = true) => { if (isRendered) { - props.renderComplete(); - setChartIsLoaded(true); + // this requestAnimationFrame call is a temporary fix for https://github.com/elastic/elastic-charts/issues/2124 + window.requestAnimationFrame(() => { + props.renderComplete(); + setChartIsLoaded(true); + }); } }, [props] diff --git a/src/plugins/chart_expressions/expression_tagcloud/public/components/tagcloud_component.tsx b/src/plugins/chart_expressions/expression_tagcloud/public/components/tagcloud_component.tsx index 7fe65370693d5..adfc3df81f97f 100644 --- a/src/plugins/chart_expressions/expression_tagcloud/public/components/tagcloud_component.tsx +++ b/src/plugins/chart_expressions/expression_tagcloud/public/components/tagcloud_component.tsx @@ -145,7 +145,10 @@ export const TagCloudChart = ({ const onRenderChange = useCallback( (isRendered) => { if (isRendered) { - renderComplete(); + // this requestAnimationFrame call is a temporary fix for https://github.com/elastic/elastic-charts/issues/2124 + window.requestAnimationFrame(() => { + renderComplete(); + }); } }, [renderComplete] diff --git a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx index 0c19cc72d691c..e1ad4fa19d1c0 100644 --- a/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx +++ b/src/plugins/chart_expressions/expression_xy/public/components/xy_chart.tsx @@ -309,7 +309,10 @@ export function XYChart({ const onRenderChange = useCallback( (isRendered: boolean = true) => { if (isRendered) { - renderComplete(); + // this requestAnimationFrame call is a temporary fix for https://github.com/elastic/elastic-charts/issues/2124 + window.requestAnimationFrame(() => { + renderComplete(); + }); } }, [renderComplete] diff --git a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx index fb73392f2866e..3e7ae0e68f377 100644 --- a/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx +++ b/src/plugins/dashboard/public/dashboard_app/top_nav/dashboard_editing_toolbar.tsx @@ -110,7 +110,7 @@ export function DashboardEditingToolbar() { dashboard.addFromLibrary()} size="s" - data-test-subj="dashboardAddPanelButton" + data-test-subj="dashboardAddFromLibraryButton" />, ]; if (dashboard.controlGroup) { diff --git a/src/plugins/dashboard/public/dashboard_listing/_dashboard_listing_strings.ts b/src/plugins/dashboard/public/dashboard_listing/_dashboard_listing_strings.ts index 8887272da3d91..79cf7d7ed22f5 100644 --- a/src/plugins/dashboard/public/dashboard_listing/_dashboard_listing_strings.ts +++ b/src/plugins/dashboard/public/dashboard_listing/_dashboard_listing_strings.ts @@ -14,6 +14,13 @@ export const dashboardListingErrorStrings = { i18n.translate('dashboard.deleteError.toastDescription', { defaultMessage: 'Error encountered while deleting dashboard', }), + getDuplicateTitleWarning: (value: string) => + i18n.translate('dashboard.dashboardListingEditErrorTitle.duplicateWarning', { + defaultMessage: 'Saving "{value}" creates a duplicate title', + values: { + value, + }, + }), }; export const getNewDashboardTitle = () => diff --git a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.tsx b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.tsx index 94f9460c8f259..6d328fdc18e20 100644 --- a/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/dashboard_listing.tsx @@ -9,11 +9,11 @@ import { FormattedRelative, I18nProvider } from '@kbn/i18n-react'; import React, { useMemo } from 'react'; +import { TableListView } from '@kbn/content-management-table-list-view'; import { type TableListViewKibanaDependencies, TableListViewKibanaProvider, } from '@kbn/content-management-table-list-view-table'; -import { TableListView } from '@kbn/content-management-table-list-view'; import { toMountPoint, useExecutionContext } from '@kbn/kibana-react-plugin/public'; @@ -41,7 +41,6 @@ export const DashboardListing = ({ http, chrome: { theme }, savedObjectsTagging, - coreContext: { executionContext }, } = pluginServices.getServices(); diff --git a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx index ceb53af4bf2eb..7716981e34942 100644 --- a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.test.tsx @@ -136,6 +136,11 @@ describe('useDashboardListingTable', () => { setPageDataTestSubject: expect.any(Function), title: 'Dashboard List', urlStateEnabled: false, + contentEditor: { + onSave: expect.any(Function), + isReadonly: false, + customValidators: expect.any(Object), + }, }; expect(tableListViewTableProps).toEqual(expectedProps); diff --git a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx index f95f2649673b0..aefa45500b450 100644 --- a/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx +++ b/src/plugins/dashboard/public/dashboard_listing/hooks/use_dashboard_listing_table.tsx @@ -12,6 +12,8 @@ import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; import { TableListViewTableProps } from '@kbn/content-management-table-list-view-table'; import { ViewMode } from '@kbn/embeddable-plugin/public'; +import { OpenContentEditorParams } from '@kbn/content-management-content-editor'; +import { DashboardContainerInput } from '../../../common'; import { DashboardListingEmptyPrompt } from '../dashboard_listing_empty_prompt'; import { pluginServices } from '../../services/plugin_services'; import { @@ -81,8 +83,13 @@ export const useDashboardListingTable = ({ const { dashboardSessionStorage, dashboardCapabilities: { showWriteControls }, - dashboardContentManagement: { findDashboards, deleteDashboards }, settings: { uiSettings }, + dashboardContentManagement: { + findDashboards, + deleteDashboards, + updateDashboardMeta, + checkForDuplicateDashboardTitle, + }, notifications: { toasts }, } = pluginServices.getServices(); @@ -110,6 +117,49 @@ export const useDashboardListingTable = ({ goToDashboard(); }, [dashboardSessionStorage, goToDashboard, useSessionStorageIntegration]); + const updateItemMeta = useCallback( + async (props: Pick) => { + await updateDashboardMeta(props); + + setUnsavedDashboardIds(dashboardSessionStorage.getDashboardIdsWithUnsavedChanges()); + }, + [dashboardSessionStorage, updateDashboardMeta] + ); + + const contentEditorValidators: OpenContentEditorParams['customValidators'] = useMemo( + () => ({ + title: [ + { + type: 'warning', + fn: async (value: string, id: string) => { + if (id) { + try { + const [dashboard] = await findDashboards.findByIds([id]); + if (dashboard.status === 'error') { + return; + } + + const validTitle = await checkForDuplicateDashboardTitle({ + title: value, + copyOnSave: false, + lastSavedTitle: dashboard.attributes.title, + isTitleDuplicateConfirmed: false, + }); + + if (!validTitle) { + throw new Error(dashboardListingErrorStrings.getDuplicateTitleWarning(value)); + } + } catch (e) { + return e.message; + } + } + }, + }, + ], + }), + [checkForDuplicateDashboardTitle, findDashboards] + ); + const emptyPrompt = useMemo( () => ( ({ + contentEditor: { + isReadonly: !showWriteControls, + onSave: updateItemMeta, + customValidators: contentEditorValidators, + }, createItem: !showWriteControls ? undefined : createItem, deleteItems: !showWriteControls ? undefined : deleteItems, editItem: !showWriteControls ? undefined : editItem, @@ -238,6 +293,7 @@ export const useDashboardListingTable = ({ urlStateEnabled, }), [ + contentEditorValidators, createItem, dashboardListingId, deleteItems, @@ -254,6 +310,7 @@ export const useDashboardListingTable = ({ onFetchSuccess, showWriteControls, title, + updateItemMeta, urlStateEnabled, ] ); diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management.stub.ts b/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management.stub.ts index 9bb54da53653d..027e1d0e7d47d 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management.stub.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management.stub.ts @@ -73,5 +73,6 @@ export const dashboardContentManagementServiceFactory: DashboardContentManagemen }, deleteDashboards: jest.fn(), checkForDuplicateDashboardTitle: jest.fn(), + updateDashboardMeta: jest.fn(), }; }; diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management_service.ts b/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management_service.ts index 5a5c67c798606..08e7176e19059 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management_service.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/dashboard_content_management_service.ts @@ -23,6 +23,7 @@ import type { } from './types'; import { loadDashboardState } from './lib/load_dashboard_state'; import { deleteDashboards } from './lib/delete_dashboards'; +import { updateDashboardMeta } from './lib/update_dashboard_meta'; export type DashboardContentManagementServiceFactory = KibanaPluginServiceFactory< DashboardContentManagementService, @@ -79,5 +80,7 @@ export const dashboardContentManagementServiceFactory: DashboardContentManagemen checkForDuplicateDashboardTitle: (props) => checkForDuplicateDashboardTitle(props, contentManagement), deleteDashboards: (ids) => deleteDashboards(ids, contentManagement), + updateDashboardMeta: (props) => + updateDashboardMeta(props, { contentManagement, savedObjectsTagging, embeddable }), }; }; diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/lib/find_dashboards.ts b/src/plugins/dashboard/public/services/dashboard_content_management/lib/find_dashboards.ts index 41bdd60d6c1d7..2b2f6ac4804f7 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/lib/find_dashboards.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/lib/find_dashboards.ts @@ -8,6 +8,7 @@ import { SavedObjectError, SavedObjectsFindOptionsReference } from '@kbn/core/public'; +import { Reference } from '@kbn/content-management-utils'; import { DashboardItem, DashboardCrudTypes, @@ -60,7 +61,7 @@ export async function searchDashboards({ } export type FindDashboardsByIdResponse = { id: string } & ( - | { status: 'success'; attributes: DashboardAttributes } + | { status: 'success'; attributes: DashboardAttributes; references: Reference[] } | { status: 'error'; error: SavedObjectError } ); @@ -78,8 +79,8 @@ export async function findDashboardsByIds( return results.map((result) => { if (result.item.error) return { status: 'error', error: result.item.error, id: result.item.id }; - const { attributes, id } = result.item; - return { id, status: 'success', attributes }; + const { attributes, id, references } = result.item; + return { id, status: 'success', attributes, references }; }); } diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/lib/update_dashboard_meta.ts b/src/plugins/dashboard/public/services/dashboard_content_management/lib/update_dashboard_meta.ts new file mode 100644 index 0000000000000..75794f16b4082 --- /dev/null +++ b/src/plugins/dashboard/public/services/dashboard_content_management/lib/update_dashboard_meta.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { DashboardContainerInput } from '../../../../common'; +import { DashboardStartDependencies } from '../../../plugin'; +import { DASHBOARD_CONTENT_ID } from '../../../dashboard_constants'; +import { DashboardCrudTypes } from '../../../../common/content_management'; +import { findDashboardsByIds } from './find_dashboards'; +import { DashboardContentManagementRequiredServices } from '../types'; + +type UpdateDashboardMetaProps = Pick< + DashboardContainerInput, + 'id' | 'title' | 'description' | 'tags' +>; +interface UpdateDashboardMetaDependencies { + contentManagement: DashboardStartDependencies['contentManagement']; + savedObjectsTagging: DashboardContentManagementRequiredServices['savedObjectsTagging']; + embeddable: DashboardContentManagementRequiredServices['embeddable']; +} + +export const updateDashboardMeta = async ( + { id, title, description = '', tags }: UpdateDashboardMetaProps, + { contentManagement, savedObjectsTagging, embeddable }: UpdateDashboardMetaDependencies +) => { + const [dashboard] = await findDashboardsByIds(contentManagement, [id]); + if (dashboard.status === 'error') { + return; + } + + const references = + savedObjectsTagging.updateTagsReferences && tags.length + ? savedObjectsTagging.updateTagsReferences(dashboard.references, tags) + : dashboard.references; + + await contentManagement.client.update< + DashboardCrudTypes['UpdateIn'], + DashboardCrudTypes['UpdateOut'] + >({ + contentTypeId: DASHBOARD_CONTENT_ID, + id, + data: { title, description }, + options: { references }, + }); +}; diff --git a/src/plugins/dashboard/public/services/dashboard_content_management/types.ts b/src/plugins/dashboard/public/services/dashboard_content_management/types.ts index 92fbe3005e9e4..41e1ce55f979f 100644 --- a/src/plugins/dashboard/public/services/dashboard_content_management/types.ts +++ b/src/plugins/dashboard/public/services/dashboard_content_management/types.ts @@ -43,6 +43,9 @@ export interface DashboardContentManagementService { loadDashboardState: (props: { id?: string }) => Promise; saveDashboardState: (props: SaveDashboardProps) => Promise; checkForDuplicateDashboardTitle: (meta: DashboardDuplicateTitleCheckProps) => Promise; + updateDashboardMeta: ( + props: Pick + ) => Promise; } /** diff --git a/src/plugins/dashboard/tsconfig.json b/src/plugins/dashboard/tsconfig.json index d867472e423c3..6fd24d4e1fb01 100644 --- a/src/plugins/dashboard/tsconfig.json +++ b/src/plugins/dashboard/tsconfig.json @@ -62,7 +62,8 @@ "@kbn/core-saved-objects-api-server", "@kbn/content-management-table-list-view", "@kbn/content-management-table-list-view-table", - "@kbn/shared-ux-prompt-not-found" + "@kbn/shared-ux-prompt-not-found", + "@kbn/content-management-content-editor" ], "exclude": ["target/**/*"] } diff --git a/test/functional/apps/console/_console_ccs.ts b/test/functional/apps/console/_console_ccs.ts index f7c85f53c38d0..486223f02d320 100644 --- a/test/functional/apps/console/_console_ccs.ts +++ b/test/functional/apps/console/_console_ccs.ts @@ -32,7 +32,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await remoteEsArchiver.unload('test/functional/fixtures/es_archiver/logstash_functional'); }); - describe('Perform CCS Search in Console', () => { + // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/163365 + describe.skip('Perform CCS Search in Console', () => { before(async () => { await PageObjects.console.clearTextArea(); }); diff --git a/test/functional/apps/dashboard/group4/dashboard_listing.ts b/test/functional/apps/dashboard/group4/dashboard_listing.ts index 73ce3e472cede..d3cde4e185b9f 100644 --- a/test/functional/apps/dashboard/group4/dashboard_listing.ts +++ b/test/functional/apps/dashboard/group4/dashboard_listing.ts @@ -14,6 +14,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const PageObjects = getPageObjects(['dashboard', 'header', 'common']); const browser = getService('browser'); const listingTable = getService('listingTable'); + const testSubjects = getService('testSubjects'); + const retry = getService('retry'); + const dashboardAddPanel = getService('dashboardAddPanel'); describe('dashboard listing page', function describeIndexTests() { const dashboardName = 'Dashboard Listing Test'; @@ -46,6 +49,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const promptExists = await PageObjects.dashboard.getCreateDashboardPromptExists(); expect(promptExists).to.be(false); + await listingTable.clearSearchFilter(); }); }); @@ -200,5 +204,36 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { expect(onDashboardLandingPage).to.equal(false); }); }); + + describe('edit meta data', () => { + it('saves changes to dashboard metadata', async () => { + await PageObjects.dashboard.gotoDashboardLandingPage(); + await PageObjects.dashboard.clickCreateDashboardPrompt(); + await dashboardAddPanel.clickOpenAddPanel(); + await dashboardAddPanel.addEveryEmbeddableOnCurrentPage(); + await dashboardAddPanel.ensureAddPanelIsClosed(); + await PageObjects.dashboard.saveDashboard(`${dashboardName}-editMetaData`); + const originalPanelCount = await PageObjects.dashboard.getPanelCount(); + + await PageObjects.dashboard.gotoDashboardLandingPage(); + await listingTable.searchForItemWithName(`${dashboardName}-editMetaData`); + await testSubjects.click('inspect-action'); + await testSubjects.setValue('nameInput', 'new title'); + await testSubjects.setValue('descriptionInput', 'new description'); + await retry.try(async () => { + await testSubjects.click('saveButton'); + await testSubjects.missingOrFail('flyoutTitle'); + }); + + await listingTable.searchAndExpectItemsCount('dashboard', 'new title', 1); + await listingTable.setSearchFilterValue('new description'); + await listingTable.expectItemsCount('dashboard', 1); + await listingTable.clickItemLink('dashboard', 'new title'); + await PageObjects.dashboard.waitForRenderComplete(); + + const newPanelCount = await PageObjects.dashboard.getPanelCount(); + expect(newPanelCount).to.equal(originalPanelCount); + }); + }); }); } diff --git a/test/functional/apps/dashboard_elements/controls/common/control_group_chaining.ts b/test/functional/apps/dashboard_elements/controls/common/control_group_chaining.ts index 8d8bcfecf39c5..55d4e160a2e9c 100644 --- a/test/functional/apps/dashboard_elements/controls/common/control_group_chaining.ts +++ b/test/functional/apps/dashboard_elements/controls/common/control_group_chaining.ts @@ -26,8 +26,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { 'header', ]); - // Failing: See https://github.com/elastic/kibana/issues/162777 - describe.skip('Dashboard control group hierarchical chaining', () => { + describe('Dashboard control group hierarchical chaining', () => { const newDocuments: Array<{ index: string; id: string }> = []; let controlIds: string[]; diff --git a/test/functional/page_objects/dashboard_page_controls.ts b/test/functional/page_objects/dashboard_page_controls.ts index ff910de1a3fd6..bc5e44cf61c02 100644 --- a/test/functional/page_objects/dashboard_page_controls.ts +++ b/test/functional/page_objects/dashboard_page_controls.ts @@ -394,8 +394,15 @@ export class DashboardPageControls extends FtrService { return (await controlElement.getVisibleText()).split('\n')[1]; } + public async isOptionsListPopoverOpen(controlId: string) { + const isPopoverOpen = await this.find.existsByCssSelector(`#control-popover-${controlId}`); + this.log.debug(`Is popover open: ${isPopoverOpen} for Options List: ${controlId}`); + return isPopoverOpen; + } + public async optionsListOpenPopover(controlId: string) { this.log.debug(`Opening popover for Options List: ${controlId}`); + await this.testSubjects.click(`optionsList-control-${controlId}`); await this.retry.try(async () => { await this.testSubjects.existOrFail(`optionsList-control-popover`); @@ -403,9 +410,14 @@ export class DashboardPageControls extends FtrService { } public async optionsListEnsurePopoverIsClosed(controlId: string) { - this.log.debug(`Opening popover for Options List: ${controlId}`); - await this.testSubjects.click(`optionsList-control-${controlId}`); - await this.testSubjects.waitForDeleted(`optionsList-control-available-options`); + this.log.debug(`Ensure popover is closed for Options List: ${controlId}`); + await this.retry.try(async () => { + const isPopoverOpen = await this.isOptionsListPopoverOpen(controlId); + if (isPopoverOpen) { + await this.testSubjects.click(`optionsList-control-${controlId}`); + await this.testSubjects.waitForDeleted(`optionsList-control-available-options`); + } + }); } public async optionsListPopoverAssertOpen() { diff --git a/test/functional/services/dashboard/add_panel.ts b/test/functional/services/dashboard/add_panel.ts index c85210e06e29e..926e19cd43474 100644 --- a/test/functional/services/dashboard/add_panel.ts +++ b/test/functional/services/dashboard/add_panel.ts @@ -19,7 +19,7 @@ export class DashboardAddPanelService extends FtrService { async clickOpenAddPanel() { this.log.debug('DashboardAddPanel.clickOpenAddPanel'); - await this.testSubjects.click('dashboardAddPanelButton'); + await this.testSubjects.click('dashboardAddFromLibraryButton'); // Give some time for the animation to complete await this.common.sleep(500); } @@ -145,6 +145,20 @@ export class DashboardAddPanelService extends FtrService { } } + async ensureAddPanelIsClosed() { + this.log.debug('DashboardAddPanel.ensureAddPanelIsClosed'); + const isOpen = await this.isAddPanelOpen(); + if (isOpen) { + await this.retry.try(async () => { + await this.closeAddPanel(); + const isNowOpen = await this.isAddPanelOpen(); + if (isNowOpen) { + throw new Error('Add panel still open, trying again.'); + } + }); + } + } + async closeAddPanel() { await this.flyout.ensureAllClosed(); } diff --git a/test/functional/services/listing_table.ts b/test/functional/services/listing_table.ts index 414e8147e66ea..7c2ecbbda89fa 100644 --- a/test/functional/services/listing_table.ts +++ b/test/functional/services/listing_table.ts @@ -38,13 +38,19 @@ export class ListingTableService extends FtrService { return await searchFilter.getAttribute('value'); } + /** + * Set search input value on landing page + */ + public async setSearchFilterValue(value: string) { + const searchFilter = await this.getSearchFilter(); + searchFilter.type(value); + } + /** * Clears search input on landing page */ public async clearSearchFilter() { - const searchFilter = await this.getSearchFilter(); - await searchFilter.clearValue(); - await searchFilter.click(); + this.testSubjects.click('clearSearchButton'); } private async getAllItemsNamesOnCurrentPage(): Promise { diff --git a/test/functional/services/remote/create_stdout_stream.ts b/test/functional/services/remote/create_stdout_stream.ts index d136c2549bca0..cb42b5bae7c6b 100644 --- a/test/functional/services/remote/create_stdout_stream.ts +++ b/test/functional/services/remote/create_stdout_stream.ts @@ -53,7 +53,7 @@ export async function createStdoutSocket() { ) ).toPromise(); - server.listen(0); + server.listen(0, '127.0.0.1'); cleanup$.subscribe(() => { server.close(); }); diff --git a/test/plugin_functional/test_suites/core_plugins/rendering.ts b/test/plugin_functional/test_suites/core_plugins/rendering.ts index d150ef4e70612..673c092a546a9 100644 --- a/test/plugin_functional/test_suites/core_plugins/rendering.ts +++ b/test/plugin_functional/test_suites/core_plugins/rendering.ts @@ -187,7 +187,6 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.apm.latestAgentVersionsUrl (string)', 'xpack.apm.featureFlags.agentConfigurationAvailable (any)', 'xpack.apm.featureFlags.configurableIndicesAvailable (any)', - 'xpack.apm.featureFlags.fastRefreshAvailable (any)', 'xpack.apm.featureFlags.infrastructureTabAvailable (any)', 'xpack.apm.featureFlags.infraUiAvailable (any)', 'xpack.apm.featureFlags.migrationToFleetAvailable (any)', @@ -223,6 +222,7 @@ export default function ({ getService }: PluginFunctionalProviderContext) { 'xpack.cloud.profile_url (string)', 'xpack.cloud.performance_url (string)', 'xpack.cloud.users_and_roles_url (string)', + 'xpack.cloud.projects_url (any)', // It's a string (any because schema.conditional) // can't be used to infer urls or customer id from the outside 'xpack.cloud.serverless.project_id (string)', 'xpack.discoverEnhanced.actions.exploreDataInChart.enabled (boolean)', diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx index 20d4ffefcdbc8..4e87f58293f8b 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx @@ -5,8 +5,8 @@ * 2.0. */ -import React, { FC, useCallback, useMemo, useState } from 'react'; -import { orderBy } from 'lodash'; +import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import { orderBy, isEqual } from 'lodash'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import { @@ -336,6 +336,46 @@ export const LogRateAnalysisResultsTable: FC = }; }, [pageIndex, pageSize, sortField, sortDirection, significantTerms]); + useEffect(() => { + // If no row is hovered or pinned or the user switched to a new page, + // fall back to set the first row into a hovered state to make the + // main document count chart show a comparison view by default. + if ( + (selectedSignificantTerm === null || + !pageOfItems.some((item) => isEqual(item, selectedSignificantTerm))) && + pinnedSignificantTerm === null && + pageOfItems.length > 0 + ) { + setSelectedSignificantTerm(pageOfItems[0]); + } + + // If a user switched pages and a pinned row is no longer visible + // on the current page, set the status of pinned rows back to `null`. + if ( + pinnedSignificantTerm !== null && + !pageOfItems.some((item) => isEqual(item, pinnedSignificantTerm)) + ) { + setPinnedSignificantTerm(null); + } + }, [ + selectedSignificantTerm, + setSelectedSignificantTerm, + setPinnedSignificantTerm, + pageOfItems, + pinnedSignificantTerm, + ]); + + // When the analysis results table unmounts, + // make sure to reset any hovered or pinned rows. + useEffect( + () => () => { + setSelectedSignificantTerm(null); + setPinnedSignificantTerm(null); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + const getRowStyle = (significantTerm: SignificantTerm) => { if ( pinnedSignificantTerm && @@ -393,7 +433,9 @@ export const LogRateAnalysisResultsTable: FC = } }, onMouseEnter: () => { - setSelectedSignificantTerm(significantTerm); + if (pinnedSignificantTerm === null) { + setSelectedSignificantTerm(significantTerm); + } }, onMouseLeave: () => { setSelectedSignificantTerm(null); diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx index 0ab75f9902845..9f45c79b0746d 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table_groups.tsx @@ -5,8 +5,8 @@ * 2.0. */ -import React, { FC, useCallback, useMemo, useState } from 'react'; -import { orderBy } from 'lodash'; +import React, { FC, useCallback, useEffect, useMemo, useState } from 'react'; +import { orderBy, isEqual } from 'lodash'; import { useEuiBackgroundColor, @@ -423,6 +423,36 @@ export const LogRateAnalysisResultsGroupsTable: FC { + // If no row is hovered or pinned or the user switched to a new page, + // fall back to set the first row into a hovered state to make the + // main document count chart show a comparison view by default. + if ( + (selectedGroup === null || !pageOfItems.some((item) => isEqual(item, selectedGroup))) && + pinnedGroup === null && + pageOfItems.length > 0 + ) { + setSelectedGroup(pageOfItems[0]); + } + + // If a user switched pages and a pinned row is no longer visible + // on the current page, set the status of pinned rows back to `null`. + if (pinnedGroup !== null && !pageOfItems.some((item) => isEqual(item, pinnedGroup))) { + setPinnedGroup(null); + } + }, [selectedGroup, setSelectedGroup, setPinnedGroup, pageOfItems, pinnedGroup]); + + // When the analysis results table unmounts, + // make sure to reset any hovered or pinned rows. + useEffect( + () => () => { + setSelectedGroup(null); + setPinnedGroup(null); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + const getRowStyle = (group: GroupTableItem) => { if (pinnedGroup && pinnedGroup.id === group.id) { return { @@ -464,7 +494,9 @@ export const LogRateAnalysisResultsGroupsTable: FC { - setSelectedGroup(group); + if (pinnedGroup === null) { + setSelectedGroup(group); + } }, onMouseLeave: () => { setSelectedGroup(null); diff --git a/x-pack/plugins/apm/common/apm_feature_flags.ts b/x-pack/plugins/apm/common/apm_feature_flags.ts index 75dd58e7e66b8..0685555d02c1e 100644 --- a/x-pack/plugins/apm/common/apm_feature_flags.ts +++ b/x-pack/plugins/apm/common/apm_feature_flags.ts @@ -16,7 +16,6 @@ export enum ApmFeatureFlagName { MigrationToFleetAvailable = 'migrationToFleetAvailable', SourcemapApiAvailable = 'sourcemapApiAvailable', StorageExplorerAvailable = 'storageExplorerAvailable', - FastRefreshAvailable = 'fastRefreshAvailable', } const apmFeatureFlagMap = { @@ -48,10 +47,6 @@ const apmFeatureFlagMap = { default: true, type: t.boolean, }, - [ApmFeatureFlagName.FastRefreshAvailable]: { - default: false, - type: t.boolean, - }, }; type ApmFeatureFlagMap = typeof apmFeatureFlagMap; diff --git a/x-pack/plugins/apm/public/components/app/infra_overview/infra_tabs/failure_prompt.tsx b/x-pack/plugins/apm/public/components/app/infra_overview/infra_tabs/failure_prompt.tsx index 5c5158ee8c491..db6baee9d6d4d 100644 --- a/x-pack/plugins/apm/public/components/app/infra_overview/infra_tabs/failure_prompt.tsx +++ b/x-pack/plugins/apm/public/components/app/infra_overview/infra_tabs/failure_prompt.tsx @@ -5,42 +5,32 @@ * 2.0. */ -import { - EuiEmptyPrompt, - EuiPageTemplate_Deprecated as EuiPageTemplate, -} from '@elastic/eui'; +import { EuiEmptyPrompt } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; export function FailurePrompt() { return ( - - - {i18n.translate('xpack.apm.infraTabs.failurePromptTitle', { - defaultMessage: 'Unable to load your infrastructure data', - })} - - } - titleSize="m" - body={ -

- {i18n.translate('xpack.apm.infraTabs.failurePromptDescription', { - defaultMessage: - 'There was a problem loading the Infrastructure tab and your data. You can contact your administrator for help.', - })} -

- } - /> -
+ + {i18n.translate('xpack.apm.infraTabs.failurePromptTitle', { + defaultMessage: 'Unable to load your infrastructure data', + })} + + } + titleSize="m" + body={ +

+ {i18n.translate('xpack.apm.infraTabs.failurePromptDescription', { + defaultMessage: + 'There was a problem loading the Infrastructure tab and your data. You can contact your administrator for help.', + })} +

+ } + /> ); } diff --git a/x-pack/plugins/apm/public/components/app/settings/agent_keys/agent_keys_table.stories.tsx b/x-pack/plugins/apm/public/components/app/settings/agent_keys/agent_keys_table.stories.tsx index ad75c7ff60edf..296f66a51e98b 100644 --- a/x-pack/plugins/apm/public/components/app/settings/agent_keys/agent_keys_table.stories.tsx +++ b/x-pack/plugins/apm/public/components/app/settings/agent_keys/agent_keys_table.stories.tsx @@ -29,6 +29,7 @@ const KibanaReactContext = createKibanaReactContext(coreMock); const agentKeys: ApiKey[] = [ { + type: 'rest', id: 'M96XSX4BQcLuJqE2VX29', name: 'apm_api_key1', creation: 1641912161726, @@ -36,10 +37,11 @@ const agentKeys: ApiKey[] = [ username: 'elastic', realm: 'reserved', expiration: 0, + role_descriptors: {}, metadata: { application: 'apm' }, }, - { + type: 'rest', id: 'Nd6XSX4BQcLuJqE2eH2A', name: 'apm_api_key2', creation: 1641912170624, @@ -47,6 +49,7 @@ const agentKeys: ApiKey[] = [ username: 'elastic', realm: 'reserved', expiration: 0, + role_descriptors: {}, metadata: { application: 'apm' }, }, ]; diff --git a/x-pack/plugins/apm/public/context/apm_plugin/mock_apm_plugin_context.tsx b/x-pack/plugins/apm/public/context/apm_plugin/mock_apm_plugin_context.tsx index 1e80036885fc0..3e3a811504a61 100644 --- a/x-pack/plugins/apm/public/context/apm_plugin/mock_apm_plugin_context.tsx +++ b/x-pack/plugins/apm/public/context/apm_plugin/mock_apm_plugin_context.tsx @@ -79,7 +79,6 @@ const mockConfig: ConfigSchema = { migrationToFleetAvailable: true, sourcemapApiAvailable: true, storageExplorerAvailable: true, - fastRefreshAvailable: false, }, serverless: { enabled: false }, }; diff --git a/x-pack/plugins/apm/public/index.ts b/x-pack/plugins/apm/public/index.ts index a25c76e8e9e4a..446bb61f181b6 100644 --- a/x-pack/plugins/apm/public/index.ts +++ b/x-pack/plugins/apm/public/index.ts @@ -24,7 +24,6 @@ export interface ConfigSchema { migrationToFleetAvailable: boolean; sourcemapApiAvailable: boolean; storageExplorerAvailable: boolean; - fastRefreshAvailable: boolean; }; serverless: { enabled: boolean; diff --git a/x-pack/plugins/apm/server/feature.ts b/x-pack/plugins/apm/server/feature.ts index 292f48bf18156..09681f01da2d6 100644 --- a/x-pack/plugins/apm/server/feature.ts +++ b/x-pack/plugins/apm/server/feature.ts @@ -35,7 +35,7 @@ export const APM_FEATURE = { privileges: { all: { app: [APM_SERVER_FEATURE_ID, 'ux', 'kibana'], - api: [APM_SERVER_FEATURE_ID, 'apm_write', 'rac', 'ai_assistant'], + api: [APM_SERVER_FEATURE_ID, 'apm_write', 'rac'], catalogue: [APM_SERVER_FEATURE_ID], savedObject: { all: [], @@ -56,7 +56,7 @@ export const APM_FEATURE = { }, read: { app: [APM_SERVER_FEATURE_ID, 'ux', 'kibana'], - api: [APM_SERVER_FEATURE_ID, 'rac', 'ai_assistant'], + api: [APM_SERVER_FEATURE_ID, 'rac'], catalogue: [APM_SERVER_FEATURE_ID], savedObject: { all: [], diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts index 9662fa7d9b0e6..f79c83683a36b 100644 --- a/x-pack/plugins/apm/server/index.ts +++ b/x-pack/plugins/apm/server/index.ts @@ -23,15 +23,6 @@ const disabledOnServerless = schema.conditional( schema.oneOf([schema.literal(true)], { defaultValue: true }) ); -const enabledOnServerless = schema.conditional( - schema.contextRef('serverless'), - true, - schema.boolean({ - defaultValue: true, - }), - schema.oneOf([schema.literal(false)], { defaultValue: false }) -); - // All options should be documented in the APM configuration settings: https://github.com/elastic/kibana/blob/main/docs/settings/apm-settings.asciidoc // and be included on cloud allow list unless there are specific reasons not to const configSchema = schema.object({ @@ -97,7 +88,6 @@ const configSchema = schema.object({ migrationToFleetAvailable: disabledOnServerless, sourcemapApiAvailable: disabledOnServerless, storageExplorerAvailable: disabledOnServerless, - fastRefreshAvailable: enabledOnServerless, }), serverless: schema.object({ enabled: schema.conditional( diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts index d3979628f14b5..618c1b388bfab 100644 --- a/x-pack/plugins/apm/server/plugin.ts +++ b/x-pack/plugins/apm/server/plugin.ts @@ -277,7 +277,6 @@ export class APMPlugin const logger = this.logger; const client = core.elasticsearch.client.asInternalUser; - const { featureFlags } = this.currentConfig; // create .apm-agent-configuration index without blocking start lifecycle createApmAgentConfigurationIndex({ client, logger }).catch((e) => { @@ -286,7 +285,7 @@ export class APMPlugin }); // create .apm-custom-link index without blocking start lifecycle - createApmCustomLinkIndex({ client, logger, featureFlags }).catch((e) => { + createApmCustomLinkIndex({ client, logger }).catch((e) => { logger.error('Failed to create .apm-custom-link index'); logger.error(e); }); diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts index 1586abb500be2..b8bfc3b3f2f72 100644 --- a/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts +++ b/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts @@ -12,29 +12,19 @@ import { Mappings, } from '@kbn/observability-plugin/server'; import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/get_apm_indices'; -import { ApmFeatureFlags } from '../../../../common/apm_feature_flags'; export const createApmCustomLinkIndex = async ({ client, logger, - featureFlags, }: { client: ElasticsearchClient; logger: Logger; - featureFlags: ApmFeatureFlags; }) => { return createOrUpdateIndex({ index: APM_CUSTOM_LINK_INDEX, client, logger, mappings, - settings: featureFlags.fastRefreshAvailable - ? { - index: { - fast_refresh: true, - }, - } - : {}, }); }; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.scss b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.scss index 204de7d4b345d..29888d862db7c 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.scss +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.scss @@ -1,8 +1,8 @@ .canvasEmbeddable { .embPanel { - border: none; - border-style: none !important; + outline: none !important; background: none; + border-radius: 0 !important; .embPanel__title { margin-bottom: $euiSizeXS; diff --git a/x-pack/plugins/canvas/public/components/toolbar/toolbar.component.tsx b/x-pack/plugins/canvas/public/components/toolbar/toolbar.component.tsx index 24dd7c55e198a..b0eedd3720e4b 100644 --- a/x-pack/plugins/canvas/public/components/toolbar/toolbar.component.tsx +++ b/x-pack/plugins/canvas/public/components/toolbar/toolbar.component.tsx @@ -106,6 +106,7 @@ export const Toolbar: FC = ({ iconType="arrowLeft" isDisabled={selectedPageNumber <= 1} aria-label={strings.getPreviousPageAriaLabel()} + data-test-subj="previousPageButton" /> @@ -124,6 +125,7 @@ export const Toolbar: FC = ({ iconType="arrowRight" isDisabled={selectedPageNumber >= totalPages} aria-label={strings.getNextPageAriaLabel()} + data-test-subj="nextPageButton" /> diff --git a/x-pack/plugins/canvas/public/state/actions/elements.js b/x-pack/plugins/canvas/public/state/actions/elements.js index eb9dc23faac4a..b94a198ee4be9 100644 --- a/x-pack/plugins/canvas/public/state/actions/elements.js +++ b/x-pack/plugins/canvas/public/state/actions/elements.js @@ -7,7 +7,7 @@ import { createAction } from 'redux-actions'; import immutable from 'object-path-immutable'; -import { get, pick, cloneDeep, without, last, debounce } from 'lodash'; +import { get, pick, cloneDeep, without, last } from 'lodash'; import { toExpression, safeElementFromExpression } from '@kbn/interpreter'; import { createThunk } from '../../lib/create_thunk'; import { isGroupId } from '../../lib/workpad'; @@ -112,13 +112,7 @@ const fetchContextFn = ({ dispatch, getState }, index, element, fullRefresh = fa }); }; -// It is necessary to debounce fetching of the context in the situations -// when the components of the arguments update the expression. For example, suppose there are -// multiple datacolumns that change the column to the first one from the list after datasource update. -// In that case, it is necessary to fetch the context only for the last version of the expression. -const fetchContextFnDebounced = debounce(fetchContextFn, 100); - -export const fetchContext = createThunk('fetchContext', fetchContextFnDebounced); +export const fetchContext = createThunk('fetchContext', fetchContextFn); const fetchRenderableWithContextFn = ({ dispatch, getState }, element, ast, context) => { const argumentPath = [element.id, 'expressionRenderable']; @@ -148,15 +142,9 @@ const fetchRenderableWithContextFn = ({ dispatch, getState }, element, ast, cont }); }; -// It is necessary to debounce fetching of the renderable with the context in the situations -// when the components of the arguments update the expression. For example, suppose there are -// multiple datacolumns that change the column to the first one from the list after datasource update. -// In that case, it is necessary to fetch the context only for the last version of the expression. -const fetchRenderableWithContextFnDebounced = debounce(fetchRenderableWithContextFn, 100); - export const fetchRenderableWithContext = createThunk( 'fetchRenderableWithContext', - fetchRenderableWithContextFnDebounced + fetchRenderableWithContextFn ); export const fetchRenderable = createThunk('fetchRenderable', ({ dispatch }, element) => { diff --git a/x-pack/plugins/cloud/public/plugin.test.ts b/x-pack/plugins/cloud/public/plugin.test.ts index e0287222df888..f7cf7cb527580 100644 --- a/x-pack/plugins/cloud/public/plugin.test.ts +++ b/x-pack/plugins/cloud/public/plugin.test.ts @@ -15,6 +15,7 @@ const baseConfig = { deployment_url: '/abc123', profile_url: '/user/settings/', organization_url: '/account/', + projects_url: '/projects/', }; describe('Cloud Plugin', () => { @@ -60,6 +61,11 @@ describe('Cloud Plugin', () => { expect(setup.deploymentUrl).toBe('https://cloud.elastic.co/abc123'); }); + it('exposes projectsUrl', () => { + const { setup } = setupPlugin(); + expect(setup.projectsUrl).toBe('https://cloud.elastic.co/projects/'); + }); + it('exposes snapshotsUrl', () => { const { setup } = setupPlugin(); expect(setup.snapshotsUrl).toBe('https://cloud.elastic.co/abc123/elasticsearch/snapshots/'); diff --git a/x-pack/plugins/cloud/public/plugin.tsx b/x-pack/plugins/cloud/public/plugin.tsx index a12d090b0c9c4..60e6d7a1af08f 100644 --- a/x-pack/plugins/cloud/public/plugin.tsx +++ b/x-pack/plugins/cloud/public/plugin.tsx @@ -22,6 +22,7 @@ export interface CloudConfigType { base_url?: string; profile_url?: string; deployment_url?: string; + projects_url?: string; billing_url?: string; organization_url?: string; users_and_roles_url?: string; @@ -41,6 +42,7 @@ interface CloudUrls { snapshotsUrl?: string; performanceUrl?: string; usersAndRolesUrl?: string; + projectsUrl?: string; } export class CloudPlugin implements Plugin { @@ -121,6 +123,7 @@ export class CloudPlugin implements Plugin { organizationUrl, performanceUrl, usersAndRolesUrl, + projectsUrl, } = this.getCloudUrls(); let decodedId: DecodedCloudId | undefined; @@ -136,6 +139,7 @@ export class CloudPlugin implements Plugin { deploymentUrl, profileUrl, organizationUrl, + projectsUrl, elasticsearchUrl: decodedId?.elasticsearchUrl, kibanaUrl: decodedId?.kibanaUrl, isServerlessEnabled: this.isServerlessEnabled, @@ -158,6 +162,7 @@ export class CloudPlugin implements Plugin { base_url: baseUrl, performance_url: performanceUrl, users_and_roles_url: usersAndRolesUrl, + projects_url: projectsUrl, } = this.config; const fullCloudDeploymentUrl = getFullCloudUrl(baseUrl, deploymentUrl); @@ -166,6 +171,7 @@ export class CloudPlugin implements Plugin { const fullCloudOrganizationUrl = getFullCloudUrl(baseUrl, organizationUrl); const fullCloudPerformanceUrl = getFullCloudUrl(baseUrl, performanceUrl); const fullCloudUsersAndRolesUrl = getFullCloudUrl(baseUrl, usersAndRolesUrl); + const fullCloudProjectsUrl = getFullCloudUrl(baseUrl, projectsUrl); const fullCloudSnapshotsUrl = `${fullCloudDeploymentUrl}/${CLOUD_SNAPSHOTS_PATH}`; return { @@ -176,6 +182,7 @@ export class CloudPlugin implements Plugin { snapshotsUrl: fullCloudSnapshotsUrl, performanceUrl: fullCloudPerformanceUrl, usersAndRolesUrl: fullCloudUsersAndRolesUrl, + projectsUrl: fullCloudProjectsUrl, }; } } diff --git a/x-pack/plugins/cloud/public/types.ts b/x-pack/plugins/cloud/public/types.ts index df4512f185ea1..f6dfc71c6dfb2 100644 --- a/x-pack/plugins/cloud/public/types.ts +++ b/x-pack/plugins/cloud/public/types.ts @@ -44,6 +44,10 @@ export interface CloudStart { * The full URL to the users and roles page on Elastic Cloud. Undefined if not running on Cloud. */ usersAndRolesUrl?: string; + /** + * The full URL to the serverless projects page on Elastic Cloud. Undefined if not running in Serverless. + */ + projectsUrl?: string; /** * The full URL to the elasticsearch cluster. */ @@ -90,6 +94,10 @@ export interface CloudSetup { * The full URL to the deployment management page on Elastic Cloud. Undefined if not running on Cloud. */ deploymentUrl?: string; + /** + * The full URL to the serverless projects page on Elastic Cloud. Undefined if not running in Serverless. + */ + projectsUrl?: string; /** * The full URL to the user profile page on Elastic Cloud. Undefined if not running on Cloud. */ diff --git a/x-pack/plugins/cloud/server/config.ts b/x-pack/plugins/cloud/server/config.ts index c13c0b255e7f2..1efd9b50fc421 100644 --- a/x-pack/plugins/cloud/server/config.ts +++ b/x-pack/plugins/cloud/server/config.ts @@ -29,6 +29,12 @@ const configSchema = schema.object({ users_and_roles_url: schema.maybe(schema.string()), organization_url: schema.maybe(schema.string()), profile_url: schema.maybe(schema.string()), + projects_url: schema.conditional( + schema.contextRef('serverless'), + true, + schema.string({ defaultValue: '/projects/' }), + schema.never() + ), trial_end_date: schema.maybe(schema.string()), is_elastic_staff_owned: schema.maybe(schema.boolean()), serverless: schema.maybe( @@ -51,6 +57,7 @@ export const config: PluginConfigDescriptor = { performance_url: true, organization_url: true, profile_url: true, + projects_url: true, trial_end_date: true, is_elastic_staff_owned: true, serverless: { diff --git a/x-pack/plugins/cloud_security_posture/public/common/constants.ts b/x-pack/plugins/cloud_security_posture/public/common/constants.ts index 6a0a82c10c9db..3ef666a1c110f 100644 --- a/x-pack/plugins/cloud_security_posture/public/common/constants.ts +++ b/x-pack/plugins/cloud_security_posture/public/common/constants.ts @@ -212,3 +212,5 @@ export const cloudPostureIntegrations: CloudPostureIntegrations = { }; export const FINDINGS_DOCS_URL = 'https://ela.st/findings'; export const MIN_VERSION_GCP_CIS = '1.5.0'; + +export const NO_FINDINGS_STATUS_REFRESH_INTERVAL_MS = 10000; diff --git a/x-pack/plugins/cloud_security_posture/public/components/no_findings_states.tsx b/x-pack/plugins/cloud_security_posture/public/components/no_findings_states.tsx index 773956b73c7a8..a3227fee83dc5 100644 --- a/x-pack/plugins/cloud_security_posture/public/components/no_findings_states.tsx +++ b/x-pack/plugins/cloud_security_posture/public/components/no_findings_states.tsx @@ -31,8 +31,7 @@ import type { IndexDetails, PostureTypes } from '../../common/types'; import { cspIntegrationDocsNavigation } from '../common/navigation/constants'; import noDataIllustration from '../assets/illustrations/no_data_illustration.svg'; import { useCspIntegrationLink } from '../common/navigation/use_csp_integration_link'; - -const REFETCH_INTERVAL_MS = 20000; +import { NO_FINDINGS_STATUS_REFRESH_INTERVAL_MS } from '../common/constants'; const NotDeployed = () => { // using an existing hook to get agent id and package policy id @@ -248,7 +247,7 @@ const ConfigurationFindingsInstalledEmptyPrompt = ({ * */ export const NoFindingsStates = ({ posturetype }: { posturetype: PostureTypes }) => { const getSetupStatus = useCspSetupStatusApi({ - refetchInterval: REFETCH_INTERVAL_MS, + refetchInterval: NO_FINDINGS_STATUS_REFRESH_INTERVAL_MS, }); const statusKspm = getSetupStatus.data?.kspm?.status; const statusCspm = getSetupStatus.data?.cspm?.status; diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx index afcaf69facef6..1c8da9db27871 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.test.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { coreMock } from '@kbn/core/public/mocks'; import { render, screen } from '@testing-library/react'; import { TestProvider } from '../../test/test_provider'; -import { ComplianceDashboard } from '.'; +import { ComplianceDashboard, getDefaultTab } from '.'; import { useCspSetupStatusApi } from '../../common/api/use_setup_status_api'; import { useLicenseManagementLocatorApi } from '../../common/api/use_license_management_locator_api'; import { useSubscriptionStatus } from '../../common/hooks/use_subscription_status'; @@ -21,6 +21,7 @@ import { KUBERNETES_DASHBOARD_CONTAINER, KUBERNETES_DASHBOARD_TAB, CLOUD_DASHBOARD_TAB, + CLOUD_POSTURE_DASHBOARD_PAGE_HEADER, } from './test_subjects'; import { mockDashboardData } from './mock'; import { createReactQueryResponse } from '../../test/fixtures/react_query'; @@ -29,7 +30,9 @@ import { expectIdsInDoc } from '../../test/utils'; import { CSPM_INTEGRATION_NOT_INSTALLED_TEST_SUBJECT, KSPM_INTEGRATION_NOT_INSTALLED_TEST_SUBJECT, + PACKAGE_NOT_INSTALLED_TEST_SUBJECT, } from '../../components/cloud_posture_page'; +import { BaseCspSetupStatus, ComplianceDashboardData, CspStatusCode } from '../../../common/types'; jest.mock('../../common/api/use_setup_status_api'); jest.mock('../../common/api/use_stats_api'); @@ -73,10 +76,10 @@ describe('', () => { ); }); - const renderComplianceDashboardPage = () => { + const ComplianceDashboardWithTestProviders = () => { const mockCore = coreMock.createStart(); - render( + return ( ', () => { ); }; + const renderComplianceDashboardPage = () => { + return render(); + }; + + it('shows package not installed page instead of tabs', () => { + (useCspSetupStatusApi as jest.Mock).mockImplementation(() => + createReactQueryResponse({ + status: 'success', + data: { + kspm: { status: 'not-installed', healthyAgents: 0, installedPackagePolicies: 0 }, + cspm: { status: 'not-installed', healthyAgents: 0, installedPackagePolicies: 0 }, + isPluginInitialized: false, + indicesDetails: [ + { index: 'logs-cloud_security_posture.findings_latest-default', status: 'empty' }, + { index: 'logs-cloud_security_posture.findings-default*', status: 'empty' }, + ], + }, + }) + ); + (useKspmStatsApi as jest.Mock).mockImplementation(() => ({ + isSuccess: true, + isLoading: false, + data: { stats: { totalFindings: 0 } }, + })); + (useCspmStatsApi as jest.Mock).mockImplementation(() => ({ + isSuccess: true, + isLoading: false, + data: { stats: { totalFindings: 0 } }, + })); + + renderComplianceDashboardPage(); + + expectIdsInDoc({ + be: [PACKAGE_NOT_INSTALLED_TEST_SUBJECT, CLOUD_POSTURE_DASHBOARD_PAGE_HEADER], + notToBe: [ + NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED, + NO_FINDINGS_STATUS_TEST_SUBJ.INDEXING, + NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, + NO_FINDINGS_STATUS_TEST_SUBJ.UNPRIVILEGED, + CLOUD_DASHBOARD_CONTAINER, + KUBERNETES_DASHBOARD_CONTAINER, + ], + }); + }); + it('no findings state: not-deployed - shows NotDeployed instead of dashboard', () => { (useCspSetupStatusApi as jest.Mock).mockImplementation(() => createReactQueryResponse({ @@ -124,11 +172,13 @@ describe('', () => { renderComplianceDashboardPage(); expectIdsInDoc({ - be: [NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED], + be: [NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED, CLOUD_DASHBOARD_TAB], notToBe: [ NO_FINDINGS_STATUS_TEST_SUBJ.INDEXING, NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, NO_FINDINGS_STATUS_TEST_SUBJ.UNPRIVILEGED, + CLOUD_DASHBOARD_CONTAINER, + KUBERNETES_DASHBOARD_CONTAINER, ], }); }); @@ -162,11 +212,53 @@ describe('', () => { renderComplianceDashboardPage(); expectIdsInDoc({ - be: [NO_FINDINGS_STATUS_TEST_SUBJ.INDEXING], + be: [NO_FINDINGS_STATUS_TEST_SUBJ.INDEXING, CLOUD_DASHBOARD_TAB], notToBe: [ NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED, NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, NO_FINDINGS_STATUS_TEST_SUBJ.UNPRIVILEGED, + CLOUD_DASHBOARD_CONTAINER, + KUBERNETES_DASHBOARD_CONTAINER, + ], + }); + }); + + it('no findings state: indexing - shows Indexing instead of dashboard when waiting_for_results', () => { + (useCspSetupStatusApi as jest.Mock).mockImplementation(() => + createReactQueryResponse({ + status: 'success', + data: { + kspm: { status: 'waiting_for_results', healthyAgents: 1, installedPackagePolicies: 1 }, + cspm: { status: 'waiting_for_results', healthyAgents: 1, installedPackagePolicies: 1 }, + installedPackageVersion: '1.2.13', + indicesDetails: [ + { index: 'logs-cloud_security_posture.findings_latest-default', status: 'empty' }, + { index: 'logs-cloud_security_posture.findings-default*', status: 'empty' }, + ], + }, + }) + ); + (useKspmStatsApi as jest.Mock).mockImplementation(() => ({ + isSuccess: true, + isLoading: false, + data: { stats: { totalFindings: 1 } }, + })); + (useCspmStatsApi as jest.Mock).mockImplementation(() => ({ + isSuccess: true, + isLoading: false, + data: { stats: { totalFindings: 1 } }, + })); + + renderComplianceDashboardPage(); + + expectIdsInDoc({ + be: [NO_FINDINGS_STATUS_TEST_SUBJ.INDEXING, CLOUD_DASHBOARD_TAB], + notToBe: [ + NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED, + NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, + NO_FINDINGS_STATUS_TEST_SUBJ.UNPRIVILEGED, + CLOUD_DASHBOARD_CONTAINER, + KUBERNETES_DASHBOARD_CONTAINER, ], }); }); @@ -200,11 +292,13 @@ describe('', () => { renderComplianceDashboardPage(); expectIdsInDoc({ - be: [NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT], + be: [NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, CLOUD_DASHBOARD_TAB], notToBe: [ NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED, NO_FINDINGS_STATUS_TEST_SUBJ.INDEXING, NO_FINDINGS_STATUS_TEST_SUBJ.UNPRIVILEGED, + CLOUD_DASHBOARD_CONTAINER, + KUBERNETES_DASHBOARD_CONTAINER, ], }); }); @@ -238,11 +332,13 @@ describe('', () => { renderComplianceDashboardPage(); expectIdsInDoc({ - be: [NO_FINDINGS_STATUS_TEST_SUBJ.UNPRIVILEGED], + be: [NO_FINDINGS_STATUS_TEST_SUBJ.UNPRIVILEGED, CLOUD_DASHBOARD_TAB], notToBe: [ NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED, NO_FINDINGS_STATUS_TEST_SUBJ.INDEXING, NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, + CLOUD_DASHBOARD_CONTAINER, + KUBERNETES_DASHBOARD_CONTAINER, ], }); }); @@ -276,7 +372,7 @@ describe('', () => { renderComplianceDashboardPage(); expectIdsInDoc({ - be: [DASHBOARD_CONTAINER], + be: [CLOUD_DASHBOARD_TAB, DASHBOARD_CONTAINER, CLOUD_DASHBOARD_CONTAINER], notToBe: [ NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED, @@ -315,7 +411,7 @@ describe('', () => { renderComplianceDashboardPage(); expectIdsInDoc({ - be: [KUBERNETES_DASHBOARD_CONTAINER], + be: [KUBERNETES_DASHBOARD_TAB, KUBERNETES_DASHBOARD_CONTAINER], notToBe: [ CLOUD_DASHBOARD_CONTAINER, NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, @@ -354,7 +450,7 @@ describe('', () => { renderComplianceDashboardPage(); expectIdsInDoc({ - be: [CLOUD_DASHBOARD_CONTAINER], + be: [CLOUD_DASHBOARD_TAB, CLOUD_DASHBOARD_CONTAINER], notToBe: [ KUBERNETES_DASHBOARD_CONTAINER, NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, @@ -550,10 +646,12 @@ describe('', () => { data: { stats: { totalFindings: 0 } }, })); - renderComplianceDashboardPage(); + const { rerender } = renderComplianceDashboardPage(); screen.getByTestId(CLOUD_DASHBOARD_TAB).click(); + rerender(); + expectIdsInDoc({ be: [CSPM_INTEGRATION_NOT_INSTALLED_TEST_SUBJECT], notToBe: [ @@ -607,4 +705,148 @@ describe('', () => { ], }); }); + + it('should not select default tab is user has already selected one themselves', () => { + (useCspSetupStatusApi as jest.Mock).mockImplementation(() => + createReactQueryResponse({ + status: 'success', + data: { + kspm: { status: 'not-installed' }, + cspm: { status: 'indexed' }, + installedPackageVersion: '1.2.13', + indicesDetails: [ + { index: 'logs-cloud_security_posture.findings_latest-default', status: 'not-empty' }, + { index: 'logs-cloud_security_posture.findings-default*', status: 'empty' }, + ], + }, + }) + ); + (useKspmStatsApi as jest.Mock).mockImplementation(() => ({ + isSuccess: true, + isLoading: false, + data: { stats: { totalFindings: 0 } }, + })); + (useCspmStatsApi as jest.Mock).mockImplementation(() => ({ + isSuccess: true, + isLoading: false, + data: mockDashboardData, + })); + + const { rerender } = renderComplianceDashboardPage(); + + expectIdsInDoc({ + be: [CLOUD_DASHBOARD_CONTAINER], + notToBe: [ + KUBERNETES_DASHBOARD_CONTAINER, + NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, + NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED, + NO_FINDINGS_STATUS_TEST_SUBJ.INDEXING, + NO_FINDINGS_STATUS_TEST_SUBJ.UNPRIVILEGED, + ], + }); + + screen.getByTestId(KUBERNETES_DASHBOARD_TAB).click(); + + rerender(); + + expectIdsInDoc({ + be: [KSPM_INTEGRATION_NOT_INSTALLED_TEST_SUBJECT], + notToBe: [ + CLOUD_DASHBOARD_CONTAINER, + NO_FINDINGS_STATUS_TEST_SUBJ.INDEX_TIMEOUT, + NO_FINDINGS_STATUS_TEST_SUBJ.NO_AGENTS_DEPLOYED, + NO_FINDINGS_STATUS_TEST_SUBJ.INDEXING, + NO_FINDINGS_STATUS_TEST_SUBJ.UNPRIVILEGED, + ], + }); + }); +}); + +describe('getDefaultTab', () => { + const getPluginStatusMock = (cspmStatus: CspStatusCode, kspmStatus: CspStatusCode) => { + return { + cspm: { status: cspmStatus }, + kspm: { status: kspmStatus }, + }; + }; + const getStatsMock = (findings: number) => { + return { + stats: { + totalFindings: findings, + }, + }; + }; + + it('returns CSPM tab if only CSPM has findings', () => { + const pluginStatus = getPluginStatusMock('indexed', 'indexed') as BaseCspSetupStatus; + const cspmStats = getStatsMock(1) as ComplianceDashboardData; + const kspmStats = getStatsMock(0) as ComplianceDashboardData; + + expect(getDefaultTab(pluginStatus, cspmStats, kspmStats)).toEqual('cspm'); + }); + + it('returns CSPM tab if both CSPM and KSPM has findings', () => { + const pluginStatus = getPluginStatusMock('indexed', 'indexed') as BaseCspSetupStatus; + const cspmStats = getStatsMock(1) as ComplianceDashboardData; + const kspmStats = getStatsMock(1) as ComplianceDashboardData; + + expect(getDefaultTab(pluginStatus, cspmStats, kspmStats)).toEqual('cspm'); + }); + + it('returns KSPM tab if only KSPM has findings', () => { + const pluginStatus = getPluginStatusMock('indexed', 'indexed') as BaseCspSetupStatus; + const cspmStats = getStatsMock(0) as ComplianceDashboardData; + const kspmStats = getStatsMock(1) as ComplianceDashboardData; + + expect(getDefaultTab(pluginStatus, cspmStats, kspmStats)).toEqual('kspm'); + }); + + it('when no findings preffers CSPM tab unless not-installed or unprivileged', () => { + const cspmStats = getStatsMock(0) as ComplianceDashboardData; + const kspmStats = getStatsMock(0) as ComplianceDashboardData; + const CspStatusCodeArray: CspStatusCode[] = [ + 'indexed', + 'indexing', + 'unprivileged', + 'index-timeout', + 'not-deployed', + 'not-installed', + 'waiting_for_results', + ]; + + CspStatusCodeArray.forEach((cspmStatus) => { + CspStatusCodeArray.forEach((kspmStatus) => { + let expectedTab = 'cspm'; + const pluginStatus = getPluginStatusMock(cspmStatus, kspmStatus) as BaseCspSetupStatus; + + if ( + (cspmStatus === 'not-installed' || cspmStatus === 'unprivileged') && + kspmStatus !== 'not-installed' && + kspmStatus !== 'unprivileged' + ) { + expectedTab = 'kspm'; + } + + expect(getDefaultTab(pluginStatus, cspmStats, kspmStats)).toEqual(expectedTab); + }); + }); + }); + + it('returns CSPM tab is plugin status and kspm status is not provided', () => { + const cspmStats = getStatsMock(1) as ComplianceDashboardData; + + expect(getDefaultTab(undefined, cspmStats, undefined)).toEqual('cspm'); + }); + + it('returns KSPM tab is plugin status and csp status is not provided', () => { + const kspmStats = getStatsMock(1) as ComplianceDashboardData; + + expect(getDefaultTab(undefined, undefined, kspmStats)).toEqual('kspm'); + }); + + it('returns CSPM tab when only plugins status data is provided', () => { + const pluginStatus = getPluginStatusMock('indexed', 'indexed') as BaseCspSetupStatus; + + expect(getDefaultTab(pluginStatus, undefined, undefined)).toEqual('cspm'); + }); }); diff --git a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx index fe4f62dbbc8f5..8b7b0d5c841af 100644 --- a/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx +++ b/x-pack/plugins/cloud_security_posture/public/pages/compliance_dashboard/compliance_dashboard.tsx @@ -6,6 +6,7 @@ */ import React, { useEffect, useMemo, useState } from 'react'; +import { UseQueryResult } from '@tanstack/react-query'; import { EuiEmptyPrompt, EuiIcon, EuiLink, EuiPageHeader, EuiSpacer } from '@elastic/eui'; import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; @@ -40,6 +41,10 @@ import { SummarySection } from './dashboard_sections/summary_section'; import { BenchmarksSection } from './dashboard_sections/benchmarks_section'; import { CSPM_POLICY_TEMPLATE, KSPM_POLICY_TEMPLATE } from '../../../common/constants'; import { cspIntegrationDocsNavigation } from '../../common/navigation/constants'; +import { NO_FINDINGS_STATUS_REFRESH_INTERVAL_MS } from '../../common/constants'; + +const POSTURE_TYPE_CSPM = CSPM_POLICY_TEMPLATE; +const POSTURE_TYPE_KSPM = KSPM_POLICY_TEMPLATE; const noDataOptions: Record< PosturePolicyTemplate, @@ -181,7 +186,7 @@ const IntegrationPostureDashboard = ({ ); }; -const getDefaultTab = ( +export const getDefaultTab = ( pluginStatus?: BaseCspSetupStatus, cspmStats?: ComplianceDashboardData, kspmStats?: ComplianceDashboardData @@ -190,42 +195,109 @@ const getDefaultTab = ( const kspmTotalFindings = kspmStats?.stats.totalFindings; const installedPolicyTemplatesCspm = pluginStatus?.cspm?.status; const installedPolicyTemplatesKspm = pluginStatus?.kspm?.status; - let preferredDashboard = CSPM_POLICY_TEMPLATE; + let preferredDashboard = POSTURE_TYPE_CSPM; // cspm has findings if (!!cspmTotalFindings) { - preferredDashboard = CSPM_POLICY_TEMPLATE; + preferredDashboard = POSTURE_TYPE_CSPM; } // kspm has findings else if (!!kspmTotalFindings) { - preferredDashboard = KSPM_POLICY_TEMPLATE; + preferredDashboard = POSTURE_TYPE_KSPM; } // cspm is installed else if ( installedPolicyTemplatesCspm !== 'unprivileged' && installedPolicyTemplatesCspm !== 'not-installed' ) { - preferredDashboard = CSPM_POLICY_TEMPLATE; + preferredDashboard = POSTURE_TYPE_CSPM; } // kspm is installed else if ( installedPolicyTemplatesKspm !== 'unprivileged' && installedPolicyTemplatesKspm !== 'not-installed' ) { - preferredDashboard = KSPM_POLICY_TEMPLATE; + preferredDashboard = POSTURE_TYPE_KSPM; } return preferredDashboard; }; -export const ComplianceDashboard = () => { - const [selectedTab, setSelectedTab] = useState(CSPM_POLICY_TEMPLATE); - const { data: getSetupStatus } = useCspSetupStatusApi(); +const determineDashboardDataRefetchInterval = (data: ComplianceDashboardData | undefined) => { + if (data?.stats.totalFindings === 0) { + return NO_FINDINGS_STATUS_REFRESH_INTERVAL_MS; + } + return false; +}; + +const TabContent = ({ posturetype }: { posturetype: PosturePolicyTemplate }) => { + const { data: getSetupStatus } = useCspSetupStatusApi({ + refetchInterval: (data) => { + if (data?.[posturetype]?.status === 'indexed') { + return false; + } + + return NO_FINDINGS_STATUS_REFRESH_INTERVAL_MS; + }, + }); + const isCloudSecurityPostureInstalled = !!getSetupStatus?.installedPackageVersion; + const getCspmDashboardData = useCspmStatsApi({ + enabled: isCloudSecurityPostureInstalled && posturetype === POSTURE_TYPE_CSPM, + refetchInterval: determineDashboardDataRefetchInterval, + }); + const getKspmDashboardData = useKspmStatsApi({ + enabled: isCloudSecurityPostureInstalled && posturetype === POSTURE_TYPE_KSPM, + refetchInterval: determineDashboardDataRefetchInterval, + }); + const setupStatus = getSetupStatus?.[posturetype]?.status; + const isStatusManagedInDashboard = setupStatus === 'indexed' || setupStatus === 'not-installed'; + const shouldRenderNoFindings = !isCloudSecurityPostureInstalled || !isStatusManagedInDashboard; const cspmIntegrationLink = useCspIntegrationLink(CSPM_POLICY_TEMPLATE); const kspmIntegrationLink = useCspIntegrationLink(KSPM_POLICY_TEMPLATE); - const isCloudSecurityPostureInstalled = !!getSetupStatus?.installedPackageVersion; + let integrationLink; + let dataTestSubj; + let policyTemplate: PosturePolicyTemplate; + let getDashboardData: UseQueryResult; + switch (posturetype) { + case POSTURE_TYPE_CSPM: + integrationLink = cspmIntegrationLink; + dataTestSubj = CLOUD_DASHBOARD_CONTAINER; + policyTemplate = CSPM_POLICY_TEMPLATE; + getDashboardData = getCspmDashboardData; + break; + case POSTURE_TYPE_KSPM: + integrationLink = kspmIntegrationLink; + dataTestSubj = KUBERNETES_DASHBOARD_CONTAINER; + policyTemplate = KSPM_POLICY_TEMPLATE; + getDashboardData = getKspmDashboardData; + break; + } + + if (shouldRenderNoFindings) { + return ; + } + + return ( + +
+ +
+
+ ); +}; + +export const ComplianceDashboard = () => { + const [selectedTab, setSelectedTab] = useState(POSTURE_TYPE_CSPM); + const [hasUserSelectedTab, setHasUserSelectedTab] = useState(false); + const { data: getSetupStatus } = useCspSetupStatusApi(); + const isCloudSecurityPostureInstalled = !!getSetupStatus?.installedPackageVersion; const getCspmDashboardData = useCspmStatsApi({ enabled: isCloudSecurityPostureInstalled, }); @@ -234,6 +306,10 @@ export const ComplianceDashboard = () => { }); useEffect(() => { + if (hasUserSelectedTab) { + return; + } + const preferredDashboard = getDefaultTab( getSetupStatus, getCspmDashboardData.data, @@ -248,6 +324,7 @@ export const ComplianceDashboard = () => { getSetupStatus, getSetupStatus?.cspm?.status, getSetupStatus?.kspm?.status, + hasUserSelectedTab, ]); const tabs = useMemo( @@ -259,75 +336,28 @@ export const ComplianceDashboard = () => { defaultMessage: 'Cloud', }), 'data-test-subj': CLOUD_DASHBOARD_TAB, - isSelected: selectedTab === CSPM_POLICY_TEMPLATE, - onClick: () => setSelectedTab(CSPM_POLICY_TEMPLATE), - content: ( - <> - {isCloudSecurityPostureInstalled && - (getSetupStatus?.cspm?.status === 'indexed' || - getSetupStatus?.cspm?.status === 'not-installed') ? ( - -
- -
-
- ) : ( - - )} - - ), + isSelected: selectedTab === POSTURE_TYPE_CSPM, + onClick: () => { + setSelectedTab(POSTURE_TYPE_CSPM); + setHasUserSelectedTab(true); + }, + content: , }, { label: i18n.translate('xpack.csp.dashboardTabs.kubernetesTab.tabTitle', { defaultMessage: 'Kubernetes', }), 'data-test-subj': KUBERNETES_DASHBOARD_TAB, - isSelected: selectedTab === KSPM_POLICY_TEMPLATE, - onClick: () => setSelectedTab(KSPM_POLICY_TEMPLATE), - content: ( - <> - {isCloudSecurityPostureInstalled && - (getSetupStatus?.kspm?.status === 'indexed' || - getSetupStatus?.kspm?.status === 'not-installed') ? ( - -
- -
-
- ) : ( - - )} - - ), + isSelected: selectedTab === POSTURE_TYPE_KSPM, + onClick: () => { + setSelectedTab(POSTURE_TYPE_KSPM); + setHasUserSelectedTab(true); + }, + content: , }, ] : [], - [ - cspmIntegrationLink, - getCspmDashboardData, - getKspmDashboardData, - kspmIntegrationLink, - selectedTab, - isCloudSecurityPostureInstalled, - getSetupStatus?.cspm?.status, - getSetupStatus?.kspm?.status, - ] + [selectedTab, isCloudSecurityPostureInstalled] ); return ( @@ -354,7 +384,7 @@ export const ComplianceDashboard = () => { `} > {tabs.find((t) => t.isSelected)?.content} - {!isCloudSecurityPostureInstalled && } + {!isCloudSecurityPostureInstalled && } ); diff --git a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/installation_stats_collector.ts b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/installation_stats_collector.ts index 0be4dd2703f79..09b197245cd5a 100644 --- a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/installation_stats_collector.ts +++ b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/installation_stats_collector.ts @@ -8,8 +8,8 @@ import type { CoreStart, Logger, SavedObjectsClientContract } from '@kbn/core/se import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server'; import { AgentPolicy, - PackagePolicy, PACKAGE_POLICY_SAVED_OBJECT_TYPE, + PackagePolicy, SO_SEARCH_LIMIT, } from '@kbn/fleet-plugin/common'; import { agentPolicyService } from '@kbn/fleet-plugin/server/services'; @@ -17,6 +17,53 @@ import type { CloudSecurityInstallationStats } from './types'; import type { CspServerPluginStart, CspServerPluginStartDeps } from '../../../types'; import { CLOUD_SECURITY_POSTURE_PACKAGE_NAME } from '../../../../common/constants'; +const getEnabledInputStreamVars = (packagePolicy: PackagePolicy) => { + const enabledInput = packagePolicy.inputs.find((input) => input.enabled); + return enabledInput?.streams[0].vars; +}; + +const getAccountTypeField = ( + packagePolicy: PackagePolicy +): CloudSecurityInstallationStats['account_type'] => { + if (packagePolicy.vars?.posture.value !== 'cspm') return; + + const inputStreamVars = getEnabledInputStreamVars(packagePolicy); + const cloudProvider = packagePolicy.vars?.deployment?.value; + const accountType = inputStreamVars?.[`${cloudProvider}.account_type`]?.value; + + // If the account_type field is not present, we can assume that the cspm integrations is a single accounts, + // as this field did not exist before organization accounts were introduced. + if (!accountType) return 'single-account'; + + return accountType; +}; + +const getInstalledPackagePolicies = ( + packagePolicies: PackagePolicy[], + agentPolicies: AgentPolicy[] +) => { + const installationStats = packagePolicies.map( + (packagePolicy: PackagePolicy): CloudSecurityInstallationStats => { + const agentCounts = + agentPolicies?.find((agentPolicy) => agentPolicy?.id === packagePolicy.policy_id)?.agents ?? + 0; + + return { + package_policy_id: packagePolicy.id, + feature: packagePolicy.vars?.posture?.value as string, + deployment_mode: packagePolicy.vars?.deployment?.value as string, + package_version: packagePolicy.package?.version as string, + created_at: packagePolicy.created_at, + agent_policy_id: packagePolicy.policy_id, + agent_count: agentCounts, + account_type: getAccountTypeField(packagePolicy), + }; + } + ); + + return installationStats; +}; + export const getInstallationStats = async ( esClient: ElasticsearchClient, soClient: SavedObjectsClientContract, @@ -34,34 +81,11 @@ export const getInstallationStats = async ( isPluginInitialized, }; - const getInstalledPackagePolicies = async ( - packagePolicies: PackagePolicy[], - agentPolicies: AgentPolicy[] - ) => { - const installationStats = await packagePolicies.map( - (packagePolicy: PackagePolicy): CloudSecurityInstallationStats => { - const agentCounts = - agentPolicies?.find((agentPolicy) => agentPolicy?.id === packagePolicy.policy_id) - ?.agents ?? 0; - - return { - package_policy_id: packagePolicy.id, - feature: packagePolicy.vars?.posture?.value as string, - deployment_mode: packagePolicy.vars?.deployment?.value as string, - package_version: packagePolicy.package?.version as string, - created_at: packagePolicy.created_at, - agent_policy_id: packagePolicy.policy_id, - agent_count: agentCounts, - }; - } - ); - return installationStats; - }; - const packagePolicies = await cspContext.packagePolicyService.list(soClient, { perPage: SO_SEARCH_LIMIT, kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name:"${CLOUD_SECURITY_POSTURE_PACKAGE_NAME}"`, }); + if (!packagePolicies) return []; const agentPolicies = await agentPolicyService.list(soClient, { perPage: SO_SEARCH_LIMIT, @@ -69,9 +93,8 @@ export const getInstallationStats = async ( esClient, withAgentCount: true, }); - if (!packagePolicies) return []; - const installationStats: CloudSecurityInstallationStats[] = await getInstalledPackagePolicies( + const installationStats: CloudSecurityInstallationStats[] = getInstalledPackagePolicies( packagePolicies.items, agentPolicies?.items || [] ); diff --git a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/schema.ts b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/schema.ts index 50c766135133f..578f2c17894df 100644 --- a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/schema.ts +++ b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/schema.ts @@ -153,6 +153,7 @@ export const cspmUsageSchema: MakeSchemaFrom = { deployment_mode: { type: 'keyword' }, created_at: { type: 'date' }, agent_count: { type: 'long' }, + account_type: { type: 'keyword' }, }, }, }; diff --git a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/types.ts b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/types.ts index bb8703480354c..53a94067ed67a 100644 --- a/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/types.ts +++ b/x-pack/plugins/cloud_security_posture/server/lib/telemetry/collectors/types.ts @@ -86,4 +86,5 @@ export interface CloudSecurityInstallationStats { deployment_mode: string; created_at: string; agent_count: number; + account_type?: 'single-account' | 'organization-account'; } diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/about_panel/about_panel.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/about_panel/about_panel.tsx index 5d0cc47dceee3..bbb486bb3e32e 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/about_panel/about_panel.tsx +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/about_panel/about_panel.tsx @@ -13,9 +13,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiSpacer, - EuiPage, - EuiPageBody, - EuiPageContent_Deprecated as EuiPageContent, + EuiPageTemplate, EuiHorizontalRule, EuiFilePicker, EuiLoadingSpinner, @@ -31,61 +29,54 @@ interface Props { export const AboutPanel: FC = ({ onFilePickerChange, hasPermissionToImport }) => { return ( - - - - - + + + + - + -
- onFilePickerChange(files)} - className="file-datavisualizer-file-picker" - /> -
- -
-
-
-
+
+ onFilePickerChange(files)} + className="file-datavisualizer-file-picker" + /> +
+ +
+ + ); }; export const LoadingPanel: FC = () => { return ( - - - -
- -

- -

-
- - - - -
-
-
-
+ + +

+ +

+ + } + > + +
+
); }; diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx index 0c420e7edc453..b54121982381b 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx @@ -14,10 +14,7 @@ import { useIsWithinMaxBreakpoint, EuiFlexGroup, EuiFlexItem, - EuiPageBody, - EuiPageContentBody_Deprecated as EuiPageContentBody, - EuiPageContentHeader_Deprecated as EuiPageContentHeader, - EuiPageContentHeaderSection_Deprecated as EuiPageContentHeaderSection, + EuiPageTemplate, EuiPanel, EuiProgress, EuiSpacer, @@ -496,59 +493,62 @@ export const IndexDataVisualizerView: FC = (dataVi }); return ( - - - - - - - -

{currentDataView.getName()}

-
- -
-
- - {isWithinLargeBreakpoint ? : null} - - {hasValidTimeField ? ( - - - - ) : null} + + + + + +

{currentDataView.getName()}

+
+ +
+ + {isWithinLargeBreakpoint ? : null} + + {hasValidTimeField ? ( - - -
-
-
- - + ) : null} + + + + + + + @@ -621,7 +621,7 @@ export const IndexDataVisualizerView: FC = (dataVi /> - -
+ + ); }; diff --git a/x-pack/plugins/fleet/server/routes/preconfiguration/index.ts b/x-pack/plugins/fleet/server/routes/preconfiguration/index.ts index 5d427b49bed69..2d46599988f1a 100644 --- a/x-pack/plugins/fleet/server/routes/preconfiguration/index.ts +++ b/x-pack/plugins/fleet/server/routes/preconfiguration/index.ts @@ -17,6 +17,9 @@ export const registerRoutes = (router: FleetAuthzRouter) => { { path: PRECONFIGURATION_API_ROUTES.RESET_PATTERN, validate: false, + options: { + access: 'internal', + }, fleetAuthz: { fleet: { all: true }, }, @@ -27,6 +30,9 @@ export const registerRoutes = (router: FleetAuthzRouter) => { { path: PRECONFIGURATION_API_ROUTES.RESET_ONE_PATTERN, validate: PostResetOnePreconfiguredAgentPoliciesSchema, + options: { + access: 'internal', + }, fleetAuthz: { fleet: { all: true }, }, diff --git a/x-pack/plugins/fleet/server/services/api_keys/transform_api_keys.ts b/x-pack/plugins/fleet/server/services/api_keys/transform_api_keys.ts index f75c8d5677b28..ab17eeaac7921 100644 --- a/x-pack/plugins/fleet/server/services/api_keys/transform_api_keys.ts +++ b/x-pack/plugins/fleet/server/services/api_keys/transform_api_keys.ts @@ -5,7 +5,10 @@ * 2.0. */ -import type { CreateAPIKeyParams } from '@kbn/security-plugin/server'; +import type { + CreateRestAPIKeyParams, + CreateRestAPIKeyWithKibanaPrivilegesParams, +} from '@kbn/security-plugin/server'; import type { FakeRawRequest, Headers } from '@kbn/core-http-server'; import { CoreKibanaRequest } from '@kbn/core-http-router-server-internal'; @@ -60,7 +63,7 @@ export async function generateTransformSecondaryAuthHeaders({ }: { authorizationHeader: HTTPAuthorizationHeader | null | undefined; logger: Logger; - createParams?: CreateAPIKeyParams; + createParams?: CreateRestAPIKeyParams | CreateRestAPIKeyWithKibanaPrivilegesParams; username?: string; pkgName?: string; pkgVersion?: string; diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts index 0990dd675a970..330400fd4ba1f 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.test.ts @@ -112,6 +112,23 @@ describe('getCloudFleetServersHosts', () => { expect(getCloudFleetServersHosts()).toBeUndefined(); }); + it('should return fleet server hosts if cloud is correctly setup in serverless', () => { + mockedAppContextService.getCloud.mockReturnValue({ + cloudId: + 'dXMtZWFzdC0xLmF3cy5mb3VuZC5pbyRjZWM2ZjI2MWE3NGJmMjRjZTMzYmI4ODExYjg0Mjk0ZiRjNmMyY2E2ZDA0MjI0OWFmMGNjN2Q3YTllOTYyNTc0Mw==', + isCloudEnabled: true, + deploymentId: 'deployment-id-1', + cloudHost: 'us-east-1.aws.found.io', + apm: {}, + isServerlessEnabled: true, + serverless: { + projectId: undefined, + }, + }); + + expect(getCloudFleetServersHosts()).toBeUndefined(); + }); + it('should return fleet server hosts if cloud is correctly setup with default port == 443', () => { mockedAppContextService.getCloud.mockReturnValue({ cloudId: diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts index d0a2dac7b641e..8c6b9680318d7 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/fleet_server_host.ts @@ -27,7 +27,12 @@ import { isDifferent } from './utils'; export function getCloudFleetServersHosts() { const cloudSetup = appContextService.getCloud(); - if (cloudSetup && cloudSetup.isCloudEnabled && cloudSetup.cloudHost) { + if ( + cloudSetup && + !cloudSetup.isServerlessEnabled && + cloudSetup.isCloudEnabled && + cloudSetup.cloudHost + ) { // Fleet Server url are formed like this `https://.fleet. return [ `https://${cloudSetup.deploymentId}.fleet.${cloudSetup.cloudHost}${ diff --git a/x-pack/plugins/fleet/server/services/security/fleet_router.test.ts b/x-pack/plugins/fleet/server/services/security/fleet_router.test.ts index 6af9c891b31fc..bb6ea59eeec82 100644 --- a/x-pack/plugins/fleet/server/services/security/fleet_router.test.ts +++ b/x-pack/plugins/fleet/server/services/security/fleet_router.test.ts @@ -201,4 +201,64 @@ describe('FleetAuthzRouter', () => { ).toEqual('forbidden'); }); }); + + describe('default access', () => { + let fakeRouter: jest.Mocked>; + beforeEach(() => { + fakeRouter = { + get: jest.fn(), + post: jest.fn(), + delete: jest.fn(), + put: jest.fn(), + patch: jest.fn(), + } as unknown as jest.Mocked>; + }); + + const METHODS: Array<'get' | 'post' | 'delete' | 'put' | 'patch'> = [ + 'get', + 'post', + 'delete', + 'put', + 'patch', + ]; + + for (const method of METHODS) { + describe(`${method}`, () => { + it('should set default access to public', () => { + const fleetAuthzRouter = makeRouterWithFleetAuthz(fakeRouter, mockLogger); + fleetAuthzRouter[method]( + { + path: '/test', + validate: false, + }, + (() => {}) as any + ); + expect(fakeRouter[method]).toBeCalledWith( + expect.objectContaining({ + options: { access: 'public' }, + }), + expect.anything() + ); + }); + + it('should not allow to define internal routes', () => { + const fleetAuthzRouter = makeRouterWithFleetAuthz(fakeRouter, mockLogger); + fleetAuthzRouter[method]( + { + path: '/test', + validate: false, + options: { access: 'internal' }, + }, + (() => {}) as any + ); + expect(fakeRouter[method]).toBeCalledWith( + expect.objectContaining({ + options: { access: 'internal' }, + }), + expect.anything() + ); + }); + }); + } + }); }); diff --git a/x-pack/plugins/fleet/server/services/security/fleet_router.ts b/x-pack/plugins/fleet/server/services/security/fleet_router.ts index 32fd25a38a948..a956f1522161c 100644 --- a/x-pack/plugins/fleet/server/services/security/fleet_router.ts +++ b/x-pack/plugins/fleet/server/services/security/fleet_router.ts @@ -13,6 +13,8 @@ import type { Logger, RequestHandler, RouteMethod, + RouteConfig, + RouteConfigOptions, } from '@kbn/core/server'; import type { FleetRequestHandlerContext } from '../..'; @@ -26,6 +28,25 @@ import { doesNotHaveRequiredFleetAuthz, } from './security'; +function withDefaultPublicAccess( + routeConfig: RouteConfig +): RouteConfig { + let newOptions: RouteConfigOptions; + if (routeConfig?.options) { + newOptions = { ...routeConfig?.options }; + } else { + newOptions = {}; + } + + if (!newOptions.access) { + newOptions.access = 'public'; + } + return { + ...routeConfig, + options: newOptions, + }; +} + export function makeRouterWithFleetAuthz( router: IRouter, logger: Logger @@ -106,27 +127,27 @@ export function makeRouterWithFleetAuthz = { get: ({ fleetAuthz: hasRequiredAuthz, ...options }, handler) => { - router.get(options, (context, request, response) => + router.get(withDefaultPublicAccess(options), (context, request, response) => fleetHandlerWrapper({ context, request, response, handler, hasRequiredAuthz }) ); }, delete: ({ fleetAuthz: hasRequiredAuthz, ...options }, handler) => { - router.delete(options, (context, request, response) => + router.delete(withDefaultPublicAccess(options), (context, request, response) => fleetHandlerWrapper({ context, request, response, handler, hasRequiredAuthz }) ); }, post: ({ fleetAuthz: hasRequiredAuthz, ...options }, handler) => { - router.post(options, (context, request, response) => + router.post(withDefaultPublicAccess(options), (context, request, response) => fleetHandlerWrapper({ context, request, response, handler, hasRequiredAuthz }) ); }, put: ({ fleetAuthz: hasRequiredAuthz, ...options }, handler) => { - router.put(options, (context, request, response) => + router.put(withDefaultPublicAccess(options), (context, request, response) => fleetHandlerWrapper({ context, request, response, handler, hasRequiredAuthz }) ); }, patch: ({ fleetAuthz: hasRequiredAuthz, ...options }, handler) => { - router.patch(options, (context, request, response) => + router.patch(withDefaultPublicAccess(options), (context, request, response) => fleetHandlerWrapper({ context, request, response, handler, hasRequiredAuthz }) ); }, diff --git a/x-pack/plugins/infra/server/features.ts b/x-pack/plugins/infra/server/features.ts index 41f60ab5eac9b..e9fec4a5b4f5d 100644 --- a/x-pack/plugins/infra/server/features.ts +++ b/x-pack/plugins/infra/server/features.ts @@ -33,7 +33,7 @@ export const METRICS_FEATURE = { all: { app: ['infra', 'metrics', 'kibana'], catalogue: ['infraops', 'metrics'], - api: ['infra', 'rac', 'ai_assistant'], + api: ['infra', 'rac'], savedObject: { all: ['infrastructure-ui-source'], read: ['index-pattern'], @@ -54,7 +54,7 @@ export const METRICS_FEATURE = { read: { app: ['infra', 'metrics', 'kibana'], catalogue: ['infraops', 'metrics'], - api: ['infra', 'rac', 'ai_assistant'], + api: ['infra', 'rac'], savedObject: { all: [], read: ['infrastructure-ui-source', 'index-pattern'], @@ -92,7 +92,7 @@ export const LOGS_FEATURE = { all: { app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging', 'logs'], - api: ['infra', 'rac', 'ai_assistant'], + api: ['infra', 'rac'], savedObject: { all: [infraSourceConfigurationSavedObjectName, logViewSavedObjectName], read: [], @@ -113,7 +113,7 @@ export const LOGS_FEATURE = { read: { app: ['infra', 'logs', 'kibana'], catalogue: ['infralogging', 'logs'], - api: ['infra', 'rac', 'ai_assistant'], + api: ['infra', 'rac'], alerting: { rule: { read: [LOG_DOCUMENT_COUNT_RULE_TYPE_ID], diff --git a/x-pack/plugins/lens/public/datasources/form_based/layer_settings.tsx b/x-pack/plugins/lens/public/datasources/form_based/layer_settings.tsx index d968b255b05a3..38f216f083d1d 100644 --- a/x-pack/plugins/lens/public/datasources/form_based/layer_settings.tsx +++ b/x-pack/plugins/lens/public/datasources/form_based/layer_settings.tsx @@ -15,6 +15,7 @@ import type { DatasourceLayerSettingsProps } from '../../types'; import type { FormBasedPrivateState } from './types'; import { isSamplingValueEnabled } from './utils'; import { IgnoreGlobalFilterRowControl } from '../../shared_components/ignore_global_filter'; +import { trackUiCounterEvents } from '../../lens_ui_telemetry'; const samplingValues = [0.00001, 0.0001, 0.001, 0.01, 0.1, 1]; @@ -93,6 +94,9 @@ export function LayerSettingsPanel({ currentValue={currentValue} data-test-subj="lns-indexPattern-random-sampling-slider" onChange={(newSamplingValue) => { + if (newSamplingValue < 1) { + trackUiCounterEvents('apply_random_sampling'); + } setState({ ...state, layers: { @@ -115,6 +119,9 @@ export function LayerSettingsPanel({ }; const newLayers = { ...state.layers }; newLayers[layerId] = newLayer; + trackUiCounterEvents( + newLayer.ignoreGlobalFilters ? `ignore_global_filters` : `use_global_filters` + ); setState({ ...state, layers: newLayers }); }} /> diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx index 36d8b4104e64c..11f50252b993e 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/suggestion_panel.tsx @@ -64,7 +64,6 @@ import { selectFrameDatasourceAPI, } from '../../state_management'; import { filterAndSortUserMessages } from '../../app_plugin/get_application_user_messages'; - const MAX_SUGGESTIONS_DISPLAYED = 5; const LOCAL_STORAGE_SUGGESTIONS_PANEL = 'LENS_SUGGESTIONS_PANEL_HIDDEN'; @@ -108,11 +107,13 @@ const PreviewRenderer = ({ ExpressionRendererComponent, expression, hasError, + onRender, }: { withLabel: boolean; expression: string | null | undefined; ExpressionRendererComponent: ReactExpressionRendererType; hasError: boolean; + onRender: () => void; }) => { const onErrorMessage = (
@@ -143,6 +144,7 @@ const PreviewRenderer = ({ padding="s" renderMode="preview" expression={expression} + onRender$={onRender} debounce={2000} renderError={() => { return onErrorMessage; @@ -159,6 +161,7 @@ const SuggestionPreview = ({ selected, onSelect, showTitleAsLabel, + onRender, }: { onSelect: () => void; preview: { @@ -170,6 +173,7 @@ const SuggestionPreview = ({ ExpressionRenderer: ReactExpressionRendererType; selected: boolean; showTitleAsLabel?: boolean; + onRender: () => void; }) => { return ( @@ -194,6 +198,7 @@ const SuggestionPreview = ({ expression={preview.expression && toExpression(preview.expression)} withLabel={Boolean(showTitleAsLabel)} hasError={Boolean(preview.error)} + onRender={onRender} /> ) : ( @@ -358,20 +363,36 @@ export function SuggestionPanel({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [existsStagedPreview]); - if (!activeDatasourceId) { - return null; - } - - if (suggestions.length === 0) { - return null; - } + const startTime = useRef(0); + const initialRenderComplete = useRef(false); + const suggestionsRendered = useRef([]); + const totalSuggestions = suggestions.length + 1; + + const onSuggestionRender = useCallback((suggestionIndex: number) => { + suggestionsRendered.current[suggestionIndex] = true; + if (initialRenderComplete.current === false && suggestionsRendered.current.every(Boolean)) { + initialRenderComplete.current = true; + // console.log( + // 'time to fetch data and perform initial render for all suggestions', + // performance.now() - startTime.current + // ); + } + }, []); - function rollbackToCurrentVisualization() { + const rollbackToCurrentVisualization = useCallback(() => { if (lastSelectedSuggestion !== -1) { setLastSelectedSuggestion(-1); dispatchLens(rollbackSuggestion()); dispatchLens(applyChanges()); } + }, [dispatchLens, lastSelectedSuggestion]); + + if (!activeDatasourceId) { + return null; + } + + if (suggestions.length === 0) { + return null; } const renderApplyChangesPrompt = () => ( @@ -400,52 +421,58 @@ export function SuggestionPanel({ ); - const renderSuggestionsUI = () => ( - <> - {currentVisualization.activeId && !hideSuggestions && ( - - )} - {!hideSuggestions && - suggestions.map((suggestion, index) => { - return ( - { - if (lastSelectedSuggestion === index) { - rollbackToCurrentVisualization(); - } else { - setLastSelectedSuggestion(index); - switchToSuggestion(dispatchLens, suggestion, { applyImmediately: true }); - } - }} - selected={index === lastSelectedSuggestion} - /> - ); - })} - - ); + const renderSuggestionsUI = () => { + suggestionsRendered.current = new Array(totalSuggestions).fill(false); + startTime.current = performance.now(); + return ( + <> + {currentVisualization.activeId && !hideSuggestions && ( + onSuggestionRender(0)} + /> + )} + {!hideSuggestions && + suggestions.map((suggestion, index) => { + return ( + { + if (lastSelectedSuggestion === index) { + rollbackToCurrentVisualization(); + } else { + setLastSelectedSuggestion(index); + switchToSuggestion(dispatchLens, suggestion, { applyImmediately: true }); + } + }} + selected={index === lastSelectedSuggestion} + onRender={() => onSuggestionRender(index + 1)} + /> + ); + })} + + ); + }; return (
diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx index f4767124afb81..3f92236c99e5d 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel.tsx @@ -138,6 +138,10 @@ export const WorkspacePanel = React.memo(function WorkspacePanel(props: Workspac ); }); +const log = (...messages: Array) => { + // console.log(...messages); +}; + // Exported for testing purposes only. export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ framePublicAPI, @@ -170,7 +174,10 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ errors: [], }); - const initialRenderComplete = useRef(); + const initialVisualizationRenderComplete = useRef(false); + + // NOTE: This does not reflect the actual visualization render + const initialWorkspaceRenderComplete = useRef(); const renderDeps = useRef<{ datasourceMap: DatasourceMap; @@ -192,8 +199,20 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ dataViews, }; + // NOTE: initialRenderTime is only set once when the component mounts + const visualizationRenderStartTime = useRef(NaN); + const dataReceivedTime = useRef(NaN); + const onRender$ = useCallback(() => { if (renderDeps.current) { + if (!initialVisualizationRenderComplete.current) { + initialVisualizationRenderComplete.current = true; + // NOTE: this metric is only reported for an initial editor load of a pre-existing visualization + log( + 'initial visualization took to render after data received', + performance.now() - dataReceivedTime.current + ); + } const datasourceEvents = Object.values(renderDeps.current.datasourceMap).reduce( (acc, datasource) => { if (!renderDeps.current!.datasourceStates[datasource.id]) return []; @@ -232,6 +251,15 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ const onData$ = useCallback( (_data: unknown, adapters?: Partial) => { if (renderDeps.current) { + dataReceivedTime.current = performance.now(); + if (!initialVisualizationRenderComplete.current) { + // NOTE: this metric is only reported for an initial editor load of a pre-existing visualization + log( + 'initial data took to arrive', + dataReceivedTime.current - visualizationRenderStartTime.current + ); + } + const [defaultLayerId] = Object.keys(renderDeps.current.datasourceLayers); const datasource = Object.values(renderDeps.current.datasourceMap)[0]; const datasourceState = Object.values(renderDeps.current.datasourceStates)[0].state; @@ -276,7 +304,8 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ [addUserMessages, dispatchLens, plugins.data.search] ); - const shouldApplyExpression = autoApplyEnabled || !initialRenderComplete.current || triggerApply; + const shouldApplyExpression = + autoApplyEnabled || !initialWorkspaceRenderComplete.current || triggerApply; const activeVisualization = visualization.activeId ? visualizationMap[visualization.activeId] : null; @@ -389,9 +418,9 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ // null signals an empty workspace which should count as an initial render if ( (expressionExists || localState.expressionToRender === null) && - !initialRenderComplete.current + !initialWorkspaceRenderComplete.current ) { - initialRenderComplete.current = true; + initialWorkspaceRenderComplete.current = true; } }, [expressionExists, localState.expressionToRender]); @@ -559,7 +588,6 @@ export const InnerWorkspacePanel = React.memo(function InnerWorkspacePanel({ return ( { + visualizationRenderStartTime.current = performance.now(); + }} /> ); }; @@ -656,7 +686,6 @@ function useReportingState(errors: UserMessage[]): { export const VisualizationWrapper = ({ expression, - framePublicAPI, lensInspector, onEvent, hasCompatibleActions, @@ -665,12 +694,11 @@ export const VisualizationWrapper = ({ errors, ExpressionRendererComponent, core, - activeDatasourceId, onRender$, onData$, + onComponentRendered, }: { expression: string | null | undefined; - framePublicAPI: FramePublicAPI; lensInspector: LensInspector; onEvent: (event: ExpressionRendererEvent) => void; hasCompatibleActions: (event: ExpressionRendererEvent) => Promise; @@ -679,14 +707,25 @@ export const VisualizationWrapper = ({ errors: UserMessage[]; ExpressionRendererComponent: ReactExpressionRendererType; core: CoreStart; - activeDatasourceId: string | null; onRender$: () => void; onData$: (data: unknown, adapters?: Partial) => void; + onComponentRendered: () => void; }) => { + useEffect(() => { + onComponentRendered(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + const context = useLensSelector(selectExecutionContext); // Used for reporting const { isRenderComplete, hasDynamicError, setIsRenderComplete, setDynamicError, nodeRef } = useReportingState(errors); + + const onRenderHandler = useCallback(() => { + setIsRenderComplete(true); + onRender$(); + }, [setIsRenderComplete, onRender$]); + const searchContext: ExecutionContextSearch = useMemo( () => ({ query: context.query, @@ -782,10 +821,7 @@ export const VisualizationWrapper = ({ onEvent={onEvent} hasCompatibleActions={hasCompatibleActions} onData$={onData$} - onRender$={() => { - setIsRenderComplete(true); - onRender$(); - }} + onRender$={onRenderHandler} inspectorAdapters={lensInspector.adapters} executionContext={executionContext} renderMode="edit" diff --git a/x-pack/plugins/lens/public/visualizations/xy/layer_settings.tsx b/x-pack/plugins/lens/public/visualizations/xy/layer_settings.tsx index 503acd276fd1e..72c92f3569cc1 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/layer_settings.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/layer_settings.tsx @@ -6,6 +6,7 @@ */ import React from 'react'; +import { trackUiCounterEvents } from '../../lens_ui_telemetry'; import { IgnoreGlobalFilterRowControl } from '../../shared_components/ignore_global_filter'; import type { VisualizationLayerSettingsProps } from '../../types'; import type { XYState } from './types'; @@ -32,6 +33,9 @@ export function LayerSettings({ const newLayer = { ...layer, ignoreGlobalFilters: !layer.ignoreGlobalFilters }; const newLayers = [...state.layers]; newLayers[layerIndex] = newLayer; + trackUiCounterEvents( + newLayer.ignoreGlobalFilters ? `ignore_global_filters` : `use_global_filters` + ); setState({ ...state, layers: newLayers }); }} /> diff --git a/x-pack/plugins/lens/readme.md b/x-pack/plugins/lens/readme.md index 334ab844c4308..764ff5f2df04f 100644 --- a/x-pack/plugins/lens/readme.md +++ b/x-pack/plugins/lens/readme.md @@ -10,7 +10,7 @@ exposed via contract. For more information check out the example in `x-pack/exam When adding visualizations to a solution page, there are multiple ways to approach this with pros and cons: * #### **Use a dashboard** - If the app page you are planning to build strongly resembles a regular dashboard, it might not even be necessary to write code - configuring a dashboard might be a better choice. The Presentation team is currently working on making it possible to embed dashboard into the solution navigation, which allows you to offer visualization and filter functionality without writing custom code. If possible this option should be chosen because of the low maintenance and development effort as well as the high flexibility for a user to clone the preset dashboard and start customizing it in various ways. + If the app page you are planning to build strongly resembles a regular dashboard, it might not even be necessary to write code - configuring a dashboard might be a better choice. Portable dasboards make it possible to embed a dashboard into your application, which allows you to offer visualization and filter functionality without writing custom code. If possible this option should be chosen because of the low maintenance and development effort as well as the high flexibility for a user to clone the preset dashboard and start customizing it in various ways. Pros: * No need to write and maintain custom code @@ -33,14 +33,14 @@ When adding visualizations to a solution page, there are multiple ways to approa * #### **Using custom data fetching and rendering** - In case the disadvantages of using the Lens embeddable heavily affect your use case, it sometimes makes sense to roll your own data fetching and rendering by using the underlying APIs of search service and `elastic-charts` directly. This allows a high degree of flexibility when it comes to data processing, efficiently querying data for multiple charts in a single query and adjusting small details in how charts are rendered. However, do not choose these option lightly as maintenance as well as initial development effort will most likely be much higher than by using the Lens embeddable directly. In this case, almost always an "Open in Lens" button can still be offered to the user to drill down and further explore the data by generating a Lens configuration which is similar to the displayed visualization given the possibilities of Lens. Keep in mind that for the "Open in Lens" flow, the most important property isn't perfect fidelity of the chart but retaining the mental context of the user when switching so they don't have to start over. It's also possible to mix this approach with Lens embeddables on a single page. **Note**: In this situation, please let the Visualizations team know what features you are missing / why you chose not to use Lens. + In case the disadvantages of using the Lens embeddable heavily affect your use case, it sometimes makes sense to roll your own data fetching and rendering by using the underlying APIs of search service and `elastic-charts` directly. This allows a high degree of flexibility when it comes to data processing, efficiently querying data for multiple charts in a single query and adjusting small details in how charts are rendered. In this case, almost always an "Open in Lens" button can still be offered to the user to drill down and further explore the data by generating a Lens configuration which is similar to the displayed visualization given the possibilities of Lens. Keep in mind that for the "Open in Lens" flow, the most important property isn't perfect fidelity of the chart but retaining the mental context of the user when switching so they don't have to start over. It's also possible to mix this approach with Lens embeddables on a single page. **Note**: In this situation, please let the Visualizations team know what features you are missing / why you chose not to use Lens. Pros: * Full flexibility in data fetching optimization and chart rendering Cons: * "Open in Lens" requires additional logic - * High maintenance and development effort + * Should follow elastic charts api changes ## Getting started @@ -80,7 +80,46 @@ On a high level there are references, datasource state, visualization state and ### References -References (`references`) are regular saved object references forming a graph of saved objects which depend on each other. For the Lens case, these references are always data views (called `type: "index-pattern"`) in code, referencing data views which are used in the current Lens visualization. Often there is just a single data view in use, but it's possible to use multiple data views for multiple layers in a Lens xy chart. The `id` of a reference needs to be the saved object id of the referenced data view (see the "Handling data views" section below). The `name` of the reference is comprised out of multiple parts used to map the data view to the correct layer : `indexpattern-datasource-layer-`. Even if multiple layers are using the same data view, there has to be one reference per layer (all pointing to the same data view id). +References (`references`) are regular saved object references forming a graph of saved objects which depend on each other. For the Lens case, these references can be annotation groups or data views (called `type: "index-pattern"` in code), referencing permanent data views which are used in the current Lens visualization. Often there is just a single data view in use, but it's possible to use multiple data views for multiple layers in a Lens xy chart. The `id` of a reference needs to be the saved object id of the referenced data view (see the "Handling data views" section below). The `name` of the reference is comprised out of multiple parts used to map the data view to the correct layer : `indexpattern-datasource-layer-`. Even if multiple layers are using the same data view, there has to be one reference per layer (all pointing to the same data view id). References array can be empty in case of adhoc dataviews (see section below). + + +### Ad-hoc data views + +In some cases a globally accessible data view is not desirable: +* You need some special runtime fields which only make sense in the context of that one visualization and you don't want to "pollute" the global data view for all consumers +* It's a "one-off" visualization which is built on data that's not normally used and having a global data view object for it would be weird +* You want to allow a read-only user to work with data and no data view exists yet - the user isn't allowed to create data views but they are allowed to access the data + +In these situations ad-hoc data views are useful - these are data views which are stored as part of the Lens visualization itself, so they do not show up in other contexts. In the UI you can create these by opening the data view picker, selecting "Create a data view" and then using the "Use without saving" button. + +Ad-hoc data views are part of the Lens attributes stored in `state.adHocDataViews`. Each data view is defined by its JSON-serializable `DataViewSpec` object. If a layer is using an ad hoc data view, the reference goes into the `state.internalReferences` array instead of the external `references` array. + +Example: +```json +"state": { + // ... + "internalReferences": [ + { + "type": "index-pattern", + "id": "adhoc-1", + "name": "indexpattern-datasource-layer-layer1" + } + ], + "adHocDataViews": { + "adhoc-1": { + "id": "adhoc-1", + "title": "my-pattern*", + "timeFieldName": "@timestamp", + "sourceFilters": [], + "fieldFormats": {}, + "runtimeFieldMap": {}, + "fieldAttrs": {}, + "allowNoIndex": false, + "name": "My ad-hoc data view" + } + } +} +``` ### Datasource state @@ -128,44 +167,6 @@ if (!dataView) { const dataViewIdForLens = dataView.id; ``` -### Ad-hoc data views - -In some cases a globally accessible data view is not desirable: -* You need some special runtime fields which only make sense in the context of that one visualization and you don't want to "pollute" the global data view for all consumers -* It's a "one-off" visualization which is built on data that's not normally used and having a global data view object for it would be weird -* You want to allow a read-only user to work with data and no data view exists yet - the user isn't allowed to create data views but they are allowed to access the data - -In these situations ad-hoc data views are useful - these are data views which are stored as part of the Lens visualization itself, so they do not show up in other contexts. In the UI you can create these by opening the data view picker, selecting "Create a data view" and then using the "Use without saving" button. - -Ad-hoc data views are part of the Lens attributes stored in `state.adHocDataViews`. Each data view is defined by its JSON-serializable `DataViewSpec` object. If a layer is using an ad hoc data view, the reference goes into the `state.internalReferences` array instead of the external `references` array. - -Example: -```json -"state": { - // ... - "internalReferences": [ - { - "type": "index-pattern", - "id": "adhoc-1", - "name": "indexpattern-datasource-layer-layer1" - } - ], - "adHocDataViews": { - "adhoc-1": { - "id": "adhoc-1", - "title": "my-pattern*", - "timeFieldName": "@timestamp", - "sourceFilters": [], - "fieldFormats": {}, - "runtimeFieldMap": {}, - "fieldAttrs": {}, - "allowNoIndex": false, - "name": "My ad-hoc data view" - } - } -} -``` - **Important!** To prevent conflicts, it's important to not re-use ad-hoc data view ids for different specs. If you change the spec in some way, make sure to also change its id. This even applies across multiple embeddables, sessions, etc. Ideally, the id will be globally unique. You can use the `uuid` package to generate a new unique id every time when you are changing the spec in some way. However, make sure to also not change the id on every single render either, as this will have a substantial performance impact. ## Refreshing a Lens embeddable diff --git a/x-pack/plugins/observability/server/assets/component_templates/slo_settings_template.ts b/x-pack/plugins/observability/server/assets/component_templates/slo_settings_template.ts index 8832c51e030be..e2adb74dd1104 100644 --- a/x-pack/plugins/observability/server/assets/component_templates/slo_settings_template.ts +++ b/x-pack/plugins/observability/server/assets/component_templates/slo_settings_template.ts @@ -11,6 +11,7 @@ export const getSLOSettingsTemplate = (name: string) => ({ name, template: { settings: { + auto_expand_replicas: '0-all', hidden: true, }, }, diff --git a/x-pack/plugins/observability/server/assets/component_templates/slo_summary_settings_template.ts b/x-pack/plugins/observability/server/assets/component_templates/slo_summary_settings_template.ts index 9224e532549dd..286434003f540 100644 --- a/x-pack/plugins/observability/server/assets/component_templates/slo_summary_settings_template.ts +++ b/x-pack/plugins/observability/server/assets/component_templates/slo_summary_settings_template.ts @@ -11,6 +11,7 @@ export const getSLOSummarySettingsTemplate = (name: string) => ({ name, template: { settings: { + auto_expand_replicas: '0-all', hidden: true, }, }, diff --git a/x-pack/plugins/observability/server/lib/annotations/create_annotations_client.ts b/x-pack/plugins/observability/server/lib/annotations/create_annotations_client.ts index 9c960ef09755d..fc74ffa880fc2 100644 --- a/x-pack/plugins/observability/server/lib/annotations/create_annotations_client.ts +++ b/x-pack/plugins/observability/server/lib/annotations/create_annotations_client.ts @@ -34,9 +34,9 @@ export function createAnnotationsClient(params: { const initIndex = () => createOrUpdateIndex({ index, + mappings, client: esClient, logger, - mappings, }); function ensureGoldLicense any>(fn: T): T { diff --git a/x-pack/plugins/observability/server/utils/create_or_update_index.ts b/x-pack/plugins/observability/server/utils/create_or_update_index.ts index 1a158594a0ed2..eaea86c18b19f 100644 --- a/x-pack/plugins/observability/server/utils/create_or_update_index.ts +++ b/x-pack/plugins/observability/server/utils/create_or_update_index.ts @@ -7,23 +7,18 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; import pRetry from 'p-retry'; import { Logger, ElasticsearchClient } from '@kbn/core/server'; -import { merge } from 'lodash'; export type Mappings = Required['body']['mappings'] & Required['body']; -type IndexSettings = Required['body']['settings']; - export async function createOrUpdateIndex({ index, mappings, - settings, client, logger, }: { index: string; mappings: Mappings; - settings?: IndexSettings; client: ElasticsearchClient; logger: Logger; }) { @@ -49,7 +44,6 @@ export async function createOrUpdateIndex({ index, client, mappings, - settings, }); if (!result.acknowledged) { @@ -70,28 +64,26 @@ export async function createOrUpdateIndex({ } } -async function createNewIndex({ +function createNewIndex({ index, client, mappings, - settings, }: { index: string; client: ElasticsearchClient; mappings: Required['body']['mappings']; - settings: Required['body']['settings']; }) { - return await client.indices.create({ + return client.indices.create({ index, body: { // auto_expand_replicas: Allows cluster to not have replicas for this index - settings: merge({ index: { auto_expand_replicas: '0-1' } }, settings), + settings: { index: { auto_expand_replicas: '0-1' } }, mappings, }, }); } -async function updateExistingIndex({ +function updateExistingIndex({ index, client, mappings, @@ -100,7 +92,7 @@ async function updateExistingIndex({ client: ElasticsearchClient; mappings: estypes.IndicesPutMappingRequest['body']; }) { - return await client.indices.putMapping({ + return client.indices.putMapping({ index, body: mappings, }); diff --git a/x-pack/plugins/observability_ai_assistant/common/feature.ts b/x-pack/plugins/observability_ai_assistant/common/feature.ts new file mode 100644 index 0000000000000..db06ec43086f2 --- /dev/null +++ b/x-pack/plugins/observability_ai_assistant/common/feature.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export const OBSERVABILITY_AI_ASSISTANT_FEATURE_ID = 'observabilityAIAssistant'; diff --git a/x-pack/plugins/observability_ai_assistant/kibana.jsonc b/x-pack/plugins/observability_ai_assistant/kibana.jsonc index 05e0e2e450553..2faf2c7de57e9 100644 --- a/x-pack/plugins/observability_ai_assistant/kibana.jsonc +++ b/x-pack/plugins/observability_ai_assistant/kibana.jsonc @@ -13,7 +13,8 @@ "requiredPlugins": [ "triggersActionsUi", "actions", - "security" + "security", + "features" ], "requiredBundles": [ "kibanaReact" diff --git a/x-pack/plugins/observability_ai_assistant/public/plugin.ts b/x-pack/plugins/observability_ai_assistant/public/plugin.ts index 607f54a3c6da7..187275b127dd3 100644 --- a/x-pack/plugins/observability_ai_assistant/public/plugin.ts +++ b/x-pack/plugins/observability_ai_assistant/public/plugin.ts @@ -5,7 +5,7 @@ * 2.0. */ -import type { CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; +import type { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from '@kbn/core/public'; import type { Logger } from '@kbn/logging'; import { createService } from './service/create_service'; import type { @@ -29,11 +29,20 @@ export class ObservabilityAIAssistantPlugin constructor(context: PluginInitializerContext) { this.logger = context.logger.get(); } - setup(): ObservabilityAIAssistantPluginSetup { + setup( + core: CoreSetup, + pluginsSetup: ObservabilityAIAssistantPluginSetupDependencies + ): ObservabilityAIAssistantPluginSetup { return {}; } - start(coreStart: CoreStart): ObservabilityAIAssistantPluginStart { - return createService(coreStart); + start( + coreStart: CoreStart, + pluginsStart: ObservabilityAIAssistantPluginStartDependencies + ): ObservabilityAIAssistantPluginStart { + return createService({ + coreStart, + enabled: coreStart.application.capabilities.observabilityAIAssistant.show === true, + }); } } diff --git a/x-pack/plugins/observability_ai_assistant/public/service/create_service.test.ts b/x-pack/plugins/observability_ai_assistant/public/service/create_service.test.ts index 010503e7abf4f..8a7ec44bfd9bc 100644 --- a/x-pack/plugins/observability_ai_assistant/public/service/create_service.test.ts +++ b/x-pack/plugins/observability_ai_assistant/public/service/create_service.test.ts @@ -41,10 +41,13 @@ describe('createService', () => { beforeEach(() => { service = createService({ - http: { - post: httpPostSpy, - }, - } as unknown as CoreStart); + coreStart: { + http: { + post: httpPostSpy, + }, + } as unknown as CoreStart, + enabled: true, + }); }); afterEach(() => { diff --git a/x-pack/plugins/observability_ai_assistant/public/service/create_service.ts b/x-pack/plugins/observability_ai_assistant/public/service/create_service.ts index 4c54bef460eb7..da29de585c9d1 100644 --- a/x-pack/plugins/observability_ai_assistant/public/service/create_service.ts +++ b/x-pack/plugins/observability_ai_assistant/public/service/create_service.ts @@ -12,12 +12,18 @@ import { createCallObservabilityAIAssistantAPI } from '../api'; import { CreateChatCompletionResponseChunk, ObservabilityAIAssistantService } from '../types'; import { readableStreamReaderIntoObservable } from '../utils/readable_stream_reader_into_observable'; -export function createService(coreStart: CoreStart): ObservabilityAIAssistantService { +export function createService({ + coreStart, + enabled, +}: { + coreStart: CoreStart; + enabled: boolean; +}): ObservabilityAIAssistantService { const client = createCallObservabilityAIAssistantAPI(coreStart); return { isEnabled: () => { - return true; + return enabled; }, async chat({ connectorId, diff --git a/x-pack/plugins/observability_ai_assistant/public/types.ts b/x-pack/plugins/observability_ai_assistant/public/types.ts index fc553cb201010..69d826c7ebf17 100644 --- a/x-pack/plugins/observability_ai_assistant/public/types.ts +++ b/x-pack/plugins/observability_ai_assistant/public/types.ts @@ -8,11 +8,13 @@ import type { TriggersAndActionsUIPublicPluginSetup, TriggersAndActionsUIPublicPluginStart, } from '@kbn/triggers-actions-ui-plugin/public'; +import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/public'; import type { CreateChatCompletionResponse, CreateChatCompletionResponseChoicesInner, } from 'openai'; import type { Observable } from 'rxjs'; +import type { FeaturesPluginSetup, FeaturesPluginStart } from '@kbn/features-plugin/public'; import type { Message } from '../common/types'; import type { ObservabilityAIAssistantAPIClient } from './api'; @@ -40,10 +42,14 @@ export interface ObservabilityAIAssistantPluginStart extends ObservabilityAIAssi export interface ObservabilityAIAssistantPluginSetup {} export interface ObservabilityAIAssistantPluginSetupDependencies { - triggersActions: TriggersAndActionsUIPublicPluginSetup; + triggersActionsUi: TriggersAndActionsUIPublicPluginSetup; + security: SecurityPluginSetup; + features: FeaturesPluginSetup; } export interface ObservabilityAIAssistantPluginStartDependencies { - triggersActions: TriggersAndActionsUIPublicPluginStart; + triggersActionsUi: TriggersAndActionsUIPublicPluginStart; + security: SecurityPluginStart; + features: FeaturesPluginStart; } export interface ConfigSchema {} diff --git a/x-pack/plugins/observability_ai_assistant/server/plugin.ts b/x-pack/plugins/observability_ai_assistant/server/plugin.ts index 23efe49ab24a7..a81b9e18a0a80 100644 --- a/x-pack/plugins/observability_ai_assistant/server/plugin.ts +++ b/x-pack/plugins/observability_ai_assistant/server/plugin.ts @@ -5,14 +5,22 @@ * 2.0. */ -import type { +import { CoreSetup, CoreStart, + DEFAULT_APP_CATEGORIES, Logger, Plugin, PluginInitializerContext, } from '@kbn/core/server'; import { mapValues } from 'lodash'; +import { i18n } from '@kbn/i18n'; +import { + CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + ACTION_SAVED_OBJECT_TYPE, + ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, +} from '@kbn/actions-plugin/server/constants/saved_objects'; +import { OBSERVABILITY_AI_ASSISTANT_FEATURE_ID } from '../common/feature'; import type { ObservabilityAIAssistantConfig } from './config'; import { registerServerRoutes } from './routes/register_routes'; import { ObservabilityAIAssistantRouteHandlerResources } from './routes/types'; @@ -50,6 +58,58 @@ export class ObservabilityAIAssistantPlugin >, plugins: ObservabilityAIAssistantPluginSetupDependencies ): ObservabilityAIAssistantPluginSetup { + plugins.features.registerKibanaFeature({ + id: OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, + name: i18n.translate('xpack.observabilityAiAssistant.featureRegistry.featureName', { + defaultMessage: 'Observability AI Assistant', + }), + order: 8600, + category: DEFAULT_APP_CATEGORIES.observability, + app: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'kibana'], + catalogue: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID], + management: { + insightsAndAlerting: ['triggersActionsConnectors'], + }, + minimumLicense: 'enterprise', + // see x-pack/plugins/features/common/feature_kibana_privileges.ts + privileges: { + all: { + app: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'kibana'], + api: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'ai_assistant'], + catalogue: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID], + savedObject: { + all: [ + ACTION_SAVED_OBJECT_TYPE, + ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, + CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + ], + read: [], + }, + management: { + insightsAndAlerting: ['triggersActionsConnectors'], + }, + ui: ['show'], + }, + read: { + app: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'kibana'], + api: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID, 'ai_assistant'], + catalogue: [OBSERVABILITY_AI_ASSISTANT_FEATURE_ID], + savedObject: { + all: [], + read: [ + ACTION_SAVED_OBJECT_TYPE, + ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, + CONNECTOR_TOKEN_SAVED_OBJECT_TYPE, + ], + }, + management: { + insightsAndAlerting: ['triggersActionsConnectors'], + }, + ui: ['show'], + }, + }, + }); + const routeHandlerPlugins = mapValues(plugins, (value, key) => { return { setup: value, diff --git a/x-pack/plugins/observability_ai_assistant/server/types.ts b/x-pack/plugins/observability_ai_assistant/server/types.ts index faa5c346541c0..58f890c80000f 100644 --- a/x-pack/plugins/observability_ai_assistant/server/types.ts +++ b/x-pack/plugins/observability_ai_assistant/server/types.ts @@ -4,18 +4,26 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - -import type { PluginSetupContract, PluginStartContract } from '@kbn/actions-plugin/server'; +import type { + PluginStartContract as FeaturesPluginStart, + PluginSetupContract as FeaturesPluginSetup, +} from '@kbn/features-plugin/server'; +import type { + PluginSetupContract as ActionsPluginSetup, + PluginStartContract as ActionsPluginStart, +} from '@kbn/actions-plugin/server'; import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin/server'; /* eslint-disable @typescript-eslint/no-empty-interface*/ export interface ObservabilityAIAssistantPluginStart {} export interface ObservabilityAIAssistantPluginSetup {} export interface ObservabilityAIAssistantPluginSetupDependencies { - actions: PluginSetupContract; + actions: ActionsPluginSetup; security: SecurityPluginSetup; + features: FeaturesPluginSetup; } export interface ObservabilityAIAssistantPluginStartDependencies { - actions: PluginStartContract; + actions: ActionsPluginStart; security: SecurityPluginStart; + features: FeaturesPluginStart; } diff --git a/x-pack/plugins/observability_ai_assistant/tsconfig.json b/x-pack/plugins/observability_ai_assistant/tsconfig.json index fbe0b8b245377..39507261898f5 100644 --- a/x-pack/plugins/observability_ai_assistant/tsconfig.json +++ b/x-pack/plugins/observability_ai_assistant/tsconfig.json @@ -24,7 +24,8 @@ "@kbn/spaces-plugin", "@kbn/kibana-react-plugin", "@kbn/shared-ux-utility", - "@kbn/alerting-plugin" + "@kbn/alerting-plugin", + "@kbn/features-plugin" ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/custom_logs/__snapshots__/generate_custom_logs_yml.test.ts.snap b/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/custom_logs/__snapshots__/generate_custom_logs_yml.test.ts.snap similarity index 100% rename from x-pack/plugins/observability_onboarding/server/routes/elastic_agent/custom_logs/__snapshots__/generate_custom_logs_yml.test.ts.snap rename to x-pack/plugins/observability_onboarding/common/elastic_agent_logs/custom_logs/__snapshots__/generate_custom_logs_yml.test.ts.snap diff --git a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/custom_logs/generate_custom_logs_yml.test.ts b/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/custom_logs/generate_custom_logs_yml.test.ts similarity index 100% rename from x-pack/plugins/observability_onboarding/server/routes/elastic_agent/custom_logs/generate_custom_logs_yml.test.ts rename to x-pack/plugins/observability_onboarding/common/elastic_agent_logs/custom_logs/generate_custom_logs_yml.test.ts diff --git a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/custom_logs/generate_custom_logs_yml.ts b/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/custom_logs/generate_custom_logs_yml.ts similarity index 100% rename from x-pack/plugins/observability_onboarding/server/routes/elastic_agent/custom_logs/generate_custom_logs_yml.ts rename to x-pack/plugins/observability_onboarding/common/elastic_agent_logs/custom_logs/generate_custom_logs_yml.ts diff --git a/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/index.ts b/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/index.ts new file mode 100644 index 0000000000000..d987fe480e7df --- /dev/null +++ b/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './custom_logs/generate_custom_logs_yml'; +export * from './system_logs/generate_system_logs_yml'; diff --git a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/system_logs/__snapshots__/generate_system_logs_yml.test.ts.snap b/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/system_logs/__snapshots__/generate_system_logs_yml.test.ts.snap similarity index 100% rename from x-pack/plugins/observability_onboarding/server/routes/elastic_agent/system_logs/__snapshots__/generate_system_logs_yml.test.ts.snap rename to x-pack/plugins/observability_onboarding/common/elastic_agent_logs/system_logs/__snapshots__/generate_system_logs_yml.test.ts.snap diff --git a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/system_logs/generate_system_logs_yml.test.ts b/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/system_logs/generate_system_logs_yml.test.ts similarity index 100% rename from x-pack/plugins/observability_onboarding/server/routes/elastic_agent/system_logs/generate_system_logs_yml.test.ts rename to x-pack/plugins/observability_onboarding/common/elastic_agent_logs/system_logs/generate_system_logs_yml.test.ts diff --git a/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/system_logs/generate_system_logs_yml.ts b/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/system_logs/generate_system_logs_yml.ts new file mode 100644 index 0000000000000..c9008c1276535 --- /dev/null +++ b/x-pack/plugins/observability_onboarding/common/elastic_agent_logs/system_logs/generate_system_logs_yml.ts @@ -0,0 +1,103 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { dump } from 'js-yaml'; + +interface SystemLogsStream { + id: string; + data_stream: { + dataset: string; + type: string; + }; + paths: string[]; + exclude_files: string[]; + multiline: { + pattern: string; + match: string; + }; + tags?: string[]; + processors: Array<{ + add_locale: string | null; + }>; +} + +export const generateSystemLogsYml = ({ + namespace = 'default', + apiKey, + esHost, + uuid, +}: { + namespace?: string; + apiKey: string; + esHost: string[]; + uuid: string; +}) => { + return dump({ + outputs: { + default: { + type: 'elasticsearch', + hosts: esHost, + api_key: apiKey, + }, + }, + inputs: [ + { + id: `system-logs-${uuid}`, + type: 'logfile', + data_stream: { + namespace, + }, + streams: getSystemLogsDataStreams(uuid), + }, + ], + }); +}; + +/* + * Utils + */ +export const getSystemLogsDataStreams = ( + uuid: string = '' +): SystemLogsStream[] => [ + { + id: `logfile-system.auth-${uuid}`, + data_stream: { + dataset: 'system.auth', + type: 'logs', + }, + paths: ['/var/log/auth.log*', '/var/log/secure*'], + exclude_files: ['.gz$'], + multiline: { + pattern: '^s', + match: 'after', + }, + tags: ['system-auth'], + processors: [ + { + add_locale: null, + }, + ], + }, + { + id: `logfile-system.syslog-${uuid}`, + data_stream: { + dataset: 'system.syslog', + type: 'logs', + }, + paths: ['/var/log/messages*', '/var/log/syslog*', '/var/log/system*'], + exclude_files: ['.gz$'], + multiline: { + pattern: '^s', + match: 'after', + }, + processors: [ + { + add_locale: null, + }, + ], + }, +]; diff --git a/x-pack/plugins/observability_onboarding/kibana.jsonc b/x-pack/plugins/observability_onboarding/kibana.jsonc index 85a387fff085a..97689407aff41 100644 --- a/x-pack/plugins/observability_onboarding/kibana.jsonc +++ b/x-pack/plugins/observability_onboarding/kibana.jsonc @@ -7,7 +7,7 @@ "server": true, "browser": true, "configPath": ["xpack", "observability_onboarding"], - "requiredPlugins": ["data", "observability", "observabilityShared"], + "requiredPlugins": ["data", "observability", "observabilityShared", "discover"], "optionalPlugins": ["cloud", "usageCollection"], "requiredBundles": ["kibanaReact"], "extraPublicDirs": ["common"] diff --git a/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx b/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx index dab59e7999068..187724f68bbb8 100644 --- a/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx +++ b/x-pack/plugins/observability_onboarding/public/components/app/custom_logs/wizard/install_elastic_agent.tsx @@ -14,10 +14,11 @@ import { EuiText, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; import { default as React, useCallback, useEffect, useState } from 'react'; +import { ObservabilityOnboardingPluginSetupDeps } from '../../../../plugin'; import { useWizard } from '.'; import { FETCH_STATUS, useFetcher } from '../../../../hooks/use_fetcher'; -import { useKibanaNavigation } from '../../../../hooks/use_kibana_navigation'; import { ElasticAgentPlatform, getElasticAgentSetupCommand, @@ -34,9 +35,14 @@ import { } from '../../../shared/step_panel'; import { ApiKeyBanner } from './api_key_banner'; import { BackButton } from './back_button'; +import { getDiscoverNavigationParams } from '../../utils'; export function InstallElasticAgent() { - const { navigateToKibanaUrl } = useKibanaNavigation(); + const { + services: { + discover: { locator }, + }, + } = useKibana(); const { goBack, goToStep, getState, setState } = useWizard(); const wizardState = getState(); const [elasticAgentPlatform, setElasticAgentPlatform] = @@ -45,8 +51,10 @@ export function InstallElasticAgent() { function onInspect() { goToStep('inspect'); } - function onContinue() { - navigateToKibanaUrl('/app/logs/stream'); + async function onContinue() { + await locator?.navigate( + getDiscoverNavigationParams([wizardState.datasetName]) + ); } function onAutoDownloadConfig() { diff --git a/x-pack/plugins/observability_onboarding/public/components/app/system_logs/install_elastic_agent.tsx b/x-pack/plugins/observability_onboarding/public/components/app/system_logs/install_elastic_agent.tsx index 5eb80c9e11525..d1744793bbd31 100644 --- a/x-pack/plugins/observability_onboarding/public/components/app/system_logs/install_elastic_agent.tsx +++ b/x-pack/plugins/observability_onboarding/public/components/app/system_logs/install_elastic_agent.tsx @@ -13,7 +13,10 @@ import { EuiText, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { useKibana } from '@kbn/kibana-react-plugin/public'; import { default as React, useCallback, useEffect, useState } from 'react'; +import { getSystemLogsDataStreams } from '../../../../common/elastic_agent_logs'; +import { ObservabilityOnboardingPluginSetupDeps } from '../../../plugin'; import { useWizard } from '.'; import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher'; import { useKibanaNavigation } from '../../../hooks/use_kibana_navigation'; @@ -32,8 +35,15 @@ import { StepPanelFooter, } from '../../shared/step_panel'; import { ApiKeyBanner } from '../custom_logs/wizard/api_key_banner'; +import { getDiscoverNavigationParams } from '../utils'; export function InstallElasticAgent() { + const { + services: { + discover: { locator }, + }, + } = useKibana(); + const { navigateToKibanaUrl } = useKibanaNavigation(); const { getState, setState } = useWizard(); const wizardState = getState(); @@ -45,8 +55,12 @@ export function InstallElasticAgent() { function onBack() { navigateToKibanaUrl('/app/observabilityOnboarding'); } - function onContinue() { - navigateToKibanaUrl('/app/logs/stream'); + async function onContinue() { + const dataStreams = getSystemLogsDataStreams(); + const dataSets = dataStreams.map( + (dataSream) => dataSream.data_stream.dataset + ); + await locator?.navigate(getDiscoverNavigationParams(dataSets)); } function onAutoDownloadConfig() { diff --git a/x-pack/plugins/observability_onboarding/public/components/app/utils.ts b/x-pack/plugins/observability_onboarding/public/components/app/utils.ts new file mode 100644 index 0000000000000..843002cb1fcc6 --- /dev/null +++ b/x-pack/plugins/observability_onboarding/public/components/app/utils.ts @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { DataViewSpec } from '@kbn/data-views-plugin/common'; +import { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; +import { Filter, FilterStateStore } from '@kbn/es-query'; + +type DiscoverPropertiesToPick = 'dataViewId' | 'dataViewSpec' | 'filters'; + +type DiscoverNavigationParams = Pick< + DiscoverAppLocatorParams, + DiscoverPropertiesToPick +>; + +const defaultFilterKey = 'data_stream.dataset'; +const defaultLogsDataViewId = 'logs-*'; +const defaultLogsDataView: DataViewSpec = { + id: defaultLogsDataViewId, + title: defaultLogsDataViewId, +}; + +const getDefaultDatasetFilter = (datasets: string[]): Filter[] => [ + { + meta: { + index: defaultLogsDataViewId, + key: defaultFilterKey, + params: datasets, + type: 'phrases', + }, + query: { + bool: { + minimum_should_match: 1, + should: datasets.map((dataset) => ({ + match_phrase: { + [defaultFilterKey]: dataset, + }, + })), + }, + }, + $state: { + store: FilterStateStore.APP_STATE, + }, + }, +]; + +export const getDiscoverNavigationParams = ( + datasets: string[] +): DiscoverNavigationParams => ({ + dataViewId: defaultLogsDataViewId, + dataViewSpec: defaultLogsDataView, + filters: getDefaultDatasetFilter(datasets), +}); diff --git a/x-pack/plugins/observability_onboarding/public/plugin.ts b/x-pack/plugins/observability_onboarding/public/plugin.ts index 22b34e0306515..8769991169090 100644 --- a/x-pack/plugins/observability_onboarding/public/plugin.ts +++ b/x-pack/plugins/observability_onboarding/public/plugin.ts @@ -23,6 +23,7 @@ import { DataPublicPluginSetup, DataPublicPluginStart, } from '@kbn/data-plugin/public'; +import type { DiscoverSetup } from '@kbn/discover-plugin/public'; import type { ObservabilityOnboardingConfig } from '../server'; export type ObservabilityOnboardingPluginSetup = void; @@ -31,6 +32,7 @@ export type ObservabilityOnboardingPluginStart = void; export interface ObservabilityOnboardingPluginSetupDeps { data: DataPublicPluginSetup; observability: ObservabilityPublicSetup; + discover: DiscoverSetup; } export interface ObservabilityOnboardingPluginStartDeps { diff --git a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/route.ts b/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/route.ts index 11741726e344c..37256a1159923 100644 --- a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/route.ts +++ b/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/route.ts @@ -7,12 +7,14 @@ import * as t from 'io-ts'; import { v4 as uuidv4 } from 'uuid'; +import { + generateSystemLogsYml, + generateCustomLogsYml, +} from '../../../common/elastic_agent_logs'; import { getAuthenticationAPIKey } from '../../lib/get_authentication_api_key'; import { getFallbackESUrl } from '../../lib/get_fallback_urls'; import { getObservabilityOnboardingFlow } from '../../lib/state'; import { createObservabilityOnboardingServerRoute } from '../create_observability_onboarding_server_route'; -import { generateCustomLogsYml } from './custom_logs/generate_custom_logs_yml'; -import { generateSystemLogsYml } from './system_logs/generate_system_logs_yml'; const generateConfig = createObservabilityOnboardingServerRoute({ endpoint: 'GET /internal/observability_onboarding/elastic_agent/config', diff --git a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/system_logs/generate_system_logs_yml.ts b/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/system_logs/generate_system_logs_yml.ts deleted file mode 100644 index c9335cb97fa28..0000000000000 --- a/x-pack/plugins/observability_onboarding/server/routes/elastic_agent/system_logs/generate_system_logs_yml.ts +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { dump } from 'js-yaml'; - -export const generateSystemLogsYml = ({ - namespace = 'default', - apiKey, - esHost, - uuid, -}: { - namespace?: string; - apiKey: string; - esHost: string[]; - uuid: string; -}) => { - return dump({ - outputs: { - default: { - type: 'elasticsearch', - hosts: esHost, - api_key: apiKey, - }, - }, - inputs: [ - { - id: `system-logs-${uuid}`, - type: 'logfile', - data_stream: { - namespace, - }, - streams: [ - { - id: `logfile-system.auth-${uuid}`, - data_stream: { - dataset: 'system.auth', - type: 'logs', - }, - paths: ['/var/log/auth.log*', '/var/log/secure*'], - exclude_files: ['.gz$'], - multiline: { - pattern: '^s', - match: 'after', - }, - tags: ['system-auth'], - processors: [ - { - add_locale: null, - }, - ], - }, - { - id: `logfile-system.syslog-${uuid}`, - data_stream: { - dataset: 'system.syslog', - type: 'logs', - }, - paths: [ - '/var/log/messages*', - '/var/log/syslog*', - '/var/log/system*', - ], - exclude_files: ['.gz$'], - multiline: { - pattern: '^s', - match: 'after', - }, - processors: [ - { - add_locale: null, - }, - ], - }, - ], - }, - ], - }); -}; diff --git a/x-pack/plugins/observability_onboarding/tsconfig.json b/x-pack/plugins/observability_onboarding/tsconfig.json index 2099683e42a59..6bb24fde8c588 100644 --- a/x-pack/plugins/observability_onboarding/tsconfig.json +++ b/x-pack/plugins/observability_onboarding/tsconfig.json @@ -14,6 +14,7 @@ "kbn_references": [ "@kbn/core", "@kbn/data-plugin", + "@kbn/discover-plugin", "@kbn/kibana-react-plugin", "@kbn/observability-plugin", "@kbn/i18n", @@ -29,6 +30,8 @@ "@kbn/core-http-server", "@kbn/security-plugin", "@kbn/std", + "@kbn/data-views-plugin", + "@kbn/es-query", ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts b/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts index ef24db6909e4c..f0956b960a7f5 100644 --- a/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts +++ b/x-pack/plugins/osquery/cypress/e2e/all/alerts.cy.ts @@ -95,7 +95,7 @@ describe('Alert Event Details', () => { }); }); - describe('Response actions', () => { + describe.skip('Response actions', () => { let multiQueryPackId: string; let multiQueryPackName: string; let ruleId: string; @@ -374,7 +374,7 @@ describe('Alert Event Details', () => { }); }); - describe('Case creation', () => { + describe.skip('Case creation', () => { let ruleId: string; let ruleName: string; let packId: string; diff --git a/x-pack/plugins/profiling/server/feature.ts b/x-pack/plugins/profiling/server/feature.ts index 446a436145c77..13e064364b7b8 100644 --- a/x-pack/plugins/profiling/server/feature.ts +++ b/x-pack/plugins/profiling/server/feature.ts @@ -27,7 +27,7 @@ export const PROFILING_FEATURE = { read: [], }, ui: ['show'], - api: [PROFILING_SERVER_FEATURE_ID, 'ai_assistant'], + api: [PROFILING_SERVER_FEATURE_ID], }, read: { app: [PROFILING_SERVER_FEATURE_ID, 'ux', 'kibana'], @@ -36,7 +36,7 @@ export const PROFILING_FEATURE = { read: [], }, ui: ['show'], - api: [PROFILING_SERVER_FEATURE_ID, 'ai_assistant'], + api: [PROFILING_SERVER_FEATURE_ID], }, }, }; diff --git a/x-pack/plugins/reporting/server/config/create_config.test.ts b/x-pack/plugins/reporting/server/config/create_config.test.ts index 81e2c2e7825b1..0a10b859bb18f 100644 --- a/x-pack/plugins/reporting/server/config/create_config.test.ts +++ b/x-pack/plugins/reporting/server/config/create_config.test.ts @@ -66,6 +66,17 @@ describe('Reporting server createConfig', () => { }, }, "encryptionKey": "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii", + "export_types": Object { + "csv": Object { + "enabled": true, + }, + "pdf": Object { + "enabled": true, + }, + "png": Object { + "enabled": true, + }, + }, "index": ".reporting", "kibanaServer": Object { "hostname": "reportingHost", diff --git a/x-pack/plugins/reporting/server/config/schema.test.ts b/x-pack/plugins/reporting/server/config/schema.test.ts index e532a2eb8426a..14ed1886e9136 100644 --- a/x-pack/plugins/reporting/server/config/schema.test.ts +++ b/x-pack/plugins/reporting/server/config/schema.test.ts @@ -112,4 +112,14 @@ describe('Reporting Config Schema', () => { ConfigSchema.validate({ export_types: { csv: { enabled: true } } }, { dev: true }) ).not.toThrow(); }); + + describe('roles', () => { + it('should have roles enabled set to false for serverless by default', () => { + expect(ConfigSchema.validate({}, { serverless: true }).roles.enabled).toBe(false); + }); + + it('should have roles enabled set to true for non-serverless by default', () => { + expect(ConfigSchema.validate({}).roles.enabled).toBe(true); + }); + }); }); diff --git a/x-pack/plugins/reporting/server/config/schema.ts b/x-pack/plugins/reporting/server/config/schema.ts index 35d77703a2448..4790a3fb6b7aa 100644 --- a/x-pack/plugins/reporting/server/config/schema.ts +++ b/x-pack/plugins/reporting/server/config/schema.ts @@ -84,8 +84,18 @@ const EncryptionKeySchema = schema.conditional( ); const RolesSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), // true: use ES API for access control (deprecated in 7.x). false: use Kibana API for application features (8.0) - allow: schema.arrayOf(schema.string(), { defaultValue: ['reporting_user'] }), + enabled: schema.conditional( + schema.contextRef('serverless'), + true, + schema.boolean({ defaultValue: false }), + schema.boolean({ defaultValue: true }) + ), // true: use ES API for access control (deprecated in 7.x). false: use Kibana API for application features (8.0) + allow: schema.conditional( + schema.contextRef('serverless'), + true, + schema.arrayOf(schema.string(), { defaultValue: [] }), + schema.arrayOf(schema.string(), { defaultValue: ['reporting_user'] }) + ), }); // Browser side polling: job completion notifier, management table auto-refresh diff --git a/x-pack/plugins/reporting/server/core.ts b/x-pack/plugins/reporting/server/core.ts index 7eb3c31a0ee1b..d81f7b8ab9808 100644 --- a/x-pack/plugins/reporting/server/core.ts +++ b/x-pack/plugins/reporting/server/core.ts @@ -109,7 +109,6 @@ export class ReportingCore { private monitorTask: MonitorReportsTask; private config: ReportingConfigType; private executing: Set; - private exportTypes: ExportType[] = []; private exportTypesRegistry = new ExportTypesRegistry(); public getContract: () => ReportingSetup; @@ -125,20 +124,9 @@ export class ReportingCore { const config = createConfig(core, context.config.get(), logger); this.config = config; - // Export Type declarations - this.exportTypes.push( - new CsvSearchSourceExportType(this.core, this.config, this.logger, this.context) - ); - this.exportTypes.push(new CsvV2ExportType(this.core, this.config, this.logger, this.context)); - this.exportTypes.push(new PdfExportType(this.core, this.config, this.logger, this.context)); - this.exportTypes.push(new PngExportType(this.core, this.config, this.logger, this.context)); - // deprecated export types for tests - this.exportTypes.push(new PdfV1ExportType(this.core, this.config, this.logger, this.context)); - - this.exportTypes.forEach((et) => { + this.getExportTypes().forEach((et) => { this.exportTypesRegistry.register(et); }); - this.deprecatedAllowedRoles = config.roles.enabled ? config.roles.allow : false; this.executeTask = new ExecuteReportTask(this, config, this.logger); this.monitorTask = new MonitorReportsTask(this, config, this.logger); @@ -164,7 +152,7 @@ export class ReportingCore { this.pluginSetup$.next(true); // trigger the observer this.pluginSetupDeps = setupDeps; // cache - this.exportTypes.forEach((et) => { + this.exportTypesRegistry.getAll().forEach((et) => { et.setup(setupDeps); }); @@ -182,7 +170,7 @@ export class ReportingCore { this.pluginStart$.next(startDeps); // trigger the observer this.pluginStartDeps = startDeps; // cache - this.exportTypes.forEach((et) => { + this.exportTypesRegistry.getAll().forEach((et) => { et.start({ ...startDeps, reporting: this.getContract() }); }); @@ -233,6 +221,30 @@ export class ReportingCore { this.pluginSetup$.next(true); } + /** + * Validate export types with config settings + * only CSV export types should be registered in the export types registry for serverless + */ + private getExportTypes(): ExportType[] { + const exportTypes = []; + if (!this.config.export_types.pdf.enabled || !this.config.export_types.png.enabled) { + exportTypes.push( + new CsvSearchSourceExportType(this.core, this.config, this.logger, this.context) + ); + exportTypes.push(new CsvV2ExportType(this.core, this.config, this.logger, this.context)); + } else { + exportTypes.push( + new CsvSearchSourceExportType(this.core, this.config, this.logger, this.context) + ); + exportTypes.push(new CsvV2ExportType(this.core, this.config, this.logger, this.context)); + exportTypes.push(new PdfExportType(this.core, this.config, this.logger, this.context)); + exportTypes.push(new PngExportType(this.core, this.config, this.logger, this.context)); + // deprecated export types for tests + exportTypes.push(new PdfV1ExportType(this.core, this.config, this.logger, this.context)); + } + return exportTypes; + } + /** * If xpack.reporting.roles.enabled === true, register Reporting as a feature * that is controlled by user role names diff --git a/x-pack/plugins/reporting/server/plugin.test.ts b/x-pack/plugins/reporting/server/plugin.test.ts index e12c1b238daa6..176b648b9d02a 100644 --- a/x-pack/plugins/reporting/server/plugin.test.ts +++ b/x-pack/plugins/reporting/server/plugin.test.ts @@ -7,6 +7,7 @@ import type { CoreSetup, CoreStart, Logger } from '@kbn/core/server'; import { coreMock, loggingSystemMock } from '@kbn/core/server/mocks'; +import { PDF_REPORT_TYPE_V2, PNG_REPORT_TYPE_V2 } from '../common/constants/report_types'; import type { ReportingCore, ReportingInternalStart } from './core'; import { ReportingPlugin } from './plugin'; import { @@ -80,4 +81,50 @@ describe('Reporting Plugin', () => { `); expect(logger.error).toHaveBeenCalledTimes(2); }); + describe('config and export types registry validation', () => { + it('expect image reporting to be in registry by default', async () => { + // wait for the setup phase background work + plugin.setup(coreSetup, pluginSetup); + await new Promise(setImmediate); + + // create a way for an error to happen + const reportingCore = (plugin as unknown as { reportingCore: ReportingCore }).reportingCore; + + // wait for the startup phase background work + plugin.start(coreStart, pluginStart); + await new Promise(setImmediate); + expect(reportingCore.getExportTypesRegistry().getById(PDF_REPORT_TYPE_V2)).toHaveProperty( + 'id', + PDF_REPORT_TYPE_V2 + ); + expect(reportingCore.getExportTypesRegistry().getById(PNG_REPORT_TYPE_V2)).toHaveProperty( + 'id', + PNG_REPORT_TYPE_V2 + ); + }); + it('expect pdf to not be in registry if config does not enable it', async () => { + configSchema = { ...createMockConfigSchema(), export_types: { pdf: { enabled: false } } }; + initContext = coreMock.createPluginInitializerContext(configSchema); + coreSetup = coreMock.createSetup(configSchema); + coreStart = coreMock.createStart(); + pluginSetup = createMockPluginSetup({}) as unknown as ReportingSetupDeps; + pluginStart = await createMockPluginStart(coreStart, configSchema); + + plugin = new ReportingPlugin(initContext); + // wait for the setup phase background work + plugin.setup(coreSetup, pluginSetup); + await new Promise(setImmediate); + + // create a way for an error to happen + const reportingCore = (plugin as unknown as { reportingCore: ReportingCore }).reportingCore; + + // wait for the startup phase background work + plugin.start(coreStart, pluginStart); + await new Promise(setImmediate); + const checkPdf = () => reportingCore.getExportTypesRegistry().getById(PDF_REPORT_TYPE_V2); + const checkPng = () => reportingCore.getExportTypesRegistry().getById(PNG_REPORT_TYPE_V2); + expect(checkPdf).toThrowError(`Unknown id ${PDF_REPORT_TYPE_V2}`); + expect(checkPng).toThrowError(`Unknown id ${PNG_REPORT_TYPE_V2}`); + }); + }); }); diff --git a/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts b/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts index a91db44ba436f..4fbacb3a8b994 100644 --- a/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts +++ b/x-pack/plugins/reporting/server/test_helpers/create_mock_reportingplugin.ts @@ -111,6 +111,11 @@ export const createMockConfigSchema = ( ...overrides.roles, }, capture: { maxAttempts: 1 }, + export_types: { + pdf: { enabled: true }, + png: { enabled: true }, + csv: { enabled: true }, + }, } as ReportingConfigType; }; diff --git a/x-pack/plugins/security/common/model/api_key.ts b/x-pack/plugins/security/common/model/api_key.ts index fcdd823b4b85e..3441f4d07a8c1 100644 --- a/x-pack/plugins/security/common/model/api_key.ts +++ b/x-pack/plugins/security/common/model/api_key.ts @@ -5,23 +5,75 @@ * 2.0. */ -import type { Role } from './role'; +import type { estypes } from '@elastic/elasticsearch'; -export interface ApiKey { - id: string; - name: string; - username: string; - realm: string; - creation: number; - expiration: number; - invalidated: boolean; - metadata: Record; - role_descriptors?: Record; +/** + * Interface representing an API key the way it is returned by Elasticsearch GET endpoint. + */ +export type ApiKey = RestApiKey | CrossClusterApiKey; + +/** + * Interface representing a REST API key the way it is returned by Elasticsearch GET endpoint. + * + * TODO: Remove this type when `@elastic/elasticsearch` has been updated. + */ +export interface RestApiKey extends BaseApiKey { + type: 'rest'; } +/** + * Interface representing a Cross-Cluster API key the way it is returned by Elasticsearch GET endpoint. + * + * TODO: Remove this type when `@elastic/elasticsearch` has been updated. + */ +export interface CrossClusterApiKey extends BaseApiKey { + type: 'cross_cluster'; + + /** + * The access to be granted to this API key. The access is composed of permissions for cross-cluster + * search and cross-cluster replication. At least one of them must be specified. + */ + access: CrossClusterApiKeyAccess; +} + +/** + * Fixing up `estypes.SecurityApiKey` type since some fields are marked as optional even though they are guaranteed to be returned. + * + * TODO: Remove this type when `@elastic/elasticsearch` has been updated. + */ +interface BaseApiKey extends estypes.SecurityApiKey { + username: Required['username']; + realm: Required['realm']; + creation: Required['creation']; + metadata: Required['metadata']; + role_descriptors: Required['role_descriptors']; +} + +// TODO: Remove this type when `@elastic/elasticsearch` has been updated. +export interface CrossClusterApiKeyAccess { + /** + * A list of indices permission entries for cross-cluster search. + */ + search?: CrossClusterApiKeySearch[]; + + /** + * A list of indices permission entries for cross-cluster replication. + */ + replication?: CrossClusterApiKeyReplication[]; +} + +// TODO: Remove this type when `@elastic/elasticsearch` has been updated. +type CrossClusterApiKeySearch = Pick< + estypes.SecurityIndicesPrivileges, + 'names' | 'field_security' | 'query' | 'allow_restricted_indices' +>; + +// TODO: Remove this type when `@elastic/elasticsearch` has been updated. +type CrossClusterApiKeyReplication = Pick; + +export type ApiKeyRoleDescriptors = Record; + export interface ApiKeyToInvalidate { id: string; name: string; } - -export type ApiKeyRoleDescriptors = Record; diff --git a/x-pack/plugins/security/common/model/index.ts b/x-pack/plugins/security/common/model/index.ts index a1f3e88fdf56c..822d6036efc06 100644 --- a/x-pack/plugins/security/common/model/index.ts +++ b/x-pack/plugins/security/common/model/index.ts @@ -5,7 +5,14 @@ * 2.0. */ -export type { ApiKey, ApiKeyToInvalidate, ApiKeyRoleDescriptors } from './api_key'; +export type { + ApiKey, + RestApiKey, + CrossClusterApiKey, + ApiKeyToInvalidate, + ApiKeyRoleDescriptors, + CrossClusterApiKeyAccess, +} from './api_key'; export type { User, EditUser, GetUserDisplayNameParams } from './user'; export type { GetUserProfileResponse, diff --git a/x-pack/plugins/security/public/components/token_field.tsx b/x-pack/plugins/security/public/components/token_field.tsx index 7363ce7b28ff8..7e1308bf37d47 100644 --- a/x-pack/plugins/security/public/components/token_field.tsx +++ b/x-pack/plugins/security/public/components/token_field.tsx @@ -57,7 +57,11 @@ export const TokenField: FunctionComponent = (props) => { })} className="euiFieldText euiFieldText--inGroup" value={props.value} - style={{ fontFamily: euiThemeVars.euiCodeFontFamily, fontSize: euiThemeVars.euiFontSizeXS }} + style={{ + fontFamily: euiThemeVars.euiCodeFontFamily, + fontSize: euiThemeVars.euiFontSizeXS, + backgroundColor: 'transparent', + }} onFocus={(event) => event.currentTarget.select()} readOnly /> diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.mock.ts b/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.mock.ts index a8f317800d8b0..4270ccbc8539b 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.mock.ts +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.mock.ts @@ -5,9 +5,12 @@ * 2.0. */ +import type { PublicMethodsOf } from '@kbn/utility-types'; + +import type { APIKeysAPIClient } from './api_keys_api_client'; + export const apiKeysAPIClientMock = { - create: () => ({ - checkPrivileges: jest.fn(), + create: (): jest.Mocked> => ({ getApiKeys: jest.fn(), invalidateApiKeys: jest.fn(), createApiKey: jest.fn(), diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.test.ts b/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.test.ts index 02b2024e609e0..de92fb637ddf2 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.test.ts +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.test.ts @@ -10,19 +10,6 @@ import { httpServiceMock } from '@kbn/core/public/mocks'; import { APIKeysAPIClient } from './api_keys_api_client'; describe('APIKeysAPIClient', () => { - it('checkPrivileges() queries correct endpoint', async () => { - const httpMock = httpServiceMock.createStartContract(); - - const mockResponse = Symbol('mockResponse'); - httpMock.get.mockResolvedValue(mockResponse); - - const apiClient = new APIKeysAPIClient(httpMock); - - await expect(apiClient.checkPrivileges()).resolves.toBe(mockResponse); - expect(httpMock.get).toHaveBeenCalledTimes(1); - expect(httpMock.get).toHaveBeenCalledWith('/internal/security/api_key/privileges'); - }); - it('getApiKeys() queries correct endpoint', async () => { const httpMock = httpServiceMock.createStartContract(); @@ -33,23 +20,8 @@ describe('APIKeysAPIClient', () => { await expect(apiClient.getApiKeys()).resolves.toBe(mockResponse); expect(httpMock.get).toHaveBeenCalledTimes(1); - expect(httpMock.get).toHaveBeenCalledWith('/internal/security/api_key', { - query: { isAdmin: false }, - }); + expect(httpMock.get).toHaveBeenCalledWith('/internal/security/api_key'); httpMock.get.mockClear(); - - await expect(apiClient.getApiKeys(false)).resolves.toBe(mockResponse); - expect(httpMock.get).toHaveBeenCalledTimes(1); - expect(httpMock.get).toHaveBeenCalledWith('/internal/security/api_key', { - query: { isAdmin: false }, - }); - httpMock.get.mockClear(); - - await expect(apiClient.getApiKeys(true)).resolves.toBe(mockResponse); - expect(httpMock.get).toHaveBeenCalledTimes(1); - expect(httpMock.get).toHaveBeenCalledWith('/internal/security/api_key', { - query: { isAdmin: true }, - }); }); it('invalidateApiKeys() queries correct endpoint', async () => { @@ -92,7 +64,7 @@ describe('APIKeysAPIClient', () => { httpMock.post.mockResolvedValue(mockResponse); const apiClient = new APIKeysAPIClient(httpMock); - const mockAPIKeys = { name: 'name', expiration: '7d' }; + const mockAPIKeys = { name: 'name', expiration: '7d' } as any; await expect(apiClient.createApiKey(mockAPIKeys)).resolves.toBe(mockResponse); expect(httpMock.post).toHaveBeenCalledTimes(1); @@ -108,7 +80,7 @@ describe('APIKeysAPIClient', () => { httpMock.put.mockResolvedValue(mockResponse); const apiClient = new APIKeysAPIClient(httpMock); - const mockApiKeyUpdate = { id: 'test_id', metadata: {}, roles_descriptor: {} }; + const mockApiKeyUpdate = { id: 'test_id', metadata: {}, roles_descriptor: {} } as any; await expect(apiClient.updateApiKey(mockApiKeyUpdate)).resolves.toBe(mockResponse); expect(httpMock.put).toHaveBeenCalledTimes(1); diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.ts b/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.ts index 6095278d73864..be236b02e4c65 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.ts +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_api_client.ts @@ -7,58 +7,29 @@ import type { HttpStart } from '@kbn/core/public'; -import type { ApiKey, ApiKeyRoleDescriptors, ApiKeyToInvalidate } from '../../../common/model'; +import type { ApiKeyToInvalidate } from '../../../common/model'; +import type { + CreateAPIKeyParams, + CreateAPIKeyResult, + GetAPIKeysResult, + UpdateAPIKeyParams, + UpdateAPIKeyResult, +} from '../../../server/routes/api_keys'; -export interface CheckPrivilegesResponse { - areApiKeysEnabled: boolean; - isAdmin: boolean; - canManage: boolean; -} +export type { CreateAPIKeyParams, CreateAPIKeyResult, UpdateAPIKeyParams, UpdateAPIKeyResult }; export interface InvalidateApiKeysResponse { itemsInvalidated: ApiKeyToInvalidate[]; errors: any[]; } -export interface GetApiKeysResponse { - apiKeys: ApiKey[]; -} - -export interface CreateApiKeyRequest { - name: string; - expiration?: string; - role_descriptors?: ApiKeyRoleDescriptors; - metadata?: Record; -} - -export interface CreateApiKeyResponse { - id: string; - name: string; - expiration: number; - api_key: string; -} - -export interface UpdateApiKeyRequest { - id: string; - role_descriptors?: ApiKeyRoleDescriptors; - metadata?: Record; -} - -export interface UpdateApiKeyResponse { - updated: boolean; -} - const apiKeysUrl = '/internal/security/api_key'; export class APIKeysAPIClient { constructor(private readonly http: HttpStart) {} - public async checkPrivileges() { - return await this.http.get(`${apiKeysUrl}/privileges`); - } - - public async getApiKeys(isAdmin = false) { - return await this.http.get(apiKeysUrl, { query: { isAdmin } }); + public async getApiKeys() { + return await this.http.get(apiKeysUrl); } public async invalidateApiKeys(apiKeys: ApiKeyToInvalidate[], isAdmin = false) { @@ -67,14 +38,14 @@ export class APIKeysAPIClient { }); } - public async createApiKey(apiKey: CreateApiKeyRequest) { - return await this.http.post(apiKeysUrl, { + public async createApiKey(apiKey: CreateAPIKeyParams) { + return await this.http.post(apiKeysUrl, { body: JSON.stringify(apiKey), }); } - public async updateApiKey(apiKey: UpdateApiKeyRequest) { - return await this.http.put(apiKeysUrl, { + public async updateApiKey(apiKey: UpdateAPIKeyParams) { + return await this.http.put(apiKeysUrl, { body: JSON.stringify(apiKey), }); } diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_key_flyout.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_key_flyout.tsx index 959c3690b623c..c4196355cda16 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_key_flyout.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_key_flyout.tsx @@ -5,23 +5,23 @@ * 2.0. */ +import type { ExclusiveUnion } from '@elastic/eui'; import { EuiCallOut, + EuiCheckableCard, EuiFieldNumber, - EuiFieldText, EuiFlexGroup, EuiFlexItem, - EuiForm, EuiFormFieldset, EuiFormRow, - EuiHealth, - EuiIcon, + EuiHorizontalRule, EuiSkeletonText, EuiSpacer, EuiSwitch, EuiText, - EuiToolTip, + EuiTitle, } from '@elastic/eui'; +import { Form, FormikProvider, useFormik } from 'formik'; import moment from 'moment-timezone'; import type { FunctionComponent } from 'react'; import React, { useEffect } from 'react'; @@ -31,51 +31,79 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { CodeEditorField, useKibana } from '@kbn/kibana-react-plugin/public'; -import type { ApiKey, ApiKeyRoleDescriptors, AuthenticatedUser } from '../../../../common/model'; +import type { ApiKeyRoleDescriptors } from '../../../../common/model'; import { DocLink } from '../../../components/doc_link'; +import { FormField } from '../../../components/form_field'; import type { FormFlyoutProps } from '../../../components/form_flyout'; import { FormFlyout } from '../../../components/form_flyout'; +import { FormRow } from '../../../components/form_row'; import { useCurrentUser } from '../../../components/use_current_user'; -import { useForm } from '../../../components/use_form'; -import type { ValidationErrors } from '../../../components/use_form'; import { useInitialFocus } from '../../../components/use_initial_focus'; import { RolesAPIClient } from '../../roles/roles_api_client'; import { APIKeysAPIClient } from '../api_keys_api_client'; import type { - CreateApiKeyRequest, - CreateApiKeyResponse, - UpdateApiKeyRequest, - UpdateApiKeyResponse, + CreateAPIKeyParams, + CreateAPIKeyResult, + UpdateAPIKeyParams, + UpdateAPIKeyResult, } from '../api_keys_api_client'; +import type { CategorizedApiKey } from './api_keys_grid_page'; +import { ApiKeyBadge, ApiKeyStatus, TimeToolTip, UsernameWithIcon } from './api_keys_grid_page'; export interface ApiKeyFormValues { name: string; + type: string; expiration: string; customExpiration: boolean; customPrivileges: boolean; includeMetadata: boolean; + access: string; role_descriptors: string; metadata: string; } -export interface ApiKeyFlyoutProps { - defaultValues?: ApiKeyFormValues; - onSuccess?: ( - createApiKeyResponse: CreateApiKeyResponse | undefined, - updateApiKeyResponse: UpdateApiKeyResponse | undefined - ) => void; +interface CommonApiKeyFlyoutProps { + initialValues?: ApiKeyFormValues; onCancel: FormFlyoutProps['onCancel']; - apiKey?: ApiKey; - readonly?: boolean; + canManageCrossClusterApiKeys?: boolean; + readOnly?: boolean; } -const defaultDefaultValues: ApiKeyFormValues = { +interface CreateApiKeyFlyoutProps extends CommonApiKeyFlyoutProps { + onSuccess?: (createApiKeyResponse: CreateAPIKeyResult) => void; +} + +interface UpdateApiKeyFlyoutProps extends CommonApiKeyFlyoutProps { + onSuccess?: (updateApiKeyResponse: UpdateAPIKeyResult) => void; + apiKey: CategorizedApiKey; +} + +export type ApiKeyFlyoutProps = ExclusiveUnion; + +const defaultInitialValues: ApiKeyFormValues = { name: '', + type: 'rest', customExpiration: false, expiration: '', includeMetadata: false, metadata: '{}', customPrivileges: false, + access: JSON.stringify( + { + search: [ + { + names: ['*'], + }, + ], + replication: [ + { + names: ['*'], + }, + ], + }, + null, + 2 + ), role_descriptors: '{}', }; @@ -83,67 +111,39 @@ export const ApiKeyFlyout: FunctionComponent = ({ onSuccess, onCancel, apiKey, - readonly = false, + canManageCrossClusterApiKeys = false, + readOnly = false, }) => { - let formTitle = 'Create API Key'; - let inProgressButtonText = 'Creating API Key…'; - let errorTitle = 'create API key'; - - const { value: currentUser, loading: isLoadingCurrentUser } = useCurrentUser(); - - let canEditApiKey = false; - - let defaultValues = defaultDefaultValues; - - if (apiKey) { - defaultValues = retrieveValuesFromApiKeyToDefaultFlyout(apiKey); - - canEditApiKey = isEditable(currentUser, apiKey); - - if (readonly || !canEditApiKey) { - formTitle = 'API key details'; - inProgressButtonText = ''; // This won't be seen since Submit will be disabled - errorTitle = ''; - } else { - formTitle = 'Update API Key'; - inProgressButtonText = 'Updating API Key…'; - errorTitle = 'update API key'; - } - } - const { services } = useKibana(); - + const { value: currentUser, loading: isLoadingCurrentUser } = useCurrentUser(); const [{ value: roles, loading: isLoadingRoles }, getRoles] = useAsyncFn( () => new RolesAPIClient(services.http!).getRoles(), [services.http] ); - const [form, eventHandlers] = useForm({ + const formik = useFormik({ onSubmit: async (values) => { try { if (apiKey) { const updateApiKeyResponse = await new APIKeysAPIClient(services.http!).updateApiKey( - mapUpdateApiKeyValues(apiKey.id, values) + mapUpdateApiKeyValues(apiKey.type, apiKey.id, values) ); - onSuccess?.(undefined, updateApiKeyResponse); + onSuccess?.(updateApiKeyResponse); } else { const createApiKeyResponse = await new APIKeysAPIClient(services.http!).createApiKey( mapCreateApiKeyValues(values) ); - onSuccess?.(createApiKeyResponse, undefined); + onSuccess?.(createApiKeyResponse); } } catch (error) { throw error; } }, - validate, - defaultValues, + initialValues: apiKey ? mapApiKeyFormValues(apiKey) : defaultInitialValues, }); - const isLoading = isLoadingCurrentUser || isLoadingRoles; - useEffect(() => { getRoles(); }, []); // eslint-disable-line react-hooks/exhaustive-deps @@ -161,431 +161,574 @@ export const ApiKeyFlyout: FunctionComponent = ({ {} ); - if (!form.touched.role_descriptors && !apiKey) { - form.setValue('role_descriptors', JSON.stringify(userPermissions, null, 2)); + if (!formik.touched.role_descriptors && !apiKey) { + formik.setFieldValue('role_descriptors', JSON.stringify(userPermissions, null, 2)); } } }, [currentUser, roles]); // eslint-disable-line react-hooks/exhaustive-deps + const isLoading = isLoadingCurrentUser || isLoadingRoles; + + const isOwner = currentUser && apiKey ? currentUser.username === apiKey.username : false; + const hasExpired = apiKey ? apiKey.expiration && moment(apiKey.expiration).isBefore() : false; + const canEdit = isOwner && !hasExpired; + const firstFieldRef = useInitialFocus([isLoading]); return ( - + - {form.submitError && ( - <> - - {(form.submitError as any).body?.message || form.submitError.message} - - - - )} - - - - 0 && !formik.isValid) || + readOnly || + (apiKey && !canEdit) + } + isSubmitButtonHidden={readOnly || (apiKey && !canEdit)} + size="m" + ownFocus + > + + {apiKey && !readOnly ? ( + !isOwner ? ( + <> + + } + /> + + + ) : hasExpired ? ( + <> + + } + /> + + + ) : null + ) : null} + +
+ } - )} - > - - - - - - - - {apiKey ? apiKey.username : currentUser?.username} - - - - - - - - - + > + + - {!!apiKey && ( - <> - - - {determineReadonlyExpiration(form.values?.expiration)} - - - )} - - - - form.setValue('customPrivileges', e.target.checked)} - disabled={readonly || (apiKey && !canEditApiKey)} - /> - {form.values.customPrivileges && ( + {apiKey ? ( <> - - + + + + } > - - - } - error={form.errors.role_descriptors} - isInvalid={form.touched.role_descriptors && !!form.errors.role_descriptors} - > - form.setValue('role_descriptors', value)} - languageId="xjson" - height={200} - options={{ readOnly: readonly || (apiKey && !canEditApiKey) }} - /> - - + + + + + + } + > + + + + + + } + > + + + + + + } + > + + + + + ) : canManageCrossClusterApiKeys ? ( + + } + fullWidth + > + + + + +

+ +

+
+ + + + + + } + onChange={() => formik.setFieldValue('type', 'rest')} + checked={formik.values.type === 'rest'} + /> +
+ + + +

+ +

+
+ + + + + + } + onChange={() => formik.setFieldValue('type', 'cross_cluster')} + checked={formik.values.type === 'cross_cluster'} + /> +
+
+
+ ) : ( + + } + > + + )} -
- - {!apiKey && ( - <> - + + + {formik.values.type === 'cross_cluster' ? ( + + } + helpText={ + + + + } + fullWidth + > + formik.setFieldValue('access', value)} + validate={(value: string) => { + if (!value) { + return i18n.translate( + 'xpack.security.management.apiKeys.apiKeyFlyout.accessRequired', + { + defaultMessage: 'Enter access permissions or disable this option.', + } + ); + } + try { + JSON.parse(value); + } catch (e) { + return i18n.translate( + 'xpack.security.management.apiKeys.apiKeyFlyout.invalidJsonError', + { + defaultMessage: 'Enter valid JSON.', + } + ); + } + }} + fullWidth + languageId="xjson" + height={200} + /> + + ) : ( form.setValue('customExpiration', e.target.checked)} - disabled={readonly || !!apiKey} - data-test-subj="apiKeyCustomExpirationSwitch" + label={ + + } + checked={formik.values.customPrivileges} + data-test-subj="apiKeysRoleDescriptorsSwitch" + onChange={(e) => formik.setFieldValue('customPrivileges', e.target.checked)} + disabled={readOnly || (apiKey && !canEdit)} /> - {form.values.customExpiration && ( + {formik.values.customPrivileges && ( <> - - + + + } + fullWidth + data-test-subj="apiKeysRoleDescriptorsCodeEditor" > - + formik.setFieldValue('role_descriptors', value) + } + validate={(value: string) => { + if (!value) { + return i18n.translate( + 'xpack.security.management.apiKeys.apiKeyFlyout.roleDescriptorsRequired', + { + defaultMessage: 'Enter role descriptors or disable this option.', + } + ); + } + try { + JSON.parse(value); + } catch (e) { + return i18n.translate( + 'xpack.security.management.apiKeys.apiKeyFlyout.invalidJsonError', + { + defaultMessage: 'Enter valid JSON.', + } + ); } - )} - name="expiration" - min={0} - defaultValue={form.values.expiration} - isInvalid={form.touched.expiration && !!form.errors.expiration && !apiKey} + }} fullWidth - data-test-subj="apiKeyCustomExpirationInput" - disabled={readonly || !!apiKey} + languageId="xjson" + height={200} /> - + )} - - )} - - - form.setValue('includeMetadata', e.target.checked)} - /> - {form.values.includeMetadata && ( + )} + + {!apiKey && ( <> - - + + + - - } - error={form.errors.metadata} - isInvalid={form.touched.metadata && !!form.errors.metadata} - > - form.setValue('metadata', value)} - languageId="xjson" - height={200} - options={{ readOnly: readonly || (apiKey && !canEditApiKey) }} + } + checked={formik.values.customExpiration} + onChange={(e) => formik.setFieldValue('customExpiration', e.target.checked)} + disabled={readOnly || !!apiKey} + data-test-subj="apiKeyCustomExpirationSwitch" /> - - + {formik.values.customExpiration && ( + <> + + + } + fullWidth + > + + + + + )} + )} - - - {/* Hidden submit button is required for enter key to trigger form submission */} - - - - + + + + } + data-test-subj="apiKeysMetadataSwitch" + checked={formik.values.includeMetadata} + disabled={readOnly || (apiKey && !canEdit)} + onChange={(e) => formik.setFieldValue('includeMetadata', e.target.checked)} + /> + {formik.values.includeMetadata && ( + <> + + + + + } + fullWidth + > + formik.setFieldValue('metadata', value)} + validate={(value: string) => { + if (!value) { + return i18n.translate( + 'xpack.security.management.apiKeys.apiKeyFlyout.metadataRequired', + { + defaultMessage: 'Enter metadata or disable this option.', + } + ); + } + try { + JSON.parse(value); + } catch (e) { + return i18n.translate( + 'xpack.security.management.apiKeys.apiKeyFlyout.invalidJsonError', + { + defaultMessage: 'Enter valid JSON.', + } + ); + } + }} + fullWidth + languageId="xjson" + height={200} + /> + + + + )} + + +
+
+ ); }; -export function validate(values: ApiKeyFormValues) { - const errors: ValidationErrors = {}; - - if (!values.name) { - errors.name = i18n.translate('xpack.security.management.apiKeys.apiKeyFlyout.nameRequired', { - defaultMessage: 'Enter a name.', - }); - } - - if (values.customExpiration) { - const parsedExpiration = parseFloat(values.expiration); - if (isNaN(parsedExpiration) || parsedExpiration <= 0) { - errors.expiration = i18n.translate( - 'xpack.security.management.apiKeys.apiKeyFlyout.expirationRequired', - { - defaultMessage: 'Enter a valid duration or disable this option.', - } - ); - } - } - - if (values.customPrivileges) { - if (!values.role_descriptors) { - errors.role_descriptors = i18n.translate( - 'xpack.security.management.apiKeys.apiKeyFlyout.roleDescriptorsRequired', - { - defaultMessage: 'Enter role descriptors or disable this option.', - } - ); - } else { - try { - JSON.parse(values.role_descriptors); - } catch (e) { - errors.role_descriptors = i18n.translate( - 'xpack.security.management.apiKeys.apiKeyFlyout.invalidJsonError', - { - defaultMessage: 'Enter valid JSON.', - } - ); - } - } +export function mapCreateApiKeyValues(values: ApiKeyFormValues): CreateAPIKeyParams { + const { type, name } = values; + const expiration = values.customExpiration ? `${values.expiration}d` : undefined; + const metadata = values.includeMetadata ? JSON.parse(values.metadata) : '{}'; + + if (type === 'cross_cluster') { + return { + type, + name, + expiration, + metadata, + access: JSON.parse(values.access), + }; } - if (values.includeMetadata) { - if (!values.metadata) { - errors.metadata = i18n.translate( - 'xpack.security.management.apiKeys.apiKeyFlyout.metadataRequired', - { - defaultMessage: 'Enter metadata or disable this option.', - } - ); - } else { - try { - JSON.parse(values.metadata); - } catch (e) { - errors.metadata = i18n.translate( - 'xpack.security.management.apiKeys.apiKeyFlyout.invalidJsonError', - { - defaultMessage: 'Enter valid JSON.', - } - ); - } - } - } - - return errors; -} - -export function mapCreateApiKeyValues(values: ApiKeyFormValues): CreateApiKeyRequest { return { - name: values.name, - expiration: values.customExpiration && values.expiration ? `${values.expiration}d` : undefined, - role_descriptors: - values.customPrivileges && values.role_descriptors - ? JSON.parse(values.role_descriptors) - : undefined, - metadata: values.includeMetadata && values.metadata ? JSON.parse(values.metadata) : undefined, + name, + expiration, + metadata, + role_descriptors: values.customPrivileges ? JSON.parse(values.role_descriptors) : '{}', }; } -export function mapUpdateApiKeyValues(id: string, values: ApiKeyFormValues): UpdateApiKeyRequest { +export function mapUpdateApiKeyValues( + type: CategorizedApiKey['type'], + id: string, + values: ApiKeyFormValues +): UpdateAPIKeyParams { + const metadata = values.includeMetadata ? JSON.parse(values.metadata) : '{}'; + + if (type === 'cross_cluster') { + return { + type, + id, + metadata, + access: JSON.parse(values.access), + }; + } + return { id, - role_descriptors: - values.customPrivileges && values.role_descriptors - ? JSON.parse(values.role_descriptors) - : undefined, - metadata: values.includeMetadata && values.metadata ? JSON.parse(values.metadata) : {}, + metadata, + role_descriptors: values.customPrivileges ? JSON.parse(values.role_descriptors) : '{}', }; } -function isEditable(currentUser: AuthenticatedUser | undefined, apiKey: ApiKey): boolean { - let result = false; - const isApiKeyOwner = currentUser && currentUser.username === apiKey.username; - const isNotExpired = !apiKey.expiration || moment(apiKey.expiration).isAfter(); - - if (isApiKeyOwner && isNotExpired) { - result = true; - } - - return result; -} - -function determineReadonlyExpiration(expiration?: string) { - const DATE_FORMAT = 'MMMM Do YYYY HH:mm:ss'; - - if (!expiration) { - return ( - - - - ); - } - - const expirationInt = parseInt(expiration, 10); - - if (Date.now() > expirationInt) { - return ( - - - - ); - } - - return ( - - - - - - ); -} - -function retrieveValuesFromApiKeyToDefaultFlyout(apiKey: ApiKey): ApiKeyFormValues { - // Collect data from the selected API key to pre-populate the form - const doesMetadataExist = Object.keys(apiKey.metadata).length > 0; - const doCustomPrivilegesExist = Object.keys(apiKey.role_descriptors ?? 0).length > 0; +/** + * Maps data from the selected API key to pre-populate the form + */ +function mapApiKeyFormValues(apiKey: CategorizedApiKey): ApiKeyFormValues { + const includeMetadata = Object.keys(apiKey.metadata).length > 0; + const customPrivileges = + apiKey.type !== 'cross_cluster' ? Object.keys(apiKey.role_descriptors).length > 0 : false; return { name: apiKey.name, + type: apiKey.type, customExpiration: !!apiKey.expiration, expiration: !!apiKey.expiration ? apiKey.expiration.toString() : '', - includeMetadata: doesMetadataExist, - metadata: doesMetadataExist ? JSON.stringify(apiKey.metadata, null, 2) : '{}', - customPrivileges: doCustomPrivilegesExist, - role_descriptors: doCustomPrivilegesExist - ? JSON.stringify(apiKey.role_descriptors, null, 2) + includeMetadata, + metadata: includeMetadata ? JSON.stringify(apiKey.metadata, null, 2) : '{}', + customPrivileges, + role_descriptors: customPrivileges + ? JSON.stringify(apiKey.type !== 'cross_cluster' && apiKey.role_descriptors, null, 2) : '{}', + access: apiKey.type === 'cross_cluster' ? JSON.stringify(apiKey.access, null, 2) : '{}', }; } diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_empty_prompt.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_empty_prompt.tsx index b6300832551e8..77d71f1f6db91 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_empty_prompt.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_empty_prompt.tsx @@ -64,7 +64,7 @@ export const ApiKeysEmptyPrompt: FunctionComponent = ({

} @@ -160,7 +160,7 @@ export const ApiKeysEmptyPrompt: FunctionComponent = ({

} diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.test.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.test.tsx index 0f20e4a5cfe96..6a7234ba10488 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.test.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.test.tsx @@ -14,7 +14,6 @@ import { coreMock, themeServiceMock } from '@kbn/core/public/mocks'; import { mockAuthenticatedUser } from '../../../../common/model/authenticated_user.mock'; import { securityMock } from '../../../mocks'; import { Providers } from '../api_keys_management_app'; -import { apiKeysAPIClientMock } from '../index.mock'; import { APIKeysGridPage } from './api_keys_grid_page'; /* @@ -35,26 +34,19 @@ describe('APIKeysGridPage', () => { let coreStart: ReturnType; const theme$ = themeServiceMock.createTheme$(); - const apiClientMock = apiKeysAPIClientMock.create(); const { authc } = securityMock.createSetup(); beforeEach(() => { coreStart = coreMock.createStart(); - apiClientMock.checkPrivileges.mockClear(); - apiClientMock.getApiKeys.mockClear(); + coreStart.http.get.mockClear(); coreStart.http.get.mockClear(); coreStart.http.post.mockClear(); authc.getCurrentUser.mockClear(); - apiClientMock.checkPrivileges.mockResolvedValue({ - areApiKeysEnabled: true, - canManage: true, - isAdmin: true, - }); - - apiClientMock.getApiKeys.mockResolvedValue({ + coreStart.http.get.mockResolvedValue({ apiKeys: [ { + type: 'rest', creation: 1571322182082, expiration: 1571408582082, id: '0QQZ2m0BO2XZwgJFuWTT', @@ -62,8 +54,11 @@ describe('APIKeysGridPage', () => { name: 'first-api-key', realm: 'reserved', username: 'elastic', + metadata: {}, + role_descriptors: {}, }, { + type: 'rest', creation: 1571322182082, expiration: 1571408582082, id: 'BO2XZwgJFuWTT0QQZ2m0', @@ -71,8 +66,13 @@ describe('APIKeysGridPage', () => { name: 'second-api-key', realm: 'reserved', username: 'elastic', + metadata: {}, + role_descriptors: {}, }, ], + canManageCrossClusterApiKeys: true, + canManageApiKeys: true, + canManageOwnApiKeys: true, }); authc.getCurrentUser.mockResolvedValue( @@ -86,6 +86,11 @@ describe('APIKeysGridPage', () => { ); }); + afterAll(() => { + // Let's make sure we restore everything just in case + consoleWarnMock.mockRestore(); + }); + it('loads and displays API keys', async () => { const history = createMemoryHistory({ initialEntries: ['/'] }); @@ -98,16 +103,11 @@ describe('APIKeysGridPage', () => { const { findByText, queryByTestId, getByText } = render( - + ); - expect(await queryByTestId('apiKeysCreateTableButton')).toBeNull(); + expect(await queryByTestId('apiKeysCreateTableButton')).not.toBeInTheDocument(); expect(await findByText(/Loading API keys/)).not.toBeInTheDocument(); @@ -119,17 +119,11 @@ describe('APIKeysGridPage', () => { expect(secondKeyEuiLink!.getAttribute('data-test-subj')).toBe('apiKeyRowName-second-api-key'); }); - afterAll(() => { - // Let's make sure we restore everything just in case - consoleWarnMock.mockRestore(); - }); - it('displays callout when API keys are disabled', async () => { const history = createMemoryHistory({ initialEntries: ['/'] }); - apiClientMock.checkPrivileges.mockResolvedValueOnce({ - areApiKeysEnabled: false, - canManage: true, - isAdmin: true, + + coreStart.http.get.mockRejectedValueOnce({ + body: { message: 'disabled.feature="api_keys"' }, }); coreStart.application.capabilities = { @@ -141,25 +135,19 @@ describe('APIKeysGridPage', () => { const { findByText } = render( - + ); expect(await findByText(/Loading API keys/)).not.toBeInTheDocument(); - await findByText(/API keys not enabled/); + await findByText(/API keys are disabled/); }); it('displays error when user does not have required permissions', async () => { const history = createMemoryHistory({ initialEntries: ['/'] }); - apiClientMock.checkPrivileges.mockResolvedValueOnce({ - areApiKeysEnabled: true, - canManage: false, - isAdmin: false, + + coreStart.http.get.mockRejectedValueOnce({ + body: { statusCode: 403, message: 'forbidden' }, }); coreStart.application.capabilities = { @@ -171,21 +159,16 @@ describe('APIKeysGridPage', () => { const { findByText } = render( - + ); expect(await findByText(/Loading API keys/)).not.toBeInTheDocument(); - await findByText(/You need permission to manage API keys/); + await findByText(/You do not have permission to manage API keys/); }); it('displays error when fetching API keys fails', async () => { - apiClientMock.getApiKeys.mockRejectedValueOnce({ + coreStart.http.get.mockRejectedValueOnce({ body: { error: 'Internal Server Error', message: 'Internal Server Error', @@ -203,12 +186,7 @@ describe('APIKeysGridPage', () => { const { findByText } = render( - + ); @@ -218,20 +196,17 @@ describe('APIKeysGridPage', () => { describe('Read Only View', () => { beforeEach(() => { - apiClientMock.checkPrivileges.mockResolvedValueOnce({ - areApiKeysEnabled: true, - canManage: false, - isAdmin: false, + coreStart.http.get.mockResolvedValue({ + apiKeys: [], + canManageCrossClusterApiKeys: false, + canManageApiKeys: false, + canManageOwnApiKeys: false, }); }); it('should not display prompt `Create Button` when no API keys are shown', async () => { const history = createMemoryHistory({ initialEntries: ['/'] }); - apiClientMock.getApiKeys.mockResolvedValue({ - apiKeys: [], - }); - coreStart.application.capabilities = { ...coreStart.application.capabilities, api_keys: { @@ -241,17 +216,12 @@ describe('APIKeysGridPage', () => { const { findByText, queryByText } = render( - + ); expect(await findByText(/Loading API keys/)).not.toBeInTheDocument(); expect(await findByText('You do not have permission to create API keys')).toBeInTheDocument(); - expect(queryByText('Create API key')).toBeNull(); + expect(queryByText('Create API key')).not.toBeInTheDocument(); }); }); }); diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.tsx index ee3aa35411782..90839fd3ac83c 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_grid/api_keys_grid_page.tsx @@ -5,758 +5,878 @@ * 2.0. */ -import type { EuiBasicTableColumn, EuiInMemoryTableProps } from '@elastic/eui'; +import type { EuiBasicTableColumn, Query, SearchFilterConfig } from '@elastic/eui'; import { EuiBadge, EuiButton, EuiCallOut, + EuiFilterButton, EuiFlexGroup, EuiFlexItem, EuiHealth, - EuiIcon, EuiInMemoryTable, EuiLink, EuiSpacer, EuiText, EuiToolTip, } from '@elastic/eui'; -import { css } from '@emotion/react'; -import type { History } from 'history'; import moment from 'moment-timezone'; -import React, { Component } from 'react'; +import type { FunctionComponent } from 'react'; +import React, { useEffect, useMemo, useState } from 'react'; +import { useHistory } from 'react-router-dom'; +import useAsyncFn from 'react-use/lib/useAsyncFn'; -import type { NotificationsStart } from '@kbn/core/public'; +import type { CoreStart } from '@kbn/core/public'; import { SectionLoading } from '@kbn/es-ui-shared-plugin/public'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; -import { reactRouterNavigate } from '@kbn/kibana-react-plugin/public'; +import { reactRouterNavigate, useKibana } from '@kbn/kibana-react-plugin/public'; import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template'; import { Route } from '@kbn/shared-ux-router'; -import type { PublicMethodsOf } from '@kbn/utility-types'; +import { UserAvatar, UserProfilesPopover } from '@kbn/user-profile-components'; -import type { ApiKey, ApiKeyToInvalidate } from '../../../../common/model'; +import type { ApiKey, AuthenticatedUser, RestApiKey } from '../../../../common/model'; import { Breadcrumb } from '../../../components/breadcrumb'; import { SelectableTokenField } from '../../../components/token_field'; -import type { - APIKeysAPIClient, - CreateApiKeyResponse, - UpdateApiKeyResponse, -} from '../api_keys_api_client'; +import { useCapabilities } from '../../../components/use_capabilities'; +import { useAuthentication } from '../../../components/use_current_user'; +import type { CreateAPIKeyResult } from '../api_keys_api_client'; +import { APIKeysAPIClient } from '../api_keys_api_client'; import { ApiKeyFlyout } from './api_key_flyout'; import { ApiKeysEmptyPrompt } from './api_keys_empty_prompt'; -import type { InvalidateApiKeys } from './invalidate_provider'; import { InvalidateProvider } from './invalidate_provider'; -import { NotEnabled } from './not_enabled'; -import { PermissionDenied } from './permission_denied'; -interface Props { - history: History; - notifications: NotificationsStart; - apiKeysAPIClient: PublicMethodsOf; - readOnly?: boolean; -} - -interface State { - isLoadingApp: boolean; - isLoadingTable: boolean; - isAdmin: boolean; - canManage: boolean; - areApiKeysEnabled: boolean; - apiKeys?: ApiKey[]; - selectedItems: ApiKey[]; - error: any; - createdApiKey?: CreateApiKeyResponse; - selectedApiKey?: ApiKey; - isUpdateFlyoutVisible: boolean; -} - -const DATE_FORMAT = 'MMMM Do YYYY HH:mm:ss'; - -export class APIKeysGridPage extends Component { - static defaultProps: Partial = { - readOnly: false, - }; - - constructor(props: any) { - super(props); - this.state = { - isLoadingApp: true, - isLoadingTable: false, - isAdmin: false, - canManage: false, - areApiKeysEnabled: false, - apiKeys: undefined, - selectedItems: [], - error: undefined, - selectedApiKey: undefined, - isUpdateFlyoutVisible: false, - }; - } - - public componentDidMount() { - this.checkPrivileges(); - } +export const APIKeysGridPage: FunctionComponent = () => { + const { services } = useKibana(); + const history = useHistory(); + const authc = useAuthentication(); + const [state, getApiKeys] = useAsyncFn( + () => Promise.all([new APIKeysAPIClient(services.http).getApiKeys(), authc.getCurrentUser()]), + [services.http] + ); + + const [createdApiKey, setCreatedApiKey] = useState(); + const [openedApiKey, setOpenedApiKey] = useState(); + const readOnly = !useCapabilities('api_keys').save; + + useEffect(() => { + getApiKeys(); + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + if (!state.value) { + if (state.loading) { + return ( + + + + ); + } - public render() { return ( - // Flyout to create new ApiKey - <> - - - { - this.props.history.push({ pathname: '/' }); - - this.reloadApiKeys(); - - this.setState({ - createdApiKey: createApiKeyResponse, - }); - }} - onCancel={() => { - this.props.history.push({ pathname: '/' }); - this.setState({ selectedApiKey: undefined }); - }} - /> - - - - { - // Flyout to update or view ApiKey - this.state.isUpdateFlyoutVisible && ( - { - this.reloadApiKeys(); - this.displayUpdatedApiKeyToast(updateApiKeyResponse); - this.setState({ - selectedApiKey: undefined, - isUpdateFlyoutVisible: false, - }); - }} - onCancel={() => { - this.setState({ selectedApiKey: undefined, isUpdateFlyoutVisible: false }); - }} - apiKey={this.state.selectedApiKey} - readonly={this.props.readOnly} - /> - ) - } - {this.renderContent()} - + + getApiKeys()}> + + + ); } - public renderContent() { - const { isLoadingApp, isLoadingTable, areApiKeysEnabled, isAdmin, canManage, error, apiKeys } = - this.state; + const [ + { apiKeys, canManageCrossClusterApiKeys, canManageApiKeys, canManageOwnApiKeys }, + currentUser, + ] = state.value; + + return ( + <> + + + { + history.push({ pathname: '/' }); + setCreatedApiKey(createApiKeyResponse); + getApiKeys(); + }} + onCancel={() => history.push({ pathname: '/' })} + canManageCrossClusterApiKeys={canManageCrossClusterApiKeys} + /> + + + + {openedApiKey && ( + { + services.notifications.toasts.addSuccess({ + title: i18n.translate('xpack.security.management.apiKeys.updateSuccessMessage', { + defaultMessage: "Updated API key '{name}'", + values: { name: openedApiKey.name }, + }), + 'data-test-subj': 'updateApiKeySuccessToast', + }); - if (!apiKeys) { - if (isLoadingApp) { - return ( - + setOpenedApiKey(undefined); + getApiKeys(); + }} + onCancel={() => setOpenedApiKey(undefined)} + apiKey={openedApiKey} + readOnly={readOnly} + /> + )} + + {!apiKeys.length ? ( + + - - ); - } - - if (!canManage) { - return ; - } - - if (error) { - return ( - - + + + ) : ( + <> + - - - ); - } - - if (!areApiKeysEnabled) { - return ; - } - } - - if (!isLoadingTable && apiKeys && apiKeys.length === 0) { - if (this.props.readOnly) { - return ; - } else { - return ( - - + } + description={ - - - ); - } - } - - const concatenated = `${this.state.createdApiKey?.id}:${this.state.createdApiKey?.api_key}`; - - const description = this.determineDescription(isAdmin, this.props.readOnly ?? false); + } + rightSideItems={ + !readOnly + ? [ + + + , + ] + : undefined + } + paddingSize="none" + bottomBorder + /> + + + {createdApiKey && !state.loading && ( + <> + + + + )} - return ( - <> - - } - description={description} - rightSideItems={ - this.props.readOnly - ? undefined - : [ - + {canManageOwnApiKeys && !canManageApiKeys ? ( + <> + - , - ] - } - /> - - {this.state.createdApiKey && !this.state.isLoadingTable && ( - <> - - + + + ) : undefined} + + -

- ( + setOpenedApiKey(apiKey)} + onDelete={(apiKeysToDelete) => + invalidateApiKeyPrompt( + apiKeysToDelete.map(({ name, id }) => ({ name, id })), + getApiKeys + ) + } + currentUser={currentUser} + createdApiKey={createdApiKey} + canManageCrossClusterApiKeys={canManageCrossClusterApiKeys} + canManageApiKeys={canManageApiKeys} + canManageOwnApiKeys={canManageOwnApiKeys} + readOnly={readOnly} + loading={state.loading} /> -

- -
- - )} - - - - - {this.renderTable()} - - - ); - } - - private renderTable = () => { - const { apiKeys, selectedItems, isLoadingTable, isAdmin, error } = this.state; + )} + +
+ + )} + + ); +}; + +export interface ApiKeyCreatedCalloutProps { + createdApiKey: CreateAPIKeyResult; +} - const message = isLoadingTable ? ( - = ({ + createdApiKey, +}) => { + const concatenated = `${createdApiKey.id}:${createdApiKey.api_key}`; + return ( + +

+ +

+ - ) : undefined; +
+ ); +}; + +export interface ApiKeysTableProps { + apiKeys: ApiKey[]; + currentUser: AuthenticatedUser; + createdApiKey?: CreateAPIKeyResult; + readOnly?: boolean; + loading?: boolean; + canManageCrossClusterApiKeys: boolean; + canManageApiKeys: boolean; + canManageOwnApiKeys: boolean; + onClick(apiKey: CategorizedApiKey): void; + onDelete(apiKeys: CategorizedApiKey[]): void; +} - const sorting = { - sort: { - field: 'creation', - direction: 'desc', - }, - } as const; - - const pagination = { - initialPageSize: 20, - pageSizeOptions: [10, 20, 50], - }; - - const selection = { - onSelectionChange: (newSelectedItems: ApiKey[]) => { - this.setState({ - selectedItems: newSelectedItems, - }); - }, - }; - - const search: EuiInMemoryTableProps['search'] = { - toolsLeft: selectedItems.length ? ( - - {(invalidateApiKeyPrompt) => { - return ( - - invalidateApiKeyPrompt( - selectedItems.map(({ name, id }) => ({ name, id })), - this.onApiKeysInvalidated - ) - } - color="danger" - data-test-subj="bulkInvalidateActionButton" - > - - - ); - }} - - ) : undefined, - box: { - incremental: true, +export const ApiKeysTable: FunctionComponent = ({ + apiKeys, + createdApiKey, + currentUser, + onClick, + onDelete, + canManageApiKeys = false, + canManageOwnApiKeys = false, + readOnly = false, + loading = false, +}) => { + const columns: Array> = []; + const [selectedItems, setSelectedItems] = useState([]); + + const { categorizedApiKeys, typeFilters, usernameFilters, expiredFilters } = useMemo( + () => categorizeApiKeys(apiKeys), + [apiKeys] + ); + + const deletable = (item: CategorizedApiKey) => + canManageApiKeys || (canManageOwnApiKeys && item.username === currentUser.username); + + columns.push( + { + field: 'name', + name: i18n.translate('xpack.security.management.apiKeys.table.nameColumnName', { + defaultMessage: 'Name', + }), + sortable: true, + render: (name: string, item: CategorizedApiKey) => { + return ( + onClick(item)} data-test-subj={`apiKeyRowName-${item.name}`}> + {name} + + ); }, - filters: isAdmin - ? [ - { - type: 'field_value_selection', - field: 'username', - name: i18n.translate('xpack.security.management.apiKeys.table.userFilterLabel', { - defaultMessage: 'User', - }), - multiSelect: false, - options: Object.keys( - apiKeys?.reduce((apiKeysMap: any, apiKey) => { - apiKeysMap[apiKey.username] = true; - return apiKeysMap; - }, {}) ?? {} - ).map((username) => { - return { - value: username, - view: ( - - - - - - - {username} - - - - ), - }; - }), - }, - { - type: 'field_value_selection', - field: 'realm', - name: i18n.translate('xpack.security.management.apiKeys.table.realmFilterLabel', { - defaultMessage: 'Realm', - }), - multiSelect: false, - options: Object.keys( - apiKeys?.reduce((apiKeysMap: any, apiKey) => { - apiKeysMap[apiKey.realm] = true; - return apiKeysMap; - }, {}) ?? {} - ).map((realm) => { - return { - value: realm, - view: realm, - }; - }), - }, - ] - : undefined, - }; + }, + { + field: 'type', + name: ( + + ), + sortable: true, + render: (type: CategorizedApiKey['type']) => , + } + ); - const callOutTitle = this.determineCallOutTitle(this.props.readOnly ?? false); + if (canManageApiKeys || usernameFilters.length > 1) { + columns.push({ + field: 'username', + name: ( + + ), + sortable: true, + render: (username: CategorizedApiKey['username']) => , + }); + } - return ( - <> - {!isAdmin ? ( - <> - - - - ) : undefined} - - - {(invalidateApiKeyPrompt) => ( - - )} - - - ); - }; + columns.push( + { + field: 'creation', + name: ( + + ), + sortable: true, + mobileOptions: { + show: false, + }, + render: (creation: number, item: CategorizedApiKey) => ( + + {item.id === createdApiKey?.id ? ( + + + + ) : null} + + ), + }, + { + field: 'expiration', + name: ( + + ), + sortable: true, + render: (expiration: number) => , + } + ); - private getColumnConfig = (invalidateApiKeyPrompt: InvalidateApiKeys) => { - const { isAdmin, createdApiKey } = this.state; - - let config: Array> = []; - - config = config.concat([ - { - field: 'name', - name: i18n.translate('xpack.security.management.apiKeys.table.nameColumnName', { - defaultMessage: 'Name', - }), - sortable: true, - render: (name: string, recordAP: ApiKey) => { - return ( - - { - this.setState({ selectedApiKey: recordAP, isUpdateFlyoutVisible: true }); - }} - > - {name} - - - ); + if (!readOnly) { + columns.push({ + width: `${24 + 2 * 8}px`, + actions: [ + { + name: ( + + ), + description: i18n.translate('xpack.security.management.apiKeys.table.deleteDescription', { + defaultMessage: 'Delete this API key', + }), + icon: 'trash', + type: 'icon', + color: 'danger', + onClick: (item) => onDelete([item]), + available: deletable, + 'data-test-subj': 'apiKeysTableDeleteAction', }, - }, - ]); + ], + }); + } + + const filters: SearchFilterConfig[] = []; + + if (typeFilters.length > 1) { + filters.push({ + type: 'custom_component', + component: ({ query, onChange }) => ( + + ), + }); + } + + if (usernameFilters.length > 1) { + filters.push({ + type: 'custom_component', + component: ({ query, onChange }) => ( + + ), + }); + } - if (isAdmin) { - config = config.concat([ + if (expiredFilters.length > 1) { + filters.push({ + type: 'field_value_toggle_group', + field: 'expired', + items: [ { - field: 'username', - name: i18n.translate('xpack.security.management.apiKeys.table.userNameColumnName', { - defaultMessage: 'User', + value: false, + name: i18n.translate('xpack.security.management.apiKeys.table.activeFilter', { + defaultMessage: 'Active', }), - sortable: true, - render: (username: string) => ( - - - - - - {username} - - - ), }, { - field: 'realm', - name: i18n.translate('xpack.security.management.apiKeys.table.realmColumnName', { - defaultMessage: 'Realm', + value: true, + name: i18n.translate('xpack.security.management.apiKeys.table.expiredFilter', { + defaultMessage: 'Expired', }), - sortable: true, }, - ]); - } + ], + }); + } - config = config.concat([ - { - field: 'creation', - name: i18n.translate('xpack.security.management.apiKeys.table.creationDateColumnName', { - defaultMessage: 'Created', - }), - sortable: true, - mobileOptions: { - show: false, + return ( + 0 + ? { + toolsLeft: selectedItems.length ? ( + onDelete(selectedItems)} + color="danger" + iconType="trash" + data-test-subj="bulkInvalidateActionButton" + > + + + ) : undefined, + box: { + incremental: true, + }, + filters, + } + : undefined + } + sorting={{ + sort: { + field: 'creation', + direction: 'desc', }, - render: (creation: string, item: ApiKey) => ( - - {item.id === createdApiKey?.id ? ( - - - - ) : ( - {moment(creation).fromNow()} - )} - - ), - }, - { - name: i18n.translate('xpack.security.management.apiKeys.table.statusColumnName', { - defaultMessage: 'Status', - }), - render: ({ expiration }: any) => { - if (!expiration) { - return ( - - - - ); - } + }} + selection={ + readOnly + ? undefined + : { + selectable: deletable, + onSelectionChange: setSelectedItems, + } + } + pagination={{ + initialPageSize: 10, + pageSizeOptions: [10, 25, 50], + }} + loading={loading} + isSelectable={canManageOwnApiKeys} + /> + ); +}; + +export interface TypesFilterButtonProps { + query: Query; + onChange?: (query: Query) => void; + types: string[]; +} - if (Date.now() > expiration) { - return ( - - - - ); +export const TypesFilterButton: FunctionComponent = ({ + query, + onChange, + types, +}) => { + if (!onChange) { + return null; + } + + return ( + <> + {types.includes('rest') ? ( + + onChange( + query.hasSimpleFieldClause('type', 'rest') + ? query.removeSimpleFieldClauses('type') + : query.removeSimpleFieldClauses('type').addSimpleFieldValue('type', 'rest') + ) + } + withNext={types.includes('cross_cluster') || types.includes('managed')} + > + + + ) : null} + {types.includes('cross_cluster') ? ( + + onChange( + query.hasSimpleFieldClause('type', 'cross_cluster') + ? query.removeSimpleFieldClauses('type') + : query + .removeSimpleFieldClauses('type') + .addSimpleFieldValue('type', 'cross_cluster') + ) } + withNext={types.includes('managed')} + > + + + ) : null} + {types.includes('managed') ? ( + + onChange( + query.hasSimpleFieldClause('type', 'managed') + ? query.removeSimpleFieldClauses('type') + : query.removeSimpleFieldClauses('type').addSimpleFieldValue('type', 'managed') + ) + } + > + + + ) : null} + + ); +}; + +export interface UsersFilterButtonProps { + query: Query; + onChange?: (query: Query) => void; + usernames: string[]; +} - return ( - - - - - - ); - }, - }, - ]); +export const UsersFilterButton: FunctionComponent = ({ + query, + onChange, + usernames, +}) => { + const [isOpen, setIsOpen] = useState(false); + const [searchTerm, setSearchTerm] = useState(''); - if (!this.props.readOnly) { - config.push({ - actions: [ - { - name: i18n.translate('xpack.security.management.apiKeys.table.deleteAction', { - defaultMessage: 'Delete', - }), - description: i18n.translate( - 'xpack.security.management.apiKeys.table.deleteDescription', - { - defaultMessage: 'Delete this API key', - } - ), - icon: 'trash', - type: 'icon', - color: 'danger', - onClick: (item) => - invalidateApiKeyPrompt([{ id: item.id, name: item.name }], this.onApiKeysInvalidated), - 'data-test-subj': 'apiKeysTableDeleteAction', - }, - ], - }); + if (!onChange) { + return null; + } + + let numActiveFilters = 0; + const clause = query.getOrFieldClause('username'); + if (clause) { + if (Array.isArray(clause.value)) { + numActiveFilters = clause.value.length; + } else { + numActiveFilters = 1; } + } - return config; - }; + const usernamesMatchingSearchTerm = searchTerm + ? usernames.filter((username) => username.includes(searchTerm)) + : usernames; + + return ( + setIsOpen((toggle) => !toggle)} + isSelected={isOpen} + numFilters={usernames.length} + hasActiveFilters={numActiveFilters ? true : false} + numActiveFilters={numActiveFilters} + > + + + } + isOpen={isOpen} + panelPaddingSize="none" + anchorPosition="downCenter" + panelClassName="euiFilterGroup__popoverPanel" + closePopover={() => setIsOpen(false)} + selectableProps={{ + options: usernamesMatchingSearchTerm.map((username) => ({ + uid: username, + user: { username }, + enabled: false, + data: {}, + })), + onSearchChange: setSearchTerm, + selectedOptions: usernames + .filter((username) => query.hasOrFieldClause('username', username)) + .map((username) => ({ + uid: username, + user: { username }, + enabled: false, + data: {}, + })), + onChange: (nextSelectedOptions) => { + const nextQuery = nextSelectedOptions.reduce( + (acc, option) => acc.addOrFieldValue('username', option.user.username), + query.removeOrFieldClauses('username') + ); + onChange(nextQuery); + }, + }} + /> + ); +}; + +export type UsernameWithIconProps = Pick; + +export const UsernameWithIcon: FunctionComponent = ({ username }) => ( + + + + + + + {username} + + + +); + +export interface TimeToolTipProps { + timestamp: number; +} - private onApiKeysInvalidated = (apiKeysInvalidated: ApiKeyToInvalidate[]): void => { - if (apiKeysInvalidated.length) { - this.reloadApiKeys(); - } - }; +export const TimeToolTip: FunctionComponent = ({ timestamp, children }) => { + return ( + + {children ?? moment(timestamp).fromNow()} + + ); +}; - private async checkPrivileges() { - try { - const { isAdmin, canManage, areApiKeysEnabled } = - await this.props.apiKeysAPIClient.checkPrivileges(); - this.setState({ isAdmin, canManage, areApiKeysEnabled }); +export type ApiKeyStatusProps = Pick; - if ((!canManage && !this.props.readOnly) || !areApiKeysEnabled) { - this.setState({ isLoadingApp: false }); - } else { - this.loadApiKeys(); - } - } catch (e) { - this.props.notifications.toasts.addDanger( - i18n.translate('xpack.security.management.apiKeys.table.fetchingApiKeysErrorMessage', { - defaultMessage: 'Error checking privileges: {message}', - values: { message: e.body?.message ?? '' }, - }) - ); - } +export const ApiKeyStatus: FunctionComponent = ({ expiration }) => { + if (!expiration) { + return ( + + + + ); } - private reloadApiKeys = () => { - this.setState({ - isLoadingApp: false, - isLoadingTable: true, - createdApiKey: undefined, - error: undefined, - }); - this.loadApiKeys(); - }; + if (Date.now() > expiration) { + return ( + + + + ); + } - private loadApiKeys = async () => { - try { - const { isAdmin } = this.state; - const { apiKeys } = await this.props.apiKeysAPIClient.getApiKeys(isAdmin); - this.setState({ apiKeys }); - } catch (e) { - this.setState({ error: e }); - } + return ( + + + + + + ); +}; - this.setState({ isLoadingApp: false, isLoadingTable: false }); - }; +export interface ApiKeyBadgeProps { + type: CategorizedApiKeyType; +} - private determineDescription(isAdmin: boolean, readOnly: boolean) { - if (isAdmin) { - return ( +export const ApiKeyBadge: FunctionComponent = ({ type }) => { + return type === 'cross_cluster' ? ( + - ); - } else if (readOnly) { - return ( + } + > + - ); - } else { - return ( + + + ) : type === 'managed' ? ( + - ); - } - } - - private determineCallOutTitle(readOnly: boolean) { - if (readOnly) { - return ( + } + > + - ); - } else { - return ( + + + ) : ( + - ); - } - } + } + > + + + + + ); +}; - private displayUpdatedApiKeyToast(updateApiKeyResponse?: UpdateApiKeyResponse) { - if (updateApiKeyResponse) { - this.props.notifications.toasts.addSuccess({ - title: i18n.translate('xpack.security.management.apiKeys.updateSuccessMessage', { - defaultMessage: "Updated API key '{name}'", - values: { name: this.state.selectedApiKey?.name }, - }), - 'data-test-subj': 'updateApiKeySuccessToast', - }); - } - } +/** + * Interface representing a REST API key that is managed by Kibana. + */ +export interface ManagedApiKey extends Omit { + type: 'managed'; +} + +/** + * Interface representing an API key the way it is presented in the Kibana UI (with Kibana system + * API keys given its own dedicated `managed` type). + */ +export type CategorizedApiKey = (ApiKey | ManagedApiKey) & { + expired: boolean; +}; + +/** + * Categorizes API keys by type (with Kibana system API keys given its own dedicated `managed` type) + * and determines applicable filter values. + */ +export function categorizeApiKeys(apiKeys: ApiKey[]) { + const categorizedApiKeys: CategorizedApiKey[] = []; + const typeFilters: Set = new Set(); + const usernameFilters: Set = new Set(); + const expiredFilters: Set = new Set(); + + apiKeys.forEach((apiKey) => { + const type = getApiKeyType(apiKey); + const expired = apiKey.expiration ? Date.now() > apiKey.expiration : false; + + typeFilters.add(type); + usernameFilters.add(apiKey.username); + expiredFilters.add(expired); + + categorizedApiKeys.push({ ...apiKey, type, expired } as CategorizedApiKey); + }); + + return { + categorizedApiKeys, + typeFilters: [...typeFilters], + usernameFilters: [...usernameFilters], + expiredFilters: [...expiredFilters], + }; +} + +export type CategorizedApiKeyType = ReturnType; + +/** + * Determines API key type the way it is presented in the UI with Kibana system API keys given its own dedicated `managed` type. + */ +export function getApiKeyType(apiKey: ApiKey) { + return apiKey.type === 'rest' && + (apiKey.metadata?.managed || apiKey.name.indexOf('Alerting: ') === 0) + ? 'managed' + : apiKey.type; } diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx index bcde6bbb619b7..b487b977b620b 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.test.tsx @@ -5,107 +5,63 @@ * 2.0. */ -jest.mock('./api_keys_grid', () => ({ - APIKeysGridPage: (props: any) => JSON.stringify(props, null, 2), -})); - import { act } from '@testing-library/react'; +import { noop } from 'lodash'; import { coreMock, scopedHistoryMock, themeServiceMock } from '@kbn/core/public/mocks'; import type { Unmount } from '@kbn/management-plugin/public/types'; +import { mockAuthenticatedUser } from '../../../common/model/authenticated_user.mock'; import { securityMock } from '../../mocks'; import { apiKeysManagementApp } from './api_keys_management_app'; +const element = document.body.appendChild(document.createElement('div')); + describe('apiKeysManagementApp', () => { - it('create() returns proper management app descriptor', () => { + it('renders application and sets breadcrumbs', async () => { const { getStartServices } = coreMock.createSetup(); + const coreStartMock = coreMock.createStart(); + getStartServices.mockResolvedValue([coreStartMock, {}, {}]); const { authc } = securityMock.createSetup(); - - expect(apiKeysManagementApp.create({ authc, getStartServices: getStartServices as any })) - .toMatchInlineSnapshot(` - Object { - "id": "api_keys", - "mount": [Function], - "order": 30, - "title": "API keys", - } - `); - }); - - it('mount() works for the `grid` page', async () => { - const coreStart = coreMock.createSetup(); - const { authc } = securityMock.createSetup(); - - const startServices = await coreStart.getStartServices(); - - const [{ application }] = startServices; - application.capabilities = { - ...application.capabilities, + const setBreadcrumbs = jest.fn(); + const history = scopedHistoryMock.create({ pathname: '/' }); + coreStartMock.application.capabilities = { + ...coreStartMock.application.capabilities, api_keys: { save: true, }, }; - const docTitle = startServices[0].chrome.docTitle; - - const container = document.createElement('div'); - - const setBreadcrumbs = jest.fn(); - - let unmount: Unmount; + coreStartMock.http.get.mockResolvedValue({ + apiKeys: [], + canManageCrossClusterApiKeys: true, + canManageApiKeys: true, + canManageOwnApiKeys: true, + }); + authc.getCurrentUser.mockResolvedValue( + mockAuthenticatedUser({ + username: 'elastic', + full_name: '', + email: '', + enabled: true, + roles: ['superuser'], + }) + ); + + let unmount: Unmount = noop; await act(async () => { - unmount = await apiKeysManagementApp - .create({ authc, getStartServices: () => Promise.resolve(startServices) as any }) - .mount({ - basePath: '/some-base-path', - element: container, - setBreadcrumbs, - history: scopedHistoryMock.create(), - theme$: themeServiceMock.createTheme$(), - }); + unmount = await apiKeysManagementApp.create({ authc, getStartServices }).mount({ + basePath: '/', + element, + setBreadcrumbs, + history, + theme$: themeServiceMock.createTheme$(), + }); }); - expect(setBreadcrumbs).toHaveBeenCalledTimes(1); - expect(setBreadcrumbs).toHaveBeenCalledWith([{ text: 'API keys' }]); - expect(docTitle.change).toHaveBeenCalledWith(['API keys']); - expect(docTitle.reset).not.toHaveBeenCalled(); - expect(container).toMatchInlineSnapshot(` -
- { - "history": { - "action": "PUSH", - "length": 1, - "location": { - "pathname": "/", - "search": "", - "hash": "" - } - }, - "notifications": { - "toasts": {} - }, - "apiKeysAPIClient": { - "http": { - "basePath": { - "basePath": "", - "serverBasePath": "" - }, - "anonymousPaths": {}, - "externalUrl": {} - } - }, - "readOnly": false - } -
- `); - - act(() => { - unmount!(); - }); + expect(setBreadcrumbs).toHaveBeenLastCalledWith([{ text: 'API keys' }]); - expect(docTitle.reset).toHaveBeenCalledTimes(1); - expect(container).toMatchInlineSnapshot(`
`); + unmount(); }); }); diff --git a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx index c7f0f675bde48..ac7b067e3371c 100644 --- a/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx +++ b/x-pack/plugins/security/public/management/api_keys/api_keys_management_app.tsx @@ -44,10 +44,9 @@ export const apiKeysManagementApp = Object.freeze({ defaultMessage: 'API keys', }), async mount({ element, theme$, setBreadcrumbs, history }) { - const [[coreStart], { APIKeysGridPage }, { APIKeysAPIClient }] = await Promise.all([ + const [[coreStart], { APIKeysGridPage }] = await Promise.all([ getStartServices(), import('./api_keys_grid'), - import('./api_keys_api_client'), ]); render( @@ -64,12 +63,7 @@ export const apiKeysManagementApp = Object.freeze({ })} href="/" > - + , element diff --git a/x-pack/plugins/security/server/authentication/api_keys/api_keys.mock.ts b/x-pack/plugins/security/server/authentication/api_keys/api_keys.mock.ts index 697f1bf355a70..cfa857ca833a2 100644 --- a/x-pack/plugins/security/server/authentication/api_keys/api_keys.mock.ts +++ b/x-pack/plugins/security/server/authentication/api_keys/api_keys.mock.ts @@ -12,6 +12,7 @@ import type { APIKeys } from './api_keys'; export const apiKeysMock = { create: (): jest.Mocked> => ({ areAPIKeysEnabled: jest.fn(), + areCrossClusterAPIKeysEnabled: jest.fn(), create: jest.fn(), update: jest.fn(), grantAsInternalUser: jest.fn(), diff --git a/x-pack/plugins/security/server/authentication/api_keys/api_keys.test.ts b/x-pack/plugins/security/server/authentication/api_keys/api_keys.test.ts index b59ff8e506380..24bebe0862591 100644 --- a/x-pack/plugins/security/server/authentication/api_keys/api_keys.test.ts +++ b/x-pack/plugins/security/server/authentication/api_keys/api_keys.test.ts @@ -140,6 +140,56 @@ describe('API Keys', () => { }); }); + describe('areCrossClusterAPIKeysEnabled()', () => { + it('returns false when security feature is disabled', async () => { + mockLicense.isEnabled.mockReturnValue(false); + + const result = await apiKeys.areCrossClusterAPIKeysEnabled(); + expect(result).toEqual(false); + expect(mockClusterClient.asInternalUser.transport.request).not.toHaveBeenCalled(); + }); + + it('returns false when the operation completes without error (which should never happen)', async () => { + mockLicense.isEnabled.mockReturnValue(true); + mockClusterClient.asInternalUser.transport.request.mockResolvedValueOnce({}); + + const result = await apiKeys.areCrossClusterAPIKeysEnabled(); + expect(result).toEqual(false); + expect(mockClusterClient.asInternalUser.transport.request).toHaveBeenCalledTimes(1); + }); + + it('returns false when the exception metadata indicates cross cluster api keys are disabled', async () => { + mockLicense.isEnabled.mockReturnValue(true); + mockClusterClient.asInternalUser.transport.request.mockRejectedValueOnce({ + statusCode: 404, + }); + + const result = await apiKeys.areCrossClusterAPIKeysEnabled(); + expect(result).toEqual(false); + expect(mockClusterClient.asInternalUser.transport.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/_security/cross_cluster/api_key/kibana-api-key-service-test', + body: {}, + }); + }); + + it('returns true when the exception metadata indicates cross cluster api keys are enabled', async () => { + mockLicense.isEnabled.mockReturnValue(true); + mockClusterClient.asInternalUser.transport.request.mockRejectedValueOnce({ + statusCode: 400, + body: { error: { type: 'action_request_validation_exception' } }, + }); + + const result = await apiKeys.areCrossClusterAPIKeysEnabled(); + expect(result).toEqual(true); + expect(mockClusterClient.asInternalUser.transport.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/_security/cross_cluster/api_key/kibana-api-key-service-test', + body: {}, + }); + }); + }); + describe('create()', () => { it('returns null when security feature is disabled', async () => { mockLicense.isEnabled.mockReturnValue(false); @@ -177,7 +227,7 @@ describe('API Keys', () => { expect(mockScopedClusterClient.asCurrentUser.security.createApiKey).not.toHaveBeenCalled(); }); - it('calls `createApiKey` with proper parameters', async () => { + it('calls `createApiKey` with proper parameters when type is `rest` or not defined', async () => { mockLicense.isEnabled.mockReturnValue(true); mockScopedClusterClient.asCurrentUser.security.createApiKey.mockResponseOnce({ @@ -199,6 +249,7 @@ describe('API Keys', () => { name: 'key-name', }); expect(mockValidateKibanaPrivileges).not.toHaveBeenCalled(); // this is only called if kibana_role_descriptors is defined + expect(mockScopedClusterClient.asCurrentUser.transport.request).not.toHaveBeenCalled(); expect(mockScopedClusterClient.asCurrentUser.security.createApiKey).toHaveBeenCalledWith({ body: { name: 'key-name', @@ -207,6 +258,42 @@ describe('API Keys', () => { }, }); }); + + it('creates Cross-Cluster API key when type is `cross_cluster`', async () => { + mockLicense.isEnabled.mockReturnValue(true); + + mockScopedClusterClient.asCurrentUser.transport.request.mockResolvedValueOnce({ + id: '123', + name: 'key-name', + expiration: '1d', + api_key: 'abc123', + }); + const result = await apiKeys.create(httpServerMock.createKibanaRequest(), { + type: 'cross_cluster', + name: 'key-name', + expiration: '1d', + access: {}, + metadata: {}, + }); + expect(result).toEqual({ + api_key: 'abc123', + expiration: '1d', + id: '123', + name: 'key-name', + }); + expect(mockValidateKibanaPrivileges).not.toHaveBeenCalled(); // this is only called if kibana_role_descriptors is defined + expect(mockScopedClusterClient.asCurrentUser.security.createApiKey).not.toHaveBeenCalled(); + expect(mockScopedClusterClient.asCurrentUser.transport.request).toHaveBeenCalledWith({ + method: 'POST', + path: '/_security/cross_cluster/api_key', + body: { + name: 'key-name', + expiration: '1d', + access: {}, + metadata: {}, + }, + }); + }); }); describe('update()', () => { @@ -300,6 +387,33 @@ describe('API Keys', () => { metadata: {}, }); }); + + it('updates Cross-Cluster API key when type is `cross_cluster`', async () => { + mockLicense.isEnabled.mockReturnValue(true); + + mockScopedClusterClient.asCurrentUser.transport.request.mockResolvedValueOnce({ + updated: true, + }); + const result = await apiKeys.update(httpServerMock.createKibanaRequest(), { + type: 'cross_cluster', + id: '123', + access: {}, + metadata: {}, + }); + expect(result).toEqual({ + updated: true, + }); + expect(mockValidateKibanaPrivileges).not.toHaveBeenCalled(); // this is only called if kibana_role_descriptors is defined + expect(mockScopedClusterClient.asCurrentUser.security.updateApiKey).not.toHaveBeenCalled(); + expect(mockScopedClusterClient.asCurrentUser.transport.request).toHaveBeenCalledWith({ + method: 'PUT', + path: '/_security/cross_cluster/api_key/123', + body: { + access: {}, + metadata: {}, + }, + }); + }); }); describe('grantAsInternalUser()', () => { diff --git a/x-pack/plugins/security/server/authentication/api_keys/api_keys.ts b/x-pack/plugins/security/server/authentication/api_keys/api_keys.ts index 854524df7d596..462630d4eae28 100644 --- a/x-pack/plugins/security/server/authentication/api_keys/api_keys.ts +++ b/x-pack/plugins/security/server/authentication/api_keys/api_keys.ts @@ -9,17 +9,34 @@ import type { IClusterClient, KibanaRequest, Logger } from '@kbn/core/server'; import type { KibanaFeature } from '@kbn/features-plugin/server'; -import type { OneOf } from '@kbn/utility-types'; import type { SecurityLicense } from '../../../common/licensing'; -import type { ElasticsearchPrivilegesType, KibanaPrivilegesType } from '../../lib'; import { transformPrivilegesToElasticsearchPrivileges, validateKibanaPrivileges } from '../../lib'; +import type { + CreateAPIKeyParams, + CreateAPIKeyResult, + CreateCrossClusterAPIKeyParams, + CreateRestAPIKeyParams, + CreateRestAPIKeyWithKibanaPrivilegesParams, + UpdateAPIKeyParams, + UpdateAPIKeyResult, +} from '../../routes/api_keys'; import { BasicHTTPAuthorizationHeaderCredentials, HTTPAuthorizationHeader, } from '../http_authentication'; import { getFakeKibanaRequest } from './fake_kibana_request'; +export type { + CreateAPIKeyParams, + CreateAPIKeyResult, + CreateRestAPIKeyParams, + CreateRestAPIKeyWithKibanaPrivilegesParams, + CreateCrossClusterAPIKeyParams, + UpdateAPIKeyParams, + UpdateAPIKeyResult, +}; + /** * Represents the options to create an APIKey class instance that will be * shared between functions (create, invalidate, etc). @@ -32,52 +49,15 @@ export interface ConstructorOptions { kibanaFeatures: KibanaFeature[]; } -interface BaseCreateAPIKeyParams { - name: string; - expiration?: string; - metadata?: Record; - role_descriptors: Record; - kibana_role_descriptors: Record< - string, - { elasticsearch: ElasticsearchPrivilegesType; kibana: KibanaPrivilegesType } - >; -} - -interface BaseUpdateAPIKeyParams { - id: string; - metadata?: Record; - role_descriptors: Record; - kibana_role_descriptors: Record< - string, - { elasticsearch: ElasticsearchPrivilegesType; kibana: KibanaPrivilegesType } - >; -} - -/** - * Represents the params for creating an API key - */ -export type CreateAPIKeyParams = OneOf< - BaseCreateAPIKeyParams, - 'role_descriptors' | 'kibana_role_descriptors' ->; - -/** - * Represents the params for updating an API key - */ -export type UpdateAPIKeyParams = OneOf< - BaseUpdateAPIKeyParams, - 'role_descriptors' | 'kibana_role_descriptors' ->; - type GrantAPIKeyParams = | { - api_key: CreateAPIKeyParams; + api_key: CreateRestAPIKeyParams | CreateRestAPIKeyWithKibanaPrivilegesParams; grant_type: 'password'; username: string; password: string; } | { - api_key: CreateAPIKeyParams; + api_key: CreateRestAPIKeyParams | CreateRestAPIKeyWithKibanaPrivilegesParams; grant_type: 'access_token'; access_token: string; }; @@ -89,42 +69,6 @@ export interface InvalidateAPIKeysParams { ids: string[]; } -/** - * The return value when creating an API key in Elasticsearch. The API key returned by this API - * can then be used by sending a request with a Authorization header with a value having the - * prefix ApiKey `{token}` where token is id and api_key joined by a colon `{id}:{api_key}` and - * then encoded to base64. - */ -export interface CreateAPIKeyResult { - /** - * Unique id for this API key - */ - id: string; - /** - * Name for this API key - */ - name: string; - /** - * Optional expiration in milliseconds for this API key - */ - expiration?: number; - /** - * Generated API key - */ - api_key: string; -} - -/** - * The return value when update an API key in Elasticsearch. The value returned by this API - * can is contains a `updated` boolean that corresponds to whether or not the API key was updated - */ -export interface UpdateAPIKeyResult { - /** - * Boolean represented if the API key was updated in ES - */ - updated: boolean; -} - export interface GrantAPIKeyResult { /** * Unique id for this API key @@ -216,7 +160,7 @@ export class APIKeys { return false; } - const id = `kibana-api-key-service-test`; + const id = 'kibana-api-key-service-test'; this.logger.debug( `Testing if API Keys are enabled by attempting to invalidate a non-existant key: ${id}` @@ -237,11 +181,39 @@ export class APIKeys { } } + /** + * Determines if Cross-Cluster API Keys are enabled in Elasticsearch. + */ + async areCrossClusterAPIKeysEnabled(): Promise { + if (!this.license.isEnabled()) { + return false; + } + + const id = 'kibana-api-key-service-test'; + + this.logger.debug( + `Testing if Cross-Cluster API Keys are enabled by attempting to update a non-existant key: ${id}` + ); + + try { + await this.clusterClient.asInternalUser.transport.request({ + method: 'PUT', + path: `/_security/cross_cluster/api_key/${id}`, + body: {}, // We are sending an empty request body and expect a validation error if Update Cross-Cluster API key endpoint is available. + }); + return false; + } catch (error) { + return !this.doesErrorIndicateCrossClusterAPIKeysAreDisabled(error); + } + } + /** * Tries to create an API key for the current user. * * Returns newly created API key or `null` if API keys are disabled. * + * User needs `manage_api_key` privilege to create REST API keys and `manage_security` for Cross-Cluster API keys. + * * @param request Request instance. * @param createParams The params to create an API key */ @@ -253,22 +225,40 @@ export class APIKeys { return null; } - const { expiration, metadata, name } = createParams; - - const roleDescriptors = this.parseRoleDescriptorsWithKibanaPrivileges(createParams, false); + const { type, expiration, name, metadata } = createParams; + const scopedClusterClient = this.clusterClient.asScoped(request); this.logger.debug('Trying to create an API key'); - // User needs `manage_api_key` privilege to use this API let result: CreateAPIKeyResult; try { - result = await this.clusterClient.asScoped(request).asCurrentUser.security.createApiKey({ - body: { role_descriptors: roleDescriptors, name, metadata, expiration }, - }); + if (type === 'cross_cluster') { + result = await scopedClusterClient.asCurrentUser.transport.request({ + method: 'POST', + path: '/_security/cross_cluster/api_key', + body: { name, expiration, metadata, access: createParams.access }, + }); + } else { + result = await scopedClusterClient.asCurrentUser.security.createApiKey({ + body: { + name, + expiration, + metadata, + role_descriptors: + 'role_descriptors' in createParams + ? createParams.role_descriptors + : this.parseRoleDescriptorsWithKibanaPrivileges( + createParams.kibana_role_descriptors, + false + ), + }, + }); + } + this.logger.debug('API key was created successfully'); - } catch (e) { - this.logger.error(`Failed to create API key: ${e.message}`); - throw e; + } catch (error) { + this.logger.error(`Failed to create API key: ${error.message}`); + throw error; } return result; } @@ -278,6 +268,8 @@ export class APIKeys { * * Returns `updated`, `true` if the update was successful, `false` if there was nothing to update * + * User needs `manage_api_key` privilege to update REST API keys and `manage_security` for Cross-Cluster API keys. + * * @param request Request instance. * @param updateParams The params to edit an API key */ @@ -289,32 +281,42 @@ export class APIKeys { return null; } - const { id, metadata } = updateParams; - - const roleDescriptors = this.parseRoleDescriptorsWithKibanaPrivileges(updateParams, true); + const { type, id, metadata } = updateParams; + const scopedClusterClient = this.clusterClient.asScoped(request); this.logger.debug('Trying to edit an API key'); - // User needs `manage_api_key` privilege to use this API let result: UpdateAPIKeyResult; - try { - result = await this.clusterClient.asScoped(request).asCurrentUser.security.updateApiKey({ - id, - role_descriptors: roleDescriptors, - metadata, - }); + if (type === 'cross_cluster') { + result = await scopedClusterClient.asCurrentUser.transport.request({ + method: 'PUT', + path: `/_security/cross_cluster/api_key/${id}`, + body: { metadata, access: updateParams.access }, + }); + } else { + result = await scopedClusterClient.asCurrentUser.security.updateApiKey({ + id, + metadata, + role_descriptors: + 'role_descriptors' in updateParams + ? updateParams.role_descriptors + : this.parseRoleDescriptorsWithKibanaPrivileges( + updateParams.kibana_role_descriptors, + true + ), + }); + } if (result.updated) { this.logger.debug('API key was updated successfully'); } else { this.logger.debug('There were no updates to make for API key'); } - } catch (e) { - this.logger.error(`Failed to update API key: ${e.message}`); - throw e; + } catch (error) { + this.logger.error(`Failed to update API key: ${error.message}`); + throw error; } - return result; } @@ -323,7 +325,10 @@ export class APIKeys { * @param request Request instance. * @param createParams Create operation parameters. */ - async grantAsInternalUser(request: KibanaRequest, createParams: CreateAPIKeyParams) { + async grantAsInternalUser( + request: KibanaRequest, + createParams: CreateRestAPIKeyParams | CreateRestAPIKeyWithKibanaPrivilegesParams + ) { if (!this.license.isEnabled()) { return null; } @@ -337,7 +342,13 @@ export class APIKeys { } const { expiration, metadata, name } = createParams; - const roleDescriptors = this.parseRoleDescriptorsWithKibanaPrivileges(createParams, false); + const roleDescriptors = + 'role_descriptors' in createParams + ? createParams.role_descriptors + : this.parseRoleDescriptorsWithKibanaPrivileges( + createParams.kibana_role_descriptors, + false + ); const params = this.getGrantParams( { expiration, metadata, name, role_descriptors: roleDescriptors }, @@ -451,8 +462,14 @@ export class APIKeys { return disabledFeature === 'api_keys'; } + private doesErrorIndicateCrossClusterAPIKeysAreDisabled(error: Record) { + return ( + error.statusCode !== 400 || error.body?.error?.type !== 'action_request_validation_exception' + ); + } + private getGrantParams( - createParams: CreateAPIKeyParams, + createParams: CreateRestAPIKeyParams | CreateRestAPIKeyWithKibanaPrivilegesParams, authorizationHeader: HTTPAuthorizationHeader ): GrantAPIKeyParams { if (authorizationHeader.scheme.toLowerCase() === 'bearer') { @@ -479,23 +496,11 @@ export class APIKeys { } private parseRoleDescriptorsWithKibanaPrivileges( - params: Partial<{ - kibana_role_descriptors: Record< - string, - { elasticsearch: ElasticsearchPrivilegesType; kibana: KibanaPrivilegesType } - >; - role_descriptors: Record; - }>, + kibanaRoleDescriptors: CreateRestAPIKeyWithKibanaPrivilegesParams['kibana_role_descriptors'], isEdit: boolean ) { - if (params.role_descriptors) { - return params.role_descriptors; - } - const roleDescriptors = Object.create(null); - const { kibana_role_descriptors: kibanaRoleDescriptors } = params; - const allValidationErrors: string[] = []; if (kibanaRoleDescriptors) { Object.entries(kibanaRoleDescriptors).forEach(([roleKey, roleDescriptor]) => { diff --git a/x-pack/plugins/security/server/authentication/api_keys/index.ts b/x-pack/plugins/security/server/authentication/api_keys/index.ts index b93043302f8d2..ae9e9c98c149b 100644 --- a/x-pack/plugins/security/server/authentication/api_keys/index.ts +++ b/x-pack/plugins/security/server/authentication/api_keys/index.ts @@ -6,9 +6,12 @@ */ export type { + CreateAPIKeyParams, CreateAPIKeyResult, + CreateRestAPIKeyParams, + CreateRestAPIKeyWithKibanaPrivilegesParams, + CreateCrossClusterAPIKeyParams, InvalidateAPIKeyResult, - CreateAPIKeyParams, InvalidateAPIKeysParams, ValidateAPIKeyParams, GrantAPIKeyResult, diff --git a/x-pack/plugins/security/server/authentication/authentication_service.ts b/x-pack/plugins/security/server/authentication/authentication_service.ts index cbd71b890761f..170d3d1d24784 100644 --- a/x-pack/plugins/security/server/authentication/authentication_service.ts +++ b/x-pack/plugins/security/server/authentication/authentication_service.ts @@ -63,6 +63,7 @@ export interface InternalAuthenticationServiceStart extends AuthenticationServic apiKeys: Pick< APIKeys, | 'areAPIKeysEnabled' + | 'areCrossClusterAPIKeysEnabled' | 'create' | 'update' | 'invalidate' @@ -83,6 +84,7 @@ export interface AuthenticationServiceStart { apiKeys: Pick< APIKeys, | 'areAPIKeysEnabled' + | 'areCrossClusterAPIKeysEnabled' | 'create' | 'invalidate' | 'validate' @@ -371,6 +373,7 @@ export class AuthenticationService { return { apiKeys: { areAPIKeysEnabled: apiKeys.areAPIKeysEnabled.bind(apiKeys), + areCrossClusterAPIKeysEnabled: apiKeys.areCrossClusterAPIKeysEnabled.bind(apiKeys), create: apiKeys.create.bind(apiKeys), update: apiKeys.update.bind(apiKeys), grantAsInternalUser: apiKeys.grantAsInternalUser.bind(apiKeys), diff --git a/x-pack/plugins/security/server/authentication/index.ts b/x-pack/plugins/security/server/authentication/index.ts index 2e844c6f60542..e207b316922dd 100644 --- a/x-pack/plugins/security/server/authentication/index.ts +++ b/x-pack/plugins/security/server/authentication/index.ts @@ -28,9 +28,12 @@ export { HTTPAuthorizationHeader, } from './http_authentication'; export type { + CreateAPIKeyParams, CreateAPIKeyResult, + CreateRestAPIKeyParams, + CreateRestAPIKeyWithKibanaPrivilegesParams, + CreateCrossClusterAPIKeyParams, InvalidateAPIKeyResult, - CreateAPIKeyParams, InvalidateAPIKeysParams, ValidateAPIKeyParams, GrantAPIKeyResult, diff --git a/x-pack/plugins/security/server/index.ts b/x-pack/plugins/security/server/index.ts index 9fbefabecd249..4cf199ef6d686 100644 --- a/x-pack/plugins/security/server/index.ts +++ b/x-pack/plugins/security/server/index.ts @@ -23,6 +23,9 @@ import { SecurityPlugin } from './plugin'; export type { CreateAPIKeyParams, CreateAPIKeyResult, + CreateRestAPIKeyParams, + CreateRestAPIKeyWithKibanaPrivilegesParams, + CreateCrossClusterAPIKeyParams, InvalidateAPIKeysParams, InvalidateAPIKeyResult, GrantAPIKeyResult, diff --git a/x-pack/plugins/security/server/plugin.test.ts b/x-pack/plugins/security/server/plugin.test.ts index 73092f856ef6a..e838016e94524 100644 --- a/x-pack/plugins/security/server/plugin.test.ts +++ b/x-pack/plugins/security/server/plugin.test.ts @@ -138,6 +138,7 @@ describe('Security Plugin', () => { "authc": Object { "apiKeys": Object { "areAPIKeysEnabled": [Function], + "areCrossClusterAPIKeysEnabled": [Function], "create": [Function], "grantAsInternalUser": [Function], "invalidate": [Function], diff --git a/x-pack/plugins/security/server/routes/api_keys/create.test.ts b/x-pack/plugins/security/server/routes/api_keys/create.test.ts index 7236e46df7ed5..27167f945aaa1 100644 --- a/x-pack/plugins/security/server/routes/api_keys/create.test.ts +++ b/x-pack/plugins/security/server/routes/api_keys/create.test.ts @@ -77,6 +77,7 @@ describe('Create API Key route', () => { api_key: 'abc123', id: 'key_id', name: 'my api key', + encoded: 'encoded123', }); const payload = { @@ -104,6 +105,7 @@ describe('Create API Key route', () => { api_key: 'abc123', id: 'key_id', name: 'my api key', + encoded: 'encoded123', }); }); diff --git a/x-pack/plugins/security/server/routes/api_keys/create.ts b/x-pack/plugins/security/server/routes/api_keys/create.ts index 8bb097ee01259..ee69a80efa103 100644 --- a/x-pack/plugins/security/server/routes/api_keys/create.ts +++ b/x-pack/plugins/security/server/routes/api_keys/create.ts @@ -5,7 +5,10 @@ * 2.0. */ +import type { estypes } from '@elastic/elasticsearch'; + import { schema } from '@kbn/config-schema'; +import type { TypeOf } from '@kbn/config-schema'; import type { RouteDefinitionParams } from '..'; import { CreateApiKeyValidationError } from '../../authentication/api_keys'; @@ -13,7 +16,27 @@ import { wrapIntoCustomErrorResponse } from '../../errors'; import { elasticsearchRoleSchema, getKibanaRoleSchema } from '../../lib'; import { createLicensedRouteHandler } from '../licensed_route_handler'; -const bodySchema = schema.object({ +/** + * Response of Kibana Create API key endpoint. + */ +export type CreateAPIKeyResult = estypes.SecurityCreateApiKeyResponse; + +/** + * Request body of Kibana Create API key endpoint. + */ +export type CreateAPIKeyParams = + | CreateRestAPIKeyParams + | CreateRestAPIKeyWithKibanaPrivilegesParams + | CreateCrossClusterAPIKeyParams; + +export type CreateRestAPIKeyParams = TypeOf; +export type CreateRestAPIKeyWithKibanaPrivilegesParams = TypeOf< + ReturnType +>; +export type CreateCrossClusterAPIKeyParams = TypeOf; + +export const restApiKeySchema = schema.object({ + type: schema.maybe(schema.literal('rest')), name: schema.string(), expiration: schema.maybe(schema.string()), role_descriptors: schema.recordOf(schema.string(), schema.object({}, { unknowns: 'allow' }), { @@ -22,12 +45,11 @@ const bodySchema = schema.object({ metadata: schema.maybe(schema.object({}, { unknowns: 'allow' })), }); -const getBodySchemaWithKibanaPrivileges = ( - getBasePrivilegeNames: () => { global: string[]; space: string[] } +export const getRestApiKeyWithKibanaPrivilegesSchema = ( + getBasePrivilegeNames: Parameters[0] ) => - schema.object({ - name: schema.string(), - expiration: schema.maybe(schema.string()), + restApiKeySchema.extends({ + role_descriptors: null, kibana_role_descriptors: schema.recordOf( schema.string(), schema.object({ @@ -35,15 +57,38 @@ const getBodySchemaWithKibanaPrivileges = ( kibana: getKibanaRoleSchema(getBasePrivilegeNames), }) ), - metadata: schema.maybe(schema.object({}, { unknowns: 'allow' })), }); +export const crossClusterApiKeySchema = restApiKeySchema.extends({ + type: schema.literal('cross_cluster'), + role_descriptors: null, + access: schema.object( + { + search: schema.maybe( + schema.arrayOf( + schema.object({ + names: schema.arrayOf(schema.string()), + }) + ) + ), + replication: schema.maybe( + schema.arrayOf( + schema.object({ + names: schema.arrayOf(schema.string()), + }) + ) + ), + }, + { unknowns: 'allow' } + ), +}); + export function defineCreateApiKeyRoutes({ router, authz, getAuthenticationService, }: RouteDefinitionParams) { - const bodySchemaWithKibanaPrivileges = getBodySchemaWithKibanaPrivileges(() => { + const bodySchemaWithKibanaPrivileges = getRestApiKeyWithKibanaPrivilegesSchema(() => { const privileges = authz.privileges.get(); return { global: Object.keys(privileges.global), @@ -54,18 +99,28 @@ export function defineCreateApiKeyRoutes({ { path: '/internal/security/api_key', validate: { - body: schema.oneOf([bodySchema, bodySchemaWithKibanaPrivileges]), + body: schema.oneOf([ + restApiKeySchema, + bodySchemaWithKibanaPrivileges, + crossClusterApiKeySchema, + ]), + }, + options: { + access: 'internal', }, }, createLicensedRouteHandler(async (context, request, response) => { try { - const apiKey = await getAuthenticationService().apiKeys.create(request, request.body); + const createdApiKey = await getAuthenticationService().apiKeys.create( + request, + request.body + ); - if (!apiKey) { - return response.badRequest({ body: { message: `API Keys are not available` } }); + if (!createdApiKey) { + return response.badRequest({ body: { message: 'API Keys are not available' } }); } - return response.ok({ body: apiKey }); + return response.ok({ body: createdApiKey }); } catch (error) { if (error instanceof CreateApiKeyValidationError) { return response.badRequest({ body: { message: error.message } }); diff --git a/x-pack/plugins/security/server/routes/api_keys/get.test.ts b/x-pack/plugins/security/server/routes/api_keys/get.test.ts index c34a67ff1bfcb..40257dc2171c5 100644 --- a/x-pack/plugins/security/server/routes/api_keys/get.test.ts +++ b/x-pack/plugins/security/server/routes/api_keys/get.test.ts @@ -4,156 +4,258 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - import Boom from '@hapi/boom'; import { kibanaResponseFactory } from '@kbn/core/server'; +import type { RequestHandler } from '@kbn/core/server'; +import type { CustomRequestHandlerMock, ScopedClusterClientMock } from '@kbn/core/server/mocks'; import { coreMock, httpServerMock } from '@kbn/core/server/mocks'; -import type { LicenseCheck } from '@kbn/licensing-plugin/server'; +import { licensingMock } from '@kbn/licensing-plugin/server/mocks'; +import type { DeeplyMockedKeys } from '@kbn/utility-types-jest'; +import type { InternalAuthenticationServiceStart } from '../../authentication'; +import { authenticationServiceMock } from '../../authentication/authentication_service.mock'; import { routeDefinitionParamsMock } from '../index.mock'; import { defineGetApiKeysRoutes } from './get'; -interface TestOptions { - isAdmin?: boolean; - licenseCheckResult?: LicenseCheck; - apiResponse?: () => unknown; - asserts: { statusCode: number; result?: Record }; -} - -describe('Get API keys', () => { - const getApiKeysTest = ( - description: string, - { licenseCheckResult = { state: 'valid' }, apiResponse, asserts, isAdmin = true }: TestOptions - ) => { - test(description, async () => { - const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); - const mockCoreContext = coreMock.createRequestHandlerContext(); - const mockLicensingContext = { - license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, - }; - const mockContext = coreMock.createCustomRequestHandlerContext({ - core: mockCoreContext, - licensing: mockLicensingContext as any, - }); - - if (apiResponse) { - mockCoreContext.elasticsearch.client.asCurrentUser.security.getApiKey.mockResponse( - // @ts-expect-error unknown type - apiResponse() - ); - } - - defineGetApiKeysRoutes(mockRouteDefinitionParams); - const [[, handler]] = mockRouteDefinitionParams.router.get.mock.calls; - - const headers = { authorization: 'foo' }; - const mockRequest = httpServerMock.createKibanaRequest({ - method: 'get', - path: '/internal/security/api_key', - query: { isAdmin: isAdmin.toString() }, - headers, - }); - - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); - expect(response.status).toBe(asserts.statusCode); - expect(response.payload).toEqual(asserts.result); - - if (apiResponse) { - expect( - mockCoreContext.elasticsearch.client.asCurrentUser.security.getApiKey - ).toHaveBeenCalledWith({ owner: !isAdmin }); - } - expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); - }); - }; - - describe('failure', () => { - getApiKeysTest('returns result of license checker', { - licenseCheckResult: { state: 'invalid', message: 'test forbidden message' }, - asserts: { statusCode: 403, result: { message: 'test forbidden message' } }, - }); - - const error = Boom.notAcceptable('test not acceptable message'); - getApiKeysTest('returns error from cluster client', { - apiResponse: async () => { - throw error; +describe('Get API Keys route', () => { + let routeHandler: RequestHandler; + let authc: DeeplyMockedKeys; + let esClientMock: ScopedClusterClientMock; + let mockContext: CustomRequestHandlerMock; + + beforeEach(async () => { + const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); + authc = authenticationServiceMock.createStart(); + mockRouteDefinitionParams.getAuthenticationService.mockReturnValue(authc); + defineGetApiKeysRoutes(mockRouteDefinitionParams); + [[, routeHandler]] = mockRouteDefinitionParams.router.get.mock.calls; + mockContext = coreMock.createCustomRequestHandlerContext({ + core: coreMock.createRequestHandlerContext(), + licensing: licensingMock.createRequestHandlerContext(), + }); + + esClientMock = (await mockContext.core).elasticsearch.client; + + authc.apiKeys.areAPIKeysEnabled.mockResolvedValue(true); + authc.apiKeys.areCrossClusterAPIKeysEnabled.mockResolvedValue(true); + + esClientMock.asCurrentUser.security.hasPrivileges.mockResponse({ + cluster: { + manage_security: true, + read_security: true, + manage_api_key: true, + manage_own_api_key: true, }, - asserts: { statusCode: 406, result: error }, + } as any); + + esClientMock.asCurrentUser.security.getApiKey.mockResponse({ + api_keys: [ + { id: '123', invalidated: false }, + { id: '456', invalidated: true }, + ], + } as any); + }); + + it('should filter out invalidated API keys', async () => { + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.status).toBe(200); + expect(response.payload.apiKeys).toContainEqual({ id: '123', invalidated: false }); + expect(response.payload.apiKeys).not.toContainEqual({ id: '456', invalidated: true }); + }); + + it('should return `404` if API keys are disabled', async () => { + authc.apiKeys.areAPIKeysEnabled.mockResolvedValue(false); + + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.status).toBe(404); + expect(response.payload).toEqual({ + message: + "API keys are disabled in Elasticsearch. To use API keys enable 'xpack.security.authc.api_key.enabled' setting.", + }); + }); + + it('should forward error from Elasticsearch GET API keys endpoint', async () => { + const error = Boom.forbidden('test not acceptable message'); + esClientMock.asCurrentUser.security.getApiKey.mockResponseImplementation(() => { + throw error; }); + + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.status).toBe(403); + expect(response.payload).toEqual(error); }); - describe('success', () => { - getApiKeysTest('returns API keys', { - apiResponse: () => ({ - api_keys: [ - { - id: 'YCLV7m0BJ3xI4hhWB648', - name: 'test-api-key', - creation: 1571670001452, - expiration: 1571756401452, - invalidated: false, - username: 'elastic', - realm: 'reserved', - }, - ], - }), - asserts: { - statusCode: 200, - result: { - apiKeys: [ - { - id: 'YCLV7m0BJ3xI4hhWB648', - name: 'test-api-key', - creation: 1571670001452, - expiration: 1571756401452, - invalidated: false, - username: 'elastic', - realm: 'reserved', - }, - ], + describe('when user has `manage_security` permission', () => { + beforeEach(() => { + esClientMock.asCurrentUser.security.hasPrivileges.mockResponse({ + cluster: { + manage_security: true, + read_security: true, + manage_api_key: true, + manage_own_api_key: true, }, - }, + } as any); + }); + + it('should calculate user privileges correctly', async () => { + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.payload).toEqual( + expect.objectContaining({ + canManageCrossClusterApiKeys: true, + canManageApiKeys: true, + canManageOwnApiKeys: true, + }) + ); + }); + + it('should disable `canManageCrossClusterApiKeys` when not supported by Elasticsearch', async () => { + authc.apiKeys.areCrossClusterAPIKeysEnabled.mockResolvedValue(false); + + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.payload).toEqual( + expect.objectContaining({ + canManageCrossClusterApiKeys: false, + canManageApiKeys: true, + canManageOwnApiKeys: true, + }) + ); + }); + + it('should request list of all Elasticsearch API keys', async () => { + await routeHandler(mockContext, httpServerMock.createKibanaRequest(), kibanaResponseFactory); + + expect(esClientMock.asCurrentUser.security.getApiKey).toHaveBeenCalledWith({ owner: false }); }); - getApiKeysTest('returns only valid API keys', { - apiResponse: () => ({ - api_keys: [ - { - id: 'YCLV7m0BJ3xI4hhWB648', - name: 'test-api-key1', - creation: 1571670001452, - expiration: 1571756401452, - invalidated: true, - username: 'elastic', - realm: 'reserved', - }, - { - id: 'YCLV7m0BJ3xI4hhWB648', - name: 'test-api-key2', - creation: 1571670001452, - expiration: 1571756401452, - invalidated: false, - username: 'elastic', - realm: 'reserved', - }, - ], - }), - asserts: { - statusCode: 200, - result: { - apiKeys: [ - { - id: 'YCLV7m0BJ3xI4hhWB648', - name: 'test-api-key2', - creation: 1571670001452, - expiration: 1571756401452, - invalidated: false, - username: 'elastic', - realm: 'reserved', - }, - ], + }); + + describe('when user has `manage_api_key` permission', () => { + beforeEach(() => { + esClientMock.asCurrentUser.security.hasPrivileges.mockResponse({ + cluster: { + manage_security: false, + read_security: false, + manage_api_key: true, + manage_own_api_key: true, }, - }, + } as any); + }); + + it('should calculate user privileges correctly ', async () => { + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.payload).toEqual( + expect.objectContaining({ + canManageCrossClusterApiKeys: false, + canManageApiKeys: true, + canManageOwnApiKeys: true, + }) + ); + }); + + it('should request list of all Elasticsearch API keys', async () => { + await routeHandler(mockContext, httpServerMock.createKibanaRequest(), kibanaResponseFactory); + + expect(esClientMock.asCurrentUser.security.getApiKey).toHaveBeenCalledWith({ owner: false }); + }); + }); + + describe('when user has `read_security` permission', () => { + beforeEach(() => { + esClientMock.asCurrentUser.security.hasPrivileges.mockResponse({ + cluster: { + manage_security: false, + read_security: true, + manage_api_key: false, + manage_own_api_key: false, + }, + } as any); + }); + + it('should calculate user privileges correctly ', async () => { + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.payload).toEqual( + expect.objectContaining({ + canManageCrossClusterApiKeys: false, + canManageApiKeys: false, + canManageOwnApiKeys: false, + }) + ); + }); + + it('should request list of all Elasticsearch API keys', async () => { + await routeHandler(mockContext, httpServerMock.createKibanaRequest(), kibanaResponseFactory); + + expect(esClientMock.asCurrentUser.security.getApiKey).toHaveBeenCalledWith({ owner: false }); + }); + }); + + describe('when user has `manage_own_api_key` permission', () => { + beforeEach(() => { + esClientMock.asCurrentUser.security.hasPrivileges.mockResponse({ + cluster: { + manage_security: false, + read_security: false, + manage_api_key: false, + manage_own_api_key: true, + }, + } as any); + }); + + it('should calculate user privileges correctly ', async () => { + const response = await routeHandler( + mockContext, + httpServerMock.createKibanaRequest(), + kibanaResponseFactory + ); + + expect(response.payload).toEqual( + expect.objectContaining({ + canManageCrossClusterApiKeys: false, + canManageApiKeys: false, + canManageOwnApiKeys: true, + }) + ); + }); + + it('should only request list of API keys owned by the user', async () => { + await routeHandler(mockContext, httpServerMock.createKibanaRequest(), kibanaResponseFactory); + + expect(esClientMock.asCurrentUser.security.getApiKey).toHaveBeenCalledWith({ owner: true }); }); }); }); diff --git a/x-pack/plugins/security/server/routes/api_keys/get.ts b/x-pack/plugins/security/server/routes/api_keys/get.ts index db0d02a20c687..47eb9274ab6b7 100644 --- a/x-pack/plugins/security/server/routes/api_keys/get.ts +++ b/x-pack/plugins/security/server/routes/api_keys/get.ts @@ -5,38 +5,79 @@ * 2.0. */ -import { schema } from '@kbn/config-schema'; - import type { RouteDefinitionParams } from '..'; +import type { ApiKey } from '../../../common/model'; import { wrapIntoCustomErrorResponse } from '../../errors'; import { createLicensedRouteHandler } from '../licensed_route_handler'; -export function defineGetApiKeysRoutes({ router }: RouteDefinitionParams) { +/** + * Response of Kibana Get API keys endpoint. + */ +export interface GetAPIKeysResult { + apiKeys: ApiKey[]; + canManageCrossClusterApiKeys: boolean; + canManageApiKeys: boolean; + canManageOwnApiKeys: boolean; +} + +export function defineGetApiKeysRoutes({ + router, + getAuthenticationService, +}: RouteDefinitionParams) { router.get( { path: '/internal/security/api_key', - validate: { - query: schema.object({ - // We don't use `schema.boolean` here, because all query string parameters are treated as - // strings and @kbn/config-schema doesn't coerce strings to booleans. - // - // A boolean flag that can be used to query API keys owned by the currently authenticated - // user. `false` means that only API keys of currently authenticated user will be returned. - isAdmin: schema.oneOf([schema.literal('true'), schema.literal('false')]), - }), + validate: false, + options: { + access: 'internal', }, }, createLicensedRouteHandler(async (context, request, response) => { try { - const isAdmin = request.query.isAdmin === 'true'; const esClient = (await context.core).elasticsearch.client; + const authenticationService = getAuthenticationService(); + + const [{ cluster: clusterPrivileges }, areApiKeysEnabled, areCrossClusterApiKeysEnabled] = + await Promise.all([ + esClient.asCurrentUser.security.hasPrivileges({ + body: { + cluster: [ + 'manage_security', + 'read_security', + 'manage_api_key', + 'manage_own_api_key', + ], + }, + }), + authenticationService.apiKeys.areAPIKeysEnabled(), + authenticationService.apiKeys.areCrossClusterAPIKeysEnabled(), + ]); + + if (!areApiKeysEnabled) { + return response.notFound({ + body: { + message: + "API keys are disabled in Elasticsearch. To use API keys enable 'xpack.security.authc.api_key.enabled' setting.", + }, + }); + } + const apiResponse = await esClient.asCurrentUser.security.getApiKey({ - owner: !isAdmin, + owner: !clusterPrivileges.manage_api_key && !clusterPrivileges.read_security, }); const validKeys = apiResponse.api_keys.filter(({ invalidated }) => !invalidated); - return response.ok({ body: { apiKeys: validKeys } }); + return response.ok({ + body: { + // @ts-expect-error Elasticsearch client types do not know about Cross-Cluster API keys yet. + apiKeys: validKeys, + canManageCrossClusterApiKeys: + clusterPrivileges.manage_security && areCrossClusterApiKeysEnabled, + canManageApiKeys: clusterPrivileges.manage_api_key, + canManageOwnApiKeys: clusterPrivileges.manage_own_api_key, + }, + }); } catch (error) { return response.customError(wrapIntoCustomErrorResponse(error)); } diff --git a/x-pack/plugins/security/server/routes/api_keys/index.ts b/x-pack/plugins/security/server/routes/api_keys/index.ts index d815fb749fb4d..15c8e149470d0 100644 --- a/x-pack/plugins/security/server/routes/api_keys/index.ts +++ b/x-pack/plugins/security/server/routes/api_keys/index.ts @@ -10,14 +10,28 @@ import { defineCreateApiKeyRoutes } from './create'; import { defineEnabledApiKeysRoutes } from './enabled'; import { defineGetApiKeysRoutes } from './get'; import { defineInvalidateApiKeysRoutes } from './invalidate'; -import { defineCheckPrivilegesRoutes } from './privileges'; import { defineUpdateApiKeyRoutes } from './update'; +export type { + CreateAPIKeyParams, + CreateAPIKeyResult, + CreateRestAPIKeyParams, + CreateCrossClusterAPIKeyParams, + CreateRestAPIKeyWithKibanaPrivilegesParams, +} from './create'; +export type { + UpdateAPIKeyParams, + UpdateAPIKeyResult, + UpdateRestAPIKeyParams, + UpdateCrossClusterAPIKeyParams, + UpdateRestAPIKeyWithKibanaPrivilegesParams, +} from './update'; +export type { GetAPIKeysResult } from './get'; + export function defineApiKeysRoutes(params: RouteDefinitionParams) { defineEnabledApiKeysRoutes(params); defineGetApiKeysRoutes(params); defineCreateApiKeyRoutes(params); defineUpdateApiKeyRoutes(params); - defineCheckPrivilegesRoutes(params); defineInvalidateApiKeysRoutes(params); } diff --git a/x-pack/plugins/security/server/routes/api_keys/privileges.test.ts b/x-pack/plugins/security/server/routes/api_keys/privileges.test.ts deleted file mode 100644 index 52d1d59a486da..0000000000000 --- a/x-pack/plugins/security/server/routes/api_keys/privileges.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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import Boom from '@hapi/boom'; - -import { kibanaResponseFactory } from '@kbn/core/server'; -import { coreMock, httpServerMock } from '@kbn/core/server/mocks'; -import type { LicenseCheck } from '@kbn/licensing-plugin/server'; - -import { authenticationServiceMock } from '../../authentication/authentication_service.mock'; -import { routeDefinitionParamsMock } from '../index.mock'; -import { defineCheckPrivilegesRoutes } from './privileges'; - -interface TestOptions { - licenseCheckResult?: LicenseCheck; - areAPIKeysEnabled?: boolean; - apiResponse?: () => unknown; - asserts: { statusCode: number; result?: Record; apiArguments?: unknown }; -} - -describe('Check API keys privileges', () => { - const getPrivilegesTest = ( - description: string, - { - licenseCheckResult = { state: 'valid' }, - areAPIKeysEnabled = true, - apiResponse, - asserts, - }: TestOptions - ) => { - test(description, async () => { - const mockRouteDefinitionParams = routeDefinitionParamsMock.create(); - const mockCoreContext = coreMock.createRequestHandlerContext(); - const mockLicensingContext = { - license: { check: jest.fn().mockReturnValue(licenseCheckResult) }, - } as any; - const mockContext = coreMock.createCustomRequestHandlerContext({ - core: mockCoreContext, - licensing: mockLicensingContext, - }); - - const authc = authenticationServiceMock.createStart(); - authc.apiKeys.areAPIKeysEnabled.mockResolvedValue(areAPIKeysEnabled); - mockRouteDefinitionParams.getAuthenticationService.mockReturnValue(authc); - - if (apiResponse) { - mockCoreContext.elasticsearch.client.asCurrentUser.security.hasPrivileges.mockResponseImplementation( - // @ts-expect-error unknown return - () => { - return { - body: apiResponse(), - }; - } - ); - } - - defineCheckPrivilegesRoutes(mockRouteDefinitionParams); - const [[, handler]] = mockRouteDefinitionParams.router.get.mock.calls; - - const headers = { authorization: 'foo' }; - const mockRequest = httpServerMock.createKibanaRequest({ - method: 'get', - path: '/internal/security/api_key/privileges', - headers, - }); - - const response = await handler(mockContext, mockRequest, kibanaResponseFactory); - expect(response.status).toBe(asserts.statusCode); - expect(response.payload).toEqual(asserts.result); - - if (asserts.apiArguments) { - expect( - mockCoreContext.elasticsearch.client.asCurrentUser.security.hasPrivileges - ).toHaveBeenCalledWith(asserts.apiArguments); - } - - expect(mockLicensingContext.license.check).toHaveBeenCalledWith('security', 'basic'); - }); - }; - - describe('failure', () => { - getPrivilegesTest('returns result of license checker', { - licenseCheckResult: { state: 'invalid', message: 'test forbidden message' }, - asserts: { statusCode: 403, result: { message: 'test forbidden message' } }, - }); - - const error = Boom.notAcceptable('test not acceptable message'); - getPrivilegesTest('returns error from cluster client', { - apiResponse: () => { - throw error; - }, - asserts: { - apiArguments: { - body: { cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'] }, - }, - statusCode: 406, - result: error, - }, - }); - }); - - describe('success', () => { - getPrivilegesTest('returns areApiKeysEnabled and isAdmin', { - apiResponse: () => ({ - username: 'elastic', - has_all_requested: true, - cluster: { manage_api_key: true, manage_security: true, manage_own_api_key: false }, - index: {}, - application: {}, - }), - asserts: { - apiArguments: { - body: { cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'] }, - }, - statusCode: 200, - result: { areApiKeysEnabled: true, isAdmin: true, canManage: true }, - }, - }); - - getPrivilegesTest( - 'returns areApiKeysEnabled=false when API Keys are disabled in Elasticsearch', - { - apiResponse: () => ({ - username: 'elastic', - has_all_requested: true, - cluster: { manage_api_key: true, manage_security: true, manage_own_api_key: true }, - index: {}, - application: {}, - }), - areAPIKeysEnabled: false, - asserts: { - apiArguments: { - body: { cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'] }, - }, - statusCode: 200, - result: { areApiKeysEnabled: false, isAdmin: true, canManage: true }, - }, - } - ); - - getPrivilegesTest('returns isAdmin=false when user has insufficient privileges', { - apiResponse: () => ({ - username: 'elastic', - has_all_requested: true, - cluster: { manage_api_key: false, manage_security: false, manage_own_api_key: false }, - index: {}, - application: {}, - }), - asserts: { - apiArguments: { - body: { cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'] }, - }, - statusCode: 200, - result: { areApiKeysEnabled: true, isAdmin: false, canManage: false }, - }, - }); - - getPrivilegesTest('returns canManage=true when user can manage their own API Keys', { - apiResponse: () => ({ - username: 'elastic', - has_all_requested: true, - cluster: { manage_api_key: false, manage_security: false, manage_own_api_key: true }, - index: {}, - application: {}, - }), - asserts: { - apiArguments: { - body: { cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'] }, - }, - statusCode: 200, - result: { areApiKeysEnabled: true, isAdmin: false, canManage: true }, - }, - }); - }); -}); diff --git a/x-pack/plugins/security/server/routes/api_keys/privileges.ts b/x-pack/plugins/security/server/routes/api_keys/privileges.ts deleted file mode 100644 index 09210e1d00d37..0000000000000 --- a/x-pack/plugins/security/server/routes/api_keys/privileges.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import type { RouteDefinitionParams } from '..'; -import { wrapIntoCustomErrorResponse } from '../../errors'; -import { createLicensedRouteHandler } from '../licensed_route_handler'; - -export function defineCheckPrivilegesRoutes({ - router, - getAuthenticationService, -}: RouteDefinitionParams) { - router.get( - { - path: '/internal/security/api_key/privileges', - validate: false, - }, - createLicensedRouteHandler(async (context, request, response) => { - try { - const esClient = (await context.core).elasticsearch.client; - const [ - { - cluster: { - manage_security: manageSecurity, - manage_api_key: manageApiKey, - manage_own_api_key: manageOwnApiKey, - }, - }, - areApiKeysEnabled, - ] = await Promise.all([ - esClient.asCurrentUser.security.hasPrivileges({ - body: { cluster: ['manage_security', 'manage_api_key', 'manage_own_api_key'] }, - }), - getAuthenticationService().apiKeys.areAPIKeysEnabled(), - ]); - - const isAdmin = manageSecurity || manageApiKey; - const canManage = manageSecurity || manageApiKey || manageOwnApiKey; - - return response.ok({ - body: { areApiKeysEnabled, isAdmin, canManage }, - }); - } catch (error) { - return response.customError(wrapIntoCustomErrorResponse(error)); - } - }) - ); -} diff --git a/x-pack/plugins/security/server/routes/api_keys/update.ts b/x-pack/plugins/security/server/routes/api_keys/update.ts index a7ff22fe58cc2..0a05ffe048205 100644 --- a/x-pack/plugins/security/server/routes/api_keys/update.ts +++ b/x-pack/plugins/security/server/routes/api_keys/update.ts @@ -5,16 +5,38 @@ * 2.0. */ +import type { estypes } from '@elastic/elasticsearch'; + import { schema } from '@kbn/config-schema'; +import type { TypeOf } from '@kbn/config-schema'; import type { RouteDefinitionParams } from '..'; -import type { UpdateAPIKeyResult } from '../../authentication/api_keys/api_keys'; import { UpdateApiKeyValidationError } from '../../authentication/api_keys/api_keys'; import { wrapIntoCustomErrorResponse } from '../../errors'; import { elasticsearchRoleSchema, getKibanaRoleSchema } from '../../lib'; import { createLicensedRouteHandler } from '../licensed_route_handler'; -const bodySchema = schema.object({ +/** + * Response of Kibana Update API key endpoint. + */ +export type UpdateAPIKeyResult = estypes.SecurityUpdateApiKeyResponse; + +/** + * Request body of Kibana Update API key endpoint. + */ +export type UpdateAPIKeyParams = + | UpdateRestAPIKeyParams + | UpdateCrossClusterAPIKeyParams + | UpdateRestAPIKeyWithKibanaPrivilegesParams; + +export type UpdateRestAPIKeyParams = TypeOf; +export type UpdateCrossClusterAPIKeyParams = TypeOf; +export type UpdateRestAPIKeyWithKibanaPrivilegesParams = TypeOf< + ReturnType +>; + +const restApiKeySchema = schema.object({ + type: schema.maybe(schema.literal('rest')), id: schema.string(), role_descriptors: schema.recordOf(schema.string(), schema.object({}, { unknowns: 'allow' }), { defaultValue: {}, @@ -22,11 +44,41 @@ const bodySchema = schema.object({ metadata: schema.maybe(schema.object({}, { unknowns: 'allow' })), }); -const getBodySchemaWithKibanaPrivileges = ( - getBasePrivilegeNames: () => { global: string[]; space: string[] } +const crossClusterApiKeySchema = restApiKeySchema.extends({ + type: schema.literal('cross_cluster'), + role_descriptors: null, + access: schema.object( + { + search: schema.maybe( + schema.arrayOf( + schema.object( + { + names: schema.arrayOf(schema.string()), + }, + { unknowns: 'allow' } + ) + ) + ), + replication: schema.maybe( + schema.arrayOf( + schema.object( + { + names: schema.arrayOf(schema.string()), + }, + { unknowns: 'allow' } + ) + ) + ), + }, + { unknowns: 'allow' } + ), +}); + +const getRestApiKeyWithKibanaPrivilegesSchema = ( + getBasePrivilegeNames: Parameters[0] ) => - schema.object({ - id: schema.string(), + restApiKeySchema.extends({ + role_descriptors: null, kibana_role_descriptors: schema.recordOf( schema.string(), schema.object({ @@ -34,7 +86,6 @@ const getBodySchemaWithKibanaPrivileges = ( kibana: getKibanaRoleSchema(getBasePrivilegeNames), }) ), - metadata: schema.maybe(schema.object({}, { unknowns: 'allow' })), }); export function defineUpdateApiKeyRoutes({ @@ -42,7 +93,7 @@ export function defineUpdateApiKeyRoutes({ authz, getAuthenticationService, }: RouteDefinitionParams) { - const bodySchemaWithKibanaPrivileges = getBodySchemaWithKibanaPrivileges(() => { + const bodySchemaWithKibanaPrivileges = getRestApiKeyWithKibanaPrivilegesSchema(() => { const privileges = authz.privileges.get(); return { global: Object.keys(privileges.global), @@ -54,7 +105,14 @@ export function defineUpdateApiKeyRoutes({ { path: '/internal/security/api_key', validate: { - body: schema.oneOf([bodySchema, bodySchemaWithKibanaPrivileges]), + body: schema.oneOf([ + restApiKeySchema, + crossClusterApiKeySchema, + bodySchemaWithKibanaPrivileges, + ]), + }, + options: { + access: 'internal', }, }, createLicensedRouteHandler(async (context, request, response) => { diff --git a/x-pack/plugins/security_solution/common/api/risk_score/create_index/create_index_route.ts b/x-pack/plugins/security_solution/common/api/risk_score/create_index/create_index_route.ts new file mode 100644 index 0000000000000..5199db8132b79 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/risk_score/create_index/create_index_route.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { TypeOf } from '@kbn/config-schema'; +import { schema } from '@kbn/config-schema'; + +export const createEsIndexRequestBody = schema.object({ + index: schema.string({ minLength: 1 }), + mappings: schema.maybe( + schema.oneOf([schema.string(), schema.recordOf(schema.string({ minLength: 1 }), schema.any())]) + ), +}); + +export type CreateEsIndexRequestBody = TypeOf; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/schema.test.ts b/x-pack/plugins/security_solution/common/api/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.test.ts similarity index 53% rename from x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/schema.test.ts rename to x-pack/plugins/security_solution/common/api/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.test.ts index 2a7d221bf610a..b37f611a6e2bb 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/schema.test.ts +++ b/x-pack/plugins/security_solution/common/api/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.test.ts @@ -5,23 +5,23 @@ * 2.0. */ -import { createPrebuiltSavedObjectsSchema } from './schema'; +import { createPrebuiltSavedObjectsRequestBody } from './create_prebuilt_saved_objects_route'; -describe('createPrebuiltSavedObjectsSchema', () => { +describe('createPrebuiltSavedObjectsRequestBody', () => { it('should throw error', () => { expect(() => - createPrebuiltSavedObjectsSchema.params.validate({ template_name: '123' }) + createPrebuiltSavedObjectsRequestBody.params.validate({ template_name: '123' }) ).toThrow(); }); it.each([['hostRiskScoreDashboards', 'userRiskScoreDashboards']])( 'should allow template %p', async (template) => { - expect(createPrebuiltSavedObjectsSchema.params.validate({ template_name: template })).toEqual( - { - template_name: template, - } - ); + expect( + createPrebuiltSavedObjectsRequestBody.params.validate({ template_name: template }) + ).toEqual({ + template_name: template, + }); } ); }); diff --git a/x-pack/plugins/security_solution/common/api/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.ts b/x-pack/plugins/security_solution/common/api/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.ts new file mode 100644 index 0000000000000..a21d45430791c --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/risk_score/create_prebuilt_saved_objects/create_prebuilt_saved_objects_route.ts @@ -0,0 +1,17 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const createPrebuiltSavedObjectsRequestBody = { + params: schema.object({ + template_name: schema.oneOf([ + schema.literal('hostRiskScoreDashboards'), + schema.literal('userRiskScoreDashboards'), + ]), + }), +}; diff --git a/x-pack/plugins/security_solution/common/api/risk_score/create_stored_script/create_stored_script_route.ts b/x-pack/plugins/security_solution/common/api/risk_score/create_stored_script/create_stored_script_route.ts new file mode 100644 index 0000000000000..4a16cdfa247bc --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/risk_score/create_stored_script/create_stored_script_route.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import type { TypeOf } from '@kbn/config-schema'; +import { schema } from '@kbn/config-schema'; + +export const createStoredScriptRequestBody = schema.object({ + id: schema.string({ minLength: 1 }), + script: schema.object({ + lang: schema.oneOf([ + schema.string(), + schema.literal('painless'), + schema.literal('expression'), + schema.literal('mustache'), + schema.literal('java'), + ]), + options: schema.maybe(schema.recordOf(schema.string(), schema.string())), + source: schema.string(), + }), +}); + +export type CreateStoredScriptRequestBody = TypeOf; diff --git a/x-pack/plugins/security_solution/common/api/risk_score/delete_indices/delete_indices_route.ts b/x-pack/plugins/security_solution/common/api/risk_score/delete_indices/delete_indices_route.ts new file mode 100644 index 0000000000000..b773a52917a73 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/risk_score/delete_indices/delete_indices_route.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { schema } from '@kbn/config-schema'; + +export const deleteIndicesRequestBody = schema.object({ + indices: schema.arrayOf(schema.string()), +}); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/schema.ts b/x-pack/plugins/security_solution/common/api/risk_score/delete_prebuilt_saved_objects/delete_prebuilt_saved_objects_route.ts similarity index 67% rename from x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/schema.ts rename to x-pack/plugins/security_solution/common/api/risk_score/delete_prebuilt_saved_objects/delete_prebuilt_saved_objects_route.ts index 17280d2a3be34..729197a18ddb6 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/schema.ts +++ b/x-pack/plugins/security_solution/common/api/risk_score/delete_prebuilt_saved_objects/delete_prebuilt_saved_objects_route.ts @@ -7,16 +7,7 @@ import { schema } from '@kbn/config-schema'; -export const createPrebuiltSavedObjectsSchema = { - params: schema.object({ - template_name: schema.oneOf([ - schema.literal('hostRiskScoreDashboards'), - schema.literal('userRiskScoreDashboards'), - ]), - }), -}; - -export const deletePrebuiltSavedObjectsSchema = { +export const deletePrebuiltSavedObjectsRequestBody = { params: schema.object({ template_name: schema.oneOf([ schema.literal('hostRiskScoreDashboards'), diff --git a/x-pack/plugins/security_solution/common/api/risk_score/delete_stored_script/delete_stored_script_route.ts b/x-pack/plugins/security_solution/common/api/risk_score/delete_stored_script/delete_stored_script_route.ts new file mode 100644 index 0000000000000..3859e25f427ed --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/risk_score/delete_stored_script/delete_stored_script_route.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { TypeOf } from '@kbn/config-schema'; +import { schema } from '@kbn/config-schema'; + +export const deleteStoredScriptRequestBody = schema.object({ + id: schema.string({ minLength: 1 }), +}); + +export type DeleteStoredScriptRequestBody = TypeOf; diff --git a/x-pack/plugins/security_solution/common/api/risk_score/index.ts b/x-pack/plugins/security_solution/common/api/risk_score/index.ts new file mode 100644 index 0000000000000..e3bb3d622c3c0 --- /dev/null +++ b/x-pack/plugins/security_solution/common/api/risk_score/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export * from './create_index/create_index_route'; +export * from './create_prebuilt_saved_objects/create_prebuilt_saved_objects_route'; +export * from './create_stored_script/create_stored_script_route'; +export * from './delete_indices/delete_indices_route'; +export * from './delete_prebuilt_saved_objects/delete_prebuilt_saved_objects_route'; +export * from './delete_stored_script/delete_stored_script_route'; +export * from './index_status/index_status_route'; +export * from './install_modules/install_modules_route'; +export * from './read_prebuilt_dev_tool_content/read_prebuilt_dev_tool_content_route'; diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/index_status/schema.ts b/x-pack/plugins/security_solution/common/api/risk_score/index_status/index_status_route.ts similarity index 87% rename from x-pack/plugins/security_solution/server/lib/risk_score/index_status/schema.ts rename to x-pack/plugins/security_solution/common/api/risk_score/index_status/index_status_route.ts index 7cff67daaa647..afe8529838878 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/index_status/schema.ts +++ b/x-pack/plugins/security_solution/common/api/risk_score/index_status/index_status_route.ts @@ -7,7 +7,7 @@ import * as t from 'io-ts'; -export const indexStatusSchema = t.type({ +export const indexStatusRequestQuery = t.type({ indexName: t.string, entity: t.string, }); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/schema.ts b/x-pack/plugins/security_solution/common/api/risk_score/install_modules/install_modules_route.ts similarity index 80% rename from x-pack/plugins/security_solution/server/lib/risk_score/onboarding/schema.ts rename to x-pack/plugins/security_solution/common/api/risk_score/install_modules/install_modules_route.ts index 0fdcfee33d2c9..a17f10d724863 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/schema.ts +++ b/x-pack/plugins/security_solution/common/api/risk_score/install_modules/install_modules_route.ts @@ -6,9 +6,9 @@ */ import { schema } from '@kbn/config-schema'; -import { RiskScoreEntity } from '../../../../common/search_strategy'; +import { RiskScoreEntity } from '../../../search_strategy'; -export const onboardingRiskScoreSchema = { +export const onboardingRiskScoreRequestBody = { body: schema.object({ riskScoreEntity: schema.oneOf([ schema.literal(RiskScoreEntity.host), diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.ts b/x-pack/plugins/security_solution/common/api/risk_score/read_prebuilt_dev_tool_content/read_prebuilt_dev_tool_content_route.ts similarity index 91% rename from x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.ts rename to x-pack/plugins/security_solution/common/api/risk_score/read_prebuilt_dev_tool_content/read_prebuilt_dev_tool_content_route.ts index cf01f0ef9f040..8f8ddd62299ff 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.ts +++ b/x-pack/plugins/security_solution/common/api/risk_score/read_prebuilt_dev_tool_content/read_prebuilt_dev_tool_content_route.ts @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; -export const ReadConsoleRequestSchema = { +export const readConsoleRequestBody = { params: schema.object({ console_id: schema.oneOf([ schema.literal('enable_host_risk_score'), diff --git a/x-pack/plugins/security_solution/common/endpoint/constants.ts b/x-pack/plugins/security_solution/common/endpoint/constants.ts index af3486dc2c92a..25380c79cf6ed 100644 --- a/x-pack/plugins/security_solution/common/endpoint/constants.ts +++ b/x-pack/plugins/security_solution/common/endpoint/constants.ts @@ -45,7 +45,7 @@ export const policyIndexPattern = 'metrics-endpoint.policy-*'; export const telemetryIndexPattern = 'metrics-endpoint.telemetry-*'; -export const ENDPOINT_HEARTBEAT_INDEX = 'logs-endpoint.heartbeat-default'; +export const ENDPOINT_HEARTBEAT_INDEX = '.logs-endpoint.heartbeat-default'; // File storage indexes supporting endpoint Upload/download export const FILE_STORAGE_METADATA_INDEX = getFileMetadataIndexName('endpoint'); diff --git a/x-pack/plugins/security_solution/common/types/app_features.ts b/x-pack/plugins/security_solution/common/types/app_features.ts index 27b59037f6cb0..80734f9f23992 100644 --- a/x-pack/plugins/security_solution/common/types/app_features.ts +++ b/x-pack/plugins/security_solution/common/types/app_features.ts @@ -48,6 +48,11 @@ export enum AppFeatureSecurityKey { * Enables Threat Intelligence */ threatIntelligence = 'threat-intelligence', + + /** + * Enables Osquery Response Actions + */ + osqueryAutomatedResponseActions = 'osquery_automated_response_actions', } export enum AppFeatureCasesKey { diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_left_panel_response_tab.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_left_panel_response_tab.cy.ts new file mode 100644 index 0000000000000..19b9eac037a4c --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_left_panel_response_tab.cy.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DOCUMENT_DETAILS_FLYOUT_RESPONSE_EMPTY } from '../../../../screens/expandable_flyout/alert_details_left_panel_response_tab'; +import { openResponseTab } from '../../../../tasks/expandable_flyout/alert_details_left_panel_response_tab'; +import { expandDocumentDetailsExpandableFlyoutLeftSection } from '../../../../tasks/expandable_flyout/alert_details_right_panel'; +import { expandFirstAlertExpandableFlyout } from '../../../../tasks/expandable_flyout/common'; +import { cleanKibana } from '../../../../tasks/common'; +import { login, visit } from '../../../../tasks/login'; +import { createRule } from '../../../../tasks/api_calls/rules'; +import { getNewRule } from '../../../../objects/rule'; +import { ALERTS_URL } from '../../../../urls/navigation'; +import { waitForAlertsToPopulate } from '../../../../tasks/create_new_rule'; + +describe( + 'Alert details expandable flyout left panel investigation', + { env: { ftrConfig: { enableExperimental: ['securityFlyoutEnabled'] } } }, + () => { + beforeEach(() => { + cleanKibana(); + login(); + createRule(getNewRule()); + visit(ALERTS_URL); + waitForAlertsToPopulate(); + expandFirstAlertExpandableFlyout(); + expandDocumentDetailsExpandableFlyoutLeftSection(); + openResponseTab(); + }); + + it('should display empty response message', () => { + cy.get(DOCUMENT_DETAILS_FLYOUT_RESPONSE_EMPTY).should('be.visible'); + }); + } +); diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts index bf6a3b27de956..9dc5dccbddcc3 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/alerts/expandable_flyout/alert_details_right_panel_overview_tab.cy.ts @@ -43,6 +43,7 @@ import { DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_SESSION_PREVIEW, DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_TABLE_FIELD_CELL, DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_HIGHLIGHTED_FIELDS_TABLE_VALUE_CELL, + DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_RESPONSE_SECTION_EMPTY_RESPONSE, } from '../../../../screens/expandable_flyout/alert_details_right_panel_overview_tab'; import { clickCorrelationsViewAllButton, @@ -53,6 +54,7 @@ import { toggleOverviewTabAboutSection, toggleOverviewTabInsightsSection, toggleOverviewTabInvestigationSection, + toggleOverviewTabResponseSection, toggleOverviewTabVisualizationsSection, } from '../../../../tasks/expandable_flyout/alert_details_right_panel_overview_tab'; import { cleanKibana } from '../../../../tasks/common'; @@ -343,5 +345,16 @@ describe( cy.get(DOCUMENT_DETAILS_FLYOUT_INSIGHTS_TAB_ENTITIES_CONTENT).should('be.visible'); // TODO update when we can navigate to Prevalence sub tab directly }); }); + + describe('response section', () => { + it('should display empty message', () => { + toggleOverviewTabAboutSection(); + toggleOverviewTabResponseSection(); + + cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_RESPONSE_SECTION_EMPTY_RESPONSE).should( + 'be.visible' + ); + }); + }); } ); diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/creation.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/creation.cy.ts index 6064b602ee0e5..fb207b1dcca31 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/creation.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/creation.cy.ts @@ -42,7 +42,7 @@ import { import { OVERVIEW_URL, TIMELINE_TEMPLATES_URL } from '../../../urls/navigation'; -describe('Create a timeline from a template', () => { +describe.skip('Create a timeline from a template', () => { before(() => { deleteTimelines(); login(); @@ -105,7 +105,7 @@ describe('Timelines', (): void => { }); }); - describe('Creates a timeline by clicking untitled timeline from bottom bar', () => { + describe.skip('Creates a timeline by clicking untitled timeline from bottom bar', () => { beforeEach(() => { login(); visit(OVERVIEW_URL); diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/notes_tab.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/notes_tab.cy.ts index 1196555a16e7d..cbde4900d2e79 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/notes_tab.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/notes_tab.cy.ts @@ -35,7 +35,7 @@ import { TIMELINES_URL } from '../../../urls/navigation'; const text = 'system_indices_superuser'; const link = 'https://www.elastic.co/'; -describe('Timeline notes tab', () => { +describe.skip('Timeline notes tab', () => { before(() => { cleanKibana(); login(); diff --git a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/query_tab.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/query_tab.cy.ts index 0d509063c6ff0..bd8d80ceed851 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/query_tab.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/investigations/timelines/query_tab.cy.ts @@ -30,7 +30,7 @@ import { import { TIMELINES_URL } from '../../../urls/navigation'; -describe('Timeline query tab', () => { +describe.skip('Timeline query tab', () => { before(() => { cleanKibana(); login(); diff --git a/x-pack/plugins/security_solution/cypress/screens/expandable_flyout/alert_details_left_panel_response_tab.ts b/x-pack/plugins/security_solution/cypress/screens/expandable_flyout/alert_details_left_panel_response_tab.ts new file mode 100644 index 0000000000000..0620d34230b8c --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/screens/expandable_flyout/alert_details_left_panel_response_tab.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { RESPONSE_TAB_TEST_ID } from '../../../public/flyout/left/test_ids'; +import { RESPONSE_EMPTY_TEST_ID } from '../../../public/flyout/left/components/test_ids'; +import { getDataTestSubjectSelector } from '../../helpers/common'; + +export const DOCUMENT_DETAILS_FLYOUT_RESPONSE_TAB = + getDataTestSubjectSelector(RESPONSE_TAB_TEST_ID); +export const DOCUMENT_DETAILS_FLYOUT_RESPONSE_EMPTY = + getDataTestSubjectSelector(RESPONSE_EMPTY_TEST_ID); diff --git a/x-pack/plugins/security_solution/cypress/screens/expandable_flyout/alert_details_right_panel_overview_tab.ts b/x-pack/plugins/security_solution/cypress/screens/expandable_flyout/alert_details_right_panel_overview_tab.ts index b0281f54abe5a..21fef179980d5 100644 --- a/x-pack/plugins/security_solution/cypress/screens/expandable_flyout/alert_details_right_panel_overview_tab.ts +++ b/x-pack/plugins/security_solution/cypress/screens/expandable_flyout/alert_details_right_panel_overview_tab.ts @@ -43,6 +43,8 @@ import { SESSION_PREVIEW_TEST_ID, VISUALIZATIONS_SECTION_HEADER_TEST_ID, HIGHLIGHTED_FIELDS_CELL_TEST_ID, + RESPONSE_SECTION_HEADER_TEST_ID, + RESPONSE_EMPTY_TEST_ID, } from '../../../public/flyout/right/components/test_ids'; /* About section */ @@ -134,6 +136,12 @@ export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_VISUALIZATIONS_SECTION_HEADER getDataTestSubjectSelector(VISUALIZATIONS_SECTION_HEADER_TEST_ID); export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_ANALYZER_TREE = getDataTestSubjectSelector(ANALYZER_TREE_TEST_ID); - export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_SESSION_PREVIEW = getDataTestSubjectSelector(SESSION_PREVIEW_TEST_ID); + +/* Response section */ + +export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_RESPONSE_SECTION_HEADER = + getDataTestSubjectSelector(RESPONSE_SECTION_HEADER_TEST_ID); +export const DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_RESPONSE_SECTION_EMPTY_RESPONSE = + getDataTestSubjectSelector(RESPONSE_EMPTY_TEST_ID); diff --git a/x-pack/plugins/security_solution/cypress/tasks/expandable_flyout/alert_details_left_panel_response_tab.ts b/x-pack/plugins/security_solution/cypress/tasks/expandable_flyout/alert_details_left_panel_response_tab.ts new file mode 100644 index 0000000000000..0721e2d6aa7c7 --- /dev/null +++ b/x-pack/plugins/security_solution/cypress/tasks/expandable_flyout/alert_details_left_panel_response_tab.ts @@ -0,0 +1,16 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { DOCUMENT_DETAILS_FLYOUT_RESPONSE_TAB } from '../../screens/expandable_flyout/alert_details_left_panel_response_tab'; + +/** + * Open the Response tab in the document details expandable flyout left section + */ +export const openResponseTab = () => { + cy.get(DOCUMENT_DETAILS_FLYOUT_RESPONSE_TAB).scrollIntoView(); + cy.get(DOCUMENT_DETAILS_FLYOUT_RESPONSE_TAB).should('be.visible').click(); +}; diff --git a/x-pack/plugins/security_solution/cypress/tasks/expandable_flyout/alert_details_right_panel_overview_tab.ts b/x-pack/plugins/security_solution/cypress/tasks/expandable_flyout/alert_details_right_panel_overview_tab.ts index b8324353f2013..0f39535b77134 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/expandable_flyout/alert_details_right_panel_overview_tab.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/expandable_flyout/alert_details_right_panel_overview_tab.ts @@ -17,6 +17,7 @@ import { DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_INVESTIGATION_GUIDE_BUTTON, DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_DESCRIPTION_TITLE, DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_OPEN_RULE_PREVIEW_BUTTON, + DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_RESPONSE_SECTION_HEADER, } from '../../screens/expandable_flyout/alert_details_right_panel_overview_tab'; /* About section */ @@ -107,6 +108,14 @@ export const toggleOverviewTabVisualizationsSection = () => { .click(); }; +/** + * Toggle the Overview tab response section in the document details expandable flyout right section + */ +export const toggleOverviewTabResponseSection = () => { + cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_RESPONSE_SECTION_HEADER).scrollIntoView(); + cy.get(DOCUMENT_DETAILS_FLYOUT_OVERVIEW_TAB_RESPONSE_SECTION_HEADER).should('be.visible').click(); +}; + /** * Click on the investigation guide button under the right section, Visualization */ diff --git a/x-pack/plugins/security_solution/public/common/lib/upsellings/types.ts b/x-pack/plugins/security_solution/public/common/lib/upsellings/types.ts index 2b68556817573..53c371a6f2153 100644 --- a/x-pack/plugins/security_solution/public/common/lib/upsellings/types.ts +++ b/x-pack/plugins/security_solution/public/common/lib/upsellings/types.ts @@ -11,6 +11,9 @@ export type PageUpsellings = Partial>; export type SectionUpsellings = Partial>; -export type UpsellingSectionId = 'entity_analytics_panel' | 'endpointPolicyProtections'; +export type UpsellingSectionId = + | 'entity_analytics_panel' + | 'endpointPolicyProtections' + | 'osquery_automated_response_actions'; export type UpsellingMessageId = 'investigation_guide'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.ts index 296ef675b28df..d62114881adad 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/api.ts @@ -26,8 +26,14 @@ import type { ReviewRuleUpgradeResponseBody, ReviewRuleInstallationResponseBody, } from '../../../../common/api/detection_engine/prebuilt_rules'; -import type { GetRuleManagementFiltersResponse } from '../../../../common/api/detection_engine/rule_management'; -import { RULE_MANAGEMENT_FILTERS_URL } from '../../../../common/api/detection_engine/rule_management'; +import type { + CoverageOverviewResponse, + GetRuleManagementFiltersResponse, +} from '../../../../common/api/detection_engine/rule_management'; +import { + RULE_MANAGEMENT_FILTERS_URL, + RULE_MANAGEMENT_COVERAGE_OVERVIEW_URL, +} from '../../../../common/api/detection_engine/rule_management'; import type { BulkActionsDryRunErrCode } from '../../../../common/constants'; import { DETECTION_ENGINE_RULES_BULK_ACTION, @@ -60,6 +66,7 @@ import * as i18n from '../../../detections/pages/detection_engine/rules/translat import type { CreateRulesProps, ExportDocumentsProps, + FetchCoverageOverviewProps, FetchRuleProps, FetchRuleSnoozingProps, FetchRulesProps, @@ -244,6 +251,18 @@ export const fetchConnectors = ( ): Promise>> => KibanaServices.get().http.fetch(`${BASE_ACTION_API_PATH}/connectors`, { method: 'GET', signal }); +export const fetchCoverageOverview = async ({ + filter, + signal, +}: FetchCoverageOverviewProps): Promise => + KibanaServices.get().http.fetch(RULE_MANAGEMENT_COVERAGE_OVERVIEW_URL, { + method: 'POST', + body: JSON.stringify({ + filter, + }), + signal, + }); + export const fetchConnectorTypes = (signal?: AbortSignal): Promise => KibanaServices.get().http.fetch(`${BASE_ACTION_API_PATH}/connector_types`, { method: 'GET', diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_install_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_install_mutation.ts index f5eb06037c75c..13e44682d95e8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_install_mutation.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_install_mutation.ts @@ -14,6 +14,7 @@ import { useInvalidateFetchRuleManagementFiltersQuery } from '../use_fetch_rule_ import { useInvalidateFetchRulesSnoozeSettingsQuery } from '../use_fetch_rules_snooze_settings'; import { useInvalidateFetchPrebuiltRulesInstallReviewQuery } from './use_fetch_prebuilt_rules_install_review_query'; import { performInstallAllRules } from '../../api'; +import { useInvalidateFetchCoverageOverviewQuery } from '../use_fetch_coverage_overview'; export const PERFORM_ALL_RULES_INSTALLATION_KEY = [ 'POST', @@ -30,6 +31,7 @@ export const usePerformAllRulesInstallMutation = ( const invalidateFetchPrebuiltRulesInstallReview = useInvalidateFetchPrebuiltRulesInstallReviewQuery(); const invalidateRuleStatus = useInvalidateFetchPrebuiltRulesStatusQuery(); + const invalidateFetchCoverageOverviewQuery = useInvalidateFetchCoverageOverviewQuery(); return useMutation(() => performInstallAllRules(), { ...options, @@ -41,6 +43,7 @@ export const usePerformAllRulesInstallMutation = ( invalidateFetchPrebuiltRulesInstallReview(); invalidateRuleStatus(); + invalidateFetchCoverageOverviewQuery(); if (options?.onSettled) { options.onSettled(...args); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_upgrade_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_upgrade_mutation.ts index 07555ed65f307..4a4bee4779f7e 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_upgrade_mutation.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_all_rules_upgrade_mutation.ts @@ -14,6 +14,7 @@ import { useInvalidateFetchRulesSnoozeSettingsQuery } from '../use_fetch_rules_s import { useInvalidateFetchPrebuiltRulesUpgradeReviewQuery } from './use_fetch_prebuilt_rules_upgrade_review_query'; import { useInvalidateFetchPrebuiltRulesStatusQuery } from './use_fetch_prebuilt_rules_status_query'; import { performUpgradeAllRules } from '../../api'; +import { useInvalidateFetchCoverageOverviewQuery } from '../use_fetch_coverage_overview'; export const PERFORM_ALL_RULES_UPGRADE_KEY = ['POST', 'ALL_RULES', PERFORM_RULE_UPGRADE_URL]; @@ -26,6 +27,7 @@ export const usePerformAllRulesUpgradeMutation = ( const invalidateFetchPrebuiltRulesUpgradeReview = useInvalidateFetchPrebuiltRulesUpgradeReviewQuery(); const invalidateRuleStatus = useInvalidateFetchPrebuiltRulesStatusQuery(); + const invalidateFetchCoverageOverviewQuery = useInvalidateFetchCoverageOverviewQuery(); return useMutation(() => performUpgradeAllRules(), { ...options, @@ -37,6 +39,7 @@ export const usePerformAllRulesUpgradeMutation = ( invalidateFetchPrebuiltRulesUpgradeReview(); invalidateRuleStatus(); + invalidateFetchCoverageOverviewQuery(); if (options?.onSettled) { options.onSettled(...args); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_specific_rules_install_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_specific_rules_install_mutation.ts index 1867b0c4e3405..9b12d4901e0fb 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_specific_rules_install_mutation.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_specific_rules_install_mutation.ts @@ -17,6 +17,7 @@ import { useInvalidateFetchRuleManagementFiltersQuery } from '../use_fetch_rule_ import { useInvalidateFetchRulesSnoozeSettingsQuery } from '../use_fetch_rules_snooze_settings'; import { useInvalidateFetchPrebuiltRulesInstallReviewQuery } from './use_fetch_prebuilt_rules_install_review_query'; import { performInstallSpecificRules } from '../../api'; +import { useInvalidateFetchCoverageOverviewQuery } from '../use_fetch_coverage_overview'; export const PERFORM_SPECIFIC_RULES_INSTALLATION_KEY = [ 'POST', @@ -38,6 +39,7 @@ export const usePerformSpecificRulesInstallMutation = ( const invalidateFetchPrebuiltRulesInstallReview = useInvalidateFetchPrebuiltRulesInstallReviewQuery(); const invalidateRuleStatus = useInvalidateFetchPrebuiltRulesStatusQuery(); + const invalidateFetchCoverageOverviewQuery = useInvalidateFetchCoverageOverviewQuery(); return useMutation< PerformRuleInstallationResponseBody, @@ -58,6 +60,7 @@ export const usePerformSpecificRulesInstallMutation = ( invalidateFetchPrebuiltRulesInstallReview(); invalidateRuleStatus(); + invalidateFetchCoverageOverviewQuery(); if (options?.onSettled) { options.onSettled(...args); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_specific_rules_upgrade_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_specific_rules_upgrade_mutation.ts index 925009a3ca29a..0c67b349302af 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_specific_rules_upgrade_mutation.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/prebuilt_rules/use_perform_specific_rules_upgrade_mutation.ts @@ -17,6 +17,7 @@ import { useInvalidateFetchRuleManagementFiltersQuery } from '../use_fetch_rule_ import { useInvalidateFetchRulesSnoozeSettingsQuery } from '../use_fetch_rules_snooze_settings'; import { performUpgradeSpecificRules } from '../../api'; import { useInvalidateFetchPrebuiltRulesUpgradeReviewQuery } from './use_fetch_prebuilt_rules_upgrade_review_query'; +import { useInvalidateFetchCoverageOverviewQuery } from '../use_fetch_coverage_overview'; export const PERFORM_SPECIFIC_RULES_UPGRADE_KEY = [ 'POST', @@ -38,6 +39,7 @@ export const usePerformSpecificRulesUpgradeMutation = ( const invalidateFetchPrebuiltRulesUpgradeReview = useInvalidateFetchPrebuiltRulesUpgradeReviewQuery(); const invalidateRuleStatus = useInvalidateFetchPrebuiltRulesStatusQuery(); + const invalidateFetchCoverageOverviewQuery = useInvalidateFetchCoverageOverviewQuery(); return useMutation( (rulesToUpgrade: UpgradeSpecificRulesRequest['rules']) => { @@ -54,6 +56,7 @@ export const usePerformSpecificRulesUpgradeMutation = ( invalidateFetchPrebuiltRulesUpgradeReview(); invalidateRuleStatus(); + invalidateFetchCoverageOverviewQuery(); if (options?.onSettled) { options.onSettled(...args); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_action_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_action_mutation.ts index aa8aec37a8bbe..bade054295965 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_action_mutation.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_bulk_action_mutation.ts @@ -17,6 +17,7 @@ import { useInvalidateFetchRuleManagementFiltersQuery } from './use_fetch_rule_m import { useInvalidateFetchPrebuiltRulesStatusQuery } from './prebuilt_rules/use_fetch_prebuilt_rules_status_query'; import { useInvalidateFetchPrebuiltRulesUpgradeReviewQuery } from './prebuilt_rules/use_fetch_prebuilt_rules_upgrade_review_query'; import { useInvalidateFetchPrebuiltRulesInstallReviewQuery } from './prebuilt_rules/use_fetch_prebuilt_rules_install_review_query'; +import { useInvalidateFetchCoverageOverviewQuery } from './use_fetch_coverage_overview'; export const BULK_ACTION_MUTATION_KEY = ['POST', DETECTION_ENGINE_RULES_BULK_ACTION]; @@ -35,6 +36,7 @@ export const useBulkActionMutation = ( useInvalidateFetchPrebuiltRulesInstallReviewQuery(); const invalidateFetchPrebuiltRulesUpgradeReviewQuery = useInvalidateFetchPrebuiltRulesUpgradeReviewQuery(); + const invalidateFetchCoverageOverviewQuery = useInvalidateFetchCoverageOverviewQuery(); const updateRulesCache = useUpdateRulesCache(); return useMutation< @@ -60,6 +62,7 @@ export const useBulkActionMutation = ( case BulkActionType.enable: case BulkActionType.disable: { invalidateFetchRuleByIdQuery(); + invalidateFetchCoverageOverviewQuery(); if (updatedRules) { // We have a list of updated rules, no need to invalidate all updateRulesCache(updatedRules); @@ -76,10 +79,12 @@ export const useBulkActionMutation = ( invalidateFetchPrebuiltRulesStatusQuery(); invalidateFetchPrebuiltRulesInstallReviewQuery(); invalidateFetchPrebuiltRulesUpgradeReviewQuery(); + invalidateFetchCoverageOverviewQuery(); break; case BulkActionType.duplicate: invalidateFindRulesQuery(); invalidateFetchRuleManagementFilters(); + invalidateFetchCoverageOverviewQuery(); break; case BulkActionType.edit: if (updatedRules) { @@ -91,6 +96,7 @@ export const useBulkActionMutation = ( } invalidateFetchRuleByIdQuery(); invalidateFetchRuleManagementFilters(); + invalidateFetchCoverageOverviewQuery(); break; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_rule_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_rule_mutation.ts index 16effcc78cf8e..199cf558137cf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_rule_mutation.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_create_rule_mutation.ts @@ -15,6 +15,7 @@ import { transformOutput } from '../../../../detections/containers/detection_eng import { createRule } from '../api'; import { useInvalidateFetchRuleManagementFiltersQuery } from './use_fetch_rule_management_filters_query'; import { useInvalidateFindRulesQuery } from './use_find_rules_query'; +import { useInvalidateFetchCoverageOverviewQuery } from './use_fetch_coverage_overview'; export const CREATE_RULE_MUTATION_KEY = ['POST', DETECTION_ENGINE_RULES_URL]; @@ -23,6 +24,7 @@ export const useCreateRuleMutation = ( ) => { const invalidateFindRulesQuery = useInvalidateFindRulesQuery(); const invalidateFetchRuleManagementFilters = useInvalidateFetchRuleManagementFiltersQuery(); + const invalidateFetchCoverageOverviewQuery = useInvalidateFetchCoverageOverviewQuery(); return useMutation( (rule: RuleCreateProps) => createRule({ rule: transformOutput(rule) }), @@ -32,6 +34,7 @@ export const useCreateRuleMutation = ( onSettled: (...args) => { invalidateFindRulesQuery(); invalidateFetchRuleManagementFilters(); + invalidateFetchCoverageOverviewQuery(); if (options?.onSettled) { options.onSettled(...args); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_coverage_overview.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_coverage_overview.ts new file mode 100644 index 0000000000000..2866245bb4e87 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_fetch_coverage_overview.ts @@ -0,0 +1,61 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { UseQueryOptions } from '@tanstack/react-query'; +import { useQuery, useQueryClient } from '@tanstack/react-query'; +import { useCallback } from 'react'; +import type { CoverageOverviewFilter } from '../../../../../common/api/detection_engine'; +import { RULE_MANAGEMENT_COVERAGE_OVERVIEW_URL } from '../../../../../common/api/detection_engine'; +import { fetchCoverageOverview } from '../api'; +import { buildCoverageOverviewDashboardModel } from '../../logic/coverage_overview/build_coverage_overview_dashboard_model'; +import type { CoverageOverviewDashboard } from '../../model/coverage_overview/dashboard'; +import { DEFAULT_QUERY_OPTIONS } from './constants'; + +const COVERAGE_OVERVIEW_QUERY_KEY = ['POST', RULE_MANAGEMENT_COVERAGE_OVERVIEW_URL]; + +/** + * A wrapper around useQuery provides default values to the underlying query, + * like query key, abortion signal, and error handler. + * + * @param filter - coverage overview filter, see CoverageOverviewFilter type + * @param options - react-query options + * @returns useQuery result + */ +export const useFetchCoverageOverviewQuery = ( + filter: CoverageOverviewFilter = {}, + options?: UseQueryOptions +) => { + return useQuery( + [...COVERAGE_OVERVIEW_QUERY_KEY, filter], + async ({ signal }) => { + const response = await fetchCoverageOverview({ signal, filter }); + + return buildCoverageOverviewDashboardModel(response); + }, + { + ...DEFAULT_QUERY_OPTIONS, + ...options, + } + ); +}; + +/** + * We should use this hook to invalidate the coverage overview cache. For example, rule + * mutations that affect rule set size, like creation or deletion, should lead + * to cache invalidation. + * + * @returns A coverage overview cache invalidation callback + */ +export const useInvalidateFetchCoverageOverviewQuery = () => { + const queryClient = useQueryClient(); + + return useCallback(() => { + queryClient.invalidateQueries(COVERAGE_OVERVIEW_QUERY_KEY, { + refetchType: 'active', + }); + }, [queryClient]); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_update_rule_mutation.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_update_rule_mutation.ts index f6167c967bbe6..53103287046be 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_update_rule_mutation.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/api/hooks/use_update_rule_mutation.ts @@ -16,6 +16,7 @@ import { updateRule } from '../api'; import { useInvalidateFindRulesQuery } from './use_find_rules_query'; import { useInvalidateFetchRuleByIdQuery } from './use_fetch_rule_by_id_query'; import { useInvalidateFetchRuleManagementFiltersQuery } from './use_fetch_rule_management_filters_query'; +import { useInvalidateFetchCoverageOverviewQuery } from './use_fetch_coverage_overview'; export const UPDATE_RULE_MUTATION_KEY = ['PUT', DETECTION_ENGINE_RULES_URL]; @@ -25,6 +26,7 @@ export const useUpdateRuleMutation = ( const invalidateFindRulesQuery = useInvalidateFindRulesQuery(); const invalidateFetchRuleManagementFilters = useInvalidateFetchRuleManagementFiltersQuery(); const invalidateFetchRuleByIdQuery = useInvalidateFetchRuleByIdQuery(); + const invalidateFetchCoverageOverviewQuery = useInvalidateFetchCoverageOverviewQuery(); return useMutation( (rule: RuleUpdateProps) => updateRule({ rule: transformOutput(rule) }), @@ -35,6 +37,7 @@ export const useUpdateRuleMutation = ( invalidateFindRulesQuery(); invalidateFetchRuleByIdQuery(); invalidateFetchRuleManagementFilters(); + invalidateFetchCoverageOverviewQuery(); if (options?.onSettled) { options.onSettled(...args); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/coverage_overview/build_coverage_overview_dashboard_model.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/coverage_overview/build_coverage_overview_dashboard_model.ts new file mode 100644 index 0000000000000..8f0275ba8d0c5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/coverage_overview/build_coverage_overview_dashboard_model.ts @@ -0,0 +1,124 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { + CoverageOverviewResponse, + CoverageOverviewRuleAttributes, +} from '../../../../../common/api/detection_engine'; +import { CoverageOverviewRuleActivity } from '../../../../../common/api/detection_engine'; + +import type { CoverageOverviewDashboard } from '../../model/coverage_overview/dashboard'; +import type { CoverageOverviewRule } from '../../model/coverage_overview/rule'; +import { buildCoverageOverviewMitreGraph } from './build_coverage_overview_mitre_graph'; + +const lazyMitreConfiguration = () => { + /** + * The specially formatted comment in the `import` expression causes the corresponding webpack chunk to be named. This aids us in debugging chunk size issues. + * See https://webpack.js.org/api/module-methods/#magic-comments + */ + return import( + /* webpackChunkName: "lazy_mitre_configuration" */ + '../../../../detections/mitre/mitre_tactics_techniques' + ); +}; + +export async function buildCoverageOverviewDashboardModel( + apiResponse: CoverageOverviewResponse +): Promise { + const mitreConfig = await lazyMitreConfiguration(); + const { tactics, technique: techniques, subtechniques } = mitreConfig; + const mitreTactics = buildCoverageOverviewMitreGraph(tactics, techniques, subtechniques); + + for (const tactic of mitreTactics) { + for (const ruleId of apiResponse.coverage[tactic.id] ?? []) { + addRule(tactic, ruleId, apiResponse.rules_data[ruleId]); + } + + for (const technique of tactic.techniques) { + for (const ruleId of apiResponse.coverage[technique.id] ?? []) { + addRule(technique, ruleId, apiResponse.rules_data[ruleId]); + } + + for (const subtechnique of technique.subtechniques) { + for (const ruleId of apiResponse.coverage[subtechnique.id] ?? []) { + addRule(subtechnique, ruleId, apiResponse.rules_data[ruleId]); + } + } + } + } + + return { + mitreTactics, + unmappedRules: buildUnmappedRules(apiResponse), + metrics: calcMetrics(apiResponse.rules_data), + }; +} + +function calcMetrics( + rulesData: Record +): CoverageOverviewDashboard['metrics'] { + const ruleIds = Object.keys(rulesData); + const metrics: CoverageOverviewDashboard['metrics'] = { + totalRulesCount: ruleIds.length, + totalEnabledRulesCount: 0, + }; + + for (const ruleId of Object.keys(rulesData)) { + if (rulesData[ruleId].activity === CoverageOverviewRuleActivity.Enabled) { + metrics.totalEnabledRulesCount++; + } + } + + return metrics; +} + +function buildUnmappedRules( + apiResponse: CoverageOverviewResponse +): CoverageOverviewDashboard['unmappedRules'] { + const unmappedRules: CoverageOverviewDashboard['unmappedRules'] = { + enabledRules: [], + disabledRules: [], + availableRules: [], + }; + + for (const ruleId of apiResponse.unmapped_rule_ids) { + addRule(unmappedRules, ruleId, apiResponse.rules_data[ruleId]); + } + + return unmappedRules; +} + +function addRule( + container: { + enabledRules: CoverageOverviewRule[]; + disabledRules: CoverageOverviewRule[]; + availableRules: CoverageOverviewRule[]; + }, + ruleId: string, + ruleData: CoverageOverviewRuleAttributes +): void { + if (!ruleData) { + return; + } + + if (ruleData.activity === CoverageOverviewRuleActivity.Enabled) { + container.enabledRules.push({ + id: ruleId, + name: ruleData.name, + }); + } else if (ruleData.activity === CoverageOverviewRuleActivity.Disabled) { + container.disabledRules.push({ + id: ruleId, + name: ruleData.name, + }); + } else if (ruleData.activity === CoverageOverviewRuleActivity.Available) { + container.availableRules.push({ + id: ruleId, + name: ruleData.name, + }); + } +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/coverage_overview/build_coverage_overview_mitre_graph.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/coverage_overview/build_coverage_overview_mitre_graph.test.ts new file mode 100644 index 0000000000000..8039da45b80a6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/coverage_overview/build_coverage_overview_mitre_graph.test.ts @@ -0,0 +1,124 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { buildCoverageOverviewMitreGraph } from './build_coverage_overview_mitre_graph'; + +describe('buildCoverageOverviewModel', () => { + it('builds domain model', () => { + const tactics = [ + { + name: 'Tactic 1', + id: 'TA001', + reference: 'https://some-link/TA001', + }, + { + name: 'Tactic 2', + id: 'TA002', + reference: 'https://some-link/TA002', + }, + ]; + const techniques = [ + { + name: 'Technique 1', + id: 'T001', + reference: 'https://some-link/T001', + tactics: ['tactic-1'], + }, + { + name: 'Technique 2', + id: 'T002', + reference: 'https://some-link/T002', + tactics: ['tactic-1', 'tactic-2'], + }, + ]; + const subtechniques = [ + { + name: 'Subtechnique 1', + id: 'T001.001', + reference: 'https://some-link/T001/001', + tactics: ['tactic-1'], + techniqueId: 'T001', + }, + { + name: 'Subtechnique 2', + id: 'T001.002', + reference: 'https://some-link/T001/002', + tactics: ['tactic-1'], + techniqueId: 'T001', + }, + ]; + + const model = buildCoverageOverviewMitreGraph(tactics, techniques, subtechniques); + + expect(model).toEqual([ + { + id: 'TA001', + name: 'Tactic 1', + reference: 'https://some-link/TA001', + techniques: [ + { + id: 'T001', + name: 'Technique 1', + reference: 'https://some-link/T001', + subtechniques: [ + { + id: 'T001.001', + name: 'Subtechnique 1', + reference: 'https://some-link/T001/001', + enabledRules: [], + disabledRules: [], + availableRules: [], + }, + { + id: 'T001.002', + name: 'Subtechnique 2', + reference: 'https://some-link/T001/002', + enabledRules: [], + disabledRules: [], + availableRules: [], + }, + ], + enabledRules: [], + disabledRules: [], + availableRules: [], + }, + { + id: 'T002', + name: 'Technique 2', + reference: 'https://some-link/T002', + subtechniques: [], + enabledRules: [], + disabledRules: [], + availableRules: [], + }, + ], + enabledRules: [], + disabledRules: [], + availableRules: [], + }, + { + id: 'TA002', + name: 'Tactic 2', + reference: 'https://some-link/TA002', + techniques: [ + { + id: 'T002', + name: 'Technique 2', + reference: 'https://some-link/T002', + subtechniques: [], + enabledRules: [], + disabledRules: [], + availableRules: [], + }, + ], + enabledRules: [], + disabledRules: [], + availableRules: [], + }, + ]); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/coverage_overview/build_coverage_overview_mitre_graph.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/coverage_overview/build_coverage_overview_mitre_graph.ts new file mode 100644 index 0000000000000..7a775b3292991 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/coverage_overview/build_coverage_overview_mitre_graph.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 { kebabCase } from 'lodash'; +import type { + MitreTactic, + MitreTechnique, + MitreSubTechnique, +} from '../../../../detections/mitre/types'; +import type { CoverageOverviewMitreSubTechnique } from '../../model/coverage_overview/mitre_subtechnique'; +import type { CoverageOverviewMitreTactic } from '../../model/coverage_overview/mitre_tactic'; +import type { CoverageOverviewMitreTechnique } from '../../model/coverage_overview/mitre_technique'; + +export function buildCoverageOverviewMitreGraph( + tactics: MitreTactic[], + techniques: MitreTechnique[], + subtechniques: MitreSubTechnique[] +): CoverageOverviewMitreTactic[] { + const techniqueToSubtechniquesMap = new Map(); // Map(TechniqueId -> SubTechniqueId[]) + + for (const subtechnique of subtechniques) { + const coverageOverviewMitreSubTechnique = { + id: subtechnique.id, + name: subtechnique.name, + reference: subtechnique.reference, + enabledRules: [], + disabledRules: [], + availableRules: [], + }; + + const techniqueSubtechniques = techniqueToSubtechniquesMap.get(subtechnique.techniqueId); + + if (!techniqueSubtechniques) { + techniqueToSubtechniquesMap.set(subtechnique.techniqueId, [ + coverageOverviewMitreSubTechnique, + ]); + } else { + techniqueSubtechniques.push(coverageOverviewMitreSubTechnique); + } + } + + const tacticToTechniquesMap = new Map(); // Map(kebabCase(tactic name) -> CoverageOverviewMitreTechnique) + + for (const technique of techniques) { + const coverageOverviewMitreTechnique: CoverageOverviewMitreTechnique = { + id: technique.id, + name: technique.name, + reference: technique.reference, + subtechniques: techniqueToSubtechniquesMap.get(technique.id) ?? [], + enabledRules: [], + disabledRules: [], + availableRules: [], + }; + + for (const kebabCaseTacticName of technique.tactics) { + const tacticTechniques = tacticToTechniquesMap.get(kebabCaseTacticName); + + if (!tacticTechniques) { + tacticToTechniquesMap.set(kebabCaseTacticName, [coverageOverviewMitreTechnique]); + } else { + tacticTechniques.push(coverageOverviewMitreTechnique); + } + } + } + + const result: CoverageOverviewMitreTactic[] = []; + + for (const tactic of tactics) { + result.push({ + id: tactic.id, + name: tactic.name, + reference: tactic.reference, + techniques: tacticToTechniquesMap.get(kebabCase(tactic.name)) ?? [], + enabledRules: [], + disabledRules: [], + availableRules: [], + }); + } + + return result; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/types.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/types.ts index ec19ad7e5511d..35441d926402b 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/types.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/logic/types.ts @@ -75,7 +75,10 @@ import { TimestampOverrideFallbackDisabled, } from '../../../../common/api/detection_engine/model/rule_schema'; -import type { PatchRuleRequestBody } from '../../../../common/api/detection_engine/rule_management'; +import type { + CoverageOverviewFilter, + PatchRuleRequestBody, +} from '../../../../common/api/detection_engine/rule_management'; import { FindRulesSortField } from '../../../../common/api/detection_engine/rule_management'; import type { RuleCreateProps, @@ -271,6 +274,11 @@ export interface FetchRuleSnoozingProps { signal?: AbortSignal; } +export interface FetchCoverageOverviewProps { + filter: CoverageOverviewFilter; + signal?: AbortSignal; +} + export interface BasicFetchProps { signal: AbortSignal; } diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/__mocks__/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/__mocks__/index.ts new file mode 100644 index 0000000000000..21a32787aa5db --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/__mocks__/index.ts @@ -0,0 +1,59 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CoverageOverviewDashboard } from '../dashboard'; +import type { CoverageOverviewMitreSubTechnique } from '../mitre_subtechnique'; +import type { CoverageOverviewMitreTactic } from '../mitre_tactic'; +import type { CoverageOverviewMitreTechnique } from '../mitre_technique'; +import type { CoverageOverviewRule } from '../rule'; + +export const getMockCoverageOverviewRule = (): CoverageOverviewRule => ({ + id: 'rule-id', + name: 'test rule', +}); + +const mockCoverageOverviewRules = { + enabledRules: [getMockCoverageOverviewRule()], + disabledRules: [getMockCoverageOverviewRule()], + availableRules: [getMockCoverageOverviewRule()], +}; + +export const getMockCoverageOverviewMitreTactic = (): CoverageOverviewMitreTactic => ({ + id: 'tactic-id', + name: 'test tactic', + reference: 'http://test-link', + techniques: [], + ...mockCoverageOverviewRules, +}); + +export const getMockCoverageOverviewMitreTechnique = (): CoverageOverviewMitreTechnique => ({ + id: 'technique-id', + name: 'test technique', + reference: 'http://test-link', + subtechniques: [], + ...mockCoverageOverviewRules, +}); + +export const getMockCoverageOverviewMitreSubTechnique = (): CoverageOverviewMitreSubTechnique => ({ + id: 'sub-technique-id', + name: 'test sub-technique', + reference: 'http://test-link', + ...mockCoverageOverviewRules, +}); + +export const getMockCoverageOverviewDashboard = (): CoverageOverviewDashboard => ({ + mitreTactics: [getMockCoverageOverviewMitreTactic()], + unmappedRules: { + enabledRules: [], + disabledRules: [], + availableRules: [], + }, + metrics: { + totalRulesCount: 3, + totalEnabledRulesCount: 1, + }, +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_subtechnique.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_subtechnique.ts new file mode 100644 index 0000000000000..622213c7e7a6f --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_subtechnique.ts @@ -0,0 +1,20 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CoverageOverviewRule } from './rule'; + +export interface CoverageOverviewMitreSubTechnique { + id: string; + name: string; + /** + * An url leading to the subtechnique's page + */ + reference: string; + enabledRules: CoverageOverviewRule[]; + disabledRules: CoverageOverviewRule[]; + availableRules: CoverageOverviewRule[]; +} diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_tactic.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_tactic.ts index 4384407e52261..a9dd6ac807d31 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_tactic.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_tactic.ts @@ -9,6 +9,7 @@ import type { CoverageOverviewRule } from './rule'; import type { CoverageOverviewMitreTechnique } from './mitre_technique'; export interface CoverageOverviewMitreTactic { + id: string; name: string; /** * An url leading to the tactic's page diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_technique.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_technique.ts index af4ee49396ea6..35587ca59fdda 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_technique.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management/model/coverage_overview/mitre_technique.ts @@ -5,22 +5,17 @@ * 2.0. */ +import type { CoverageOverviewMitreSubTechnique } from './mitre_subtechnique'; import type { CoverageOverviewRule } from './rule'; export interface CoverageOverviewMitreTechnique { + id: string; name: string; /** * An url leading to the technique's page */ reference: string; - /** - * A number of covered subtechniques (having at least one enabled rule associated with it) - */ - numOfCoveredSubtechniques: number; - /** - * A total number of subtechniques associated with this technique - */ - numOfSubtechniques: number; + subtechniques: CoverageOverviewMitreSubTechnique[]; enabledRules: CoverageOverviewRule[]; disabledRules: CoverageOverviewRule[]; availableRules: CoverageOverviewRule[]; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/constants.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/constants.ts new file mode 100644 index 0000000000000..76322812ecf27 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/constants.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { euiPalettePositive } from '@elastic/eui'; + +export const coverageOverviewPaletteColors = euiPalettePositive(5); + +export const coverageOverviewPanelWidth = 160; + +export const coverageOverviewLegendWidth = 380; + +/** + * Rules count -> color map + * + * A corresponding color is applied if rules count >= a specific threshold + */ +export const coverageOverviewCardColorThresholds = [ + { threshold: 10, color: coverageOverviewPaletteColors[3] }, + { threshold: 7, color: coverageOverviewPaletteColors[2] }, + { threshold: 3, color: coverageOverviewPaletteColors[1] }, + { threshold: 1, color: coverageOverviewPaletteColors[0] }, +]; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/coverage_overview_page.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/coverage_overview_page.test.tsx new file mode 100644 index 0000000000000..794a8ca09d1f5 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/coverage_overview_page.test.tsx @@ -0,0 +1,42 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { render } from '@testing-library/react'; +import React from 'react'; +import { useFetchCoverageOverviewQuery } from '../../../rule_management/api/hooks/use_fetch_coverage_overview'; + +import { getMockCoverageOverviewDashboard } from '../../../rule_management/model/coverage_overview/__mocks__'; +import { TestProviders } from '../../../../common/mock'; +import { CoverageOverviewPage } from './coverage_overview_page'; + +jest.mock('../../../../common/utils/route/spy_routes', () => ({ SpyRoute: () => null })); +jest.mock('../../../rule_management/api/hooks/use_fetch_coverage_overview'); + +(useFetchCoverageOverviewQuery as jest.Mock).mockReturnValue({ + data: getMockCoverageOverviewDashboard(), +}); + +const renderCoverageOverviewDashboard = () => { + return render( + + + + ); +}; + +describe('CoverageOverviewPage', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + test('it renders', () => { + const wrapper = renderCoverageOverviewDashboard(); + + expect(wrapper.getByTestId('coverageOverviewPage')).toBeInTheDocument(); + expect(useFetchCoverageOverviewQuery).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/coverage_overview_page.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/coverage_overview_page.tsx new file mode 100644 index 0000000000000..ae2115d031e50 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/coverage_overview_page.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useCallback, useReducer } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui'; +import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; +import { SpyRoute } from '../../../../common/utils/route/spy_routes'; +import { SecurityPageName } from '../../../../app/types'; +import { HeaderPage } from '../../../../common/components/header_page'; + +import * as i18n from './translations'; +import { useFetchCoverageOverviewQuery } from '../../../rule_management/api/hooks/use_fetch_coverage_overview'; +import { CoverageOverviewTacticPanel } from './tactic_panel'; +import { CoverageOverviewMitreTechniquePanelPopover } from './technique_panel_popover'; +import { CoverageOverviewFiltersPanel } from './filters_panel'; +import { createCoverageOverviewDashboardReducer, initialState } from './reducer'; + +const CoverageOverviewPageComponent = () => { + const { data } = useFetchCoverageOverviewQuery(); + + const [{ showExpandedCells }, dispatch] = useReducer( + createCoverageOverviewDashboardReducer(), + initialState + ); + + const setShowExpandedCells = useCallback( + (value: boolean): void => { + dispatch({ + type: 'setShowExpandedCells', + value, + }); + }, + [dispatch] + ); + + return ( + <> + + + + + + + + {data?.mitreTactics.map((tactic) => ( + + + + + + {tactic.techniques.map((technique, techniqueKey) => ( + + + + ))} + + ))} + + + + ); +}; + +export const CoverageOverviewPage = React.memo(CoverageOverviewPageComponent); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/filters_panel.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/filters_panel.tsx new file mode 100644 index 0000000000000..283f7a77d7036 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/filters_panel.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFilterButton, EuiFilterGroup, EuiFlexGroup, EuiFlexItem, EuiPanel } from '@elastic/eui'; +import React, { memo } from 'react'; +import { CoverageOverviewLegend } from './shared_components/dashboard_legend'; +import * as i18n from './translations'; + +export interface CoverageOverviewFiltersPanelProps { + setShowExpandedCells: (arg: boolean) => void; + showExpandedCells: boolean; +} + +const CoverageOverviewFiltersPanelComponent = ({ + setShowExpandedCells, + showExpandedCells, +}: CoverageOverviewFiltersPanelProps) => { + const handleExpandCellsFilterClick = () => setShowExpandedCells(true); + const handleCollapseCellsFilterClick = () => setShowExpandedCells(false); + + return ( + + + + + + {i18n.COLLAPSE_CELLS_FILTER_BUTTON} + + + {i18n.EXPAND_CELLS_FILTER_BUTTON} + + + + + + + + + ); +}; + +export const CoverageOverviewFiltersPanel = memo(CoverageOverviewFiltersPanelComponent); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.test.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.test.ts new file mode 100644 index 0000000000000..b6d6c48749a10 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.test.ts @@ -0,0 +1,51 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + getMockCoverageOverviewMitreSubTechnique, + getMockCoverageOverviewMitreTactic, + getMockCoverageOverviewMitreTechnique, +} from '../../../rule_management/model/coverage_overview/__mocks__'; +import { getNumOfCoveredSubtechniques, getNumOfCoveredTechniques } from './helpers'; + +describe('helpers', () => { + describe('getCoveredTechniques', () => { + it('returns 0 when no techniques are present', () => { + const payload = getMockCoverageOverviewMitreTactic(); + expect(getNumOfCoveredTechniques(payload)).toEqual(0); + }); + + it('returns number of techniques when present', () => { + const payload = { + ...getMockCoverageOverviewMitreTactic(), + techniques: [ + getMockCoverageOverviewMitreTechnique(), + getMockCoverageOverviewMitreTechnique(), + ], + }; + expect(getNumOfCoveredTechniques(payload)).toEqual(2); + }); + }); + + describe('getCoveredSubtechniques', () => { + it('returns 0 when no subtechniques are present', () => { + const payload = getMockCoverageOverviewMitreTechnique(); + expect(getNumOfCoveredSubtechniques(payload)).toEqual(0); + }); + + it('returns number of subtechniques when present', () => { + const payload = { + ...getMockCoverageOverviewMitreTechnique(), + subtechniques: [ + getMockCoverageOverviewMitreSubTechnique(), + getMockCoverageOverviewMitreSubTechnique(), + ], + }; + expect(getNumOfCoveredSubtechniques(payload)).toEqual(2); + }); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.ts new file mode 100644 index 0000000000000..9611759fad271 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/helpers.ts @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { CoverageOverviewMitreTactic } from '../../../rule_management/model/coverage_overview/mitre_tactic'; +import type { CoverageOverviewMitreTechnique } from '../../../rule_management/model/coverage_overview/mitre_technique'; +import { coverageOverviewCardColorThresholds } from './constants'; + +export const getNumOfCoveredTechniques = (tactic: CoverageOverviewMitreTactic): number => + tactic.techniques.filter((technique) => technique.enabledRules.length !== 0).length; + +export const getNumOfCoveredSubtechniques = (technique: CoverageOverviewMitreTechnique): number => + technique.subtechniques.filter((subtechnique) => subtechnique.enabledRules.length !== 0).length; + +export const getCardBackgroundColor = (value: number) => { + for (const { threshold, color } of coverageOverviewCardColorThresholds) { + if (value >= threshold) { + return color; + } + } +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/index.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/index.ts new file mode 100644 index 0000000000000..324ce06e2d418 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { CoverageOverviewPage } from './coverage_overview_page'; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/index.tsx deleted file mode 100644 index 4d0900fae8ab9..0000000000000 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/index.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import React from 'react'; -import { SecuritySolutionPageWrapper } from '../../../../common/components/page_wrapper'; -import { SpyRoute } from '../../../../common/utils/route/spy_routes'; -import { SecurityPageName } from '../../../../app/types'; -import { HeaderPage } from '../../../../common/components/header_page'; - -import * as i18n from './translations'; - -const CoverageOverviewPageComponent = () => { - return ( - <> - - - - - - - ); -}; - -export const CoverageOverviewPage = React.memo(CoverageOverviewPageComponent); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/reducer.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/reducer.ts new file mode 100644 index 0000000000000..cdafe0aa6b756 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/reducer.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export interface State { + showExpandedCells: boolean; +} + +export const initialState: State = { + showExpandedCells: false, +}; + +export interface Action { + type: 'setShowExpandedCells'; + value: boolean; +} + +export const createCoverageOverviewDashboardReducer = + () => + (state: State, action: Action): State => { + switch (action.type) { + case 'setShowExpandedCells': { + const { value } = action; + return { ...state, showExpandedCells: value }; + } + default: + return state; + } + }; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/shared_components/dashboard_legend.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/shared_components/dashboard_legend.tsx new file mode 100644 index 0000000000000..5a72efc13f1f3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/shared_components/dashboard_legend.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { + EuiFacetButton, + EuiBetaBadge, + EuiPanel, + EuiFlexGroup, + EuiText, + EuiSpacer, +} from '@elastic/eui'; +import React, { useMemo } from 'react'; +import { coverageOverviewCardColorThresholds, coverageOverviewLegendWidth } from '../constants'; +import * as i18n from '../translations'; + +const LegendLabel = ({ label, color }: { label: string; color?: string }) => ( + + } + > + {label} + +); + +export const CoverageOverviewLegend = () => { + const thresholds = useMemo( + () => + coverageOverviewCardColorThresholds.map(({ threshold, color }, index, thresholdsMap) => ( + + )), + [] + ); + + return ( + + + +

{i18n.CoverageOverviewLegendTitle}

+
+ + {i18n.CoverageOverviewLegendSubtitle} + +
+ + + + {thresholds} + + + +
+ ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/shared_components/panel_metadata.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/shared_components/panel_metadata.tsx new file mode 100644 index 0000000000000..06b995c34ba83 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/shared_components/panel_metadata.tsx @@ -0,0 +1,57 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiText, EuiNotificationBadge } from '@elastic/eui'; +import { css, cx } from '@emotion/css'; +import React from 'react'; +import * as i18n from '../translations'; + +export interface CoverageOverviewPanelMetadataProps { + disabledRules: number; + enabledRules: number; +} + +const metadataLabelClass = css` + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +`; + +export const CoverageOverviewPanelMetadata = ({ + disabledRules, + enabledRules, +}: CoverageOverviewPanelMetadataProps) => { + return ( + + + + + {i18n.DISABLED_RULES_METADATA_LABEL} + + + + + {disabledRules} + + + + + + + + {i18n.ENABLED_RULES_METADATA_LABEL} + + + + + {enabledRules} + + + + + ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/shared_components/popover_list_header.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/shared_components/popover_list_header.tsx new file mode 100644 index 0000000000000..3baf97feca2ae --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/shared_components/popover_list_header.tsx @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiText, EuiNotificationBadge } from '@elastic/eui'; +import React from 'react'; + +export const CoverageOverviewRuleListHeader = ({ + listTitle, + listLength, +}: { + listTitle: string; + listLength: number; +}) => { + return ( + + + +

{listTitle}

+
+
+ + + {listLength} + + +
+ ); +}; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/tactic_panel.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/tactic_panel.test.tsx new file mode 100644 index 0000000000000..cddd257c130fa --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/tactic_panel.test.tsx @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { render } from '@testing-library/react'; +import React from 'react'; + +import { getMockCoverageOverviewMitreTactic } from '../../../rule_management/model/coverage_overview/__mocks__'; +import { TestProviders } from '../../../../common/mock'; +import { CoverageOverviewTacticPanel } from './tactic_panel'; +import type { CoverageOverviewMitreTactic } from '../../../rule_management/model/coverage_overview/mitre_tactic'; + +const renderTacticPanel = ( + tactic: CoverageOverviewMitreTactic = getMockCoverageOverviewMitreTactic() +) => { + return render( + + + + ); +}; + +describe('CoverageOverviewTacticPanel', () => { + test('it renders information correctly', () => { + const wrapper = renderTacticPanel(); + + expect(wrapper.getByTestId('coverageOverviewTacticPanel')).toBeInTheDocument(); + expect(wrapper.getByTestId('metadataDisabledRulesCount')).toHaveTextContent('1'); + expect(wrapper.getByTestId('metadataEnabledRulesCount')).toHaveTextContent('1'); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/tactic_panel.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/tactic_panel.tsx new file mode 100644 index 0000000000000..12431fe237617 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/tactic_panel.tsx @@ -0,0 +1,79 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiPanel, EuiProgress, EuiSpacer, EuiText, EuiToolTip } from '@elastic/eui'; +import { css } from '@emotion/css'; +import React, { memo, useMemo } from 'react'; +import { euiThemeVars } from '@kbn/ui-theme'; +import type { CoverageOverviewMitreTactic } from '../../../rule_management/model/coverage_overview/mitre_tactic'; +import { coverageOverviewPanelWidth } from './constants'; +import { getNumOfCoveredTechniques } from './helpers'; +import * as i18n from './translations'; +import { CoverageOverviewPanelMetadata } from './shared_components/panel_metadata'; + +export interface CoverageOverviewTacticPanelProps { + tactic: CoverageOverviewMitreTactic; +} + +const CoverageOverviewTacticPanelComponent = ({ tactic }: CoverageOverviewTacticPanelProps) => { + const coveredTechniques = useMemo(() => getNumOfCoveredTechniques(tactic), [tactic]); + + const ProgressLabel = useMemo( + () => ( + +
{i18n.COVERED_MITRE_TECHNIQUES(coveredTechniques, tactic.techniques.length)}
+
+ ), + [tactic.techniques, coveredTechniques] + ); + + return ( + + + +

{tactic.name}

+
+
+ + + + +
+ ); +}; + +export const CoverageOverviewTacticPanel = memo(CoverageOverviewTacticPanelComponent); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel.test.tsx new file mode 100644 index 0000000000000..38e10e6299b8e --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel.test.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { render } from '@testing-library/react'; +import React from 'react'; + +import { getMockCoverageOverviewMitreTechnique } from '../../../rule_management/model/coverage_overview/__mocks__'; +import { TestProviders } from '../../../../common/mock'; +import { CoverageOverviewMitreTechniquePanel } from './technique_panel'; +import type { CoverageOverviewMitreTechnique } from '../../../rule_management/model/coverage_overview/mitre_technique'; + +const renderTechniquePanel = ( + technique: CoverageOverviewMitreTechnique = getMockCoverageOverviewMitreTechnique(), + isExpanded: boolean = false +) => { + return render( + + {}} + isPopoverOpen={false} + isExpanded={isExpanded} + /> + + ); +}; + +describe('CoverageOverviewMitreTechniquePanel', () => { + test('it renders collapsed view', () => { + const wrapper = renderTechniquePanel(); + + expect(wrapper.getByTestId('coverageOverviewTechniquePanel')).toBeInTheDocument(); + expect(wrapper.queryByTestId('coverageOverviewPanelMetadata')).not.toBeInTheDocument(); + }); + + test('it renders expanded view', () => { + const wrapper = renderTechniquePanel(getMockCoverageOverviewMitreTechnique(), true); + + expect(wrapper.getByTestId('coverageOverviewTechniquePanel')).toBeInTheDocument(); + expect(wrapper.getByTestId('coverageOverviewPanelMetadata')).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel.tsx new file mode 100644 index 0000000000000..d8af376d32bab --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel.tsx @@ -0,0 +1,96 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFlexGroup, EuiFlexItem, EuiPanel, EuiText } from '@elastic/eui'; +import { css } from '@emotion/css'; +import React, { memo, useCallback, useMemo } from 'react'; +import type { CoverageOverviewMitreTechnique } from '../../../rule_management/model/coverage_overview/mitre_technique'; +import { coverageOverviewPanelWidth } from './constants'; +import { getCardBackgroundColor } from './helpers'; +import { CoverageOverviewPanelMetadata } from './shared_components/panel_metadata'; +import * as i18n from './translations'; + +export interface CoverageOverviewMitreTechniquePanelProps { + technique: CoverageOverviewMitreTechnique; + coveredSubtechniques: number; + setIsPopoverOpen: (isOpen: boolean) => void; + isPopoverOpen: boolean; + isExpanded: boolean; +} + +const CoverageOverviewMitreTechniquePanelComponent = ({ + technique, + coveredSubtechniques, + setIsPopoverOpen, + isPopoverOpen, + isExpanded, +}: CoverageOverviewMitreTechniquePanelProps) => { + const techniqueBackgroundColor = useMemo( + () => getCardBackgroundColor(technique.enabledRules.length), + [technique.enabledRules.length] + ); + + const handlePanelOnClick = useCallback( + () => setIsPopoverOpen(!isPopoverOpen), + [isPopoverOpen, setIsPopoverOpen] + ); + + const SubtechniqueInfo = useMemo( + () => ( + + + {i18n.SUBTECHNIQUES} + + + {`${coveredSubtechniques}/${technique.subtechniques.length}`} + + + ), + [technique.subtechniques, coveredSubtechniques] + ); + + return ( + + + + +

{technique.name}

+
+ {SubtechniqueInfo} +
+ {isExpanded && ( + + + + )} +
+
+ ); +}; + +export const CoverageOverviewMitreTechniquePanel = memo( + CoverageOverviewMitreTechniquePanelComponent +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx new file mode 100644 index 0000000000000..dba2b381deb88 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.test.tsx @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { act, fireEvent, render, within } from '@testing-library/react'; +import React from 'react'; + +import { getMockCoverageOverviewMitreTechnique } from '../../../rule_management/model/coverage_overview/__mocks__'; +import { TestProviders } from '../../../../common/mock'; +import type { CoverageOverviewMitreTechnique } from '../../../rule_management/model/coverage_overview/mitre_technique'; +import { CoverageOverviewMitreTechniquePanelPopover } from './technique_panel_popover'; +import { useExecuteBulkAction } from '../../../rule_management/logic/bulk_actions/use_execute_bulk_action'; + +jest.mock('../../../rule_management/logic/bulk_actions/use_execute_bulk_action'); + +const mockExecuteBulkAction = jest.fn(); + +(useExecuteBulkAction as jest.Mock).mockReturnValue({ + executeBulkAction: mockExecuteBulkAction, +}); + +const renderTechniquePanelPopover = ( + technique: CoverageOverviewMitreTechnique = getMockCoverageOverviewMitreTechnique(), + isExpanded: boolean = false +) => { + return render( + + + + ); +}; + +describe('CoverageOverviewMitreTechniquePanelPopover', () => { + test('it renders all rules in correct areas', () => { + const wrapper = renderTechniquePanelPopover(); + + act(() => { + fireEvent.click(wrapper.getByTestId('coverageOverviewTechniquePanel')); + }); + + expect(wrapper.getByTestId('coverageOverviewPopover')).toBeInTheDocument(); + expect( + within(wrapper.getByTestId('coverageOverviewEnabledRulesList')).getByText( + getMockCoverageOverviewMitreTechnique().enabledRules[0].name + ) + ).toBeInTheDocument(); + expect( + within(wrapper.getByTestId('coverageOverviewDisabledRulesList')).getByText( + getMockCoverageOverviewMitreTechnique().disabledRules[0].name + ) + ).toBeInTheDocument(); + }); + + test('calls bulk action enable when "Enable all disabled" button is pressed', async () => { + const wrapper = renderTechniquePanelPopover(); + + act(() => { + fireEvent.click(wrapper.getByTestId('coverageOverviewTechniquePanel')); + }); + await act(async () => { + fireEvent.click(wrapper.getByTestId('enableAllDisabledButton')); + }); + + expect(mockExecuteBulkAction).toHaveBeenCalledWith({ ids: ['rule-id'], type: 'enable' }); + }); + + test('"Enable all disabled" button is disabled when there are no disabled rules', async () => { + const mockTechnique: CoverageOverviewMitreTechnique = { + ...getMockCoverageOverviewMitreTechnique(), + disabledRules: [], + }; + const wrapper = renderTechniquePanelPopover(mockTechnique); + + act(() => { + fireEvent.click(wrapper.getByTestId('coverageOverviewTechniquePanel')); + }); + expect(wrapper.getByTestId('enableAllDisabledButton')).toBeDisabled(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx new file mode 100644 index 0000000000000..2a7ca6f6a22f3 --- /dev/null +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/technique_panel_popover.tsx @@ -0,0 +1,199 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license 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 { EuiListGroupItemProps } from '@elastic/eui'; +import { + EuiButton, + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiListGroup, + EuiPopover, + EuiPopoverFooter, + EuiPopoverTitle, + EuiText, + EuiSpacer, + EuiAccordion, +} from '@elastic/eui'; +import { css, cx } from '@emotion/css'; +import React, { memo, useCallback, useMemo, useState } from 'react'; +import { BulkActionType } from '../../../../../common/api/detection_engine'; +import { useExecuteBulkAction } from '../../../rule_management/logic/bulk_actions/use_execute_bulk_action'; +import type { CoverageOverviewMitreTechnique } from '../../../rule_management/model/coverage_overview/mitre_technique'; +import { getNumOfCoveredSubtechniques } from './helpers'; +import { CoverageOverviewRuleListHeader } from './shared_components/popover_list_header'; +import { CoverageOverviewMitreTechniquePanel } from './technique_panel'; +import * as i18n from './translations'; +import { RuleLink } from '../../components/rules_table/use_columns'; + +export interface CoverageOverviewMitreTechniquePanelPopoverProps { + technique: CoverageOverviewMitreTechnique; + isExpanded: boolean; +} + +const CoverageOverviewMitreTechniquePanelPopoverComponent = ({ + technique, + isExpanded, +}: CoverageOverviewMitreTechniquePanelPopoverProps) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const [isEnableButtonLoading, setIsDisableButtonLoading] = useState(false); + const closePopover = useCallback(() => setIsPopoverOpen(false), []); + const coveredSubtechniques = useMemo(() => getNumOfCoveredSubtechniques(technique), [technique]); + const { executeBulkAction } = useExecuteBulkAction(); + const isEnableButtonDisabled = useMemo( + () => technique.disabledRules.length === 0, + [technique.disabledRules.length] + ); + + const handleEnableAllDisabled = useCallback(async () => { + setIsDisableButtonLoading(true); + const ruleIds = technique.disabledRules.map((rule) => rule.id); + await executeBulkAction({ type: BulkActionType.enable, ids: ruleIds }); + setIsDisableButtonLoading(false); + closePopover(); + }, [closePopover, executeBulkAction, technique.disabledRules]); + + const TechniquePanel = ( + + ); + const CoveredSubtechniquesLabel = useMemo( + () => ( + +

+ {i18n.COVERED_MITRE_SUBTECHNIQUES(coveredSubtechniques, technique.subtechniques.length)} +

+
+ ), + [coveredSubtechniques, technique.subtechniques.length] + ); + + const enabledRuleListItems: EuiListGroupItemProps[] = useMemo( + () => + technique.enabledRules.map((rule) => ({ + label: , + color: 'primary', + })), + [technique.enabledRules] + ); + + const disabledRuleListItems: EuiListGroupItemProps[] = useMemo( + () => + technique.disabledRules.map((rule) => ({ + label: , + color: 'primary', + })), + [technique.disabledRules] + ); + + const EnabledRulesAccordionButton = useMemo( + () => ( + + ), + [technique.enabledRules.length] + ); + + const DisabledRulesAccordionButton = useMemo( + () => ( + + ), + [technique.disabledRules.length] + ); + + return ( + + + + + + +

{technique.name}

+
+
+
+ {CoveredSubtechniquesLabel} +
+
+
+ 0} + buttonContent={EnabledRulesAccordionButton} + > + + + + 0} + buttonContent={DisabledRulesAccordionButton} + > + + + +
+ + + + + {i18n.ENABLE_ALL_DISABLED} + + + + +
+ ); +}; + +export const CoverageOverviewMitreTechniquePanelPopover = memo( + CoverageOverviewMitreTechniquePanelPopoverComponent +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/translations.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/translations.ts index df25731c71cb4..ce4587fb01aea 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/translations.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/coverage_overview/translations.ts @@ -13,3 +13,95 @@ export const COVERAGE_OVERVIEW_DASHBOARD_TITLE = i18n.translate( defaultMessage: 'MITRE ATT&CK\u00AE Coverage', } ); + +export const COLLAPSE_CELLS_FILTER_BUTTON = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.collapseCellsButton', + { + defaultMessage: 'Collapse cells', + } +); + +export const EXPAND_CELLS_FILTER_BUTTON = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.expandCellsButton', + { + defaultMessage: 'Expand cells', + } +); + +export const DISABLED_RULES_METADATA_LABEL = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.disabledRulesMetadataLabel', + { + defaultMessage: 'Disabled Rules:', + } +); + +export const ENABLED_RULES_METADATA_LABEL = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.enabledRulesMetadataLabel', + { + defaultMessage: 'Enabled Rules:', + } +); + +export const SUBTECHNIQUES = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.subtechniques', + { + defaultMessage: 'Sub-techniques', + } +); + +export const ENABLE_ALL_DISABLED = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.enableAllDisabledButtonLabel', + { + defaultMessage: 'Enable all disabled', + } +); + +export const COVERED_MITRE_TECHNIQUES = (enabledTechniques: number, totalTechniques: number) => + i18n.translate('xpack.securitySolution.coverageOverviewDashboard.coveredMitreTechniques', { + values: { enabledTechniques, totalTechniques }, + defaultMessage: '{enabledTechniques}/{totalTechniques} techniques', + }); + +export const COVERED_MITRE_SUBTECHNIQUES = ( + enabledSubtechniques: number, + totalSubtechniques: number +) => + i18n.translate('xpack.securitySolution.coverageOverviewDashboard.coveredMitreSubtechniques', { + values: { enabledSubtechniques, totalSubtechniques }, + defaultMessage: 'Sub-techniques {enabledSubtechniques}/{totalSubtechniques}', + }); + +export const DISABLED_RULES_LIST_LABEL = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.disabledRulesListLabel', + { + defaultMessage: 'Disabled rules', + } +); + +export const ENABLED_RULES_LIST_LABEL = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.enabledRulesListLabel', + { + defaultMessage: 'Enabled rules', + } +); + +export const CoverageOverviewLegendTitle = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.legendTitle', + { + defaultMessage: 'Legend', + } +); + +export const CoverageOverviewLegendSubtitle = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.legendSubtitle', + { + defaultMessage: '(count will include all rules selected)', + } +); + +export const CoverageOverviewLegendRulesLabel = i18n.translate( + 'xpack.securitySolution.coverageOverviewDashboard.legendRulesLabel', + { + defaultMessage: 'rules', + } +); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx index 42de0cb40fd58..2f5a202459f79 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/pages/rule_management/index.tsx @@ -33,6 +33,7 @@ import { importRules } from '../../../rule_management/logic'; import { AllRules } from '../../components/rules_table'; import { RulesTableContextProvider } from '../../components/rules_table/rules_table/rules_table_context'; import { SuperHeader } from './super_header'; +import { useInvalidateFetchCoverageOverviewQuery } from '../../../rule_management/api/hooks/use_fetch_coverage_overview'; const RulesPageComponent: React.FC = () => { const [isImportModalVisible, showImportModal, hideImportModal] = useBoolState(); @@ -40,11 +41,17 @@ const RulesPageComponent: React.FC = () => { const kibanaServices = useKibana().services; const { navigateToApp } = kibanaServices.application; const invalidateFindRulesQuery = useInvalidateFindRulesQuery(); + const invalidateFetchCoverageOverviewQuery = useInvalidateFetchCoverageOverviewQuery(); const invalidateFetchRuleManagementFilters = useInvalidateFetchRuleManagementFiltersQuery(); const invalidateRules = useCallback(() => { invalidateFindRulesQuery(); invalidateFetchRuleManagementFilters(); - }, [invalidateFindRulesQuery, invalidateFetchRuleManagementFilters]); + invalidateFetchCoverageOverviewQuery(); + }, [ + invalidateFindRulesQuery, + invalidateFetchRuleManagementFilters, + invalidateFetchCoverageOverviewQuery, + ]); const [ { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/osquery/osquery_response_action.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/osquery/osquery_response_action.tsx index 955a2f43966f7..f72ca73c607c0 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/osquery/osquery_response_action.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_response_actions/osquery/osquery_response_action.tsx @@ -9,6 +9,8 @@ import React, { useMemo } from 'react'; import { EuiCode, EuiEmptyPrompt } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; import { useIsMounted } from '@kbn/securitysolution-hook-utils'; +import { useUpsellingComponent } from '../../../common/hooks/use_upselling'; +import { AppFeatureKey } from '../../../../common'; import { ResponseActionFormField } from './osquery_response_action_form_field'; import type { ArrayItem } from '../../../shared_imports'; import { useKibana } from '../../../common/lib/kibana'; @@ -29,6 +31,9 @@ export const OsqueryResponseAction = React.memo((props: OsqueryResponseActionPro ); const isMounted = useIsMounted(); + // serverless component that is returned when users do not have Endpoint.Complete tier + const UpsellingComponent = useUpsellingComponent(AppFeatureKey.osqueryAutomatedResponseActions); + if (osquery) { const { disabled, permissionDenied } = osquery.fetchInstallationStatus(); const disabledOsqueryPermission = !( @@ -38,6 +43,10 @@ export const OsqueryResponseAction = React.memo((props: OsqueryResponseActionPro application?.capabilities?.osquery?.readPacks)) ); + if (UpsellingComponent) { + return ; + } + if (permissionDenied || disabledOsqueryPermission) { return ( <> diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx index b928c4403fce0..6fe5693796cbf 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_investigate_in_timeline.tsx @@ -9,7 +9,11 @@ import { useDispatch } from 'react-redux'; import { i18n } from '@kbn/i18n'; import { ALERT_RULE_EXCEPTIONS_LIST, ALERT_RULE_PARAMETERS } from '@kbn/rule-data-utils'; -import type { ExceptionListId } from '@kbn/securitysolution-io-ts-list-types'; +import type { + ExceptionListId, + ExceptionListIdentifiers, +} from '@kbn/securitysolution-io-ts-list-types'; +import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types'; import { useApi } from '@kbn/securitysolution-list-hooks'; import type { Filter } from '@kbn/es-query'; @@ -35,6 +39,56 @@ interface UseInvestigateInTimelineActionProps { onInvestigateInTimelineAlertClick?: () => void; } +const detectionExceptionList = (ecsData: Ecs): ExceptionListId[] => { + let exceptionsList = getField(ecsData, ALERT_RULE_EXCEPTIONS_LIST) ?? []; + let detectionExceptionsList: ExceptionListId[] = []; + try { + if (Array.isArray(exceptionsList) && exceptionsList.length === 0) { + const ruleParameters = getField(ecsData, ALERT_RULE_PARAMETERS) ?? {}; + if (ruleParameters.length > 0) { + const parametersObject = JSON.parse(ruleParameters[0]); + exceptionsList = parametersObject?.exceptions_list ?? []; + } + } else if (exceptionsList && exceptionsList.list_id) { + return exceptionsList.list_id + .map((listId: string, index: number) => { + const type = exceptionsList.type[index]; + return { + exception_list_id: listId, + namespace_type: exceptionsList.namespace_type[index], + type, + }; + }) + .filter( + (exception: ExceptionListIdentifiers) => + exception.type === ExceptionListTypeEnum.DETECTION + ); + } + } catch (error) { + // do nothing, just fail silently as parametersObject is initialized + } + detectionExceptionsList = exceptionsList.reduce( + (acc: ExceptionListId[], next: string | object) => { + // parsed rule.parameters returns an object else use the default string representation + try { + const parsedList = typeof next === 'string' ? JSON.parse(next) : next; + if (parsedList.type === ExceptionListTypeEnum.DETECTION) { + const formattedList = { + exception_list_id: parsedList.list_id, + namespace_type: parsedList.namespace_type, + }; + acc.push(formattedList); + } + // eslint-disable-next-line no-empty + } catch {} + + return acc; + }, + [] + ); + return detectionExceptionsList; +}; + export const useInvestigateInTimeline = ({ ecsRowData, onInvestigateInTimelineAlertClick, @@ -51,39 +105,8 @@ export const useInvestigateInTimeline = ({ const getExceptionFilter = useCallback( async (ecsData: Ecs): Promise => { - // This pulls exceptions list information from `_source` - // This primarily matters for the old `signal` alerts a user may be viewing - // as new exception lists are pulled from kibana.alert.rule.parameters[0].exception_lists; - // Source was removed in favour of the fields api which passes the exceptions_list via `kibana.alert.rule.parameters` - let exceptionsList = getField(ecsData, ALERT_RULE_EXCEPTIONS_LIST) ?? []; - - if (exceptionsList.length === 0) { - try { - const ruleParameters = getField(ecsData, ALERT_RULE_PARAMETERS) ?? {}; - if (ruleParameters.length > 0) { - const parametersObject = JSON.parse(ruleParameters[0]); - exceptionsList = parametersObject?.exceptions_list ?? []; - } - } catch (error) { - // do nothing, just fail silently as parametersObject is initialized - } - } - const detectionExceptionsLists = exceptionsList.reduce( - (acc: ExceptionListId[], next: string | object) => { - // parsed rule.parameters returns an object else use the default string representation - const parsedList = typeof next === 'string' ? JSON.parse(next) : next; - if (parsedList.type === 'detection') { - const formattedList = { - exception_list_id: parsedList.list_id, - namespace_type: parsedList.namespace_type, - }; - acc.push(formattedList); - } - return acc; - }, - [] - ); - + // This pulls exceptions list information from `_source` for timeline or the fields api for alerts. + const detectionExceptionsLists = detectionExceptionList(ecsData); let exceptionFilter; if (detectionExceptionsLists.length > 0) { await getExceptionFilterFromIds({ diff --git a/x-pack/plugins/security_solution/public/detections/mitre/types.ts b/x-pack/plugins/security_solution/public/detections/mitre/types.ts index 031b42e097ac2..4f6de5ad1f6fb 100644 --- a/x-pack/plugins/security_solution/public/detections/mitre/types.ts +++ b/x-pack/plugins/security_solution/public/detections/mitre/types.ts @@ -24,3 +24,24 @@ export interface MitreTechniquesOptions extends MitreOptions { export interface MitreSubtechniquesOptions extends MitreTechniquesOptions { techniqueId: string; } + +export interface MitreTactic { + id: string; + name: string; + reference: string; // A link to the tactic's page +} + +export interface MitreTechnique { + id: string; + name: string; + reference: string; // A link to the technique's page + tactics: string[]; // Tactics this technique assigned to (lowercase dash separated) +} + +export interface MitreSubTechnique { + id: string; + name: string; + reference: string; // A link to the subtechnique's page + tactics: string[]; // Tactics this technique assigned to (lowercase dash separated) + techniqueId: string; // A technique id this subtechnique assigned to +} diff --git a/x-pack/plugins/security_solution/public/flyout/left/components/response_details.tsx b/x-pack/plugins/security_solution/public/flyout/left/components/response_details.tsx index 0fed098e0d1ee..e3c7b6b9de3e8 100644 --- a/x-pack/plugins/security_solution/public/flyout/left/components/response_details.tsx +++ b/x-pack/plugins/security_solution/public/flyout/left/components/response_details.tsx @@ -20,8 +20,6 @@ import { useOsqueryTab } from '../../../common/components/event_details/osquery_ import { useResponseActionsView } from '../../../common/components/event_details/response_actions_view'; import * as i18n from './translations'; -export const RESPONSE_TAB_ID = 'response-details'; - const ExtendedFlyoutWrapper = styled.div` figure { background-color: white diff --git a/x-pack/plugins/security_solution/public/flyout/left/index.tsx b/x-pack/plugins/security_solution/public/flyout/left/index.tsx index fbba35ae43b57..c8a3a73b5b84d 100644 --- a/x-pack/plugins/security_solution/public/flyout/left/index.tsx +++ b/x-pack/plugins/security_solution/public/flyout/left/index.tsx @@ -17,12 +17,13 @@ import type { LeftPanelTabsType } from './tabs'; import { tabs } from './tabs'; import { useLeftPanelContext } from './context'; -export type LeftPanelPaths = 'visualize' | 'insights' | 'investigation'; +export type LeftPanelPaths = 'visualize' | 'insights' | 'investigation' | 'response'; export const LeftPanelKey: LeftPanelProps['key'] = 'document-details-left'; export const LeftPanelVisualizeTabPath: LeftPanelProps['path'] = ['visualize']; export const LeftPanelInsightsTabPath: LeftPanelProps['path'] = ['insights']; export const LeftPanelInvestigationTabPath: LeftPanelProps['path'] = ['investigation']; +export const LeftPanelResponseTabPath: LeftPanelProps['path'] = ['response']; export interface LeftPanelProps extends FlyoutPanelProps { key: 'document-details-left'; diff --git a/x-pack/plugins/security_solution/public/flyout/left/tabs.tsx b/x-pack/plugins/security_solution/public/flyout/left/tabs.tsx index 6e3386e334036..a7c557bbc7def 100644 --- a/x-pack/plugins/security_solution/public/flyout/left/tabs.tsx +++ b/x-pack/plugins/security_solution/public/flyout/left/tabs.tsx @@ -8,10 +8,16 @@ import React from 'react'; import { VisualizeTab } from './tabs/visualize_tab'; import { InvestigationTab } from './tabs/investigation_tab'; -import { INSIGHTS_TAB, INVESTIGATIONS_TAB, VISUALIZE_TAB } from './translations'; +import { INSIGHTS_TAB, INVESTIGATIONS_TAB, RESPONSE_TAB, VISUALIZE_TAB } from './translations'; import { InsightsTab } from './tabs/insights_tab'; import type { LeftPanelPaths } from '.'; -import { INSIGHTS_TAB_TEST_ID, INVESTIGATION_TAB_TEST_ID, VISUALIZE_TAB_TEST_ID } from './test_ids'; +import { + INSIGHTS_TAB_TEST_ID, + INVESTIGATION_TAB_TEST_ID, + RESPONSE_TAB_TEST_ID, + VISUALIZE_TAB_TEST_ID, +} from './test_ids'; +import { ResponseTab } from './tabs/response_tab'; export type LeftPanelTabsType = Array<{ id: LeftPanelPaths; @@ -39,4 +45,10 @@ export const tabs: LeftPanelTabsType = [ name: INVESTIGATIONS_TAB, content: , }, + { + id: 'response', + 'data-test-subj': RESPONSE_TAB_TEST_ID, + name: RESPONSE_TAB, + content: , + }, ]; diff --git a/x-pack/plugins/security_solution/public/flyout/left/tabs/insights_tab.tsx b/x-pack/plugins/security_solution/public/flyout/left/tabs/insights_tab.tsx index 75c6a04f94cc3..3db07a1d455a2 100644 --- a/x-pack/plugins/security_solution/public/flyout/left/tabs/insights_tab.tsx +++ b/x-pack/plugins/security_solution/public/flyout/left/tabs/insights_tab.tsx @@ -9,14 +9,12 @@ import React, { memo, useCallback, useState } from 'react'; import { EuiButtonGroup, EuiSpacer } from '@elastic/eui'; import type { EuiButtonGroupOptionProps } from '@elastic/eui/src/components/button/button_group/button_group'; -import { RESPONSE_TAB_ID, ResponseDetails } from '../components/response_details'; import { INSIGHTS_TAB_BUTTON_GROUP_TEST_ID, INSIGHTS_TAB_ENTITIES_BUTTON_TEST_ID, INSIGHTS_TAB_THREAT_INTELLIGENCE_BUTTON_TEST_ID, INSIGHTS_TAB_PREVALENCE_BUTTON_TEST_ID, INSIGHTS_TAB_CORRELATIONS_BUTTON_TEST_ID, - INSIGHTS_TAB_RESPONSE_BUTTON_TEST_ID, } from './test_ids'; import { @@ -25,7 +23,6 @@ import { THREAT_INTELLIGENCE_BUTTON, PREVALENCE_BUTTON, CORRELATIONS_BUTTON, - RESPONSE_BUTTON, } from './translations'; import { ENTITIES_TAB_ID, EntitiesDetails } from '../components/entities_details'; import { @@ -56,11 +53,6 @@ const insightsButtons: EuiButtonGroupOptionProps[] = [ label: CORRELATIONS_BUTTON, 'data-test-subj': INSIGHTS_TAB_CORRELATIONS_BUTTON_TEST_ID, }, - { - id: RESPONSE_TAB_ID, - label: RESPONSE_BUTTON, - 'data-test-subj': INSIGHTS_TAB_RESPONSE_BUTTON_TEST_ID, - }, ]; /** @@ -91,7 +83,6 @@ export const InsightsTab: React.FC = memo(() => { {activeInsightsId === THREAT_INTELLIGENCE_TAB_ID && } {activeInsightsId === PREVALENCE_TAB_ID && } {activeInsightsId === CORRELATIONS_TAB_ID && } - {activeInsightsId === RESPONSE_TAB_ID && } ); }); diff --git a/x-pack/plugins/security_solution/public/flyout/left/tabs/response_tab.tsx b/x-pack/plugins/security_solution/public/flyout/left/tabs/response_tab.tsx new file mode 100644 index 0000000000000..ddfe0a7f806a0 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/left/tabs/response_tab.tsx @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { memo } from 'react'; + +import { EuiPanel } from '@elastic/eui'; +import { ResponseDetails } from '../components/response_details'; +import { RESPONSE_TAB_CONTENT_TEST_ID } from './test_ids'; + +/** + * Response view displayed in the document details expandable flyout left section + */ +export const ResponseTab: React.FC = memo(() => { + return ( + + + + ); +}); + +ResponseTab.displayName = 'ResponseTab'; diff --git a/x-pack/plugins/security_solution/public/flyout/left/tabs/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/left/tabs/test_ids.ts index dc11772253374..7c0e3ca332e8b 100644 --- a/x-pack/plugins/security_solution/public/flyout/left/tabs/test_ids.ts +++ b/x-pack/plugins/security_solution/public/flyout/left/tabs/test_ids.ts @@ -21,7 +21,7 @@ export const INSIGHTS_TAB_PREVALENCE_BUTTON_TEST_ID = 'securitySolutionDocumentDetailsFlyoutInsightsTabPrevalenceButton'; export const INSIGHTS_TAB_CORRELATIONS_BUTTON_TEST_ID = 'securitySolutionDocumentDetailsFlyoutInsightsTabCorrelationsButton'; -export const INSIGHTS_TAB_RESPONSE_BUTTON_TEST_ID = - 'securitySolutionDocumentDetailsFlyoutInsightsTabResponseButton'; export const INVESTIGATION_TAB_CONTENT_TEST_ID = 'securitySolutionDocumentDetailsFlyoutInvestigationsTabContent'; +export const RESPONSE_TAB_CONTENT_TEST_ID = + 'securitySolutionDocumentDetailsFlyoutResponseTabContent'; diff --git a/x-pack/plugins/security_solution/public/flyout/left/tabs/translations.ts b/x-pack/plugins/security_solution/public/flyout/left/tabs/translations.ts index f91152661f25e..d77cd21e733d1 100644 --- a/x-pack/plugins/security_solution/public/flyout/left/tabs/translations.ts +++ b/x-pack/plugins/security_solution/public/flyout/left/tabs/translations.ts @@ -62,10 +62,3 @@ export const CORRELATIONS_BUTTON = i18n.translate( defaultMessage: 'Correlations', } ); - -export const RESPONSE_BUTTON = i18n.translate( - 'xpack.securitySolution.flyout.documentDetails.responseButton', - { - defaultMessage: 'Response', - } -); diff --git a/x-pack/plugins/security_solution/public/flyout/left/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/left/test_ids.ts index b1bed3dbb04a9..65d70f7d674d5 100644 --- a/x-pack/plugins/security_solution/public/flyout/left/test_ids.ts +++ b/x-pack/plugins/security_solution/public/flyout/left/test_ids.ts @@ -8,3 +8,4 @@ export const VISUALIZE_TAB_TEST_ID = 'securitySolutionDocumentDetailsFlyoutVisualizeTab'; export const INSIGHTS_TAB_TEST_ID = 'securitySolutionDocumentDetailsFlyoutInsightsTab'; export const INVESTIGATION_TAB_TEST_ID = 'securitySolutionDocumentDetailsFlyoutInvestigationTab'; +export const RESPONSE_TAB_TEST_ID = 'securitySolutionDocumentDetailsFlyoutResponseTab'; diff --git a/x-pack/plugins/security_solution/public/flyout/left/translations.ts b/x-pack/plugins/security_solution/public/flyout/left/translations.ts index b07d5552b0ddd..c2dc888ab9aef 100644 --- a/x-pack/plugins/security_solution/public/flyout/left/translations.ts +++ b/x-pack/plugins/security_solution/public/flyout/left/translations.ts @@ -27,3 +27,10 @@ export const INVESTIGATIONS_TAB = i18n.translate( defaultMessage: 'Investigation', } ); + +export const RESPONSE_TAB = i18n.translate( + 'xpack.securitySolution.flyout.documentDetails.responseTab', + { + defaultMessage: 'Response', + } +); diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide_button.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide_button.test.tsx index 44d435adf4e62..faf5ac6fe8e09 100644 --- a/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide_button.test.tsx +++ b/x-pack/plugins/security_solution/public/flyout/right/components/investigation_guide_button.test.tsx @@ -19,7 +19,7 @@ const mockUseRuleWithFallback = useRuleWithFallback as jest.Mock; jest.mock('../../../detection_engine/rule_management/logic/use_rule_with_fallback'); describe('', () => { - it('should render investigation guide button corerctly', () => { + it('should render investigation guide button correctly', () => { mockUseRuleWithFallback.mockReturnValue({ rule: { note: 'test note' } }); const { getByTestId } = render( diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/response_button.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/response_button.test.tsx new file mode 100644 index 0000000000000..3cbed8191f342 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/components/response_button.test.tsx @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render } from '@testing-library/react'; +import { RightPanelContext } from '../context'; +import { RESPONSE_BUTTON_TEST_ID, RESPONSE_EMPTY_TEST_ID } from './test_ids'; +import { mockContextValue } from '../mocks/mock_right_panel_context'; +import { mockFlyoutContextValue } from '../../shared/mocks/mock_flyout_context'; +import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context'; +import { ResponseButton } from './response_button'; +import type { SearchHit } from '../../../../common/search_strategy'; + +const mockValidSearchHit = { + fields: { + 'kibana.alert.rule.parameters': [ + { + response_actions: [ + { + action_type_id: 'action_type_id', + params: {}, + }, + ], + }, + ], + }, +} as unknown as SearchHit; + +const mockInvalidSearchHit = { + fields: {}, +} as unknown as SearchHit; + +describe('', () => { + it('should render response button correctly', () => { + const { getByTestId } = render( + + + + + + ); + expect(getByTestId(RESPONSE_BUTTON_TEST_ID)).toBeInTheDocument(); + }); + + it('should not render response button when searchHit is undefined', () => { + const { getByTestId } = render( + + + + + + ); + + expect(getByTestId(RESPONSE_EMPTY_TEST_ID)).toBeInTheDocument(); + }); + + it(`should not render investigation guide button when searchHit doesn't have correct data`, () => { + const { getByTestId } = render( + + + + + + ); + expect(getByTestId(RESPONSE_EMPTY_TEST_ID)).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/response_button.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/response_button.tsx new file mode 100644 index 0000000000000..df1196358dfa9 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/components/response_button.tsx @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useCallback } from 'react'; +import { EuiButton } from '@elastic/eui'; +import { useExpandableFlyoutContext } from '@kbn/expandable-flyout'; +import { expandDottedObject } from '../../../../common/utils/expand_dotted'; +import type { + ExpandedEventFieldsObject, + RawEventData, +} from '../../../../common/types/response_actions'; +import { useRightPanelContext } from '../context'; +import { LeftPanelKey, LeftPanelResponseTabPath } from '../../left'; +import { RESPONSE_BUTTON_TEST_ID, RESPONSE_EMPTY_TEST_ID } from './test_ids'; +import { RESPONSE_EMPTY, RESPONSE_TITLE } from './translations'; + +/** + * Response button that opens Response section in the left panel + */ +export const ResponseButton: React.FC = () => { + const { openLeftPanel } = useExpandableFlyoutContext(); + const { eventId, indexName, scopeId, searchHit } = useRightPanelContext(); + + const expandedEventFieldsObject = searchHit + ? (expandDottedObject((searchHit as RawEventData).fields) as ExpandedEventFieldsObject) + : undefined; + const responseActions = + expandedEventFieldsObject?.kibana?.alert?.rule?.parameters?.[0].response_actions; + + const goToResponseTab = useCallback(() => { + openLeftPanel({ + id: LeftPanelKey, + path: LeftPanelResponseTabPath, + params: { + id: eventId, + indexName, + scopeId, + }, + }); + }, [eventId, indexName, openLeftPanel, scopeId]); + + if (!responseActions) return
{RESPONSE_EMPTY}
; + + return ( + + {RESPONSE_TITLE} + + ); +}; + +ResponseButton.displayName = 'ResponseButton'; diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/response_section.test.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/response_section.test.tsx new file mode 100644 index 0000000000000..d15ad34790ea6 --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/components/response_section.test.tsx @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { render } from '@testing-library/react'; +import { RESPONSE_SECTION_CONTENT_TEST_ID, RESPONSE_SECTION_HEADER_TEST_ID } from './test_ids'; +import { RightPanelContext } from '../context'; +import { ExpandableFlyoutContext } from '@kbn/expandable-flyout/src/context'; +import { ResponseSection } from './response_section'; + +const flyoutContextValue = {} as unknown as ExpandableFlyoutContext; +const panelContextValue = {} as unknown as RightPanelContext; + +describe('', () => { + it('should render the component collapsed', () => { + const { getByTestId } = render( + + + + + + ); + + expect(getByTestId(RESPONSE_SECTION_HEADER_TEST_ID)).toBeInTheDocument(); + }); + + it('should render the component expanded', () => { + const { getByTestId } = render( + + + + + + ); + + expect(getByTestId(RESPONSE_SECTION_HEADER_TEST_ID)).toBeInTheDocument(); + expect(getByTestId(RESPONSE_SECTION_CONTENT_TEST_ID)).toBeInTheDocument(); + }); + + it('should expand the component when clicking on the arrow on header', () => { + const { getByTestId } = render( + + + + + + ); + + getByTestId(RESPONSE_SECTION_HEADER_TEST_ID).click(); + expect(getByTestId(RESPONSE_SECTION_CONTENT_TEST_ID)).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/response_section.tsx b/x-pack/plugins/security_solution/public/flyout/right/components/response_section.tsx new file mode 100644 index 0000000000000..18480dde09dde --- /dev/null +++ b/x-pack/plugins/security_solution/public/flyout/right/components/response_section.tsx @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { VFC } from 'react'; +import React from 'react'; +import { ResponseButton } from './response_button'; +import { ExpandableSection } from './expandable_section'; +import { RESPONSE_SECTION_TEST_ID } from './test_ids'; +import { RESPONSE_TITLE } from './translations'; +export interface ResponseSectionProps { + /** + * Boolean to allow the component to be expanded or collapsed on first render + */ + expanded?: boolean; +} + +/** + * Most bottom section of the overview tab. It contains a summary of the response tab. + */ +export const ResponseSection: VFC = ({ expanded = false }) => { + return ( + + + + ); +}; + +ResponseSection.displayName = 'ResponseSection'; diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/test_ids.ts b/x-pack/plugins/security_solution/public/flyout/right/components/test_ids.ts index b0cd575b7a1c5..3224619575a07 100644 --- a/x-pack/plugins/security_solution/public/flyout/right/components/test_ids.ts +++ b/x-pack/plugins/security_solution/public/flyout/right/components/test_ids.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { RESPONSE_BASE_TEST_ID } from '../../left/components/test_ids'; import { CONTENT_TEST_ID, HEADER_TEST_ID } from './expandable_section'; /* Header */ @@ -142,3 +143,11 @@ export const ANALYZER_TREE_ERROR_TEST_ID = 'securitySolutionDocumentDetailsAnala export const SESSION_PREVIEW_TEST_ID = 'securitySolutionDocumentDetailsSessionPreview'; export const SESSION_PREVIEW_VIEW_DETAILS_BUTTON_TEST_ID = 'securitySolutionDocumentDetailsSessionPreviewViewDetailsButton'; + +/* Response section */ + +export const RESPONSE_SECTION_TEST_ID = 'securitySolutionDocumentDetailsFlyoutResponseSection'; +export const RESPONSE_SECTION_HEADER_TEST_ID = RESPONSE_SECTION_TEST_ID + HEADER_TEST_ID; +export const RESPONSE_SECTION_CONTENT_TEST_ID = RESPONSE_SECTION_TEST_ID + CONTENT_TEST_ID; +export const RESPONSE_BUTTON_TEST_ID = 'securitySolutionDocumentDetailsFlyoutResponseButton'; +export const RESPONSE_EMPTY_TEST_ID = `${RESPONSE_BASE_TEST_ID}Empty` as const; diff --git a/x-pack/plugins/security_solution/public/flyout/right/components/translations.ts b/x-pack/plugins/security_solution/public/flyout/right/components/translations.ts index 46b5ebe95b1a1..daa6eaf4787ca 100644 --- a/x-pack/plugins/security_solution/public/flyout/right/components/translations.ts +++ b/x-pack/plugins/security_solution/public/flyout/right/components/translations.ts @@ -341,3 +341,21 @@ export const SESSION_PREVIEW_COMMAND_TEXT = i18n.translate( defaultMessage: 'by', } ); + +export const RESPONSE_TITLE = i18n.translate( + 'xpack.securitySolution.flyout.documentDetails.responseSectionTitle', + { + defaultMessage: 'Response', + } +); + +export const RESPONSE_BUTTON = i18n.translate( + 'xpack.securitySolution.flyout.documentDetails.responseSectionButton', + { + defaultMessage: 'Response details', + } +); + +export const RESPONSE_EMPTY = i18n.translate('xpack.securitySolution.flyout.response.empty', { + defaultMessage: 'There are no response actions defined for this event.', +}); diff --git a/x-pack/plugins/security_solution/public/flyout/right/tabs/overview_tab.tsx b/x-pack/plugins/security_solution/public/flyout/right/tabs/overview_tab.tsx index 852b3fa5942c0..5a59c56a2394d 100644 --- a/x-pack/plugins/security_solution/public/flyout/right/tabs/overview_tab.tsx +++ b/x-pack/plugins/security_solution/public/flyout/right/tabs/overview_tab.tsx @@ -8,6 +8,7 @@ import type { FC } from 'react'; import React, { memo } from 'react'; import { EuiHorizontalRule } from '@elastic/eui'; +import { ResponseSection } from '../components/response_section'; import { InvestigationSection } from '../components/investigation_section'; import { AboutSection } from '../components/about_section'; import { InsightsSection } from '../components/insights_section'; @@ -26,6 +27,8 @@ export const OverviewTab: FC = memo(() => { + + ); }); diff --git a/x-pack/plugins/security_solution/server/lib/app_features/security_kibana_features.ts b/x-pack/plugins/security_solution/server/lib/app_features/security_kibana_features.ts index ad4c412ba06eb..549ee7e7f9fdd 100644 --- a/x-pack/plugins/security_solution/server/lib/app_features/security_kibana_features.ts +++ b/x-pack/plugins/security_solution/server/lib/app_features/security_kibana_features.ts @@ -227,5 +227,7 @@ export const getSecurityAppFeaturesConfig = ( }, ], }, + + [AppFeatureSecurityKey.osqueryAutomatedResponseActions]: {}, }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts index e89d53629f5e2..38396fd936737 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/threshold.ts @@ -38,6 +38,7 @@ import { import { withSecuritySpan } from '../../../../utils/with_security_span'; import { buildThresholdSignalHistory } from './build_signal_history'; import type { IRuleExecutionLogForExecutors } from '../../rule_monitoring'; +import { getSignalHistory } from './utils'; export const thresholdExecutor = async ({ inputIndex, @@ -98,22 +99,10 @@ export const thresholdExecutor = async ({ ruleDataReader, }); - if (state.initialized) { - // Clean up any signal history that has fallen outside the window - const toDelete: string[] = []; - for (const [hash, entry] of Object.entries(signalHistory)) { - if (entry.lastSignalTimestamp < tuple.from.valueOf()) { - toDelete.push(hash); - } - } - for (const hash of toDelete) { - delete signalHistory[hash]; - } - } - + const validSignalHistory = getSignalHistory(state, signalHistory, tuple); // Eliminate dupes const bucketFilters = await getThresholdBucketFilters({ - signalHistory, + signalHistory: validSignalHistory, aggregatableTimestampField, }); @@ -157,7 +146,7 @@ export const thresholdExecutor = async ({ signalsIndex: ruleParams.outputIndex, startedAt, from: tuple.from.toDate(), - signalHistory, + signalHistory: validSignalHistory, bulkCreate, wrapHits, ruleExecutionLogger, @@ -191,7 +180,7 @@ export const thresholdExecutor = async ({ ...state, initialized: true, signalHistory: { - ...signalHistory, + ...validSignalHistory, ...newSignalHistory, }, }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/utils.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/utils.test.ts index 0022e88217f8b..0323f3263a92a 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/utils.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/utils.test.ts @@ -5,18 +5,65 @@ * 2.0. */ -import { calculateThresholdSignalUuid } from './utils'; +import dateMath from '@kbn/datemath'; -describe('calculateThresholdSignalUuid', () => { - it('should generate a uuid without key', () => { - const startedAt = new Date('2020-12-17T16:27:00Z'); - const signalUuid = calculateThresholdSignalUuid('abcd', startedAt, ['agent.name']); - expect(signalUuid).toEqual('a4832768-a379-583a-b1a2-e2ce2ad9e6e9'); - }); +import { getThresholdRuleParams } from '../../rule_schema/mocks'; +import { calculateThresholdSignalUuid, getSignalHistory, getThresholdTermsHash } from './utils'; + +describe('threshold utils', () => { + describe('calcualteThresholdSignalUuid', () => { + it('should generate a uuid without key', () => { + const startedAt = new Date('2020-12-17T16:27:00Z'); + const signalUuid = calculateThresholdSignalUuid('abcd', startedAt, ['agent.name']); + expect(signalUuid).toEqual('a4832768-a379-583a-b1a2-e2ce2ad9e6e9'); + }); - it('should generate a uuid with key', () => { - const startedAt = new Date('2019-11-18T13:32:00Z'); - const signalUuid = calculateThresholdSignalUuid('abcd', startedAt, ['host.ip'], '1.2.3.4'); - expect(signalUuid).toEqual('ee8870dc-45ff-5e6c-a2f9-80886651ce03'); + it('should generate a uuid with key', () => { + const startedAt = new Date('2019-11-18T13:32:00Z'); + const signalUuid = calculateThresholdSignalUuid('abcd', startedAt, ['host.ip'], '1.2.3.4'); + expect(signalUuid).toEqual('ee8870dc-45ff-5e6c-a2f9-80886651ce03'); + }); + }); + describe('getSignalHistory', () => { + const params = getThresholdRuleParams(); + const tuple = { + from: dateMath.parse(params.from)!, + to: dateMath.parse(params.to)!, + maxSignals: params.maxSignals, + }; + it('should return terms which do not fall outside of the search interval tuple', () => { + const terms1 = [ + { + field: 'host.name', + value: 'elastic-pc-1', + }, + ]; + const signalHistoryRecord1 = { + terms: terms1, + lastSignalTimestamp: tuple.from.valueOf() - 60 * 1000, + }; + const terms2 = [ + { + field: 'host.name', + value: 'elastic-pc-2', + }, + ]; + const signalHistoryRecord2 = { + terms: terms2, + lastSignalTimestamp: tuple.from.valueOf() + 60 * 1000, + }; + const hashOne = `${getThresholdTermsHash(terms1)}`; + const hashTwo = `${getThresholdTermsHash(terms2)}`; + const state = { + initialized: true, + signalHistory: { + [hashOne]: signalHistoryRecord1, + [hashTwo]: signalHistoryRecord2, + }, + }; + const validSignalHistory = getSignalHistory(state, state.signalHistory, tuple); + expect(validSignalHistory[hashOne]).toBe(undefined); + expect(validSignalHistory[hashTwo]).toBe(state.signalHistory[hashTwo]); + }); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/utils.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/utils.ts index 6d2273391abe6..b1f5ed818e506 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/utils.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_types/threshold/utils.ts @@ -11,6 +11,39 @@ import type { ThresholdNormalized, ThresholdWithCardinality, } from '../../../../../common/api/detection_engine/model/rule_schema'; +import type { RuleRangeTuple } from '../types'; +import type { ThresholdSignalHistory, ThresholdAlertState } from './types'; + +/** + * Returns a new signal history based on what the previous + * threshold rule state had stored and what the current rule + * run tuple timestamp is. + * + * This is used to determine which terms buckets over + * which periods of time are to be used in the search after + * + * @param state ThresholdAlertState + * @param signalHistory ThresholdSignalHistory + * @param tuple RuleRangeTuple + * @returns ThresholdSignalHistory + */ +export const getSignalHistory = ( + state: ThresholdAlertState, + signalHistory: ThresholdSignalHistory, + tuple: RuleRangeTuple +): ThresholdSignalHistory => { + if (state.initialized) { + return Object.entries(signalHistory).reduce((acc, [hash, entry]) => { + if (entry.lastSignalTimestamp > tuple.from.valueOf()) { + acc[hash] = entry; + return acc; + } else { + return acc; + } + }, {} as ThresholdSignalHistory); + } + return signalHistory; +}; export const shouldFilterByCardinality = ( threshold: ThresholdNormalized diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.ts b/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.ts index e1ecfb037c178..698724545585d 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/index_status/index.ts @@ -11,14 +11,14 @@ import { APP_ID, RISK_SCORE_INDEX_STATUS_API_URL } from '../../../../common/cons import type { SecuritySolutionPluginRouter } from '../../../types'; import { buildRouteValidation } from '../../../utils/build_validation/route_validation'; import { buildSiemResponse } from '../../detection_engine/routes/utils'; -import { indexStatusSchema } from './schema'; +import { indexStatusRequestQuery } from '../../../../common/api/risk_score'; export const getRiskScoreIndexStatusRoute = (router: SecuritySolutionPluginRouter) => { router.get( { path: RISK_SCORE_INDEX_STATUS_API_URL, validate: { - query: buildRouteValidation(indexStatusSchema), + query: buildRouteValidation(indexStatusRequestQuery), }, options: { tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.ts index a22a503a071e3..24391b35bf4bc 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/indices/create_index_route.ts @@ -11,13 +11,14 @@ import type { Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; import { RISK_SCORE_CREATE_INDEX } from '../../../../common/constants'; import type { SecuritySolutionPluginRouter } from '../../../types'; -import { createEsIndexBodySchema, createIndex } from './lib/create_index'; +import { createIndex } from './lib/create_index'; +import { createEsIndexRequestBody } from '../../../../common/api/risk_score'; export const createEsIndexRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { router.put( { path: RISK_SCORE_CREATE_INDEX, - validate: { body: createEsIndexBodySchema }, + validate: { body: createEsIndexRequestBody }, options: { tags: ['access:securitySolution'], }, diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.ts index ad202d757a4ee..9413b31765012 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/indices/delete_indices_route.ts @@ -4,23 +4,19 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { schema } from '@kbn/config-schema'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { RISK_SCORE_DELETE_INDICES } from '../../../../common/constants'; import type { SecuritySolutionPluginRouter } from '../../../types'; import { deleteEsIndices } from './lib/delete_indices'; - -const bodySchema = schema.object({ - indices: schema.arrayOf(schema.string()), -}); +import { deleteIndicesRequestBody } from '../../../../common/api/risk_score'; export const deleteEsIndicesRoute = (router: SecuritySolutionPluginRouter) => { router.post( { path: RISK_SCORE_DELETE_INDICES, - validate: { body: bodySchema }, + validate: { body: deleteIndicesRequestBody }, options: { tags: ['access:securitySolution'], }, diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/create_index.ts b/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/create_index.ts index 035be5e7d0e8d..48d3c333dff09 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/create_index.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/indices/lib/create_index.ts @@ -4,19 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { TypeOf } from '@kbn/config-schema'; -import { schema } from '@kbn/config-schema'; import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; - -export const createEsIndexBodySchema = schema.object({ - index: schema.string({ minLength: 1 }), - mappings: schema.maybe( - schema.oneOf([schema.string(), schema.recordOf(schema.string({ minLength: 1 }), schema.any())]) - ), -}); - -type CreateEsIndexBodySchema = TypeOf; +import type { CreateEsIndexRequestBody } from '../../../../../common/api/risk_score'; export const createIndex = async ({ esClient, @@ -25,7 +15,7 @@ export const createIndex = async ({ }: { esClient: ElasticsearchClient; logger: Logger; - options: CreateEsIndexBodySchema; + options: CreateEsIndexRequestBody; }) => { try { await esClient.indices.create({ diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.ts b/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.ts index 499cdc4a4df3a..dc71b70148703 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/onboarding/routes/install_risk_scores.ts @@ -16,7 +16,7 @@ import type { SetupPlugins } from '../../../../plugin'; import { buildSiemResponse } from '../../../detection_engine/routes/utils'; import { installRiskScoreModule } from '../helpers/install_risk_score_module'; -import { onboardingRiskScoreSchema } from '../schema'; +import { onboardingRiskScoreRequestBody } from '../../../../../common/api/risk_score'; export const installRiskScoresRoute = ( router: SecuritySolutionPluginRouter, @@ -26,7 +26,7 @@ export const installRiskScoresRoute = ( router.post( { path: INTERNAL_RISK_SCORE_URL, - validate: onboardingRiskScoreSchema, + validate: onboardingRiskScoreRequestBody, options: { tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], }, diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.ts index 07f0c15773ecc..766d32456c5e3 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/routes/read_prebuilt_dev_tool_content_route.ts @@ -14,7 +14,7 @@ import { DEV_TOOL_PREBUILT_CONTENT } from '../../../../../common/constants'; import type { SecuritySolutionPluginRouter } from '../../../../types'; import { consoleMappings } from '../console_mappings'; -import { ReadConsoleRequestSchema } from '../schema'; +import { readConsoleRequestBody } from '../../../../../common/api/risk_score'; import { RiskScoreEntity } from '../../../../../common/search_strategy'; import { getView } from '../utils'; @@ -48,7 +48,7 @@ export const readPrebuiltDevToolContentRoute = (router: SecuritySolutionPluginRo router.get( { path: DEV_TOOL_PREBUILT_CONTENT, - validate: ReadConsoleRequestSchema, + validate: readConsoleRequestBody, options: { tags: ['access:securitySolution'], }, diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.test.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.test.ts index 13b318158aac3..bf02aae37e5ca 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.test.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_dev_tool_content/schema.test.ts @@ -5,17 +5,17 @@ * 2.0. */ -import { ReadConsoleRequestSchema } from './schema'; +import { readConsoleRequestBody } from '../../../../common/api/risk_score'; describe('ReadConsoleRequestSchema', () => { it('should throw error', () => { - expect(() => ReadConsoleRequestSchema.params.validate({ console_id: '123' })).toThrow(); + expect(() => readConsoleRequestBody.params.validate({ console_id: '123' })).toThrow(); }); it.each([['enable_host_risk_score', 'enable_user_risk_score']])( 'should allow console_id %p', async (template) => { - expect(ReadConsoleRequestSchema.params.validate({ console_id: template })).toEqual({ + expect(readConsoleRequestBody.params.validate({ console_id: template })).toEqual({ console_id: template, }); } diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.ts index ffdb693278dd1..5c0235418a241 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/create_prebuilt_saved_objects.ts @@ -16,7 +16,7 @@ import { buildSiemResponse } from '../../../detection_engine/routes/utils'; import { buildFrameworkRequest } from '../../../timeline/utils/common'; import { bulkCreateSavedObjects } from '../helpers/bulk_create_saved_objects'; -import { createPrebuiltSavedObjectsSchema } from '../schema'; +import { createPrebuiltSavedObjectsRequestBody } from '../../../../../common/api/risk_score'; export const createPrebuiltSavedObjectsRoute = ( router: SecuritySolutionPluginRouter, @@ -26,7 +26,7 @@ export const createPrebuiltSavedObjectsRoute = ( router.post( { path: PREBUILT_SAVED_OBJECTS_BULK_CREATE, - validate: createPrebuiltSavedObjectsSchema, + validate: createPrebuiltSavedObjectsRequestBody, options: { tags: ['access:securitySolution'], }, diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.ts b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.ts index 825dd0049e35b..fc3ce460e19bb 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/prebuilt_saved_objects/routes/delete_prebuilt_saved_objects.ts @@ -16,7 +16,7 @@ import { buildSiemResponse } from '../../../detection_engine/routes/utils'; import { buildFrameworkRequest } from '../../../timeline/utils/common'; import { bulkDeleteSavedObjects } from '../helpers/bulk_delete_saved_objects'; -import { deletePrebuiltSavedObjectsSchema } from '../schema'; +import { deletePrebuiltSavedObjectsRequestBody } from '../../../../../common/api/risk_score'; export const deletePrebuiltSavedObjectsRoute = ( router: SecuritySolutionPluginRouter, @@ -25,7 +25,7 @@ export const deletePrebuiltSavedObjectsRoute = ( router.post( { path: PREBUILT_SAVED_OBJECTS_BULK_DELETE, - validate: deletePrebuiltSavedObjectsSchema, + validate: deletePrebuiltSavedObjectsRequestBody, options: { tags: ['access:securitySolution'], }, diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.ts index 0e19e160ea944..86969b76461b2 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/create_script_route.ts @@ -8,15 +8,16 @@ import type { Logger } from '@kbn/core/server'; import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { transformError } from '@kbn/securitysolution-es-utils'; +import { createStoredScriptRequestBody } from '../../../../common/api/risk_score'; import { RISK_SCORE_CREATE_STORED_SCRIPT } from '../../../../common/constants'; import type { SecuritySolutionPluginRouter } from '../../../types'; -import { createStoredScriptBodySchema, createStoredScript } from './lib/create_script'; +import { createStoredScript } from './lib/create_script'; export const createStoredScriptRoute = (router: SecuritySolutionPluginRouter, logger: Logger) => { router.put( { path: RISK_SCORE_CREATE_STORED_SCRIPT, - validate: { body: createStoredScriptBodySchema }, + validate: { body: createStoredScriptRequestBody }, options: { tags: ['access:securitySolution'], }, diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.ts index 753607966be62..f355c931b8fd4 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/delete_script_route.ts @@ -9,13 +9,14 @@ import { transformError } from '@kbn/securitysolution-es-utils'; import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { RISK_SCORE_DELETE_STORED_SCRIPT } from '../../../../common/constants'; import type { SecuritySolutionPluginRouter } from '../../../types'; -import { deleteStoredScriptBodySchema, deleteStoredScript } from './lib/delete_script'; +import { deleteStoredScript } from './lib/delete_script'; +import { deleteStoredScriptRequestBody } from '../../../../common/api/risk_score'; export const deleteStoredScriptRoute = (router: SecuritySolutionPluginRouter) => { router.delete( { path: RISK_SCORE_DELETE_STORED_SCRIPT, - validate: { body: deleteStoredScriptBodySchema }, + validate: { body: deleteStoredScriptRequestBody }, options: { tags: ['access:securitySolution'], }, diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/create_script.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/create_script.ts index 6617021d92d6d..fc56a3e049269 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/create_script.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/create_script.ts @@ -4,27 +4,9 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { TypeOf } from '@kbn/config-schema'; -import { schema } from '@kbn/config-schema'; import type { ElasticsearchClient, Logger } from '@kbn/core/server'; import { transformError } from '@kbn/securitysolution-es-utils'; - -export const createStoredScriptBodySchema = schema.object({ - id: schema.string({ minLength: 1 }), - script: schema.object({ - lang: schema.oneOf([ - schema.string(), - schema.literal('painless'), - schema.literal('expression'), - schema.literal('mustache'), - schema.literal('java'), - ]), - options: schema.maybe(schema.recordOf(schema.string(), schema.string())), - source: schema.string(), - }), -}); - -type CreateStoredScriptBodySchema = TypeOf; +import type { CreateStoredScriptRequestBody } from '../../../../../common/api/risk_score'; export const createStoredScript = async ({ esClient, @@ -33,7 +15,7 @@ export const createStoredScript = async ({ }: { esClient: ElasticsearchClient; logger: Logger; - options: CreateStoredScriptBodySchema; + options: CreateStoredScriptRequestBody; }) => { try { await esClient.putScript(options); diff --git a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/delete_script.ts b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/delete_script.ts index c4adefc1674ef..b6113b5f9f318 100644 --- a/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/delete_script.ts +++ b/x-pack/plugins/security_solution/server/lib/risk_score/stored_scripts/lib/delete_script.ts @@ -4,22 +4,15 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { TypeOf } from '@kbn/config-schema'; -import { schema } from '@kbn/config-schema'; import type { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; - -export const deleteStoredScriptBodySchema = schema.object({ - id: schema.string({ minLength: 1 }), -}); - -type DeleteStoredScriptBodySchema = TypeOf; +import type { DeleteStoredScriptRequestBody } from '../../../../../common/api/risk_score'; export const deleteStoredScript = async ({ client, options, }: { client: IScopedClusterClient; - options: DeleteStoredScriptBodySchema; + options: DeleteStoredScriptRequestBody; }) => { await client.asCurrentUser.deleteScript(options); }; diff --git a/x-pack/plugins/security_solution_serverless/common/pli/pli_config.ts b/x-pack/plugins/security_solution_serverless/common/pli/pli_config.ts index a07f3ca8d102b..82f180d4a541e 100644 --- a/x-pack/plugins/security_solution_serverless/common/pli/pli_config.ts +++ b/x-pack/plugins/security_solution_serverless/common/pli/pli_config.ts @@ -29,7 +29,10 @@ export const PLI_APP_FEATURES: PliAppFeatures = { AppFeatureKey.endpointPolicyProtections, AppFeatureKey.endpointArtifactManagement, ], - complete: [AppFeatureKey.endpointResponseActions], + complete: [ + AppFeatureKey.endpointResponseActions, + AppFeatureKey.osqueryAutomatedResponseActions, + ], }, cloud: { essentials: [], diff --git a/x-pack/plugins/security_solution_serverless/public/upselling/pages/osquery_automated_response_actions.tsx b/x-pack/plugins/security_solution_serverless/public/upselling/pages/osquery_automated_response_actions.tsx new file mode 100644 index 0000000000000..2168390eb31a2 --- /dev/null +++ b/x-pack/plugins/security_solution_serverless/public/upselling/pages/osquery_automated_response_actions.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiEmptyPrompt, EuiIcon } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import React from 'react'; +import type { AppFeatureKey } from '@kbn/security-solution-plugin/common'; +import { getProductTypeByPLI } from '../hooks/use_product_type_by_pli'; + +const OsqueryResponseActionsUpsellingSection: React.FC<{ requiredPLI: AppFeatureKey }> = React.memo( + ({ requiredPLI }) => { + const productTypeRequired = getProductTypeByPLI(requiredPLI); + + return ( + } + color="subdued" + title={ +

+ +

+ } + body={ +

+ +

+ } + /> + ); + } +); + +OsqueryResponseActionsUpsellingSection.displayName = 'OsqueryResponseActionsUpsellingSection'; + +// eslint-disable-next-line import/no-default-export +export { OsqueryResponseActionsUpsellingSection as default }; diff --git a/x-pack/plugins/security_solution_serverless/public/upselling/register_upsellings.tsx b/x-pack/plugins/security_solution_serverless/public/upselling/register_upsellings.tsx index b2c6fd23ca9b5..2997a39b544e1 100644 --- a/x-pack/plugins/security_solution_serverless/public/upselling/register_upsellings.tsx +++ b/x-pack/plugins/security_solution_serverless/public/upselling/register_upsellings.tsx @@ -20,6 +20,7 @@ import { EndpointPolicyProtectionsLazy } from './sections/endpoint_management'; import type { SecurityProductTypes } from '../../common/config'; import { getProductAppFeatures } from '../../common/pli/pli_features'; import investigationGuideUpselling from './pages/investigation_guide_upselling'; + const ThreatIntelligencePaywallLazy = lazy(async () => { const ThreatIntelligencePaywall = (await import('./pages/threat_intelligence_paywall')).default; @@ -27,6 +28,21 @@ const ThreatIntelligencePaywallLazy = lazy(async () => { default: () => , }; }); + +const OsqueryResponseActionsUpsellingSectionlLazy = lazy(async () => { + const OsqueryResponseActionsUpsellingSection = ( + await import('./pages/osquery_automated_response_actions') + ).default; + + return { + default: () => ( + + ), + }; +}); + interface UpsellingsConfig { pli: AppFeatureKey; component: React.LazyExoticComponent; @@ -108,6 +124,11 @@ export const upsellingSections: UpsellingSections = [ // pli: AppFeatureKey.advancedInsights, // component: () => , // }, + { + id: 'osquery_automated_response_actions', + pli: AppFeatureKey.osqueryAutomatedResponseActions, + component: OsqueryResponseActionsUpsellingSectionlLazy, + }, { id: 'endpointPolicyProtections', diff --git a/x-pack/plugins/security_solution_serverless/server/cloud_security/types.ts b/x-pack/plugins/security_solution_serverless/server/cloud_security/types.ts index e752621f23cb0..378c86eea8e7d 100644 --- a/x-pack/plugins/security_solution_serverless/server/cloud_security/types.ts +++ b/x-pack/plugins/security_solution_serverless/server/cloud_security/types.ts @@ -30,7 +30,7 @@ export type PostureType = | typeof CNVM_POLICY_TEMPLATE; export interface CloudSecurityMeteringCallbackInput - extends Omit { + extends Omit { projectId: string; postureType: PostureType; } diff --git a/x-pack/plugins/security_solution_serverless/server/constants.ts b/x-pack/plugins/security_solution_serverless/server/constants.ts index ed59ace5f9c15..c648276abeeba 100644 --- a/x-pack/plugins/security_solution_serverless/server/constants.ts +++ b/x-pack/plugins/security_solution_serverless/server/constants.ts @@ -5,7 +5,6 @@ * 2.0. */ -// TODO: this probably shouldn't live in code const namespace = 'elastic-system'; const USAGE_SERVICE_BASE_API_URL = `https://usage-api.${namespace}/api`; const USAGE_SERVICE_BASE_API_URL_V1 = `${USAGE_SERVICE_BASE_API_URL}/v1`; diff --git a/x-pack/plugins/security_solution_serverless/server/endpoint/services/metering_service.ts b/x-pack/plugins/security_solution_serverless/server/endpoint/services/metering_service.ts index 2e6a1b881c2c8..2ec94d78722e0 100644 --- a/x-pack/plugins/security_solution_serverless/server/endpoint/services/metering_service.ts +++ b/x-pack/plugins/security_solution_serverless/server/endpoint/services/metering_service.ts @@ -7,29 +7,49 @@ import type { AggregationsAggregate, SearchResponse } from '@elastic/elasticsearch/lib/api/types'; import type { ElasticsearchClient } from '@kbn/core/server'; -// import { ENDPOINT_HEARTBEAT_INDEX } from '@kbn/security-solution-plugin/common/endpoint/constants'; +import { ENDPOINT_HEARTBEAT_INDEX } from '@kbn/security-solution-plugin/common/endpoint/constants'; import type { EndpointHeartbeat } from '@kbn/security-solution-plugin/common/endpoint/types'; +import { ProductLine, type ProductTier } from '../../../common/product'; + import type { UsageRecord, MeteringCallbackInput } from '../../types'; +import type { ServerlessSecurityConfig } from '../../config'; // 1 hour const SAMPLE_PERIOD_SECONDS = 3600; -// const THRESHOLD_MINUTES = 30; +const THRESHOLD_MINUTES = 30; export class EndpointMeteringService { - public async getUsageRecords({ + private tier: ProductTier | undefined; + + public getUsageRecords = async ({ taskId, cloudSetup, esClient, abortController, lastSuccessfulReport, - }: MeteringCallbackInput): Promise { + config, + }: MeteringCallbackInput): Promise => { + this.setTier(config); + const heartbeatsResponse = await this.getHeartbeatsSince( esClient, abortController, lastSuccessfulReport ); + if (!heartbeatsResponse?.hits?.hits) { + return []; + } + + if (!this.tier) { + throw new Error( + `no product tier information found for heartbeats: ${JSON.stringify( + heartbeatsResponse.hits.hits + )}` + ); + } + return heartbeatsResponse.hits.hits.reduce((acc, { _source }) => { if (!_source) { return acc; @@ -45,50 +65,30 @@ export class EndpointMeteringService { return [...acc, record]; }, [] as UsageRecord[]); - } + }; private async getHeartbeatsSince( esClient: ElasticsearchClient, abortController: AbortController, since?: Date ): Promise>> { - const timestamp = new Date().toISOString(); - return { - hits: { - hits: [ - { - _source: { - '@timestamp': timestamp, - agent: { - id: '123', - }, - event: { - ingested: timestamp, - }, + const thresholdDate = new Date(Date.now() - THRESHOLD_MINUTES * 60 * 1000); + const searchFrom = since && since > thresholdDate ? since : thresholdDate; + + return esClient.search( + { + index: ENDPOINT_HEARTBEAT_INDEX, + sort: 'event.ingested', + query: { + range: { + 'event.ingested': { + gt: searchFrom.toISOString(), }, }, - ], + }, }, - } as SearchResponse>; - - // TODO: enable when heartbeat index is ready - // const thresholdDate = new Date(Date.now() - THRESHOLD_MINUTES * 60 * 1000); - // const searchFrom = since && since > thresholdDate ? since : thresholdDate; - - // return esClient.search( - // { - // index: ENDPOINT_HEARTBEAT_INDEX, - // sort: 'event.ingested', - // query: { - // range: { - // 'event.ingested': { - // gt: searchFrom.toISOString(), - // }, - // }, - // }, - // }, - // { signal: abortController.signal } - // ); + { signal: abortController.signal, ignore: [404] } + ); } private buildMeteringRecord({ @@ -113,8 +113,7 @@ export class EndpointMeteringService { creation_timestamp: timestampStr, usage: { type: 'security_solution_endpoint', - // TODO: get actual sub_type - sub_type: 'essential', + sub_type: this.tier, period_seconds: SAMPLE_PERIOD_SECONDS, quantity: 1, }, @@ -124,6 +123,17 @@ export class EndpointMeteringService { }, }; } + + private setTier(config: ServerlessSecurityConfig) { + if (this.tier) { + return; + } + + const endpoint = config.productTypes.find( + (productType) => productType.product_line === ProductLine.endpoint + ); + this.tier = endpoint?.product_tier; + } } export const endpointMeteringService = new EndpointMeteringService(); diff --git a/x-pack/plugins/security_solution_serverless/server/plugin.ts b/x-pack/plugins/security_solution_serverless/server/plugin.ts index c303266f51b83..4ecf5196cbd61 100644 --- a/x-pack/plugins/security_solution_serverless/server/plugin.ts +++ b/x-pack/plugins/security_solution_serverless/server/plugin.ts @@ -68,6 +68,7 @@ export class SecuritySolutionServerlessPlugin this.cspmUsageReportingTask = new SecurityUsageReportingTask({ core: _coreSetup, logFactory: this.initializerContext.logger, + config: this.config, taskManager: pluginsSetup.taskManager, cloudSetup: pluginsSetup.cloudSetup, taskType: cloudSecurityMetringTaskProperties.taskType, @@ -79,6 +80,7 @@ export class SecuritySolutionServerlessPlugin this.endpointUsageReportingTask = new SecurityUsageReportingTask({ core: _coreSetup, logFactory: this.initializerContext.logger, + config: this.config, taskType: ENDPOINT_METERING_TASK.TYPE, taskTitle: ENDPOINT_METERING_TASK.TITLE, version: ENDPOINT_METERING_TASK.VERSION, diff --git a/x-pack/plugins/security_solution_serverless/server/task_manager/usage_reporting_task.ts b/x-pack/plugins/security_solution_serverless/server/task_manager/usage_reporting_task.ts index d23a478299057..673bda309aec7 100644 --- a/x-pack/plugins/security_solution_serverless/server/task_manager/usage_reporting_task.ts +++ b/x-pack/plugins/security_solution_serverless/server/task_manager/usage_reporting_task.ts @@ -15,7 +15,9 @@ import type { MeteringCallback, SecurityUsageReportingTaskStartContract, SecurityUsageReportingTaskSetupContract, + UsageRecord, } from '../types'; +import type { ServerlessSecurityConfig } from '../config'; const SCOPE = ['serverlessSecurity']; const TIMEOUT = '1m'; @@ -29,11 +31,13 @@ export class SecurityUsageReportingTask { private version: string; private logger: Logger; private abortController = new AbortController(); + private config: ServerlessSecurityConfig; constructor(setupContract: SecurityUsageReportingTaskSetupContract) { const { core, logFactory, + config, taskManager, cloudSetup, taskType, @@ -46,6 +50,7 @@ export class SecurityUsageReportingTask { this.taskType = taskType; this.version = version; this.logger = logFactory.get(this.taskId); + this.config = config; try { taskManager.registerTaskDefinitions({ @@ -114,14 +119,21 @@ export class SecurityUsageReportingTask { const lastSuccessfulReport = taskInstance.state.lastSuccessfulReport; - const usageRecords = await meteringCallback({ - esClient, - cloudSetup: this.cloudSetup, - logger: this.logger, - taskId: this.taskId, - lastSuccessfulReport, - abortController: this.abortController, - }); + let usageRecords: UsageRecord[] = []; + try { + usageRecords = await meteringCallback({ + esClient, + cloudSetup: this.cloudSetup, + logger: this.logger, + taskId: this.taskId, + lastSuccessfulReport, + abortController: this.abortController, + config: this.config, + }); + } catch (err) { + this.logger.error(`failed to retrieve usage records: ${JSON.stringify(err)}`); + return; + } this.logger.debug(`received usage records: ${JSON.stringify(usageRecords)}`); diff --git a/x-pack/plugins/security_solution_serverless/server/types.ts b/x-pack/plugins/security_solution_serverless/server/types.ts index d11b4dbd39339..ac45cadd21c6d 100644 --- a/x-pack/plugins/security_solution_serverless/server/types.ts +++ b/x-pack/plugins/security_solution_serverless/server/types.ts @@ -19,6 +19,8 @@ import type { CloudSetup } from '@kbn/cloud-plugin/server'; import type { SecuritySolutionEssPluginSetup } from '@kbn/security-solution-ess/server'; import type { MlPluginSetup } from '@kbn/ml-plugin/server'; +import type { ServerlessSecurityConfig } from './config'; + // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface SecuritySolutionServerlessPluginSetup {} // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -66,6 +68,7 @@ export interface UsageSource { export interface SecurityUsageReportingTaskSetupContract { core: CoreSetup; logFactory: LoggerFactory; + config: ServerlessSecurityConfig; taskManager: TaskManagerSetupContract; cloudSetup: CloudSetup; taskType: string; @@ -90,6 +93,7 @@ export interface MeteringCallbackInput { taskId: string; lastSuccessfulReport: Date; abortController: AbortController; + config: ServerlessSecurityConfig; } export interface MetringTaskProperties { diff --git a/x-pack/plugins/serverless/kibana.jsonc b/x-pack/plugins/serverless/kibana.jsonc index 5a724f7641a6a..35b21a5fc39b5 100644 --- a/x-pack/plugins/serverless/kibana.jsonc +++ b/x-pack/plugins/serverless/kibana.jsonc @@ -15,6 +15,7 @@ "requiredPlugins": [ "kibanaReact", "management", + "cloud" ], "optionalPlugins": [], "requiredBundles": [] diff --git a/x-pack/plugins/serverless/public/plugin.tsx b/x-pack/plugins/serverless/public/plugin.tsx index e7b88fea56ffb..d49447e4d36dd 100644 --- a/x-pack/plugins/serverless/public/plugin.tsx +++ b/x-pack/plugins/serverless/public/plugin.tsx @@ -65,6 +65,9 @@ export class ServerlessPlugin // Casting the "chrome.projects" service to an "internal" type: this is intentional to obscure the property from Typescript. const { project } = core.chrome as InternalChromeStart; + if (dependencies.cloud.projectsUrl) { + project.setProjectsUrl(dependencies.cloud.projectsUrl); + } return { setSideNavComponent: (sideNavigationComponent) => diff --git a/x-pack/plugins/serverless/public/types.ts b/x-pack/plugins/serverless/public/types.ts index 685e8757f9a98..1de2e2fd75e1a 100644 --- a/x-pack/plugins/serverless/public/types.ts +++ b/x-pack/plugins/serverless/public/types.ts @@ -13,6 +13,7 @@ import type { ChromeProjectNavigationNode, } from '@kbn/core-chrome-browser'; import type { ManagementSetup, ManagementStart } from '@kbn/management-plugin/public'; +import type { CloudSetup, CloudStart } from '@kbn/cloud-plugin/public'; import type { Observable } from 'rxjs'; // eslint-disable-next-line @typescript-eslint/no-empty-interface @@ -31,8 +32,10 @@ export interface ServerlessPluginStart { export interface ServerlessPluginSetupDependencies { management: ManagementSetup; + cloud: CloudSetup; } export interface ServerlessPluginStartDependencies { management: ManagementStart; + cloud: CloudStart; } diff --git a/x-pack/plugins/serverless/tsconfig.json b/x-pack/plugins/serverless/tsconfig.json index c4cf602f928c7..88f7b5af1636c 100644 --- a/x-pack/plugins/serverless/tsconfig.json +++ b/x-pack/plugins/serverless/tsconfig.json @@ -24,5 +24,6 @@ "@kbn/core-chrome-browser", "@kbn/core-chrome-browser-internal", "@kbn/i18n-react", + "@kbn/cloud-plugin", ] } diff --git a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json index 26c5e84449552..9acfe9e364a4d 100644 --- a/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json +++ b/x-pack/plugins/telemetry_collection_xpack/schema/xpack_plugins.json @@ -6579,6 +6579,9 @@ }, "agent_count": { "type": "long" + }, + "account_type": { + "type": "keyword" } } } diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 567157a2bdbeb..034ddf93a27ad 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -1033,7 +1033,6 @@ "core.ui.overlays.banner.attentionTitle": "Attention", "core.ui.overlays.banner.closeButtonLabel": "Fermer", "core.ui.primaryNav.addData": "Ajouter des intégrations", - "core.ui.primaryNav.cloud.linkToDeployments": "Mes déploiements", "core.ui.primaryNav.goToHome.ariaLabel": "Accéder à la page d’accueil", "core.ui.primaryNav.pinnedLinksAriaLabel": "Liens épinglés", "core.ui.primaryNav.screenReaderLabel": "Principale", @@ -29088,9 +29087,6 @@ "xpack.searchProfiler.registryProviderTitle": "Search Profiler", "xpack.searchProfiler.scoreTimeDescription": "Temps passé sur l'attribution de score au document par rapport à la recherche.", "xpack.searchProfiler.trialLicenseTitle": "Trial", - "xpack.security.accountManagement.apiKeyFlyout.errorMessage": "Impossible de {errorTitle}", - "xpack.security.accountManagement.apiKeyFlyout.submitButton": "{isSubmitting, select, true {{inProgressButtonText}} other {{formTitle}}}", - "xpack.security.accountManagement.apiKeyFlyout.title": "{formTitle}", "xpack.security.accountManagement.userProfile.saveChangesButton": "{isSubmitting, select, true {Enregistrement des modifications…} other {Enregistrer les modifications}}", "xpack.security.accountManagement.userProfile.unsavedChangesMessage": "{count, plural, one {# modification non enregistrée} many {# modifications non enregistrées} other {# modifications non enregistrées}}", "xpack.security.changePasswordForm.confirmButton": "{isSubmitting, select, true {Modification du mot de passe…} other {Modifier le mot de passe}}", @@ -29110,7 +29106,6 @@ "xpack.security.management.apiKeys.deleteApiKey.errorMultipleNotificationTitle": "Erreur lors de la suppression de {count} clés d'API", "xpack.security.management.apiKeys.deleteApiKey.successMultipleNotificationTitle": "{count} clés d'API supprimées", "xpack.security.management.apiKeys.table.apiKeysDisabledErrorDescription": "Contactez votre administrateur système et reportez-vous à {link} pour activer les clés d'API.", - "xpack.security.management.apiKeys.table.fetchingApiKeysErrorMessage": "Erreur de vérification des privilèges : {message}", "xpack.security.management.apiKeys.table.invalidateApiKeyButton": "Supprimer {count, plural, one {Clé d'API} many {Clés d'API} other {Clés d'API}}", "xpack.security.management.apiKeys.table.statusExpires": "Expiration : {timeFromNow}", "xpack.security.management.editRole.featureTable.actionLegendText": "Privilège de fonctionnalité {featureName}", @@ -29319,8 +29314,6 @@ "xpack.security.management.apiKeys.apiKeyFlyout.metadataRequired": "Entrez des métadonnées ou désactivez cette option.", "xpack.security.management.apiKeys.apiKeyFlyout.nameRequired": "Entrez un nom.", "xpack.security.management.apiKeys.apiKeyFlyout.roleDescriptorsRequired": "Entrez des descripteurs de rôles ou désactivez cette option.", - "xpack.security.management.apiKeys.base64Description": "Format utilisé pour l'authentification avec Elasticsearch.", - "xpack.security.management.apiKeys.base64Label": "Base64", "xpack.security.management.apiKeys.beatsDescription": "Format utilisé pour la configuration de Beats.", "xpack.security.management.apiKeys.beatsLabel": "Beats", "xpack.security.management.apiKeys.createBreadcrumb": "Créer", @@ -29331,8 +29324,6 @@ "xpack.security.management.apiKeys.deleteApiKey.errorSingleNotificationTitle": "Erreur lors de la suppression de la clé d'API \"{name}\"", "xpack.security.management.apiKeys.deleteApiKey.successSingleNotificationTitle": "Suppression de la clé d'API \"{name}\" effectuée", "xpack.security.management.apiKeys.deniedPermissionTitle": "Vous devez disposer d'une autorisation pour gérer les clés d'API", - "xpack.security.management.apiKeys.jsonDescription": "Réponse API complète.", - "xpack.security.management.apiKeys.jsonLabel": "JSON", "xpack.security.management.apiKeys.logstashDescription": "Format utilisé pour la configuration de Logstash.", "xpack.security.management.apiKeys.logstashLabel": "Logstash", "xpack.security.management.apiKeys.noPermissionToManageRolesDescription": "Contactez votre administrateur système.", @@ -29340,26 +29331,17 @@ "xpack.security.management.apiKeys.table.apiKeysAllDescription": "Affichez et supprimez les clés d'API, qui envoient des requêtes au nom d'un utilisateur.", "xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText": "documents", "xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle": "Clés d'API non activées dans Elasticsearch", - "xpack.security.management.apiKeys.table.apiKeysOwnDescription": "Affichez et supprimez vos clés d'API, qui envoient des requêtes en votre nom.", - "xpack.security.management.apiKeys.table.apiKeysReadOnlyDescription": "Affichez vos clés d'API, qui envoient des requêtes en votre nom.", - "xpack.security.management.apiKeys.table.apiKeysTableLoadingMessage": "Chargement des clés d'API…", "xpack.security.management.apiKeys.table.apiKeysTitle": "Clés d'API", "xpack.security.management.apiKeys.table.createButton": "Créer une clé d'API", "xpack.security.management.apiKeys.table.createdBadge": "Juste maintenant", - "xpack.security.management.apiKeys.table.creationDateColumnName": "Créé", "xpack.security.management.apiKeys.table.deleteAction": "Supprimer", "xpack.security.management.apiKeys.table.deleteDescription": "Supprimer cette clé d'API", "xpack.security.management.apiKeys.table.loadingApiKeysDescription": "Chargement des clés d'API…", "xpack.security.management.apiKeys.table.manageOwnKeysWarning": "Vous avez uniquement l'autorisation de gérer vos propres clés d'API.", "xpack.security.management.apiKeys.table.nameColumnName": "Nom", - "xpack.security.management.apiKeys.table.readOnlyOwnKeysWarning": "Vous avez uniquement l'autorisation d'afficher vos propres clés d'API.", - "xpack.security.management.apiKeys.table.realmColumnName": "Domaine", - "xpack.security.management.apiKeys.table.realmFilterLabel": "Domaine", "xpack.security.management.apiKeys.table.statusActive": "Actif", "xpack.security.management.apiKeys.table.statusColumnName": "Statut", "xpack.security.management.apiKeys.table.statusExpired": "Expiré", - "xpack.security.management.apiKeys.table.userFilterLabel": "Utilisateur", - "xpack.security.management.apiKeys.table.userNameColumnName": "Utilisateur", "xpack.security.management.apiKeys.updateSuccessMessage": "Mise à jour de la clé d'API \"{name}\" effectuée", "xpack.security.management.apiKeysEmptyPrompt.disabledErrorMessage": "Les clés d'API sont désactivées.", "xpack.security.management.apiKeysEmptyPrompt.docsLinkText": "Découvrez comment activer les clés d'API.", @@ -29638,7 +29620,6 @@ "xpack.security.management.roles.statusColumnName": "Statut", "xpack.security.management.roles.subtitle": "Appliquez les rôles aux groupes d'utilisateurs et gérez les autorisations dans toute la Suite.", "xpack.security.management.rolesTitle": "Rôles", - "xpack.security.management.users.changePasswordFlyout.userLabel": "Utilisateur", "xpack.security.management.users.changePasswordForm.confirmPasswordInvalidError": "Les mots de passe ne correspondent pas.", "xpack.security.management.users.changePasswordForm.confirmPasswordLabel": "Confirmer le mot de passe", "xpack.security.management.users.changePasswordForm.currentPasswordInvalidError": "Mot de passe non valide.", @@ -33426,7 +33407,6 @@ "xpack.securitySolution.flyout.documentDetails.overviewTab.threatIntelligenceText": "champs de Threat Intelligence", "xpack.securitySolution.flyout.documentDetails.prevalenceButton": "Prévalence", "xpack.securitySolution.flyout.documentDetails.prevalenceTitle": "Prévalence", - "xpack.securitySolution.flyout.documentDetails.responseButton": "Réponse", "xpack.securitySolution.flyout.documentDetails.riskScoreTitle": "Score de risque", "xpack.securitySolution.flyout.documentDetails.ruleDescriptionTitle": "Description de la règle", "xpack.securitySolution.flyout.documentDetails.sessionPreview.commandText": "par", @@ -40489,4 +40469,4 @@ "xpack.painlessLab.walkthroughButtonLabel": "Présentation", "xpack.serverlessObservability.nav.getStarted": "Démarrer" } -} +} \ 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 934e36fec297c..7b24e76e72564 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -1047,7 +1047,6 @@ "core.ui.overlays.banner.attentionTitle": "注意", "core.ui.overlays.banner.closeButtonLabel": "閉じる", "core.ui.primaryNav.addData": "統合の追加", - "core.ui.primaryNav.cloud.linkToDeployments": "マイデプロイ", "core.ui.primaryNav.goToHome.ariaLabel": "ホームページに移動", "core.ui.primaryNav.pinnedLinksAriaLabel": "ピン留めされたリンク", "core.ui.primaryNav.screenReaderLabel": "プライマリ", @@ -29088,9 +29087,6 @@ "xpack.searchProfiler.registryProviderTitle": "検索プロファイラー", "xpack.searchProfiler.scoreTimeDescription": "クエリに対してドキュメントを実際にスコアリングするためにかかった時間。", "xpack.searchProfiler.trialLicenseTitle": "トライアル", - "xpack.security.accountManagement.apiKeyFlyout.errorMessage": "{errorTitle}できませんでした", - "xpack.security.accountManagement.apiKeyFlyout.submitButton": "{isSubmitting, select, true {{inProgressButtonText}} other {{formTitle}}}", - "xpack.security.accountManagement.apiKeyFlyout.title": "{formTitle}", "xpack.security.accountManagement.userProfile.saveChangesButton": "{isSubmitting, select, true {変更を保存中...} other {変更を保存}}", "xpack.security.accountManagement.userProfile.unsavedChangesMessage": "{count, plural, other {#個の保存されていない変更}}", "xpack.security.changePasswordForm.confirmButton": "{isSubmitting, select, true {パスワードを変更中...} other {パスワードを変更}}", @@ -29110,7 +29106,6 @@ "xpack.security.management.apiKeys.deleteApiKey.errorMultipleNotificationTitle": "{count}個のAPIキーの削除中にエラーが発生", "xpack.security.management.apiKeys.deleteApiKey.successMultipleNotificationTitle": "APIキー{count}を削除しました", "xpack.security.management.apiKeys.table.apiKeysDisabledErrorDescription": "システム管理者に連絡し、{link}を伝えてAPIキーを有効にしてください。", - "xpack.security.management.apiKeys.table.fetchingApiKeysErrorMessage": "権限の確認エラー:{message}", "xpack.security.management.apiKeys.table.invalidateApiKeyButton": "{count, plural, other {APIキー}}削除", "xpack.security.management.apiKeys.table.statusExpires": "有効期限:{timeFromNow}", "xpack.security.management.editRole.featureTable.actionLegendText": "{featureName}機能権限", @@ -29318,8 +29313,6 @@ "xpack.security.management.apiKeys.apiKeyFlyout.metadataRequired": "メタデータを入力するか、このオプションを無効にします。", "xpack.security.management.apiKeys.apiKeyFlyout.nameRequired": "名前を入力します。", "xpack.security.management.apiKeys.apiKeyFlyout.roleDescriptorsRequired": "ロール記述子を入力するか、このオプションを無効にします。", - "xpack.security.management.apiKeys.base64Description": "Elasticsearchで認証するために使用される形式。", - "xpack.security.management.apiKeys.base64Label": "Base64", "xpack.security.management.apiKeys.beatsDescription": "Beatsを構成するために使用される形式。", "xpack.security.management.apiKeys.beatsLabel": "ビート", "xpack.security.management.apiKeys.createBreadcrumb": "作成", @@ -29330,8 +29323,6 @@ "xpack.security.management.apiKeys.deleteApiKey.errorSingleNotificationTitle": "API キー「{name}」の削除中にエラーが発生", "xpack.security.management.apiKeys.deleteApiKey.successSingleNotificationTitle": "APIキー'{name}'を削除しました", "xpack.security.management.apiKeys.deniedPermissionTitle": "API キーを管理するにはパーミッションが必要です", - "xpack.security.management.apiKeys.jsonDescription": "完全なAPI応答。", - "xpack.security.management.apiKeys.jsonLabel": "JSON", "xpack.security.management.apiKeys.logstashDescription": "Logstashを構成するために使用される形式。", "xpack.security.management.apiKeys.logstashLabel": "Logstash", "xpack.security.management.apiKeys.noPermissionToManageRolesDescription": "システム管理者にお問い合わせください。", @@ -29339,26 +29330,17 @@ "xpack.security.management.apiKeys.table.apiKeysAllDescription": "ユーザーの代わりにリクエストを送信するAPIキーを表示、削除します。", "xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText": "ドキュメント", "xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle": "Elasticsearch で API キーが有効ではありません", - "xpack.security.management.apiKeys.table.apiKeysOwnDescription": "自分の代わりにリクエストを送信するAPIキーを表示、削除します。", - "xpack.security.management.apiKeys.table.apiKeysReadOnlyDescription": "自分の代わりにリクエストを送信するAPIキーを表示します。", - "xpack.security.management.apiKeys.table.apiKeysTableLoadingMessage": "API キーを読み込み中…", "xpack.security.management.apiKeys.table.apiKeysTitle": "API キー", "xpack.security.management.apiKeys.table.createButton": "APIキーを作成", "xpack.security.management.apiKeys.table.createdBadge": "たった今", - "xpack.security.management.apiKeys.table.creationDateColumnName": "作成済み", "xpack.security.management.apiKeys.table.deleteAction": "削除", "xpack.security.management.apiKeys.table.deleteDescription": "このAPIキーを削除", "xpack.security.management.apiKeys.table.loadingApiKeysDescription": "API キーを読み込み中…", "xpack.security.management.apiKeys.table.manageOwnKeysWarning": "自分のAPIキーを管理する権限のみが付与されています。", "xpack.security.management.apiKeys.table.nameColumnName": "名前", - "xpack.security.management.apiKeys.table.readOnlyOwnKeysWarning": "自分のAPIキーを表示する権限のみが付与されています。", - "xpack.security.management.apiKeys.table.realmColumnName": "レルム", - "xpack.security.management.apiKeys.table.realmFilterLabel": "レルム", "xpack.security.management.apiKeys.table.statusActive": "アクティブ", "xpack.security.management.apiKeys.table.statusColumnName": "ステータス", "xpack.security.management.apiKeys.table.statusExpired": "期限切れ", - "xpack.security.management.apiKeys.table.userFilterLabel": "ユーザー", - "xpack.security.management.apiKeys.table.userNameColumnName": "ユーザー", "xpack.security.management.apiKeys.updateSuccessMessage": "API キー'{name}'を更新しました", "xpack.security.management.apiKeysEmptyPrompt.disabledErrorMessage": "APIキーが無効です。", "xpack.security.management.apiKeysEmptyPrompt.docsLinkText": "APIキーを有効にする方法をご覧ください。", @@ -29637,7 +29619,6 @@ "xpack.security.management.roles.statusColumnName": "ステータス", "xpack.security.management.roles.subtitle": "ユーザーのグループにロールを適用してスタック全体のパーミッションを管理します。", "xpack.security.management.rolesTitle": "ロール", - "xpack.security.management.users.changePasswordFlyout.userLabel": "ユーザー", "xpack.security.management.users.changePasswordForm.confirmPasswordInvalidError": "パスワードが一致していません。", "xpack.security.management.users.changePasswordForm.confirmPasswordLabel": "パスワードの確認", "xpack.security.management.users.changePasswordForm.currentPasswordInvalidError": "無効なパスワードです。", @@ -33425,7 +33406,6 @@ "xpack.securitySolution.flyout.documentDetails.overviewTab.threatIntelligenceText": "脅威インテリジェンスのフィールド", "xpack.securitySolution.flyout.documentDetails.prevalenceButton": "発生率", "xpack.securitySolution.flyout.documentDetails.prevalenceTitle": "発生率", - "xpack.securitySolution.flyout.documentDetails.responseButton": "応答", "xpack.securitySolution.flyout.documentDetails.riskScoreTitle": "リスクスコア", "xpack.securitySolution.flyout.documentDetails.ruleDescriptionTitle": "ルールの説明", "xpack.securitySolution.flyout.documentDetails.sessionPreview.commandText": "グループ基準", @@ -40480,4 +40460,4 @@ "xpack.painlessLab.walkthroughButtonLabel": "実地検証", "xpack.serverlessObservability.nav.getStarted": "使ってみる" } -} +} \ 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 fe4771e5cbd82..f3dbabafc450e 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -1047,7 +1047,6 @@ "core.ui.overlays.banner.attentionTitle": "注意", "core.ui.overlays.banner.closeButtonLabel": "关闭", "core.ui.primaryNav.addData": "添加集成", - "core.ui.primaryNav.cloud.linkToDeployments": "我的部署", "core.ui.primaryNav.goToHome.ariaLabel": "前往主页", "core.ui.primaryNav.pinnedLinksAriaLabel": "置顶链接", "core.ui.primaryNav.screenReaderLabel": "主分片", @@ -29084,9 +29083,6 @@ "xpack.searchProfiler.registryProviderTitle": "Search Profiler", "xpack.searchProfiler.scoreTimeDescription": "基于查询实际评分文档所用的时间。", "xpack.searchProfiler.trialLicenseTitle": "试用", - "xpack.security.accountManagement.apiKeyFlyout.errorMessage": "无法 {errorTitle}", - "xpack.security.accountManagement.apiKeyFlyout.submitButton": "{isSubmitting, select, true {{inProgressButtonText}} other {{formTitle}}}", - "xpack.security.accountManagement.apiKeyFlyout.title": "{formTitle}", "xpack.security.accountManagement.userProfile.saveChangesButton": "{isSubmitting, select, true {正在保存更改……} other {保存更改}}", "xpack.security.accountManagement.userProfile.unsavedChangesMessage": "{count, plural, other {# 个未保存更改}}", "xpack.security.changePasswordForm.confirmButton": "{isSubmitting, select, true {正在更改密码……} other {更改密码}}", @@ -29106,7 +29102,6 @@ "xpack.security.management.apiKeys.deleteApiKey.errorMultipleNotificationTitle": "删除 {count} 个 api 密钥时出错", "xpack.security.management.apiKeys.deleteApiKey.successMultipleNotificationTitle": "已删除 {count} 个 API 密钥", "xpack.security.management.apiKeys.table.apiKeysDisabledErrorDescription": "请联系您的系统管理员并参阅{link}以启用 API 密钥。", - "xpack.security.management.apiKeys.table.fetchingApiKeysErrorMessage": "检查权限时出错:{message}", "xpack.security.management.apiKeys.table.invalidateApiKeyButton": "删除 {count, plural, other {API 密钥}}", "xpack.security.management.apiKeys.table.statusExpires": "{timeFromNow} 后过期", "xpack.security.management.editRole.featureTable.actionLegendText": "{featureName} 功能权限", @@ -29314,8 +29309,6 @@ "xpack.security.management.apiKeys.apiKeyFlyout.metadataRequired": "输入元数据或禁用此选项。", "xpack.security.management.apiKeys.apiKeyFlyout.nameRequired": "输入名称。", "xpack.security.management.apiKeys.apiKeyFlyout.roleDescriptorsRequired": "输入角色描述符或禁用此选项。", - "xpack.security.management.apiKeys.base64Description": "用于通过 Elasticsearch 进行身份验证的格式。", - "xpack.security.management.apiKeys.base64Label": "Base64", "xpack.security.management.apiKeys.beatsDescription": "用于配置 Beats 的格式。", "xpack.security.management.apiKeys.beatsLabel": "Beats", "xpack.security.management.apiKeys.createBreadcrumb": "创建", @@ -29326,8 +29319,6 @@ "xpack.security.management.apiKeys.deleteApiKey.errorSingleNotificationTitle": "删除 API 密钥“{name}”时出错", "xpack.security.management.apiKeys.deleteApiKey.successSingleNotificationTitle": "已删除 API 密钥“{name}”", "xpack.security.management.apiKeys.deniedPermissionTitle": "您需要管理 API 密钥的权限", - "xpack.security.management.apiKeys.jsonDescription": "完全的 API 响应。", - "xpack.security.management.apiKeys.jsonLabel": "JSON", "xpack.security.management.apiKeys.logstashDescription": "用于配置 Logstash 的格式。", "xpack.security.management.apiKeys.logstashLabel": "Logstash", "xpack.security.management.apiKeys.noPermissionToManageRolesDescription": "请联系您的系统管理员。", @@ -29335,26 +29326,17 @@ "xpack.security.management.apiKeys.table.apiKeysAllDescription": "查看并删除代表用户发送请求的 API 密钥。", "xpack.security.management.apiKeys.table.apiKeysDisabledErrorLinkText": "文档", "xpack.security.management.apiKeys.table.apiKeysDisabledErrorTitle": "Elasticsearch 中未启用 API 密钥", - "xpack.security.management.apiKeys.table.apiKeysOwnDescription": "查看并删除代表您发送请求的 API 密钥。", - "xpack.security.management.apiKeys.table.apiKeysReadOnlyDescription": "查看代表您发送请求的 API 密钥。", - "xpack.security.management.apiKeys.table.apiKeysTableLoadingMessage": "正在加载 API 密钥……", "xpack.security.management.apiKeys.table.apiKeysTitle": "API 密钥", "xpack.security.management.apiKeys.table.createButton": "创建 API 密钥", "xpack.security.management.apiKeys.table.createdBadge": "刚刚", - "xpack.security.management.apiKeys.table.creationDateColumnName": "创建时间", "xpack.security.management.apiKeys.table.deleteAction": "删除", "xpack.security.management.apiKeys.table.deleteDescription": "删除此 API 密钥", "xpack.security.management.apiKeys.table.loadingApiKeysDescription": "正在加载 API 密钥……", "xpack.security.management.apiKeys.table.manageOwnKeysWarning": "您仅有权管理自己的 API 密钥。", "xpack.security.management.apiKeys.table.nameColumnName": "名称", - "xpack.security.management.apiKeys.table.readOnlyOwnKeysWarning": "您仅有权查看自己的 API 密钥。", - "xpack.security.management.apiKeys.table.realmColumnName": "Realm", - "xpack.security.management.apiKeys.table.realmFilterLabel": "Realm", "xpack.security.management.apiKeys.table.statusActive": "活动", "xpack.security.management.apiKeys.table.statusColumnName": "状态", "xpack.security.management.apiKeys.table.statusExpired": "已过期", - "xpack.security.management.apiKeys.table.userFilterLabel": "用户", - "xpack.security.management.apiKeys.table.userNameColumnName": "用户", "xpack.security.management.apiKeys.updateSuccessMessage": "已更新 API 密钥“{name}”", "xpack.security.management.apiKeysEmptyPrompt.disabledErrorMessage": "API 密钥已禁用。", "xpack.security.management.apiKeysEmptyPrompt.docsLinkText": "了解如何启用 API 密钥。", @@ -29633,7 +29615,6 @@ "xpack.security.management.roles.statusColumnName": "状态", "xpack.security.management.roles.subtitle": "将角色应用到用户组并管理整个堆栈的权限。", "xpack.security.management.rolesTitle": "角色", - "xpack.security.management.users.changePasswordFlyout.userLabel": "用户", "xpack.security.management.users.changePasswordForm.confirmPasswordInvalidError": "密码不匹配。", "xpack.security.management.users.changePasswordForm.confirmPasswordLabel": "确认密码", "xpack.security.management.users.changePasswordForm.currentPasswordInvalidError": "密码无效。", @@ -33421,7 +33402,6 @@ "xpack.securitySolution.flyout.documentDetails.overviewTab.threatIntelligenceText": "威胁情报字段", "xpack.securitySolution.flyout.documentDetails.prevalenceButton": "普及率", "xpack.securitySolution.flyout.documentDetails.prevalenceTitle": "普及率", - "xpack.securitySolution.flyout.documentDetails.responseButton": "响应", "xpack.securitySolution.flyout.documentDetails.riskScoreTitle": "风险分数", "xpack.securitySolution.flyout.documentDetails.ruleDescriptionTitle": "规则描述", "xpack.securitySolution.flyout.documentDetails.sessionPreview.commandText": "依据", @@ -40474,4 +40454,4 @@ "xpack.painlessLab.walkthroughButtonLabel": "指导", "xpack.serverlessObservability.nav.getStarted": "开始使用" } -} +} \ No newline at end of file diff --git a/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/index.ts b/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/index.ts index 7f853e73cd590..06ce0e73084ee 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/index.ts +++ b/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/index.ts @@ -15,6 +15,7 @@ import { ClientPluginsStart } from '../../../plugin'; import { initDurationAnomalyAlertType } from './duration_anomaly'; export type AlertTypeInitializer = (dependencies: { + isHidden: boolean; core: CoreStart; plugins: ClientPluginsStart; }) => TAlertTypeModel; diff --git a/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/monitor_status.test.ts b/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/monitor_status.test.ts index 26c81563dbaee..b994d671ba6b3 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/monitor_status.test.ts +++ b/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/monitor_status.test.ts @@ -209,7 +209,7 @@ describe('monitor status alert type', () => { "format": [Function], "iconClass": "uptimeApp", "id": "xpack.uptime.alerts.monitorStatus", - "requiresAppContext": false, + "requiresAppContext": undefined, "ruleParamsExpression": [Function], "validate": [Function], } diff --git a/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/monitor_status.tsx b/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/monitor_status.tsx index 9af2ede31e42e..c42b3a0d8a952 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/monitor_status.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/monitor_status.tsx @@ -32,6 +32,7 @@ let validateFunc: (ruleParams: any) => ValidationResult; export const initMonitorStatusAlertType: AlertTypeInitializer = ({ core, plugins, + isHidden, }): ObservabilityRuleTypeModel => ({ id: CLIENT_ALERT_TYPES.MONITOR_STATUS, description, @@ -55,7 +56,7 @@ export const initMonitorStatusAlertType: AlertTypeInitializer = ({ }, defaultActionMessage, defaultRecoveryMessage, - requiresAppContext: false, + requiresAppContext: isHidden, format: ({ fields }) => ({ reason: fields[ALERT_REASON] || '', link: getMonitorRouteFromMonitorId({ diff --git a/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/tls.tsx b/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/tls.tsx index c44949f930ae6..a80c4567335bb 100644 --- a/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/tls.tsx +++ b/x-pack/plugins/uptime/public/legacy_uptime/lib/alert_types/tls.tsx @@ -24,6 +24,7 @@ const TLSAlert = React.lazy(() => import('./lazy_wrapper/tls_alert')); export const initTlsAlertType: AlertTypeInitializer = ({ core, plugins, + isHidden, }): ObservabilityRuleTypeModel => ({ id: CLIENT_ALERT_TYPES.TLS, iconClass: 'uptimeApp', @@ -50,7 +51,7 @@ export const initTlsAlertType: AlertTypeInitializer = ({ }, defaultActionMessage, defaultRecoveryMessage, - requiresAppContext: false, + requiresAppContext: isHidden, format: ({ fields }) => ({ reason: fields[ALERT_REASON] || '', link: `/app/uptime${CERTIFICATES_ROUTE}`, diff --git a/x-pack/plugins/uptime/public/plugin.ts b/x-pack/plugins/uptime/public/plugin.ts index 26a88d6dc11e4..0b4942e4020d7 100644 --- a/x-pack/plugins/uptime/public/plugin.ts +++ b/x-pack/plugins/uptime/public/plugin.ts @@ -58,8 +58,8 @@ import { } from './legacy_uptime/components/fleet_package'; import { LazySyntheticsCustomAssetsExtension } from './legacy_uptime/components/fleet_package/lazy_synthetics_custom_assets_extension'; import { - uptimeAlertTypeInitializers, legacyAlertTypeInitializers, + uptimeAlertTypeInitializers, } from './legacy_uptime/lib/alert_types'; import { setStartServices } from './kibana_services'; @@ -203,34 +203,10 @@ export class UptimePlugin } public start(coreStart: CoreStart, pluginsStart: ClientPluginsStart): void { - const { triggersActionsUi } = pluginsStart; - const { registerExtension } = pluginsStart.fleet; setStartServices(coreStart); registerUptimeFleetExtensions(registerExtension); - uptimeAlertTypeInitializers.forEach((init) => { - const { observabilityRuleTypeRegistry } = pluginsStart.observability; - - const alertInitializer = init({ - core: coreStart, - plugins: pluginsStart, - }); - if (!triggersActionsUi.ruleTypeRegistry.has(alertInitializer.id)) { - observabilityRuleTypeRegistry.register(alertInitializer); - } - }); - - legacyAlertTypeInitializers.forEach((init) => { - const alertInitializer = init({ - core: coreStart, - plugins: pluginsStart, - }); - if (!triggersActionsUi.ruleTypeRegistry.has(alertInitializer.id)) { - triggersActionsUi.ruleTypeRegistry.register(alertInitializer); - } - }); - setUptimeAppStatus(coreStart, pluginsStart, this.uptimeAppUpdater); } @@ -301,6 +277,7 @@ function setUptimeAppStatus( const isEnabled = coreStart.uiSettings.get(enableLegacyUptimeApp); if (isEnabled) { registerUptimeRoutesWithNavigation(coreStart, pluginsStart); + registerAlertRules(coreStart, pluginsStart, false); updater.next(() => ({ status: AppStatus.accessible })); } else { const indexStatusPromise = UptimeDataHelper(coreStart).indexStatus('now-7d', 'now'); @@ -308,10 +285,42 @@ function setUptimeAppStatus( if (indexStatus.indexExists) { registerUptimeRoutesWithNavigation(coreStart, pluginsStart); updater.next(() => ({ status: AppStatus.accessible })); + registerAlertRules(coreStart, pluginsStart, false); } else { updater.next(() => ({ status: AppStatus.inaccessible })); + registerAlertRules(coreStart, pluginsStart, true); } }); } }); } + +function registerAlertRules( + coreStart: CoreStart, + pluginsStart: ClientPluginsStart, + isHidden = false +) { + uptimeAlertTypeInitializers.forEach((init) => { + const { observabilityRuleTypeRegistry } = pluginsStart.observability; + + const alertInitializer = init({ + isHidden, + core: coreStart, + plugins: pluginsStart, + }); + if (!pluginsStart.triggersActionsUi.ruleTypeRegistry.has(alertInitializer.id)) { + observabilityRuleTypeRegistry.register(alertInitializer); + } + }); + + legacyAlertTypeInitializers.forEach((init) => { + const alertInitializer = init({ + isHidden, + core: coreStart, + plugins: pluginsStart, + }); + if (!pluginsStart.triggersActionsUi.ruleTypeRegistry.has(alertInitializer.id)) { + pluginsStart.triggersActionsUi.ruleTypeRegistry.register(alertInitializer); + } + }); +} diff --git a/x-pack/test/api_integration/apis/features/features/features.ts b/x-pack/test/api_integration/apis/features/features/features.ts index d5038a7c51ded..fd91262d57a61 100644 --- a/x-pack/test/api_integration/apis/features/features/features.ts +++ b/x-pack/test/api_integration/apis/features/features/features.ts @@ -107,6 +107,7 @@ export default function ({ getService }: FtrProviderContext) { 'graph', 'guidedOnboardingFeature', 'monitoring', + 'observabilityAIAssistant', 'observabilityCases', 'savedObjectsManagement', 'savedObjectsTagging', diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index c03f9fb91db65..ad9eb9b3bd6eb 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -24,6 +24,7 @@ export default function ({ getService }: FtrProviderContext) { maps: ['all', 'read', 'minimal_all', 'minimal_read'], generalCases: ['all', 'read', 'minimal_all', 'minimal_read', 'cases_delete'], observabilityCases: ['all', 'read', 'minimal_all', 'minimal_read', 'cases_delete'], + observabilityAIAssistant: ['all', 'read', 'minimal_all', 'minimal_read'], slo: ['all', 'read', 'minimal_all', 'minimal_read'], fleetv2: ['all', 'read', 'minimal_all', 'minimal_read'], fleet: ['all', 'read', 'minimal_all', 'minimal_read'], diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index 201590cdcaf5a..680bd9fd13298 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -32,6 +32,7 @@ export default function ({ getService }: FtrProviderContext) { maps: ['all', 'read', 'minimal_all', 'minimal_read'], generalCases: ['all', 'read', 'minimal_all', 'minimal_read'], observabilityCases: ['all', 'read', 'minimal_all', 'minimal_read'], + observabilityAIAssistant: ['all', 'read', 'minimal_all', 'minimal_read'], slo: ['all', 'read', 'minimal_all', 'minimal_read'], canvas: ['all', 'read', 'minimal_all', 'minimal_read'], infrastructure: ['all', 'read', 'minimal_all', 'minimal_read'], @@ -97,6 +98,7 @@ export default function ({ getService }: FtrProviderContext) { maps: ['all', 'read', 'minimal_all', 'minimal_read'], generalCases: ['all', 'read', 'minimal_all', 'minimal_read', 'cases_delete'], observabilityCases: ['all', 'read', 'minimal_all', 'minimal_read', 'cases_delete'], + observabilityAIAssistant: ['all', 'read', 'minimal_all', 'minimal_read'], slo: ['all', 'read', 'minimal_all', 'minimal_read'], fleetv2: ['all', 'read', 'minimal_all', 'minimal_read'], fleet: ['all', 'read', 'minimal_all', 'minimal_read'], diff --git a/x-pack/test/functional/apps/api_keys/home_page.ts b/x-pack/test/functional/apps/api_keys/home_page.ts index abc2db92906d8..316a2e32c47fd 100644 --- a/x-pack/test/functional/apps/api_keys/home_page.ts +++ b/x-pack/test/functional/apps/api_keys/home_page.ts @@ -66,7 +66,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { it('Loads the app', async () => { await security.testUser.setRoles(['test_api_keys']); - log.debug('Checking for create API key call to action'); + log.debug('Checking for Create API key call to action'); await find.existsByLinkText('Create API key'); }); @@ -91,9 +91,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const apiKeyName = 'Happy API Key'; await pageObjects.apiKeys.clickOnPromptCreateApiKey(); expect(await browser.getCurrentUrl()).to.contain('app/management/security/api_keys/create'); - expect(await pageObjects.apiKeys.getFlyoutTitleText()).to.be('Create API Key'); - - expect(await pageObjects.apiKeys.getFlyoutUsername()).to.be('test_user'); + expect(await pageObjects.apiKeys.getFlyoutTitleText()).to.be('Create API key'); await pageObjects.apiKeys.setApiKeyName(apiKeyName); await pageObjects.apiKeys.clickSubmitButtonOnApiKeyFlyout(); @@ -114,11 +112,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.apiKeys.setApiKeyName(apiKeyName); await pageObjects.apiKeys.toggleCustomExpiration(); - await pageObjects.apiKeys.clickSubmitButtonOnApiKeyFlyout(); - expect(await pageObjects.apiKeys.getErrorCallOutText()).to.be( - 'Enter a valid duration or disable this option.' - ); - await pageObjects.apiKeys.setApiKeyCustomExpiration('12'); await pageObjects.apiKeys.clickSubmitButtonOnApiKeyFlyout(); const newApiKeyCreation = await pageObjects.apiKeys.getNewApiKeyCreation(); @@ -175,7 +168,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await pageObjects.apiKeys.waitForSubmitButtonOnApiKeyFlyoutEnabled(); - expect(await pageObjects.apiKeys.getFlyoutTitleText()).to.be('Update API Key'); + expect(await pageObjects.apiKeys.getFlyoutTitleText()).to.be('Update API key'); // Verify name input box are disabled const apiKeyNameInput = await pageObjects.apiKeys.getApiKeyName(); @@ -372,8 +365,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { expect(await browser.getCurrentUrl()).to.contain('app/management/security/api_keys'); expect(await pageObjects.apiKeys.getFlyoutTitleText()).to.be('API key details'); - expect(await pageObjects.apiKeys.getFlyoutUsername()).to.be('elastic'); - // Verify name input box are disabled const apiKeyNameInput = await pageObjects.apiKeys.getApiKeyName(); expect(await apiKeyNameInput.isEnabled()).to.be(false); diff --git a/x-pack/test/functional/apps/canvas/embeddables/lens.ts b/x-pack/test/functional/apps/canvas/embeddables/lens.ts index 1c6e0bb2c7075..de7a2eb753204 100644 --- a/x-pack/test/functional/apps/canvas/embeddables/lens.ts +++ b/x-pack/test/functional/apps/canvas/embeddables/lens.ts @@ -5,11 +5,9 @@ * 2.0. */ -import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; export default function canvasLensTest({ getService, getPageObjects }: FtrProviderContext) { - const retry = getService('retry'); const PageObjects = getPageObjects(['canvas', 'common', 'header', 'lens']); const esArchiver = getService('esArchiver'); const dashboardAddPanel = getService('dashboardAddPanel'); @@ -27,12 +25,8 @@ export default function canvasLensTest({ getService, getPageObjects }: FtrProvid await kibanaServer.savedObjects.cleanStandardList(); await kibanaServer.importExport.load(archives.kbn); await kibanaServer.uiSettings.replace({ defaultIndex: 'logstash-lens' }); - // open canvas home await PageObjects.common.navigateToApp('canvas'); - // load test workpad - await PageObjects.common.navigateToApp('canvas', { - hash: '/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31/page/1', - }); + await PageObjects.canvas.createNewWorkpad(); }); after(async () => { @@ -41,16 +35,7 @@ export default function canvasLensTest({ getService, getPageObjects }: FtrProvid }); describe('by-reference', () => { - it('renders lens visualization using savedLens expression', async () => { - await PageObjects.header.waitUntilLoadingHasFinished(); - - await PageObjects.lens.assertLegacyMetric('Maximum of bytes', '16,788'); - }); - it('adds existing lens embeddable from the visualize library', async () => { - await PageObjects.canvas.goToListingPageViaBreadcrumbs(); - await PageObjects.canvas.createNewWorkpad(); - await PageObjects.canvas.setWorkpadName('lens tests'); await PageObjects.canvas.clickAddFromLibrary(); await dashboardAddPanel.addEmbeddable('Artistpreviouslyknownaslens', 'lens'); await testSubjects.existOrFail('embeddablePanelHeading-Artistpreviouslyknownaslens'); @@ -61,12 +46,21 @@ export default function canvasLensTest({ getService, getPageObjects }: FtrProvid await PageObjects.lens.save('Artistpreviouslyknownaslens v2', false, true); await testSubjects.existOrFail('embeddablePanelHeading-Artistpreviouslyknownaslensv2'); }); + + it('renders lens visualization using savedLens expression', async () => { + // load test workpad + await PageObjects.common.navigateToApp('canvas', { + hash: '/workpad/workpad-1705f884-6224-47de-ba49-ca224fe6ec31/page/1', + }); + await PageObjects.header.waitUntilLoadingHasFinished(); + + await PageObjects.lens.assertLegacyMetric('Maximum of bytes', '16,788'); + }); }); describe('by-value', () => { it('creates new lens embeddable', async () => { - await PageObjects.canvas.deleteSelectedElement(); - const originalEmbeddableCount = await PageObjects.canvas.getEmbeddableCount(); + await PageObjects.canvas.addNewPage(); await PageObjects.canvas.createNewVis('lens'); await PageObjects.lens.goToTimeRange(); await PageObjects.lens.configureDimension({ @@ -80,21 +74,26 @@ export default function canvasLensTest({ getService, getPageObjects }: FtrProvid field: 'bytes', }); await PageObjects.lens.saveAndReturn(); - await retry.try(async () => { - const embeddableCount = await PageObjects.canvas.getEmbeddableCount(); - expect(embeddableCount).to.eql(originalEmbeddableCount + 1); - }); + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.exists('xyVisChart'); }); it('edits lens by-value embeddable', async () => { - const originalEmbeddableCount = await PageObjects.canvas.getEmbeddableCount(); - await dashboardPanelActions.openContextMenu(); + await PageObjects.header.waitUntilLoadingHasFinished(); + const panelHeader = await testSubjects.find('embeddablePanelHeading-'); + await dashboardPanelActions.openContextMenu(panelHeader); await dashboardPanelActions.clickEdit(); - await PageObjects.lens.saveAndReturn(); - await retry.try(async () => { - const embeddableCount = await PageObjects.canvas.getEmbeddableCount(); - expect(embeddableCount).to.eql(originalEmbeddableCount); - }); + await await PageObjects.lens.saveAndReturn(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await testSubjects.exists('xyVisChart'); + }); + }); + + describe('switch page smoke test', async () => { + it('loads embeddables on page change', async () => { + await PageObjects.canvas.goToPreviousPage(); + await PageObjects.header.waitUntilLoadingHasFinished(); + await PageObjects.lens.assertLegacyMetric('Maximum of bytes', '16,788'); }); }); }); diff --git a/x-pack/test/functional/apps/dev_tools/feature_controls/dev_tools_security.ts b/x-pack/test/functional/apps/dev_tools/feature_controls/dev_tools_security.ts index 5f0d5f6759521..e2c21c6c59c58 100644 --- a/x-pack/test/functional/apps/dev_tools/feature_controls/dev_tools_security.ts +++ b/x-pack/test/functional/apps/dev_tools/feature_controls/dev_tools_security.ts @@ -193,8 +193,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/113080 - describe.skip('no dev_tools privileges', () => { + describe('no dev_tools privileges', () => { before(async () => { await security.role.create('no_dev_tools_privileges_role', { kibana: [ diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts index 820f8620e8af9..52da33a14c5ac 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts @@ -123,7 +123,6 @@ export default function ({ getService }: FtrProviderContext) { 'Model memory limit', '25mb', 'Version', - '8.10.0', ], }, { diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts index a28afe4bd06ff..02c14a37277ec 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation_saved_search.ts @@ -123,7 +123,6 @@ export default function ({ getService }: FtrProviderContext) { 'Model memory limit', '20mb', 'Version', - '8.10.0', ], }, { @@ -224,7 +223,6 @@ export default function ({ getService }: FtrProviderContext) { 'Model memory limit', '20mb', 'Version', - '8.10.0', ], }, { @@ -318,14 +316,7 @@ export default function ({ getService }: FtrProviderContext) { { section: 'state', // Don't include the 'Create time' value entry as it's not stable. - expectedEntries: [ - 'STOPPED', - 'Create time', - 'Model memory limit', - '7mb', - 'Version', - '8.10.0', - ], + expectedEntries: ['STOPPED', 'Create time', 'Model memory limit', '7mb', 'Version'], }, { section: 'stats', @@ -415,14 +406,7 @@ export default function ({ getService }: FtrProviderContext) { { section: 'state', // Don't include the 'Create time' value entry as it's not stable. - expectedEntries: [ - 'STOPPED', - 'Create time', - 'Model memory limit', - '6mb', - 'Version', - '8.10.0', - ], + expectedEntries: ['STOPPED', 'Create time', 'Model memory limit', '6mb', 'Version'], }, { section: 'stats', diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts index 4c73a36bd174a..b92421143fc52 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts @@ -130,14 +130,7 @@ export default function ({ getService }: FtrProviderContext) { { section: 'state', // Don't include the 'Create time' value entry as it's not stable. - expectedEntries: [ - 'STOPPED', - 'Create time', - 'Model memory limit', - '2mb', - 'Version', - '8.10.0', - ], + expectedEntries: ['STOPPED', 'Create time', 'Model memory limit', '2mb', 'Version'], }, { section: 'stats', diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts index 4eb223017dbd0..a6f68a8eafd0b 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation_saved_search.ts @@ -83,14 +83,7 @@ export default function ({ getService }: FtrProviderContext) { { section: 'state', // Don't include the 'Create time' value entry as it's not stable. - expectedEntries: [ - 'STOPPED', - 'Create time', - 'Model memory limit', - '1mb', - 'Version', - '8.10.0', - ], + expectedEntries: ['STOPPED', 'Create time', 'Model memory limit', '1mb', 'Version'], }, { section: 'stats', @@ -167,14 +160,7 @@ export default function ({ getService }: FtrProviderContext) { { section: 'state', // Don't include the 'Create time' value entry as it's not stable. - expectedEntries: [ - 'STOPPED', - 'Create time', - 'Model memory limit', - '1mb', - 'Version', - '8.10.0', - ], + expectedEntries: ['STOPPED', 'Create time', 'Model memory limit', '1mb', 'Version'], }, { section: 'stats', @@ -251,14 +237,7 @@ export default function ({ getService }: FtrProviderContext) { { section: 'state', // Don't include the 'Create time' value entry as it's not stable. - expectedEntries: [ - 'STOPPED', - 'Create time', - 'Model memory limit', - '1mb', - 'Version', - '8.10.0', - ], + expectedEntries: ['STOPPED', 'Create time', 'Model memory limit', '1mb', 'Version'], }, { section: 'stats', @@ -336,14 +315,7 @@ export default function ({ getService }: FtrProviderContext) { { section: 'state', // Don't include the 'Create time' value entry as it's not stable. - expectedEntries: [ - 'STOPPED', - 'Create time', - 'Model memory limit', - '1mb', - 'Version', - '8.10.0', - ], + expectedEntries: ['STOPPED', 'Create time', 'Model memory limit', '1mb', 'Version'], }, { section: 'stats', diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts index 96f0add69704b..df965dae9cce1 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation.ts @@ -119,7 +119,6 @@ export default function ({ getService }: FtrProviderContext) { 'Model memory limit', '16mb', 'Version', - '8.10.0', ], }, { @@ -190,7 +189,8 @@ export default function ({ getService }: FtrProviderContext) { ]; for (const testData of testDataList) { - describe(`${testData.suiteTitle}`, function () { + // FAILED ES PROMOTION: https://github.com/elastic/kibana/issues/163338 + describe.skip(`${testData.suiteTitle}`, function () { after(async () => { await ml.api.deleteIndices(testData.destinationIndex); await ml.testResources.deleteIndexPatternByTitle(testData.destinationIndex); diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation_saved_search.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation_saved_search.ts index 119fe25b35c55..043f546dea69f 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation_saved_search.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/regression_creation_saved_search.ts @@ -94,7 +94,6 @@ export default function ({ getService }: FtrProviderContext) { 'Model memory limit', '10mb', 'Version', - '8.10.0', ], }, { @@ -183,7 +182,6 @@ export default function ({ getService }: FtrProviderContext) { 'Model memory limit', '10mb', 'Version', - '8.10.0', ], }, { @@ -266,14 +264,7 @@ export default function ({ getService }: FtrProviderContext) { { section: 'state', // Don't include the 'Create time' value entry as it's not stable. - expectedEntries: [ - 'STOPPED', - 'Create time', - 'Model memory limit', - '5mb', - 'Version', - '8.10.0', - ], + expectedEntries: ['STOPPED', 'Create time', 'Model memory limit', '5mb', 'Version'], }, { section: 'stats', @@ -355,14 +346,7 @@ export default function ({ getService }: FtrProviderContext) { { section: 'state', // Don't include the 'Create time' value entry as it's not stable. - expectedEntries: [ - 'STOPPED', - 'Create time', - 'Model memory limit', - '5mb', - 'Version', - '8.10.0', - ], + expectedEntries: ['STOPPED', 'Create time', 'Model memory limit', '5mb', 'Version'], }, { section: 'stats', diff --git a/x-pack/test/functional/page_objects/api_keys_page.ts b/x-pack/test/functional/page_objects/api_keys_page.ts index 348b7025b733a..23f63c87107fa 100644 --- a/x-pack/test/functional/page_objects/api_keys_page.ts +++ b/x-pack/test/functional/page_objects/api_keys_page.ts @@ -74,11 +74,6 @@ export function ApiKeysPageProvider({ getService }: FtrProviderContext) { return euiCallOutHeader.getVisibleText(); }, - async getErrorCallOutText() { - const alertElem = await find.byCssSelector('[role="dialog"] [role="alert"] .euiText'); - return await alertElem.getVisibleText(); - }, - async getApiKeysFirstPromptTitle() { const titlePromptElem = await find.byCssSelector('.euiEmptyPrompt .euiTitle'); return await titlePromptElem.getVisibleText(); @@ -135,11 +130,6 @@ export function ApiKeysPageProvider({ getService }: FtrProviderContext) { return header.getVisibleText(); }, - async getFlyoutUsername() { - const usernameField = await testSubjects.find('apiKeyFlyoutUsername'); - return usernameField.getVisibleText(); - }, - async getFlyoutApiKeyStatus() { const apiKeyStatusField = await testSubjects.find('apiKeyStatus'); return apiKeyStatusField.getVisibleText(); diff --git a/x-pack/test/functional/page_objects/canvas_page.ts b/x-pack/test/functional/page_objects/canvas_page.ts index 5cc801be9fbeb..e2a2c6438d1f3 100644 --- a/x-pack/test/functional/page_objects/canvas_page.ts +++ b/x-pack/test/functional/page_objects/canvas_page.ts @@ -191,5 +191,29 @@ export function CanvasPageProvider({ getService, getPageObjects }: FtrProviderCo log.debug('CanvasPage.saveDatasourceChanges'); await testSubjects.click('canvasSaveDatasourceButton'); }, + + async goToPreviousPage() { + log.debug('CanvasPage.goToPreviousPage'); + await testSubjects.click('previousPageButton'); + }, + + async goToNextPage() { + log.debug('CanvasPage.goToNextPage'); + await testSubjects.click('nextPageButton'); + }, + + async togglePageManager() { + log.debug('CanvasPage.openPageManager'); + await testSubjects.click('canvasPageManagerButton'); + }, + + async addNewPage() { + log.debug('CanvasPage.addNewPage'); + if (!(await testSubjects.exists('canvasAddPageButton'))) { + await this.togglePageManager(); + } + await testSubjects.click('canvasAddPageButton'); + await this.togglePageManager(); + }, }; } diff --git a/x-pack/test/observability_functional/with_rac_write.config.ts b/x-pack/test/observability_functional/with_rac_write.config.ts index 1181d322198bd..83227af64d701 100644 --- a/x-pack/test/observability_functional/with_rac_write.config.ts +++ b/x-pack/test/observability_functional/with_rac_write.config.ts @@ -84,6 +84,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { uiSettings: { defaults: { 'dateFormat:tz': 'UTC', + 'observability:enableLegacyUptimeApp': true, }, }, testFiles: [resolve(__dirname, './apps/observability')], diff --git a/x-pack/test/saved_object_tagging/functional/tests/listing.ts b/x-pack/test/saved_object_tagging/functional/tests/listing.ts index 7b2d19095359e..8cb8ded66e1f7 100644 --- a/x-pack/test/saved_object_tagging/functional/tests/listing.ts +++ b/x-pack/test/saved_object_tagging/functional/tests/listing.ts @@ -14,7 +14,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const PageObjects = getPageObjects(['common', 'security', 'savedObjects', 'tagManagement']); const tagManagementPage = PageObjects.tagManagement; - describe('table listing', () => { + // FLAKY: https://github.com/elastic/kibana/issues/90578 + describe.skip('table listing', () => { before(async () => { await kibanaServer.importExport.load( 'x-pack/test/saved_object_tagging/common/fixtures/es_archiver/functional_base/data.json' diff --git a/x-pack/test_serverless/shared/lib/security/kibana_roles/project_controller_security_roles.yml b/x-pack/test_serverless/shared/lib/security/kibana_roles/project_controller_security_roles.yml index 6ab28435f0d7e..eff113dee5ac9 100644 --- a/x-pack/test_serverless/shared/lib/security/kibana_roles/project_controller_security_roles.yml +++ b/x-pack/test_serverless/shared/lib/security/kibana_roles/project_controller_security_roles.yml @@ -52,6 +52,11 @@ t1_analyst: privileges: - all resources: "*" + - application: osquery + privileges: + - read + - run_saved_queries + resources: "*" t2_analyst: cluster: @@ -106,6 +111,11 @@ t2_analyst: privileges: - all resources: "*" + - application: osquery + privileges: + - read + - run_saved_queries + resources: "*" t3_analyst: cluster: @@ -239,6 +249,10 @@ threat_intelligence_analyst: privileges: - all resources: "*" + - application: osquery + privileges: + - all + resources: "*" rule_author: cluster: @@ -386,6 +400,10 @@ soc_manager: privileges: - all resources: "*" + - application: osquery + privileges: + - all + resources: "*" detections_admin: cluster: @@ -510,6 +528,10 @@ platform_engineer: privileges: - all resources: "*" + - application: osquery + privileges: + - all + resources: "*" endpoint_operations_analyst: cluster: