From 78bcab310ce77f1d6fcc05a01dfc3a8d452a749f Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Wed, 21 Sep 2022 12:59:57 -0400 Subject: [PATCH 01/36] [Fleet] Hide API reference for integration with custom UI extension (#141237) --- x-pack/plugins/fleet/common/constants/epm.ts | 6 ++++ .../single_page_layout/index.tsx | 14 ++++++-- .../edit_package_policy_page/index.tsx | 8 ++++- .../sections/epm/screens/detail/index.tsx | 34 +++++++++++-------- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/fleet/common/constants/epm.ts b/x-pack/plugins/fleet/common/constants/epm.ts index 776691a895c17..f12cd9585851b 100644 --- a/x-pack/plugins/fleet/common/constants/epm.ts +++ b/x-pack/plugins/fleet/common/constants/epm.ts @@ -43,6 +43,12 @@ export const autoUpdatePackages = [ FLEET_SYNTHETICS_PACKAGE, ]; +export const HIDDEN_API_REFERENCE_PACKAGES = [ + FLEET_ENDPOINT_PACKAGE, + FLEET_APM_PACKAGE, + FLEET_SYNTHETICS_PACKAGE, +]; + export const autoUpgradePoliciesPackages = [FLEET_APM_PACKAGE, FLEET_SYNTHETICS_PACKAGE]; export const agentAssetTypes = { diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx index cc49d03f1f1c6..f517d4092942e 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/single_page_layout/index.tsx @@ -27,7 +27,11 @@ import { useCancelAddPackagePolicy, useOnSaveNavigate } from '../hooks'; import type { CreatePackagePolicyRequest } from '../../../../../../../common/types'; import { splitPkgKey } from '../../../../../../../common/services'; -import { dataTypes, FLEET_SYSTEM_PACKAGE } from '../../../../../../../common/constants'; +import { + dataTypes, + FLEET_SYSTEM_PACKAGE, + HIDDEN_API_REFERENCE_PACKAGES, +} from '../../../../../../../common/constants'; import { useConfirmForceInstall } from '../../../../../integrations/hooks'; import type { AgentPolicy, @@ -557,7 +561,13 @@ export const CreatePackagePolicySinglePage: CreatePackagePolicyParams = ({ }, ]; - const { showDevtoolsRequest } = ExperimentalFeaturesService.get(); + const { showDevtoolsRequest: isShowDevtoolRequestExperimentEnabled } = + ExperimentalFeaturesService.get(); + + const showDevtoolsRequest = + !HIDDEN_API_REFERENCE_PACKAGES.includes(packageInfo?.name ?? '') && + isShowDevtoolRequestExperimentEnabled; + const devtoolRequest = useMemo( () => generateCreatePackagePolicyDevToolsRequest({ diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx index c0eeb7044c1cf..e11d1ccda3b91 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/edit_package_policy_page/index.tsx @@ -63,6 +63,7 @@ import type { GetOnePackagePolicyResponse, UpgradePackagePolicyDryRunResponse, } from '../../../../../../common/types/rest_spec'; +import { HIDDEN_API_REFERENCE_PACKAGES } from '../../../../../../common/constants'; import type { PackagePolicyEditExtensionComponentProps } from '../../../types'; import { ExperimentalFeaturesService, pkgKeyFromPackageInfo } from '../../../services'; import { generateUpdatePackagePolicyDevToolsRequest } from '../services'; @@ -577,7 +578,12 @@ export const EditPackagePolicyForm = memo<{ ] ); - const { showDevtoolsRequest } = ExperimentalFeaturesService.get(); + const { showDevtoolsRequest: isShowDevtoolRequestExperimentEnabled } = + ExperimentalFeaturesService.get(); + + const showDevtoolsRequest = + !HIDDEN_API_REFERENCE_PACKAGES.includes(packageInfo?.name ?? '') && + isShowDevtoolRequestExperimentEnabled; const devtoolRequest = useMemo( () => diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx index c55adfe4768d1..d43afbb28835c 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/detail/index.tsx @@ -25,6 +25,8 @@ import { FormattedMessage } from '@kbn/i18n-react'; import semverLt from 'semver/functions/lt'; import { splitPkgKey } from '../../../../../../../common/services'; +import { HIDDEN_API_REFERENCE_PACKAGES } from '../../../../../../../common/constants'; + import { useGetPackageInstallStatus, useSetPackageInstallStatus, @@ -490,21 +492,23 @@ export function Detail() { }); } - tabs.push({ - id: 'api-reference', - name: ( - - ), - isSelected: panel === 'api-reference', - 'data-test-subj': `tab-api-reference`, - href: getHref('integration_details_api_reference', { - pkgkey: packageInfoKey, - ...(integration ? { integration } : {}), - }), - }); + if (!HIDDEN_API_REFERENCE_PACKAGES.includes(packageInfo.name)) { + tabs.push({ + id: 'api-reference', + name: ( + + ), + isSelected: panel === 'api-reference', + 'data-test-subj': `tab-api-reference`, + href: getHref('integration_details_api_reference', { + pkgkey: packageInfoKey, + ...(integration ? { integration } : {}), + }), + }); + } return tabs; }, [ From 37a197d73cc70ded8508baebd1ecb12a58dad067 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Wed, 21 Sep 2022 10:02:10 -0700 Subject: [PATCH 02/36] skip failing test (#141052) Signed-off-by: Tyler Smalley --- .../sections/rules_list/components/rules_list.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx index 02f2a722c9012..3bde062935a86 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rules_list/components/rules_list.test.tsx @@ -1876,7 +1876,8 @@ describe('rules_list with disabled items', () => { }); }); -describe('Rules list bulk actions', () => { +// Failing: https://github.com/elastic/kibana/issues/141052 +describe.skip('Rules list bulk actions', () => { let wrapper: ReactWrapper; async function setup(authorized: boolean = true) { From 621640e2690467b761636357120e1aea7d2a9534 Mon Sep 17 00:00:00 2001 From: Chandler Prall Date: Wed, 21 Sep 2022 11:02:38 -0600 Subject: [PATCH 03/36] Upgrade EUI to 64.0.5 (#141264) Co-authored-by: Chandler Prall --- package.json | 2 +- src/dev/license_checker/config.ts | 2 +- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index c138d74d8f0a8..339dd1a7822a9 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "@elastic/datemath": "5.0.3", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@8.3.0-canary.1", "@elastic/ems-client": "8.3.3", - "@elastic/eui": "64.0.4", + "@elastic/eui": "64.0.5", "@elastic/filesaver": "1.1.2", "@elastic/node-crypto": "1.2.1", "@elastic/numeral": "^2.5.1", diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index 840d7564681a8..de299c1298f9f 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -84,6 +84,6 @@ export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint '@elastic/ems-client@8.3.3': ['Elastic License 2.0'], - '@elastic/eui@64.0.4': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/eui@64.0.5': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry }; diff --git a/yarn.lock b/yarn.lock index 4e681bb73808f..1d81724e537b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1530,10 +1530,10 @@ resolved "https://registry.yarnpkg.com/@elastic/eslint-plugin-eui/-/eslint-plugin-eui-0.0.2.tgz#56b9ef03984a05cc213772ae3713ea8ef47b0314" integrity sha512-IoxURM5zraoQ7C8f+mJb9HYSENiZGgRVcG4tLQxE61yHNNRDXtGDWTZh8N1KIHcsqN1CEPETjuzBXkJYF/fDiQ== -"@elastic/eui@64.0.4": - version "64.0.4" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-64.0.4.tgz#4a6a997a3f43f459c82e3b992ac2e6ab318d5a12" - integrity sha512-4wpZcVJyNvxfZA58kVSwnJxIbWCrFriU6vARr/DoDB6Vvt/5zHeFrHzXFjdo+hqTWZApPoEQlK7aJ7FDZTEbkw== +"@elastic/eui@64.0.5": + version "64.0.5" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-64.0.5.tgz#d68dcebc2acd9ec360a84cb8688919de0d802417" + integrity sha512-6sJpnHYIUErA+IFJBLrXB8a86E+VR6dOBKpWVfQZVL+ZXrt4fy6uWXNompsz0geT8ylvW85oSpfpxRh+cgb0lw== dependencies: "@types/chroma-js" "^2.0.0" "@types/lodash" "^4.14.160" From 0ee0ec2fb08f40e2ed78be67b2e5e50f99a1cf41 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Wed, 21 Sep 2022 10:49:11 -0700 Subject: [PATCH 04/36] Edit rule strings (#140866) --- .../sections/common/components/rule_quick_edit_buttons.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx index c149a6c4143cd..0b7db1ebeceba 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/common/components/rule_quick_edit_buttons.tsx @@ -326,7 +326,7 @@ export const RuleQuickEditButtons: React.FunctionComponent = ({ > From f7f8fa6553c296cf57b0c86a4c80ab3b603a668c Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Wed, 21 Sep 2022 12:00:02 -0700 Subject: [PATCH 05/36] Adds 8.5 branch to versions file (#141282) Signed-off-by: Tyler Smalley Signed-off-by: Tyler Smalley --- versions.json | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/versions.json b/versions.json index 5b70f97320e23..a39a1412c46f6 100644 --- a/versions.json +++ b/versions.json @@ -2,11 +2,17 @@ "notice": "This file is not maintained outside of the main branch and should only be used for tooling.", "versions": [ { - "version": "8.5.0", + "version": "8.6.0", "branch": "main", "currentMajor": true, "currentMinor": true }, + { + "version": "8.5.0", + "branch": "8.5", + "currentMajor": true, + "previousMinor": true + }, { "version": "8.4.3", "branch": "8.4", From 96af8ce7992a2e032e1acbecca73338f337d84b9 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 21 Sep 2022 16:02:24 -0400 Subject: [PATCH 06/36] synthetics - fix monitor editing (#141284) --- .../public/legacy_uptime/state/api/monitor_management.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_management.ts b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_management.ts index 02857fafb69a9..67ac37e4b101d 100644 --- a/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_management.ts +++ b/x-pack/plugins/synthetics/public/legacy_uptime/state/api/monitor_management.ts @@ -35,7 +35,7 @@ export const setMonitor = async ({ id?: string; }): Promise<{ attributes: { errors: ServiceLocationErrors } } | SyntheticsMonitor> => { if (id) { - return await apiService.put(`${API_URLS.SYNTHETICS_MONITORS}/${id}`); + return await apiService.put(`${API_URLS.SYNTHETICS_MONITORS}/${id}`, monitor); } else { return await apiService.post(API_URLS.SYNTHETICS_MONITORS, monitor, undefined, { preserve_namespace: true, From fcfa6fb72cbd3d75b9831a7edba6e6bb1e5ef610 Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Wed, 21 Sep 2022 14:02:37 -0600 Subject: [PATCH 07/36] [Maps] functional test for adhoc data view (#141155) * [Maps] functional test for adhoc data view * revert unrelated changes * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * fix telemetry test * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../apis/maps/maps_telemetry.ts | 142 +++++++++--------- .../apps/maps/group2/adhoc_data_view.ts | 34 +++++ .../test/functional/apps/maps/group2/index.js | 1 + .../fixtures/kbn_archiver/maps.json | 22 +++ 4 files changed, 129 insertions(+), 70 deletions(-) create mode 100644 x-pack/test/functional/apps/maps/group2/adhoc_data_view.ts diff --git a/x-pack/test/api_integration/apis/maps/maps_telemetry.ts b/x-pack/test/api_integration/apis/maps/maps_telemetry.ts index 8c0191187bc4b..d4d4c48c60336 100644 --- a/x-pack/test/api_integration/apis/maps/maps_telemetry.ts +++ b/x-pack/test/api_integration/apis/maps/maps_telemetry.ts @@ -27,86 +27,88 @@ export default function ({ getService }: FtrProviderContext) { const mapUsage = apiResponse.stack_stats.kibana.plugins.maps; delete mapUsage.timeCaptured; - expect(mapUsage.geoShapeAggLayersCount).eql(1); - expect(mapUsage.indexPatternsWithGeoFieldCount).eql(6); - expect(mapUsage.indexPatternsWithGeoPointFieldCount).eql(4); - expect(mapUsage.indexPatternsWithGeoShapeFieldCount).eql(2); - expect(mapUsage.mapsTotalCount).eql(26); - expect(mapUsage.basemaps).eql({}); - expect(mapUsage.joins).eql({ term: { min: 1, max: 1, total: 3, avg: 0.11538461538461539 } }); - expect(mapUsage.layerTypes).eql({ - es_docs: { min: 1, max: 2, total: 18, avg: 0.6923076923076923 }, - es_agg_grids: { min: 1, max: 1, total: 6, avg: 0.23076923076923078 }, - es_point_to_point: { min: 1, max: 1, total: 1, avg: 0.038461538461538464 }, - es_top_hits: { min: 1, max: 1, total: 2, avg: 0.07692307692307693 }, - es_agg_heatmap: { min: 1, max: 1, total: 1, avg: 0.038461538461538464 }, - kbn_tms_raster: { min: 1, max: 1, total: 1, avg: 0.038461538461538464 }, - ems_basemap: { min: 1, max: 1, total: 1, avg: 0.038461538461538464 }, - ems_region: { min: 1, max: 1, total: 1, avg: 0.038461538461538464 }, - }); - expect(mapUsage.resolutions).eql({ - coarse: { min: 1, max: 1, total: 4, avg: 0.15384615384615385 }, - super_fine: { min: 1, max: 1, total: 3, avg: 0.11538461538461539 }, - }); - expect(mapUsage.scalingOptions).eql({ - limit: { min: 1, max: 2, total: 14, avg: 0.5384615384615384 }, - clusters: { min: 1, max: 1, total: 1, avg: 0.038461538461538464 }, - mvt: { min: 1, max: 1, total: 3, avg: 0.11538461538461539 }, - }); - expect(mapUsage.attributesPerMap).eql({ - customIconsCount: { - avg: 0, - max: 0, - min: 0, + expect(mapUsage).eql({ + geoShapeAggLayersCount: 1, + indexPatternsWithGeoFieldCount: 6, + indexPatternsWithGeoPointFieldCount: 4, + indexPatternsWithGeoShapeFieldCount: 2, + mapsTotalCount: 27, + basemaps: {}, + joins: { term: { min: 1, max: 1, total: 3, avg: 0.1111111111111111 } }, + layerTypes: { + es_docs: { min: 1, max: 2, total: 19, avg: 0.7037037037037037 }, + es_agg_grids: { min: 1, max: 1, total: 6, avg: 0.2222222222222222 }, + es_point_to_point: { min: 1, max: 1, total: 1, avg: 0.037037037037037035 }, + es_top_hits: { min: 1, max: 1, total: 2, avg: 0.07407407407407407 }, + es_agg_heatmap: { min: 1, max: 1, total: 1, avg: 0.037037037037037035 }, + kbn_tms_raster: { min: 1, max: 1, total: 1, avg: 0.037037037037037035 }, + ems_basemap: { min: 1, max: 1, total: 1, avg: 0.037037037037037035 }, + ems_region: { min: 1, max: 1, total: 1, avg: 0.037037037037037035 }, }, - dataSourcesCount: { - avg: 1.1538461538461537, - max: 5, - min: 1, + resolutions: { + coarse: { min: 1, max: 1, total: 4, avg: 0.14814814814814814 }, + super_fine: { min: 1, max: 1, total: 3, avg: 0.1111111111111111 }, }, - emsVectorLayersCount: { - idThatDoesNotExitForEMSFileSource: { - avg: 0.038461538461538464, - max: 1, - min: 1, - }, + scalingOptions: { + limit: { min: 1, max: 2, total: 14, avg: 0.5185185185185185 }, + clusters: { min: 1, max: 1, total: 1, avg: 0.037037037037037035 }, + mvt: { min: 1, max: 1, total: 4, avg: 0.14814814814814814 }, }, - layerTypesCount: { - BLENDED_VECTOR: { - avg: 0.038461538461538464, - max: 1, - min: 1, + attributesPerMap: { + customIconsCount: { + avg: 0, + max: 0, + min: 0, }, - EMS_VECTOR_TILE: { - avg: 0.038461538461538464, - max: 1, + dataSourcesCount: { + avg: 1.1481481481481481, + max: 5, min: 1, }, - GEOJSON_VECTOR: { - avg: 0.8076923076923077, - max: 4, - min: 1, + emsVectorLayersCount: { + idThatDoesNotExitForEMSFileSource: { + avg: 0.037037037037037035, + max: 1, + min: 1, + }, }, - HEATMAP: { - avg: 0.038461538461538464, - max: 1, - min: 1, + layerTypesCount: { + BLENDED_VECTOR: { + avg: 0.037037037037037035, + max: 1, + min: 1, + }, + EMS_VECTOR_TILE: { + avg: 0.037037037037037035, + max: 1, + min: 1, + }, + GEOJSON_VECTOR: { + avg: 0.7777777777777778, + max: 4, + min: 1, + }, + HEATMAP: { + avg: 0.037037037037037035, + max: 1, + min: 1, + }, + MVT_VECTOR: { + avg: 0.25925925925925924, + max: 1, + min: 1, + }, + RASTER_TILE: { + avg: 0.037037037037037035, + max: 1, + min: 1, + }, }, - MVT_VECTOR: { - avg: 0.23076923076923078, - max: 1, + layersCount: { + avg: 1.1851851851851851, + max: 6, min: 1, }, - RASTER_TILE: { - avg: 0.038461538461538464, - max: 1, - min: 1, - }, - }, - layersCount: { - avg: 1.1923076923076923, - max: 6, - min: 1, }, }); }); diff --git a/x-pack/test/functional/apps/maps/group2/adhoc_data_view.ts b/x-pack/test/functional/apps/maps/group2/adhoc_data_view.ts new file mode 100644 index 0000000000000..15824a1beb63f --- /dev/null +++ b/x-pack/test/functional/apps/maps/group2/adhoc_data_view.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ getPageObjects, getService }: FtrProviderContext) { + const security = getService('security'); + const PageObjects = getPageObjects(['maps']); + + describe('maps adhoc data view', () => { + before(async () => { + await security.testUser.setRoles(['global_maps_all', 'test_logstash_reader'], { + skipBrowserRefresh: true, + }); + await PageObjects.maps.loadSavedMap('adhoc data view'); + }); + + it('should render saved map with adhoc data view', async () => { + const tooltipText = await PageObjects.maps.getLayerTocTooltipMsg('adhocDataView'); + expect(tooltipText).to.equal( + 'adhocDataView\nFound 908 documents.\nResults narrowed by global search\nResults narrowed by global time' + ); + }); + + after(async () => { + await security.testUser.restoreDefaults(); + }); + }); +} diff --git a/x-pack/test/functional/apps/maps/group2/index.js b/x-pack/test/functional/apps/maps/group2/index.js index b8b3a15a10ed5..884c7a500c446 100644 --- a/x-pack/test/functional/apps/maps/group2/index.js +++ b/x-pack/test/functional/apps/maps/group2/index.js @@ -59,6 +59,7 @@ export default function ({ loadTestFile, getService }) { }); loadTestFile(require.resolve('./es_geo_grid_source')); + loadTestFile(require.resolve('./adhoc_data_view')); loadTestFile(require.resolve('./embeddable')); }); } diff --git a/x-pack/test/functional/fixtures/kbn_archiver/maps.json b/x-pack/test/functional/fixtures/kbn_archiver/maps.json index fcd89cc41c724..92507529a1b8a 100644 --- a/x-pack/test/functional/fixtures/kbn_archiver/maps.json +++ b/x-pack/test/functional/fixtures/kbn_archiver/maps.json @@ -990,6 +990,28 @@ "version": "WzQ5LDJd" } +{ + "id": "68f85360-3913-11ed-aa60-654006132508", + "type": "map", + "namespaces": [ + "default" + ], + "updated_at": "2022-09-20T18:39:40.421Z", + "version": "WzM0OSwxXQ==", + "attributes": { + "title": "adhoc data view", + "description": "", + "layerListJSON": "[{\"id\":\"e5b830e4-d939-4b82-b3df-ccb4c3fce478\",\"sourceDescriptor\":{\"geoField\":\"geo.coordinates\",\"id\":\"5883a356-bef3-4e87-89f4-6dfd95a5794d\",\"indexPatternId\":\"1a9589c7-c919-4d35-bd4c-fbe1bcf8dfe4\",\"label\":\"logstash-*\",\"scalingType\":\"MVT\",\"tooltipProperties\":[],\"type\":\"ES_SEARCH\"},\"type\":\"MVT_VECTOR\",\"visible\":true,\"style\":{},\"label\":\"adhocDataView\"}]", + "mapStateJSON": "{\"adHocDataViews\":[{\"id\":\"1a9589c7-c919-4d35-bd4c-fbe1bcf8dfe4\",\"title\":\"logstash-*\",\"timeFieldName\":\"@timestamp\",\"sourceFilters\":[],\"fieldFormats\":{},\"runtimeFieldMap\":{},\"fieldAttrs\":{},\"allowNoIndex\":false,\"name\":\"logstash adhoc data view\"}],\"zoom\":2.36,\"center\":{\"lon\":-116.75537,\"lat\":55.05932},\"timeFilters\":{\"from\":\"2015-09-20T00:00:00.000Z\",\"to\":\"2015-09-22T00:00:00.000Z\"},\"refreshConfig\":{\"isPaused\":false,\"interval\":0},\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filters\":[{\"meta\":{\"index\":\"1a9589c7-c919-4d35-bd4c-fbe1bcf8dfe4\",\"params\":{\"lt\":1000,\"gte\":0},\"field\":\"bytes\",\"alias\":null,\"negate\":false,\"disabled\":false,\"type\":\"range\",\"key\":\"bytes\",\"value\":{\"lt\":1000,\"gte\":0}},\"query\":{\"range\":{\"bytes\":{\"lt\":1000,\"gte\":0}}},\"$state\":{\"store\":\"appState\"}}],\"settings\":{\"autoFitToDataBounds\":false,\"backgroundColor\":\"#ffffff\",\"customIcons\":[],\"disableInteractive\":false,\"disableTooltipControl\":false,\"hideToolbarOverlay\":false,\"hideLayerControl\":false,\"hideViewControl\":false,\"initialLocation\":\"LAST_SAVED_LOCATION\",\"fixedLocation\":{\"lat\":0,\"lon\":0,\"zoom\":2},\"browserLocation\":{\"zoom\":2},\"keydownScrollZoom\":false,\"maxZoom\":24,\"minZoom\":0,\"showScaleControl\":false,\"showSpatialFilters\":true,\"showTimesliderToggleButton\":true,\"spatialFiltersAlpa\":0.3,\"spatialFiltersFillColor\":\"#DA8B45\",\"spatialFiltersLineColor\":\"#DA8B45\"}}", + "uiStateJSON": "{\"isLayerTOCOpen\":true,\"openTOCDetails\":[]}" + }, + "references": [], + "migrationVersion": { + "map": "8.4.0" + }, + "coreMigrationVersion": "8.5.0" +} + { "attributes": { "description": "", From ea79440df512aa999b96d45f823fd8b7289e2638 Mon Sep 17 00:00:00 2001 From: Sean Story Date: Wed, 21 Sep 2022 15:08:52 -0500 Subject: [PATCH 08/36] Add pipeline mapping to .elastic-connectors (#141267) * Add pipeline mapping to .elastic-connectors * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * update test * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../server/index_management/setup_indices.test.ts | 8 ++++++++ .../server/index_management/setup_indices.ts | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts index 59e7edf1d21d5..69bc3c4ab7e6e 100644 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts +++ b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.test.ts @@ -46,6 +46,14 @@ describe('Setup Indices', () => { last_sync_status: { type: 'keyword' }, last_synced: { type: 'date' }, name: { type: 'keyword' }, + pipeline: { + properties: { + extract_binary_content: { type: 'boolean' }, + name: { type: 'keyword' }, + reduce_whitespace: { type: 'boolean' }, + run_ml_inference: { type: 'boolean' }, + }, + }, scheduling: { properties: { enabled: { type: 'boolean' }, diff --git a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts index c428986f9c31f..bf6d2d3f96011 100644 --- a/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts +++ b/x-pack/plugins/enterprise_search/server/index_management/setup_indices.ts @@ -42,6 +42,14 @@ const connectorMappingsProperties: Record = { last_sync_status: { type: 'keyword' }, last_synced: { type: 'date' }, name: { type: 'keyword' }, + pipeline: { + properties: { + extract_binary_content: { type: 'boolean' }, + name: { type: 'keyword' }, + reduce_whitespace: { type: 'boolean' }, + run_ml_inference: { type: 'boolean' }, + }, + }, scheduling: { properties: { enabled: { type: 'boolean' }, From 4af903daf07bb2306cb793731c125020857c3023 Mon Sep 17 00:00:00 2001 From: Lisa Cawley Date: Wed, 21 Sep 2022 13:09:52 -0700 Subject: [PATCH 09/36] [DOCS] Augment run connector API with Swimlane details (#140340) --- .../actions-and-connectors/execute.asciidoc | 92 ++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/docs/api/actions-and-connectors/execute.asciidoc b/docs/api/actions-and-connectors/execute.asciidoc index e477d7237c273..b5c59bb86bc70 100644 --- a/docs/api/actions-and-connectors/execute.asciidoc +++ b/docs/api/actions-and-connectors/execute.asciidoc @@ -437,6 +437,60 @@ the security incident. The IPs are added as observables to the security incident `message`:: (Required, string) The message to log. ===== + +.{swimlane} connectors +[%collapsible%open] +===== +`subAction`:: +(Required, string) The action to test. It must be `pushToService`. + +`subActionParams`:: +(Required, object) The set of configuration properties. ++ +.Properties of `subActionParams` +[%collapsible%open] +====== +`comments`::: +(Optional, array of objects) Additional information that is sent to {swimlane}. ++ +.Properties of `comments` objects +[%collapsible%open] +======= +comment:::: +(string) A comment related to the incident. For example, describe how to +troubleshoot the issue. + +commentId:::: +(integer) A unique identifier for the comment. + +======= + +`incident`::: +(Required, object) Information necessary to create or update a {swimlane} incident. ++ +.Properties of `incident` +[%collapsible%open] +======= +`alertId`:::: +(Optional, string) The alert identifier. + +`caseId`:::: +(Optional, string) The case identifier for the incident. + +`caseName`:::: +(Optional, string) The case name for the incident. + +`description`:::: +(Optional, string) The description of the incident. + +`ruleName`:::: +(Optional, string) The rule name. + +`severity`:::: +(Optional, string) The severity of the incident. +======= +====== +===== ==== -- @@ -549,6 +603,41 @@ The API returns the following: } -------------------------------------------------- +Create then update a {swimlane} incident: +[source,sh] +-------------------------------------------------- +POST api/actions/connector/a4746470-2f94-11ed-b0e0-87533c532698/_execute +{ + "params":{ + "subAction":"pushToService", + "subActionParams":{ + "incident":{ + "description":"Description of the incident", + "caseName":"Case name", + "caseId":"1000" + }, + "comments":[ + {"commentId":"1","comment":"A comment about the incident"} + ] + } + } +} + +POST api/actions/connector/a4746470-2f94-11ed-b0e0-87533c532698/_execute +{ + "params":{ + "subAction":"pushToService", + "subActionParams":{ + "incident":{ + "caseId":"1000", + "caseName":"A new case name" + } + } + } +} +-------------------------------------------------- +// KIBANA + Retrieve the list of choices for a {sn-itom} connector: [source,sh] @@ -583,4 +672,5 @@ The API returns the severity and urgency choices, for example: {"dependent_value":"","label":"3 - Low","value":"3","element":"urgency"}], "connector_id":"9d9be270-2fd2-11ed-b0e0-87533c532698" } --------------------------------------------------- \ No newline at end of file +-------------------------------------------------- + From eae478dbe9fa7c7dfe5be93ed2e74d4f649fcfa7 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Wed, 21 Sep 2022 13:22:40 -0700 Subject: [PATCH 10/36] Updates backport config for v8.6 (#141302) Signed-off-by: Tyler Smalley Signed-off-by: Tyler Smalley --- .backportrc.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.backportrc.json b/.backportrc.json index db7ad3b0eb887..94c2549418f17 100644 --- a/.backportrc.json +++ b/.backportrc.json @@ -3,6 +3,7 @@ "repoName": "kibana", "targetBranchChoices": [ "main", + "8.5", "8.4", "8.3", "8.2", @@ -41,7 +42,7 @@ "backport" ], "branchLabelMapping": { - "^v8.5.0$": "main", + "^v8.6.0$": "main", "^v(\\d+).(\\d+).\\d+$": "$1.$2" }, "autoMerge": true, From 54e109a8e2406b20fade3dfca3a18b5dcb217fe0 Mon Sep 17 00:00:00 2001 From: Hannah Mudge Date: Wed, 21 Sep 2022 14:30:45 -0600 Subject: [PATCH 11/36] [Dashboard] [Controls] Fix dashboard to dashboard drilldowns where source dashboard has controls (#140548) * Remove `isFilters` check when calculating new filters * Remove `disabled` boolean type check as well * Fix initial load of dashboard * Fix pinned filters being dropped * Fix pinned filters bug * Try simplified logic * Go back to modified original logic * Add new + organize old functional tests * Fix flakiness of new test additions --- .../src/filters/helpers/meta_filter.ts | 6 +- .../lib/convert_dashboard_state.ts | 21 +- .../embeddable_to_dashboard_drilldown.tsx | 11 +- .../dashboard_to_dashboard_drilldown.ts | 285 +++++++++++++----- 4 files changed, 223 insertions(+), 100 deletions(-) diff --git a/packages/kbn-es-query/src/filters/helpers/meta_filter.ts b/packages/kbn-es-query/src/filters/helpers/meta_filter.ts index 484b85d608cff..3406ad5a5a1ce 100644 --- a/packages/kbn-es-query/src/filters/helpers/meta_filter.ts +++ b/packages/kbn-es-query/src/filters/helpers/meta_filter.ts @@ -113,11 +113,7 @@ export const unpinFilter = (filter: Filter) => * @public */ export const isFilter = (x: unknown): x is Filter => - !!x && - typeof x === 'object' && - !!(x as Filter).meta && - typeof (x as Filter).meta === 'object' && - typeof (x as Filter).meta.disabled === 'boolean'; + !!x && typeof x === 'object' && !!(x as Filter).meta && typeof (x as Filter).meta === 'object'; /** * @param {unknown} filters diff --git a/src/plugins/dashboard/public/application/lib/convert_dashboard_state.ts b/src/plugins/dashboard/public/application/lib/convert_dashboard_state.ts index 298b93c3a2fdb..c9e954a081ca2 100644 --- a/src/plugins/dashboard/public/application/lib/convert_dashboard_state.ts +++ b/src/plugins/dashboard/public/application/lib/convert_dashboard_state.ts @@ -10,15 +10,15 @@ import _ from 'lodash'; import type { KibanaExecutionContext } from '@kbn/core/public'; import type { ControlGroupInput } from '@kbn/controls-plugin/public'; +import { type EmbeddablePackageState, ViewMode } from '@kbn/embeddable-plugin/public'; import { compareFilters, - isFilterPinned, - migrateFilter, COMPARE_ALL_OPTIONS, - type Filter, + Filter, + isFilterPinned, + TimeRange, } from '@kbn/es-query'; -import { type EmbeddablePackageState, ViewMode } from '@kbn/embeddable-plugin/public'; -import type { TimeRange } from '@kbn/es-query'; +import { mapAndFlattenFilters } from '@kbn/data-plugin/public'; import type { DashboardSavedObject } from '../../saved_dashboards'; import { getTagsFromSavedDashboard, migrateAppState } from '.'; @@ -72,6 +72,7 @@ export const savedObjectToDashboardState = ({ if (rawState.timeRestore) { rawState.timeRange = { from: savedDashboard.timeFrom, to: savedDashboard.timeTo } as TimeRange; } + rawState.controlGroupInput = deserializeControlGroupFromDashboardSavedObject( savedDashboard ) as ControlGroupInput; @@ -89,9 +90,10 @@ export const stateToDashboardContainerInput = ({ executionContext, }: StateToDashboardContainerInputProps): DashboardContainerInput => { const { - data: { query: queryService }, + data: { + query: { filterManager, timefilter: timefilterService }, + }, } = pluginServices.getServices(); - const { filterManager, timefilter: timefilterService } = queryService; const { timefilter } = timefilterService; const { @@ -109,6 +111,7 @@ export const stateToDashboardContainerInput = ({ filters: dashboardFilters, } = dashboardState; + const migratedDashboardFilters = mapAndFlattenFilters(_.cloneDeep(dashboardFilters)); return { refreshConfig: timefilter.getRefreshInterval(), filters: filterManager @@ -116,8 +119,8 @@ export const stateToDashboardContainerInput = ({ .filter( (filter) => isFilterPinned(filter) || - dashboardFilters.some((dashboardFilter) => - filtersAreEqual(migrateFilter(_.cloneDeep(dashboardFilter)), filter) + migratedDashboardFilters.some((dashboardFilter) => + filtersAreEqual(dashboardFilter, filter) ) ), isFullScreenMode: fullScreenMode, diff --git a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/embeddable_to_dashboard_drilldown/embeddable_to_dashboard_drilldown.tsx b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/embeddable_to_dashboard_drilldown/embeddable_to_dashboard_drilldown.tsx index e18a8a37cf22e..5452e26207450 100644 --- a/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/embeddable_to_dashboard_drilldown/embeddable_to_dashboard_drilldown.tsx +++ b/x-pack/plugins/dashboard_enhanced/public/services/drilldowns/embeddable_to_dashboard_drilldown/embeddable_to_dashboard_drilldown.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { type Filter, isFilters, isFilterPinned, Query, TimeRange } from '@kbn/es-query'; +import { type Filter, isFilterPinned, Query, TimeRange } from '@kbn/es-query'; import type { KibanaLocation } from '@kbn/share-plugin/public'; import { DashboardAppLocatorParams, cleanEmptyKeys } from '@kbn/dashboard-plugin/public'; import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public'; @@ -62,12 +62,11 @@ export class EmbeddableToDashboardDrilldown extends AbstractDashboardDrilldown isFilterPinned(f)); + params.filters = config.useCurrentFilters + ? input.filters + : input.filters?.filter((f) => isFilterPinned(f)); } const { restOfFilters: filtersFromEvent, timeRange: timeRangeFromEvent } = extractTimeRange( diff --git a/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_dashboard_drilldown.ts b/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_dashboard_drilldown.ts index 1040498a9bd05..3b1f9c2065180 100644 --- a/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_dashboard_drilldown.ts +++ b/x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_dashboard_drilldown.ts @@ -6,6 +6,8 @@ */ import expect from '@kbn/expect'; +import { OPTIONS_LIST_CONTROL, RANGE_SLIDER_CONTROL } from '@kbn/controls-plugin/common'; + import { FtrProviderContext } from '../../../../ftr_provider_context'; const DRILLDOWN_TO_PIE_CHART_NAME = 'Go to pie chart dashboard'; @@ -18,6 +20,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const dashboardDrilldownsManage = getService('dashboardDrilldownsManage'); const PageObjects = getPageObjects([ 'dashboard', + 'dashboardControls', 'common', 'header', 'timePicker', @@ -46,20 +49,202 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async () => { await security.testUser.restoreDefaults(); - await clearFilters(dashboardDrilldownsManage.DASHBOARD_WITH_PIE_CHART_NAME); - await clearFilters(dashboardDrilldownsManage.DASHBOARD_WITH_AREA_CHART_NAME); }); - const clearFilters = async (dashboardName: string) => { - await PageObjects.dashboard.gotoDashboardEditMode(dashboardName); - await filterBar.removeAllFilters(); - await PageObjects.dashboard.clearUnsavedChanges(); - }; + describe('test dashboard to dashboard drilldown', async () => { + before(async () => { + await createDrilldown(); + }); + + after(async () => { + await cleanFiltersAndTimePicker(dashboardDrilldownsManage.DASHBOARD_WITH_PIE_CHART_NAME); + await cleanFiltersAndTimePicker(dashboardDrilldownsManage.DASHBOARD_WITH_AREA_CHART_NAME); + }); + + it('use dashboard to dashboard drilldown via onClick action', async () => { + await testCircularDashboardDrilldowns( + dashboardDrilldownPanelActions.clickActionByText.bind(dashboardDrilldownPanelActions) // preserve 'this' + ); + }); + + it('use dashboard to dashboard drilldown via getHref action', async () => { + await testCircularDashboardDrilldowns( + dashboardDrilldownPanelActions.openHrefByText.bind(dashboardDrilldownPanelActions) // preserve 'this' + ); + }); + + it('delete dashboard to dashboard drilldown', async () => { + // delete drilldown + await PageObjects.dashboard.switchToEditMode(); + await dashboardPanelActions.openContextMenu(); + await dashboardDrilldownPanelActions.expectExistsManageDrilldownsAction(); + await dashboardDrilldownPanelActions.clickManageDrilldowns(); + await dashboardDrilldownsManage.expectsManageDrilldownsFlyoutOpen(); + + await dashboardDrilldownsManage.deleteDrilldownsByTitles([DRILLDOWN_TO_AREA_CHART_NAME]); + await dashboardDrilldownsManage.closeFlyout(); + + // check that drilldown notification badge is not shown + expect(await PageObjects.dashboard.getPanelDrilldownCount()).to.be(0); + }); + + it('browser back/forward navigation works after drilldown navigation', async () => { + await PageObjects.dashboard.loadSavedDashboard( + dashboardDrilldownsManage.DASHBOARD_WITH_AREA_CHART_NAME + ); + const originalTimeRangeDurationHours = + await PageObjects.timePicker.getTimeDurationInHours(); + await brushAreaChart(); + await dashboardDrilldownPanelActions.expectMultipleActionsMenuOpened(); + await navigateWithinDashboard(async () => { + await dashboardDrilldownPanelActions.clickActionByText(DRILLDOWN_TO_PIE_CHART_NAME); + }); + // check that new time range duration was applied + const newTimeRangeDurationHours = await PageObjects.timePicker.getTimeDurationInHours(); + expect(newTimeRangeDurationHours).to.be.lessThan(originalTimeRangeDurationHours); + + await navigateWithinDashboard(async () => { + await browser.goBack(); + }); + + expect(await PageObjects.timePicker.getTimeDurationInHours()).to.be( + originalTimeRangeDurationHours + ); + }); + + const testCircularDashboardDrilldowns = async ( + drilldownAction: (text: string) => Promise + ) => { + await testPieChartDashboardDrilldown(drilldownAction); + expect(await filterBar.getFilterCount()).to.be(1); + + const originalTimeRangeDurationHours = + await PageObjects.timePicker.getTimeDurationInHours(); + await PageObjects.dashboard.clearUnsavedChanges(); + + // brush area chart and drilldown back to pie chat dashboard + await brushAreaChart(); + await dashboardDrilldownPanelActions.expectMultipleActionsMenuOpened(); + await navigateWithinDashboard(async () => { + await drilldownAction(DRILLDOWN_TO_PIE_CHART_NAME); + }); + + // because filters are preserved during navigation, we expect that only one slice is displayed (filter is still applied) + expect(await filterBar.getFilterCount()).to.be(1); + await pieChart.expectPieSliceCount(1); + // check that new time range duration was applied + const newTimeRangeDurationHours = await PageObjects.timePicker.getTimeDurationInHours(); + expect(newTimeRangeDurationHours).to.be.lessThan(originalTimeRangeDurationHours); + await PageObjects.dashboard.clearUnsavedChanges(); + }; + + const cleanFiltersAndTimePicker = async (dashboardName: string) => { + await PageObjects.dashboard.gotoDashboardEditMode(dashboardName); + await filterBar.removeAllFilters(); + await PageObjects.timePicker.setDefaultAbsoluteRange(); + await PageObjects.dashboard.clearUnsavedChanges(); + }; + }); - it('create dashboard to dashboard drilldown', async () => { + describe('test dashboard to dashboard drilldown with controls', async () => { + before('add controls and make selections', async () => { + /** Source Dashboard */ + await createDrilldown(); + await addControls(dashboardDrilldownsManage.DASHBOARD_WITH_PIE_CHART_NAME, [ + { field: 'geo.src', type: OPTIONS_LIST_CONTROL }, + { field: 'bytes', type: RANGE_SLIDER_CONTROL }, + ]); + const controlIds = await PageObjects.dashboardControls.getAllControlIds(); + const [optionsListControl, rangeSliderControl] = controlIds; + await PageObjects.dashboardControls.optionsListOpenPopover(optionsListControl); + await PageObjects.dashboardControls.optionsListPopoverSelectOption('CN'); + await PageObjects.dashboardControls.optionsListPopoverSelectOption('US'); + await PageObjects.dashboardControls.rangeSliderWaitForLoading(); // wait for range slider to respond to options list selections before proceeding + await PageObjects.dashboardControls.rangeSliderSetLowerBound(rangeSliderControl, '1000'); + await PageObjects.dashboardControls.rangeSliderSetUpperBound(rangeSliderControl, '15000'); + await PageObjects.dashboard.clickQuickSave(); + await PageObjects.dashboard.waitForRenderComplete(); + + /** Destination Dashboard */ + await addControls(dashboardDrilldownsManage.DASHBOARD_WITH_AREA_CHART_NAME, [ + { field: 'geo.src', type: OPTIONS_LIST_CONTROL }, + ]); + }); + + after(async () => { + await cleanFiltersAndControls(dashboardDrilldownsManage.DASHBOARD_WITH_PIE_CHART_NAME); + await cleanFiltersAndControls(dashboardDrilldownsManage.DASHBOARD_WITH_AREA_CHART_NAME); + }); + + it('use dashboard to dashboard drilldown via onClick action', async () => { + await testSingleDashboardDrilldown( + dashboardDrilldownPanelActions.clickActionByText.bind(dashboardDrilldownPanelActions) // preserve 'this' + ); + }); + + it('use dashboard to dashboard drilldown via getHref action', async () => { + await testSingleDashboardDrilldown( + dashboardDrilldownPanelActions.openHrefByText.bind(dashboardDrilldownPanelActions) // preserve 'this' + ); + }); + + const addControls = async ( + dashboardName: string, + controls: Array<{ field: string; type: string }> + ) => { + await PageObjects.dashboard.gotoDashboardEditMode(dashboardName); + await PageObjects.common.clearAllToasts(); // toasts get in the way of bottom "Save and close" button in create control flyout + + for (const control of controls) { + await PageObjects.dashboardControls.createControl({ + controlType: control.type, + dataViewTitle: 'logstash-*', + fieldName: control.field, + }); + } + await PageObjects.dashboard.clickQuickSave(); + }; + + const testSingleDashboardDrilldown = async ( + drilldownAction: (text: string) => Promise + ) => { + await testPieChartDashboardDrilldown(drilldownAction); + + // drilldown creates filter pills for control selections + expect(await filterBar.hasFilter('geo.src', 'CN, US')).to.be(true); + expect(await filterBar.hasFilter('bytes', '1,000 to 15,000')).to.be(true); + + // control filter pills impact destination dashboard controls + const controlIds = await PageObjects.dashboardControls.getAllControlIds(); + const optionsListControl = controlIds[0]; + await PageObjects.dashboardControls.optionsListOpenPopover(optionsListControl); + expect( + await PageObjects.dashboardControls.optionsListPopoverGetAvailableOptionsCount() + ).to.equal(2); + await PageObjects.dashboardControls.optionsListEnsurePopoverIsClosed(optionsListControl); + + // can clear unsaved changes badge after drilldown with controls + await PageObjects.dashboard.clearUnsavedChanges(); + + // clean up filters in destination dashboard + await filterBar.removeAllFilters(); + expect(await filterBar.getFilterCount()).to.be(0); + await PageObjects.dashboard.clickQuickSave(); + }; + + const cleanFiltersAndControls = async (dashboardName: string) => { + await PageObjects.dashboard.gotoDashboardEditMode(dashboardName); + await filterBar.removeAllFilters(); + await PageObjects.dashboardControls.deleteAllControls(); + await PageObjects.dashboard.clickQuickSave(); + }; + }); + + const createDrilldown = async () => { await PageObjects.dashboard.gotoDashboardEditMode( dashboardDrilldownsManage.DASHBOARD_WITH_PIE_CHART_NAME ); + await PageObjects.common.clearAllToasts(); // toasts get in the way of bottom "Create drilldown" button in flyout // create drilldown await dashboardPanelActions.openContextMenu(); await dashboardDrilldownPanelActions.expectExistsCreateDrilldownAction(); @@ -87,63 +272,21 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { } ); await testSubjects.missingOrFail('dashboardUnsavedChangesBadge'); - }); - - it('use dashboard to dashboard drilldown via onClick action', async () => { - await testDashboardDrilldown( - dashboardDrilldownPanelActions.clickActionByText.bind(dashboardDrilldownPanelActions) // preserve 'this' - ); - }); - - it('use dashboard to dashboard drilldown via getHref action', async () => { - await testDashboardDrilldown( - dashboardDrilldownPanelActions.openHrefByText.bind(dashboardDrilldownPanelActions) // preserve 'this' - ); - }); - - it('delete dashboard to dashboard drilldown', async () => { - // delete drilldown - await PageObjects.dashboard.switchToEditMode(); - await dashboardPanelActions.openContextMenu(); - await dashboardDrilldownPanelActions.expectExistsManageDrilldownsAction(); - await dashboardDrilldownPanelActions.clickManageDrilldowns(); - await dashboardDrilldownsManage.expectsManageDrilldownsFlyoutOpen(); - - await dashboardDrilldownsManage.deleteDrilldownsByTitles([DRILLDOWN_TO_AREA_CHART_NAME]); - await dashboardDrilldownsManage.closeFlyout(); - - // check that drilldown notification badge is not shown - expect(await PageObjects.dashboard.getPanelDrilldownCount()).to.be(0); - }); - - it('browser back/forward navigation works after drilldown navigation', async () => { - await PageObjects.dashboard.loadSavedDashboard( - dashboardDrilldownsManage.DASHBOARD_WITH_AREA_CHART_NAME - ); - const originalTimeRangeDurationHours = - await PageObjects.timePicker.getTimeDurationInHours(); - await brushAreaChart(); - await dashboardDrilldownPanelActions.expectMultipleActionsMenuOpened(); - await navigateWithinDashboard(async () => { - await dashboardDrilldownPanelActions.clickActionByText(DRILLDOWN_TO_PIE_CHART_NAME); - }); - // check that new time range duration was applied - const newTimeRangeDurationHours = await PageObjects.timePicker.getTimeDurationInHours(); - expect(newTimeRangeDurationHours).to.be.lessThan(originalTimeRangeDurationHours); - - await navigateWithinDashboard(async () => { - await browser.goBack(); - }); + }; - expect(await PageObjects.timePicker.getTimeDurationInHours()).to.be( - originalTimeRangeDurationHours + const testPieChartDashboardDrilldown = async ( + drilldownAction: (text: string) => Promise + ) => { + await PageObjects.dashboard.gotoDashboardEditMode( + dashboardDrilldownsManage.DASHBOARD_WITH_PIE_CHART_NAME ); - }); - const testDashboardDrilldown = async (drilldownAction: (text: string) => Promise) => { // trigger drilldown action by clicking on a pie and picking drilldown action by it's name - await pieChart.clickOnPieSlice('40000'); - await dashboardDrilldownPanelActions.expectMultipleActionsMenuOpened(); + await retry.waitFor('drilldown action menu to appear', async () => { + // avoid flakiness of context menu opening + await pieChart.clickOnPieSlice('40000'); // + return await testSubjects.exists('multipleActionsContextMenu'); + }); const href = await dashboardDrilldownPanelActions.getActionHrefByText( DRILLDOWN_TO_AREA_CHART_NAME @@ -160,25 +303,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { ); // check that we drilled-down with filter from pie chart - expect(await filterBar.getFilterCount()).to.be(1); - const originalTimeRangeDurationHours = - await PageObjects.timePicker.getTimeDurationInHours(); - await PageObjects.dashboard.clearUnsavedChanges(); - - // brush area chart and drilldown back to pie chat dashboard - await brushAreaChart(); - await dashboardDrilldownPanelActions.expectMultipleActionsMenuOpened(); - await navigateWithinDashboard(async () => { - await drilldownAction(DRILLDOWN_TO_PIE_CHART_NAME); - }); - - // because filters are preserved during navigation, we expect that only one slice is displayed (filter is still applied) - expect(await filterBar.getFilterCount()).to.be(1); - await pieChart.expectPieSliceCount(1); - // check that new time range duration was applied - const newTimeRangeDurationHours = await PageObjects.timePicker.getTimeDurationInHours(); - expect(newTimeRangeDurationHours).to.be.lessThan(originalTimeRangeDurationHours); - await PageObjects.dashboard.clearUnsavedChanges(); + expect(await filterBar.hasFilter('memory', '40,000 to 80,000')).to.be(true); }; }); From b77de155c62ebcd5ffeea04b12b8c0d171b04b17 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Wed, 21 Sep 2022 14:28:56 -0700 Subject: [PATCH 12/36] Bumps version to 8.6.0 (#141257) * Bumps version to 8.6.0 Signed-off-by: Tyler Smalley * Ignore version in snapshot Signed-off-by: Tyler Smalley * Skip test with Kibana version in assertion Signed-off-by: Tyler Smalley Signed-off-by: Tyler Smalley --- package.json | 2 +- .../src/analytics_service.test.ts | 16 +++++++++++++--- x-pack/package.json | 2 +- .../apps/endpoint/endpoint_list.ts | 3 ++- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 339dd1a7822a9..c257e1a46fc9a 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "dashboarding" ], "private": true, - "version": "8.5.0", + "version": "8.6.0", "branch": "main", "types": "./kibana.d.ts", "tsdocMetadata": "./build/tsdoc-metadata.json", diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts index 2609859ae9d8c..164e692e1c845 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts @@ -22,16 +22,26 @@ describe('AnalyticsService', () => { expect(analyticsClientMock.registerContextProvider).toHaveBeenCalledTimes(1); await expect( await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) - ).toMatchInlineSnapshot(` + ).toMatchInlineSnapshot( + { + branch: 'main', + buildNum: 9007199254740991, + buildSha: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + isDev: true, + isDistributable: false, + version: expect.any(String), + }, + ` Object { "branch": "main", "buildNum": 9007199254740991, "buildSha": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "isDev": true, "isDistributable": false, - "version": "8.5.0", + "version": Any, } - `); + ` + ); }); test('should register the `performance_metric` event type on creation', () => { diff --git a/x-pack/package.json b/x-pack/package.json index 2433a70c26123..fe6050dd8f95d 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -1,6 +1,6 @@ { "name": "x-pack", - "version": "8.5.0", + "version": "8.6.0", "author": "Elastic", "private": true, "license": "Elastic-License", diff --git a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts index a5b13c083b278..730486ccf94f5 100644 --- a/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts +++ b/x-pack/test/security_solution_endpoint/apps/endpoint/endpoint_list.ts @@ -96,7 +96,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - describe('when there is data,', () => { + // Version specific: https://github.com/elastic/kibana/issues/141298 + describe.skip('when there is data,', () => { before(async () => { indexedData = await endpointTestResources.loadEndpointData({ numHosts: 3 }); await pageObjects.endpoint.navigateToEndpointList(); From 77f73294dbf72396058d8e3b88cd5b6560391c64 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Wed, 21 Sep 2022 17:00:51 -0500 Subject: [PATCH 13/36] [Enterprise Search] update supported ml models filter (#141307) Updated the list of keys for the inference_config that we support for models in enterprise search. --- .../pipelines/ml_inference/utils.test.ts | 24 ++++++++++++++----- .../pipelines/ml_inference/utils.ts | 3 ++- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.test.ts index 3ea6890c41932..4a9c11faa7f73 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.test.ts @@ -31,11 +31,6 @@ describe('ml inference utils', () => { ner: {}, }, }), - makeFakeModel({ - inference_config: { - classification: {}, - }, - }), makeFakeModel({ inference_config: { text_classification: {}, @@ -53,6 +48,16 @@ describe('ml inference utils', () => { }, }, }), + makeFakeModel({ + inference_config: { + question_answering: {}, + }, + }), + makeFakeModel({ + inference_config: { + fill_mask: {}, + }, + }), ]; for (const model of models) { @@ -61,7 +66,14 @@ describe('ml inference utils', () => { }); it('returns false for expected models', () => { - const models: TrainedModelConfigResponse[] = [makeFakeModel({})]; + const models: TrainedModelConfigResponse[] = [ + makeFakeModel({}), + makeFakeModel({ + inference_config: { + classification: {}, + }, + }), + ]; for (const model of models) { expect(isSupportedMLModel(model)).toBe(false); diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.ts b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.ts index 83cf04585b5ff..b788a522d395f 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/utils.ts @@ -11,10 +11,11 @@ import { TrainedModelConfigResponse } from '@kbn/ml-plugin/common/types/trained_ import { AddInferencePipelineFormErrors, InferencePipelineConfiguration } from './types'; const NLP_CONFIG_KEYS = [ + 'fill_mask', 'ner', - 'classification', 'text_classification', 'text_embedding', + 'question_answering', 'zero_shot_classification', ]; export const isSupportedMLModel = (model: TrainedModelConfigResponse): boolean => { From 5ee90a4795f3cbcfc5c2aa7bcfe7e760f8e520b3 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Wed, 21 Sep 2022 17:02:04 -0500 Subject: [PATCH 14/36] [Enterprise Search] remove pipelines feature flag (#141275) --- .../server/collectors/management/schema.ts | 4 ---- .../server/collectors/management/types.ts | 1 - src/plugins/telemetry/schema/oss_plugins.json | 6 ------ .../enterprise_search/common/ui_settings_keys.ts | 1 - .../plugins/enterprise_search/server/ui_settings.ts | 13 ------------- 5 files changed, 25 deletions(-) diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts index d8511298f6ac9..41df488839358 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/schema.ts @@ -562,10 +562,6 @@ export const stackManagementSchema: MakeSchemaFrom = { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, }, - 'enterpriseSearch:enableIndexTransformsTab': { - type: 'boolean', - _meta: { description: 'Non-default value of setting.' }, - }, 'enterpriseSearch:enableBehavioralAnalyticsSection': { type: 'boolean', _meta: { description: 'Non-default value of setting.' }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts index 7ca9ddfeef5b9..2bd59dc69084f 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/management/types.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/management/types.ts @@ -150,6 +150,5 @@ export interface UsageStats { 'securitySolution:enableGroupedNav': boolean; 'securitySolution:showRelatedIntegrations': boolean; 'visualization:visualize:legacyGaugeChartsLibrary': boolean; - 'enterpriseSearch:enableIndexTransformsTab': boolean; 'enterpriseSearch:enableBehavioralAnalyticsSection': boolean; } diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index 0a4d6c347674d..1a97586dffa62 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -8888,12 +8888,6 @@ "description": "Non-default value of setting." } }, - "enterpriseSearch:enableIndexTransformsTab": { - "type": "boolean", - "_meta": { - "description": "Non-default value of setting." - } - }, "enterpriseSearch:enableBehavioralAnalyticsSection": { "type": "boolean", "_meta": { diff --git a/x-pack/plugins/enterprise_search/common/ui_settings_keys.ts b/x-pack/plugins/enterprise_search/common/ui_settings_keys.ts index dc960fb103ddd..d06902fe04fab 100644 --- a/x-pack/plugins/enterprise_search/common/ui_settings_keys.ts +++ b/x-pack/plugins/enterprise_search/common/ui_settings_keys.ts @@ -6,5 +6,4 @@ */ export const enterpriseSearchFeatureId = 'enterpriseSearch'; -export const enableIndexPipelinesTab = 'enterpriseSearch:enableIndexTransformsTab'; export const enableBehavioralAnalyticsSection = 'enterpriseSearch:enableBehavioralAnalyticsSection'; diff --git a/x-pack/plugins/enterprise_search/server/ui_settings.ts b/x-pack/plugins/enterprise_search/server/ui_settings.ts index 0be413f8d9c6a..3334e625bc08f 100644 --- a/x-pack/plugins/enterprise_search/server/ui_settings.ts +++ b/x-pack/plugins/enterprise_search/server/ui_settings.ts @@ -11,7 +11,6 @@ import { i18n } from '@kbn/i18n'; import { enterpriseSearchFeatureId, - enableIndexPipelinesTab, enableBehavioralAnalyticsSection, } from '../common/ui_settings_keys'; @@ -31,16 +30,4 @@ export const uiSettings: Record> = { schema: schema.boolean(), value: false, }, - [enableIndexPipelinesTab]: { - category: [enterpriseSearchFeatureId], - description: i18n.translate('xpack.enterpriseSearch.uiSettings.indexPipelines.description', { - defaultMessage: 'Enable the new index pipelines tab in Enterprise Search.', - }), - name: i18n.translate('xpack.enterpriseSearch.uiSettings.indexPipelines.name', { - defaultMessage: 'Enable index pipelines', - }), - requiresPageReload: false, - schema: schema.boolean(), - value: false, - }, }; From a7bd74322b74053174534376469ee1f39e1238d7 Mon Sep 17 00:00:00 2001 From: "Quynh Nguyen (Quinn)" <43350163+qn895@users.noreply.github.com> Date: Wed, 21 Sep 2022 17:17:42 -0500 Subject: [PATCH 15/36] [ML] Fix Open in Single Metric Viewer links not reflecting custom time range for Anomaly chart embeddables (#141007) --- .../explorer_anomalies_container.tsx | 3 +++ .../explorer_charts_container.js | 27 +++++++++++++++---- .../ml/public/application/util/chart_utils.js | 11 ++------ ...ble_anomaly_charts_container.test.tsx.snap | 1 + ...beddable_anomaly_charts_container.test.tsx | 2 +- .../embeddable_anomaly_charts_container.tsx | 4 +++ 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_anomalies_container.tsx b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_anomalies_container.tsx index 960564fa5dfbf..542c71fa9fd4f 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_anomalies_container.tsx +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_anomalies_container.tsx @@ -34,6 +34,7 @@ interface ExplorerAnomaliesContainerProps { onSelectEntity: (fieldName: string, fieldValue: string, operation: EntityFieldOperation) => void; showSelectedInterval?: boolean; chartsService: ChartsPluginStart; + timeRange: { from: string; to: string } | undefined; } const tooManyBucketsCalloutMsg = i18n.translate( @@ -56,6 +57,7 @@ export const ExplorerAnomaliesContainer: FC = ( onSelectEntity, showSelectedInterval, chartsService, + timeRange, }) => { return ( <> @@ -87,6 +89,7 @@ export const ExplorerAnomaliesContainer: FC = ( mlLocator, timeBuckets, timefilter, + timeRange, onSelectEntity, tooManyBucketsCalloutMsg, showSelectedInterval, diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container.js index d000b5cd465ef..30a32f1953a16 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container.js @@ -94,6 +94,7 @@ function ExplorerChartContainer({ mlLocator, timeBuckets, timefilter, + timeRange, onSelectEntity, recentlyAccessed, tooManyBucketsCalloutMsg, @@ -105,7 +106,6 @@ function ExplorerChartContainer({ const { services: { - data, share, application: { navigateToApp }, }, @@ -118,20 +118,35 @@ function ExplorerChartContainer({ const locator = share.url.locators.get(MAPS_APP_LOCATOR); const location = await locator.getLocation({ initialLayers: initialLayers, - timeRange: data.query.timefilter.timefilter.getTime(), + timeRange: timeRange ?? timefilter?.getTime(), ...(queryString !== undefined ? { query } : {}), }); return location; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [series?.jobId]); + }, [series?.jobId, timeRange]); useEffect(() => { let isCancelled = false; const generateLink = async () => { + // Prioritize timeRange from embeddable panel or case + // Else use the time range from data plugins's timefilters service + let mergedTimeRange = timeRange; + const bounds = timefilter?.getActiveBounds(); + if (!timeRange && bounds) { + mergedTimeRange = { + from: bounds.min.toISOString(), + to: bounds.max.toISOString(), + }; + } + if (!isCancelled && series.functionDescription !== ML_JOB_AGGREGATION.LAT_LONG) { try { - const singleMetricViewerLink = await getExploreSeriesLink(mlLocator, series, timefilter); + const singleMetricViewerLink = await getExploreSeriesLink( + mlLocator, + series, + mergedTimeRange + ); setExplorerSeriesLink(singleMetricViewerLink); } catch (error) { setExplorerSeriesLink(''); @@ -143,7 +158,7 @@ function ExplorerChartContainer({ isCancelled = true; }; // eslint-disable-next-line react-hooks/exhaustive-deps - }, [mlLocator, series]); + }, [mlLocator, series, timeRange]); useEffect( function getMapsPluginLink() { @@ -358,6 +373,7 @@ export const ExplorerChartsContainerUI = ({ mlLocator, timeBuckets, timefilter, + timeRange, onSelectEntity, tooManyBucketsCalloutMsg, showSelectedInterval, @@ -420,6 +436,7 @@ export const ExplorerChartsContainerUI = ({ mlLocator={mlLocator} timeBuckets={timeBuckets} timefilter={timefilter} + timeRange={timeRange} onSelectEntity={onSelectEntity} recentlyAccessed={recentlyAccessed} tooManyBucketsCalloutMsg={tooManyBucketsCalloutMsg} diff --git a/x-pack/plugins/ml/public/application/util/chart_utils.js b/x-pack/plugins/ml/public/application/util/chart_utils.js index b05c8b20b22ca..4936f80f1911c 100644 --- a/x-pack/plugins/ml/public/application/util/chart_utils.js +++ b/x-pack/plugins/ml/public/application/util/chart_utils.js @@ -174,12 +174,9 @@ export function getChartType(config) { return chartType; } -export async function getExploreSeriesLink(mlLocator, series, timefilter) { +export async function getExploreSeriesLink(mlLocator, series, timeRange) { // Open the Single Metric dashboard over the same overall bounds and // zoomed in to the same time as the current chart. - const bounds = timefilter.getActiveBounds(); - const from = bounds.min.toISOString(); // e.g. 2016-02-08T16:00:00.000Z - const to = bounds.max.toISOString(); const zoomFrom = moment(series.plotEarliest).toISOString(); const zoomTo = moment(series.plotLatest).toISOString(); @@ -206,11 +203,7 @@ export async function getExploreSeriesLink(mlLocator, series, timefilter) { pause: true, value: 0, }, - timeRange: { - from: from, - to: to, - mode: 'absolute', - }, + timeRange, zoom: { from: zoomFrom, to: zoomTo, diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/__snapshots__/embeddable_anomaly_charts_container.test.tsx.snap b/x-pack/plugins/ml/public/embeddables/anomaly_charts/__snapshots__/embeddable_anomaly_charts_container.test.tsx.snap index cb9a915a105a8..531db022eb4ad 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/__snapshots__/embeddable_anomaly_charts_container.test.tsx.snap +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/__snapshots__/embeddable_anomaly_charts_container.test.tsx.snap @@ -31,6 +31,7 @@ Object { "barTarget": undefined, "maxBars": undefined, }, + "timeRange": undefined, "timefilter": Object { "calculateBounds": [MockFunction], "createFilter": [MockFunction], diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.test.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.test.tsx index 5a22cb7809a8c..95012ed2e890b 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.test.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.test.tsx @@ -163,7 +163,7 @@ describe('EmbeddableAnomalyChartsContainer', () => { }); test('should render an error in case it could not fetch the ML charts data', async () => { - (useAnomalyChartsInputResolver as jest.Mock).mockReturnValueOnce({ + (useAnomalyChartsInputResolver as jest.Mock).mockReturnValue({ chartsData: undefined, isLoading: false, error: 'No anomalies', diff --git a/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.tsx b/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.tsx index a0275176afa24..e9a22f1ad244e 100644 --- a/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.tsx +++ b/x-pack/plugins/ml/public/embeddables/anomaly_charts/embeddable_anomaly_charts_container.tsx @@ -11,6 +11,7 @@ import { Observable } from 'rxjs'; import { FormattedMessage } from '@kbn/i18n-react'; import { throttle } from 'lodash'; import { UI_SETTINGS } from '@kbn/data-plugin/common'; +import useObservable from 'react-use/lib/useObservable'; import { useEmbeddableExecutionContext } from '../common/use_embeddable_execution_context'; import { useAnomalyChartsInputResolver } from './use_anomaly_charts_input_resolver'; import type { IAnomalyChartsEmbeddable } from './anomaly_charts_embeddable'; @@ -90,6 +91,8 @@ export const EmbeddableAnomalyChartsContainer: FC { onInputChange({ severityThreshold: severity.val, @@ -204,6 +207,7 @@ export const EmbeddableAnomalyChartsContainer: FC )} From 87f62e75f200d06003c6b012d714e0e779c7a3bc Mon Sep 17 00:00:00 2001 From: gchaps <33642766+gchaps@users.noreply.github.com> Date: Wed, 21 Sep 2022 15:24:19 -0700 Subject: [PATCH 16/36] [DOCS] Updates version for highlights (#141281) --- docs/user/whats-new.asciidoc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/user/whats-new.asciidoc b/docs/user/whats-new.asciidoc index 640a824180480..399de14d5f18c 100644 --- a/docs/user/whats-new.asciidoc +++ b/docs/user/whats-new.asciidoc @@ -1,8 +1,12 @@ [[whats-new]] -== What's new in 8.0 +== What's new in {minor-version} -This section summarizes the most important changes in each release. For the -full list, see <> and <>. +Here are the highlights of what's new and improved in {minor-version}. +For detailed information about this release, +check the <>. + +Previous versions: {kibana-ref-all}/8.4/whats-new.html[8.4] | {kibana-ref-all}/8.3/whats-new.html[8.3] | {kibana-ref-all}/8.2/whats-new.html[8.2] +| {kibana-ref-all}/8.1/whats-new.html[8.1] | {kibana-ref-all}/8.0/whats-new.html[8.0] //NOTE: The notable-highlights tagged regions are re-used in the //Installation and Upgrade Guide From 2b0754c48672caf42bf661674fb1bdaabf0c2326 Mon Sep 17 00:00:00 2001 From: Tyler Smalley Date: Wed, 21 Sep 2022 15:45:32 -0700 Subject: [PATCH 17/36] Ignores branch in snapshot Signed-off-by: Tyler Smalley --- .../src/analytics_service.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts index 164e692e1c845..6e21336bbb6fe 100644 --- a/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts +++ b/packages/core/analytics/core-analytics-server-internal/src/analytics_service.test.ts @@ -24,7 +24,7 @@ describe('AnalyticsService', () => { await firstValueFrom(analyticsClientMock.registerContextProvider.mock.calls[0][0].context$) ).toMatchInlineSnapshot( { - branch: 'main', + branch: expect.any(String), buildNum: 9007199254740991, buildSha: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', isDev: true, @@ -33,7 +33,7 @@ describe('AnalyticsService', () => { }, ` Object { - "branch": "main", + "branch": Any, "buildNum": 9007199254740991, "buildSha": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", "isDev": true, From e4c7bbf75edfe3a3942a239ac3001239fbb22516 Mon Sep 17 00:00:00 2001 From: gchaps <33642766+gchaps@users.noreply.github.com> Date: Wed, 21 Sep 2022 16:11:41 -0700 Subject: [PATCH 18/36] [DOCS] Updates saved objects & other docs (#139328) * [DOCS] Updates saved objects doc * [DOCS] Edtis tags doc * [DOCS] Removes video from discover docs * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-tags.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-tags.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-tags.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-tags.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-tags.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * Update docs/management/managing-saved-objects.asciidoc Co-authored-by: Kaarina Tungseth * [DOCS] Incorporates review comments Co-authored-by: Kaarina Tungseth Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- docs/discover/document-explorer.asciidoc | 18 +-- .../managing-saved-objects.asciidoc | 128 ++++++++++-------- docs/management/managing-tags.asciidoc | 28 ++-- docs/user/graph/getting-started.asciidoc | 2 +- 4 files changed, 93 insertions(+), 83 deletions(-) diff --git a/docs/discover/document-explorer.asciidoc b/docs/discover/document-explorer.asciidoc index 32811cfbe7728..9547dbaf4477f 100644 --- a/docs/discover/document-explorer.asciidoc +++ b/docs/discover/document-explorer.asciidoc @@ -3,23 +3,11 @@ *Discover* displays your documents in table format, so you can -best explore your data. -Use the document table to resize columns, set row height, +best explore your data. Resize columns, set row height, perform multi-column sorting, compare data, and more. -++++ - - -
-++++ +[role="screenshot"] +image:images/customer.png[Customer last name, first initial in the document table] [float] [[document-explorer-columns]] diff --git a/docs/management/managing-saved-objects.asciidoc b/docs/management/managing-saved-objects.asciidoc index ee1247501e8da..7fccd6c6c93f7 100644 --- a/docs/management/managing-saved-objects.asciidoc +++ b/docs/management/managing-saved-objects.asciidoc @@ -1,11 +1,10 @@ [[managing-saved-objects]] -== Saved Objects +== Manage saved objects -The *Saved Objects* UI helps you keep track of and manage your saved objects. These objects -store data for later use, including dashboards, visualizations, maps, data views, -Canvas workpads, and more. +Edit, import, export, and copy your saved objects. These objects include +dashboards, visualizations, maps, {data-sources}, *Canvas* workpads, and other saved objects. -To get started, open the main menu, then click *Stack Management > Saved Objects*. +To get started, open the main menu, and then click *Stack Management > Saved Objects*. [role="screenshot"] image::images/management-saved-objects.png[Saved Objects] @@ -13,23 +12,24 @@ image::images/management-saved-objects.png[Saved Objects] [float] === Required permissions -The `Saved Objects Management` {kib} privilege is required to access the *Saved Objects* UI. +To access *Saved Objects*, you must have the required `Saved Objects Management` {kib} privilege. -To add the privilege, open the menu, then click *Stack Management > Roles*. +To add the privilege, open the main menu, and then click *Stack Management > Roles*. -NOTE: -Granting access to Saved Objects Management will authorize users to manage all saved objects in {kib}, including objects that are managed by applications they may not otherwise be authorized to access. +NOTE: Granting access to `Saved Objects Management` authorizes users to +manage all saved objects in {kib}, including objects that are managed by +applications they may not otherwise be authorized to access. [float] [[managing-saved-objects-view]] === View and delete -* To view and edit an object in its associated application, click the object title. +* To view and edit a saved object in its associated application, click the object title. * To show objects that use this object, so you know the impact of deleting it, click the actions icon image:images/actions_icon.png[Actions icon] -and select *Relationships*. +and then select *Relationships*. * To delete one or more objects, select their checkboxes, and then click *Delete*. @@ -37,58 +37,67 @@ and select *Relationships*. [[managing-saved-objects-export-objects]] === Import and export -Using the import and export actions, you can move objects between different -{kib} instances. This action is useful when you -have multiple environments for development and production. -Import and export also work well when you have a large number -of objects to update and want to batch the process. +Use import and export to move objects between different {kib} instances. +These actions are useful when you have multiple environments for development and production. +Import and export also work well when you have a large number of objects to update and want to batch the process. -In addition to the user interface, {kib} provides beta <> and <> APIs if -you want to automate this process. +{kib} also provides <> and +<> APIs to automate this process. -[float] -==== Compatibility across versions - -With each release, {kib} introduces changes to the way saved objects are stored. When importing a saved object, {kib} will run the necessary migrations to ensure that the imported saved objects are compatible with the current version. - -However, saved objects can only be imported into the same version, a newer minor on the same major, or the next major. Exported saved objects are not backwards compatible and cannot be imported into an older version of {kib}. See the table below for compatibility examples: - -|======= -| Exporting version | Importing version | Compatible? -| 6.7.0 | 6.8.1 | Yes -| 6.8.1 | 7.3.0 | Yes -| 7.3.0 | 7.11.1 | Yes -| 7.11.1 | 7.6.0 | No -| 6.8.1 | 8.0.0 | No -|======= [float] ==== Import -You can import multiple objects in a single operation. Click *Import* and -navigate to the NDJSON file that -represents the objects to import. By default, +Import multiple objects in a single operation. + +. In the toolbar, click *Import*. +. Select the NDJSON file that +includes the objects you want to import. +. Select the import options. By default, saved objects already in {kib} are overwritten. +. Click *Import*. NOTE: The <> configuration setting -limits the number of saved objects which may be included in this file. Similarly, the +limits the number of saved objects to include in the file. The <> setting limits the overall -size of the file that can be imported. +size of the file that you can import. [float] ==== Export -You have two options for exporting saved objects. +Export objects by selection or type. -* Select the checkboxes of objects that you want to export, and then click *Export*. -* Click *Export x objects*, and export objects by type. +* To export specific objects, select them in the table, and then click *Export*. +* To export objects by type, click *Export objects* in the toolbar. -This action creates an NDJSON with all your saved objects. By default, the NDJSON includes child objects that are related to the saved -objects. Exported dashboards include their associated data views. +{kib} creates an NDJSON with all your saved objects. By default, the NDJSON includes child objects related to the saved +objects. Exported dashboards include their associated {data-sources}. NOTE: The <> configuration setting -limits the number of saved objects which may be exported. +limits the number of saved objects that you can export. + +[float] +==== Compatibility across versions + +With each release, {kib} introduces changes to the way saved objects are stored. +When importing a saved object, {kib} runs the necessary migrations to ensure +that the imported saved objects are compatible with the current version. + +However, saved objects can only be imported into the same version, +a newer minor on the same major, or the next major. +Exported saved objects are not backward compatible and cannot be imported +into an older version of {kib}. For example: + +|======= +| Exporting version | Importing version | Compatible? +| 6.7.0 | 6.8.1 | Yes +| 6.8.1 | 7.3.0 | Yes +| 7.3.0 | 7.11.1 | Yes +| 7.11.1 | 7.6.0 | No +| 6.8.1 | 8.0.0 | No +|======= + [float] @@ -96,12 +105,16 @@ limits the number of saved objects which may be exported. [[managing-saved-objects-copy-to-space]] === Copy to other {kib} spaces -To copy a saved object to another space, click the actions icon image:images/actions_icon.png[Actions icon] -and select *Copy to spaces*. From here, you can select the spaces in which to copy the object. -You can also select whether to automatically overwrite any conflicts in the target spaces, or -resolve them manually. +Copy saved objects and their related objects between spaces. -WARNING: The copy operation automatically includes child objects that are related to the saved objects. If you don't want this behavior, use +. Click the actions icon image:images/actions_icon.png[Actions icon]. +. Click *Copy to spaces*. +. Select the spaces in which to copy the object. +. Specify whether to automatically overwrite any objects that already exist +in the target spaces, or resolve them on a per-object basis. ++ +The copy operation automatically includes child objects that are related to +the saved object. If you don't want this behavior, use the <> instead. [float] @@ -109,13 +122,18 @@ the <> instead. [[managing-saved-objects-share-to-space]] === Share to other {kib} spaces -To share a saved object to another space -- which makes a single saved object available in multiple spaces -- click the actions icon -image:images/actions_icon.png[Actions icon] and select *Share to spaces*. From here, you can select the spaces in which to share the object, -or indicate that you want the object to be shared to _all spaces_, which includes those that exist now and any created in the future. +Make a single saved object available in multiple spaces. -Not all saved object types are shareable. If an object is shareable, the Spaces column shows which spaces it exists in. You can also click +. Click the actions icon +image:images/actions_icon.png[Actions icon]. +. Select *Share to spaces*. +. Select the spaces in which to share the object. +Or, indicate that you want the object to be shared to _all spaces_, +which includes those that exist now and any created in the future. ++ +Not all saved object types are shareable. If an object is shareable, the *Spaces* column shows where the object exists. You can click those space icons to open the Share UI. - -WARNING: The share operation automatically includes child objects that are related to the saved objects. ++ +The share operation automatically includes child objects that are related to the saved objects. include::saved-objects/saved-object-ids.asciidoc[] diff --git a/docs/management/managing-tags.asciidoc b/docs/management/managing-tags.asciidoc index a0b3dce7f4b27..b9fbe85760786 100644 --- a/docs/management/managing-tags.asciidoc +++ b/docs/management/managing-tags.asciidoc @@ -2,8 +2,10 @@ [[managing-tags]] == Tags -Tags enable you to categorize your saved objects. -You can then filter for related objects based on shared tags. +Use tags to categorize your saved objects, +then filter for related objects based on shared tags. + +To get started, open the main menu, and then click *Stack Management > Tags*. [role="screenshot"] image::images/tags/tag-management-section.png[Tags management] @@ -29,7 +31,6 @@ from the global search. Create a tag to assign to your saved objects. -. Open the main menu, and then click *Stack Management > Tags*. . Click *Create tag*. . Enter a name and select a color for the new tag. @@ -41,23 +42,21 @@ The name cannot be longer than 50 characters. [[settings-assign-tag]] === Assign a tag to an object -To assign and remove tags from saved objects, you must have `write` permission +To assign and remove tags, you must have `write` permission on the objects to which you assign the tags. -. In the *Tags* view, find the tag you want to assign. -. Click the action menu (...) in the tag row, -and then select the *Manage assignments* action. +. Find the tag you want to assign. +. Click the actions icon +image:images/actions_icon.png[Actions icon], +and then select *Manage assignments*. . Select the objects to which you want to assign or remove tags. + [role="screenshot"] -image::images/tags/manage-assignments-flyout.png[Assign flyout] +image::images/tags/manage-assignments-flyout.png[Assign flyout, width=75%] . Click *Save tag assignments*. -TIP: To assign, delete, or clear multiple tags at once, -select their checkboxes in the *Tags* view, and then select -the desired action from the *selected tags* menu. [float] [[settings-delete-tag]] @@ -65,6 +64,11 @@ the desired action from the *selected tags* menu. When you delete a tag, you remove it from all saved objects that use it. -. Click the action menu (...) in the tag row, and then select the *Delete* action. +. Click the actions icon +image:images/actions_icon.png[Actions icon], and then select *Delete*. . Click *Delete tag*. + +TIP: To assign, delete, or clear multiple tags, +select them in the *Tags* view, and then select +the action from the *selected tags* menu. diff --git a/docs/user/graph/getting-started.asciidoc b/docs/user/graph/getting-started.asciidoc index 5e87efc5e8aca..03274bec76714 100644 --- a/docs/user/graph/getting-started.asciidoc +++ b/docs/user/graph/getting-started.asciidoc @@ -95,7 +95,7 @@ a field, select *Edit Settings*, and change *Terms per hop*. Documents that match a blocked term are not allowed in the graph. To block a term, select its vertex and click the block icon -image:user/graph/images/graph-block-button.png[Block selection] +image:user/graph/images/graph-block-button.png[Block list] in the control panel. For a list of blocked terms, go to *Settings > Blocked terms*. From 2eb17e8191a284e9320db1b145927034c5d89145 Mon Sep 17 00:00:00 2001 From: Rodney Norris Date: Wed, 21 Sep 2022 18:35:35 -0500 Subject: [PATCH 19/36] [Enterprise Search] fix ml pipeline name help text (#141311) Reverted the help text to use `ml-inference-` as the name prefix since we decided to not include the index name in the pipeline name. This will make it easier to re-use pipelines in future releases. Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../pipelines/ml_inference/configure_pipeline.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx index 64875e5e6b638..da95bd6d081f4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_content/components/search_index/pipelines/ml_inference/configure_pipeline.tsx @@ -27,7 +27,7 @@ import { MLInferenceLogic } from './ml_inference_logic'; export const ConfigurePipeline: React.FC = () => { const { - addInferencePipelineModal: { configuration, indexName }, + addInferencePipelineModal: { configuration }, formErrors, supportedMLModels, sourceFields, @@ -78,10 +78,7 @@ export const ConfigurePipeline: React.FC = () => { 'xpack.enterpriseSearch.content.indices.pipelines.addInferencePipelineModal.steps.configure.name.helpText', { defaultMessage: - 'Pipeline names can only contain letters, numbers, underscores, and hyphens. The pipeline name will be automatically prefixed with "ml-inference@{indexName}-".', - values: { - indexName, - }, + 'Pipeline names can only contain letters, numbers, underscores, and hyphens. The pipeline name will be automatically prefixed with "ml-inference-".', } ) } From 9b7a65cf2a3b5be534374d3719ebe643b3a15cff Mon Sep 17 00:00:00 2001 From: JD Kurma Date: Wed, 21 Sep 2022 19:45:35 -0400 Subject: [PATCH 20/36] [Security Solution] Telemetry Task Metric Collector (#140503) * task metric logger * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * add start time and end time to task metric * update test * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * merge * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * return 0 in catch Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../server/lib/telemetry/constants.ts | 2 + .../server/lib/telemetry/helpers.test.ts | 40 ++ .../server/lib/telemetry/helpers.ts | 18 + .../lib/telemetry/tasks/detection_rule.ts | 129 ++-- .../lib/telemetry/tasks/diagnostic.test.ts | 1 + .../server/lib/telemetry/tasks/diagnostic.ts | 50 +- .../server/lib/telemetry/tasks/endpoint.ts | 557 +++++++++--------- .../telemetry/tasks/prebuilt_rule_alerts.ts | 16 +- .../lib/telemetry/tasks/security_lists.ts | 149 ++--- .../lib/telemetry/tasks/timelines.test.ts | 1 - .../server/lib/telemetry/tasks/timelines.ts | 254 ++++---- .../server/lib/telemetry/types.ts | 9 + .../group4/telemetry/task_based/all_types.ts | 40 +- .../telemetry/task_based/detection_rules.ts | 97 ++- .../telemetry/task_based/security_lists.ts | 52 +- .../utils/index.ts | 1 + ...remove_time_fields_from_telemetry_stats.ts | 20 + 17 files changed, 877 insertions(+), 559 deletions(-) create mode 100644 x-pack/test/detection_engine_api_integration/utils/remove_time_fields_from_telemetry_stats.ts diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts b/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts index 3aab67794669f..dc339bf565cdc 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts @@ -33,6 +33,8 @@ export const LIST_TRUSTED_APPLICATION = 'trusted_application'; export const INSIGHTS_CHANNEL = 'security-insights-v1'; +export const TASK_METRICS_CHANNEL = 'task-metrics'; + export const DEFAULT_ADVANCED_POLICY_CONFIG_SETTINGS = { linux: { advanced: { diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts index a07995029cd76..330add4425192 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.test.ts @@ -24,6 +24,7 @@ import { metricsResponseToValueListMetaData, tlog, setIsElasticCloudDeployment, + createTaskMetric, } from './helpers'; import type { ESClusterInfo, ESLicense, ExceptionListItem } from './types'; import type { PolicyConfig, PolicyData } from '../../../common/endpoint/types'; @@ -931,3 +932,42 @@ describe('test tlog', () => { expect(logger.debug).toHaveBeenCalled(); }); }); + +describe('test create task metrics', () => { + test('can succeed when all parameters are given', async () => { + const stubTaskName = 'test'; + const stubPassed = true; + const stubStartTime = Date.now(); + await new Promise((r) => setTimeout(r, 11)); + const response = createTaskMetric(stubTaskName, stubPassed, stubStartTime); + const { + time_executed_in_ms: timeExecutedInMs, + start_time: startTime, + end_time: endTime, + ...rest + } = response; + expect(timeExecutedInMs).toBeGreaterThan(10); + expect(rest).toEqual({ + name: 'test', + passed: true, + }); + }); + test('can succeed when error given', async () => { + const stubTaskName = 'test'; + const stubPassed = false; + const stubStartTime = Date.now(); + const errorMessage = 'failed'; + const response = createTaskMetric(stubTaskName, stubPassed, stubStartTime, errorMessage); + const { + time_executed_in_ms: timeExecutedInMs, + start_time: startTime, + end_time: endTime, + ...rest + } = response; + expect(rest).toEqual({ + name: 'test', + passed: false, + error_message: 'failed', + }); + }); +}); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts index 0c42a35a317e7..0fd7a0f6604c9 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/helpers.ts @@ -22,6 +22,7 @@ import type { ValueListExceptionListResponseAggregation, ValueListItemsResponseAggregation, ValueListIndicatorMatchResponseAggregation, + TaskMetric, } from './types'; import { LIST_DETECTION_RULE_EXCEPTION, @@ -280,3 +281,20 @@ export const tlog = (logger: Logger, message: string) => { logger.debug(message); } }; + +export const createTaskMetric = ( + name: string, + passed: boolean, + startTime: number, + errorMessage?: string +): TaskMetric => { + const endTime = Date.now(); + return { + name, + passed, + time_executed_in_ms: endTime - startTime, + start_time: startTime, + end_time: endTime, + error_message: errorMessage, + }; +}; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts index 1f22a4c97327d..4562cbb725cb4 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/detection_rule.ts @@ -6,8 +6,12 @@ */ import type { Logger } from '@kbn/core/server'; -import { LIST_DETECTION_RULE_EXCEPTION, TELEMETRY_CHANNEL_LISTS } from '../constants'; -import { batchTelemetryRecords, templateExceptionList, tlog } from '../helpers'; +import { + LIST_DETECTION_RULE_EXCEPTION, + TELEMETRY_CHANNEL_LISTS, + TASK_METRICS_CHANNEL, +} from '../constants'; +import { batchTelemetryRecords, templateExceptionList, tlog, createTaskMetric } from '../helpers'; import type { ITelemetryEventsSender } from '../sender'; import type { ITelemetryReceiver } from '../receiver'; import type { ExceptionListItem, ESClusterInfo, ESLicense, RuleSearchResult } from '../types'; @@ -27,74 +31,87 @@ export function createTelemetryDetectionRuleListsTaskConfig(maxTelemetryBatch: n sender: ITelemetryEventsSender, taskExecutionPeriod: TaskExecutionPeriod ) => { - tlog(logger, 'test'); - const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ - receiver.fetchClusterInfo(), - receiver.fetchLicenseInfo(), - ]); + const startTime = Date.now(); + const taskName = 'Security Solution Detection Rule Lists Telemetry'; + try { + const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ + receiver.fetchClusterInfo(), + receiver.fetchLicenseInfo(), + ]); - const clusterInfo = - clusterInfoPromise.status === 'fulfilled' - ? clusterInfoPromise.value - : ({} as ESClusterInfo); - const licenseInfo = - licenseInfoPromise.status === 'fulfilled' - ? licenseInfoPromise.value - : ({} as ESLicense | undefined); + const clusterInfo = + clusterInfoPromise.status === 'fulfilled' + ? clusterInfoPromise.value + : ({} as ESClusterInfo); + const licenseInfo = + licenseInfoPromise.status === 'fulfilled' + ? licenseInfoPromise.value + : ({} as ESLicense | undefined); - // Lists Telemetry: Detection Rules + // Lists Telemetry: Detection Rules - const { body: prebuiltRules } = await receiver.fetchDetectionRules(); + const { body: prebuiltRules } = await receiver.fetchDetectionRules(); - if (!prebuiltRules) { - tlog(logger, 'no prebuilt rules found'); - return 0; - } + if (!prebuiltRules) { + tlog(logger, 'no prebuilt rules found'); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return 0; + } - const cacheArray = prebuiltRules.hits.hits.reduce((cache, searchHit) => { - const rule = searchHit._source as RuleSearchResult; - const ruleId = rule.alert.params.ruleId; + const cacheArray = prebuiltRules.hits.hits.reduce((cache, searchHit) => { + const rule = searchHit._source as RuleSearchResult; + const ruleId = rule.alert.params.ruleId; - const shouldNotProcess = - rule === null || - rule === undefined || - ruleId === null || - ruleId === undefined || - searchHit._source?.alert.params.exceptionsList.length === 0; + const shouldNotProcess = + rule === null || + rule === undefined || + ruleId === null || + ruleId === undefined || + searchHit._source?.alert.params.exceptionsList.length === 0; - if (shouldNotProcess) { - return cache; - } + if (shouldNotProcess) { + return cache; + } - cache.push(rule); - return cache; - }, [] as RuleSearchResult[]); + cache.push(rule); + return cache; + }, [] as RuleSearchResult[]); - const detectionRuleExceptions = [] as ExceptionListItem[]; - for (const item of cacheArray) { - const ruleVersion = item.alert.params.version; + const detectionRuleExceptions = [] as ExceptionListItem[]; + for (const item of cacheArray) { + const ruleVersion = item.alert.params.version; - for (const ex of item.alert.params.exceptionsList) { - const listItem = await receiver.fetchDetectionExceptionList(ex.list_id, ruleVersion); - for (const exceptionItem of listItem.data) { - detectionRuleExceptions.push(exceptionItem); + for (const ex of item.alert.params.exceptionsList) { + const listItem = await receiver.fetchDetectionExceptionList(ex.list_id, ruleVersion); + for (const exceptionItem of listItem.data) { + detectionRuleExceptions.push(exceptionItem); + } } } - } - const detectionRuleExceptionsJson = templateExceptionList( - detectionRuleExceptions, - clusterInfo, - licenseInfo, - LIST_DETECTION_RULE_EXCEPTION - ); - tlog(logger, `Detection rule exception json length ${detectionRuleExceptionsJson.length}`); - const batches = batchTelemetryRecords(detectionRuleExceptionsJson, maxTelemetryBatch); - for (const batch of batches) { - await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); + const detectionRuleExceptionsJson = templateExceptionList( + detectionRuleExceptions, + clusterInfo, + licenseInfo, + LIST_DETECTION_RULE_EXCEPTION + ); + tlog(logger, `Detection rule exception json length ${detectionRuleExceptionsJson.length}`); + const batches = batchTelemetryRecords(detectionRuleExceptionsJson, maxTelemetryBatch); + for (const batch of batches) { + await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); + } + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return detectionRuleExceptions.length; + } catch (err) { + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, false, startTime, err.message), + ]); + return 0; } - - return detectionRuleExceptions.length; }, }; } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts index 45d3eeb40a801..a83326334c9d7 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.test.ts @@ -46,5 +46,6 @@ describe('diagnostics telemetry task test', () => { expect(mockTelemetryEventsSender.queueTelemetryEvents).toHaveBeenCalledWith( testDiagnosticsAlerts.hits.hits.flatMap((doc) => [doc._source]) ); + expect(mockTelemetryEventsSender.sendOnDemand).toBeCalledTimes(1); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts index 579e0e6cf9675..5c4604289eb51 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/diagnostic.ts @@ -6,11 +6,12 @@ */ import type { Logger } from '@kbn/core/server'; -import { tlog, getPreviousDiagTaskTimestamp } from '../helpers'; +import { tlog, getPreviousDiagTaskTimestamp, createTaskMetric } from '../helpers'; import type { ITelemetryEventsSender } from '../sender'; import type { TelemetryEvent } from '../types'; import type { ITelemetryReceiver } from '../receiver'; import type { TaskExecutionPeriod } from '../task'; +import { TASK_METRICS_CHANNEL } from '../constants'; export function createTelemetryDiagnosticsTaskConfig() { return { @@ -27,26 +28,41 @@ export function createTelemetryDiagnosticsTaskConfig() { sender: ITelemetryEventsSender, taskExecutionPeriod: TaskExecutionPeriod ) => { - if (!taskExecutionPeriod.last) { - throw new Error('last execution timestamp is required'); - } + const startTime = Date.now(); + const taskName = 'Security Solution Telemetry Diagnostics task'; + try { + if (!taskExecutionPeriod.last) { + throw new Error('last execution timestamp is required'); + } - const response = await receiver.fetchDiagnosticAlerts( - taskExecutionPeriod.last, - taskExecutionPeriod.current - ); + const response = await receiver.fetchDiagnosticAlerts( + taskExecutionPeriod.last, + taskExecutionPeriod.current + ); - const hits = response.hits?.hits || []; - if (!Array.isArray(hits) || !hits.length) { - tlog(logger, 'no diagnostic alerts retrieved'); + const hits = response.hits?.hits || []; + if (!Array.isArray(hits) || !hits.length) { + tlog(logger, 'no diagnostic alerts retrieved'); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return 0; + } + tlog(logger, `Received ${hits.length} diagnostic alerts`); + const diagAlerts: TelemetryEvent[] = hits.flatMap((h) => + h._source != null ? [h._source] : [] + ); + sender.queueTelemetryEvents(diagAlerts); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return diagAlerts.length; + } catch (err) { + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, false, startTime, err.message), + ]); return 0; } - tlog(logger, `Received ${hits.length} diagnostic alerts`); - const diagAlerts: TelemetryEvent[] = hits.flatMap((h) => - h._source != null ? [h._source] : [] - ); - sender.queueTelemetryEvents(diagAlerts); - return diagAlerts.length; }, }; } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts index c3c1cdf54e4d9..d3c40b29e218f 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/endpoint.ts @@ -27,9 +27,10 @@ import { getPreviousDailyTaskTimestamp, isPackagePolicyList, tlog, + createTaskMetric, } from '../helpers'; import type { PolicyData } from '../../../../common/endpoint/types'; -import { TELEMETRY_CHANNEL_ENDPOINT_META } from '../constants'; +import { TELEMETRY_CHANNEL_ENDPOINT_META, TASK_METRICS_CHANNEL } from '../constants'; // Endpoint agent uses this Policy ID while it's installing. const DefaultEndpointPolicyIdToIgnore = '00000000-0000-0000-0000-000000000000'; @@ -58,294 +59,320 @@ export function createTelemetryEndpointTaskConfig(maxTelemetryBatch: number) { sender: ITelemetryEventsSender, taskExecutionPeriod: TaskExecutionPeriod ) => { - tlog(logger, 'test'); - if (!taskExecutionPeriod.last) { - throw new Error('last execution timestamp is required'); - } - const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ - receiver.fetchClusterInfo(), - receiver.fetchLicenseInfo(), - ]); - - const clusterInfo = - clusterInfoPromise.status === 'fulfilled' - ? clusterInfoPromise.value - : ({} as ESClusterInfo); - const licenseInfo = - licenseInfoPromise.status === 'fulfilled' - ? licenseInfoPromise.value - : ({} as ESLicense | undefined); - - const endpointData = await fetchEndpointData( - receiver, - taskExecutionPeriod.last, - taskExecutionPeriod.current - ); - - /** STAGE 1 - Fetch Endpoint Agent Metrics - * - * Reads Endpoint Agent metrics out of the `.ds-metrics-endpoint.metrics` data stream - * and buckets them by Endpoint Agent id and sorts by the top hit. The EP agent will - * report its metrics once per day OR every time a policy change has occured. If - * a metric document(s) exists for an EP agent we map to fleet agent and policy - */ - if (endpointData.endpointMetrics === undefined) { - tlog(logger, `no endpoint metrics to report`); - return 0; - } + const startTime = Date.now(); + const taskName = 'Security Solution Telemetry Endpoint Metrics and Info task'; + try { + if (!taskExecutionPeriod.last) { + throw new Error('last execution timestamp is required'); + } + const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ + receiver.fetchClusterInfo(), + receiver.fetchLicenseInfo(), + ]); + + const clusterInfo = + clusterInfoPromise.status === 'fulfilled' + ? clusterInfoPromise.value + : ({} as ESClusterInfo); + const licenseInfo = + licenseInfoPromise.status === 'fulfilled' + ? licenseInfoPromise.value + : ({} as ESLicense | undefined); + + const endpointData = await fetchEndpointData( + receiver, + taskExecutionPeriod.last, + taskExecutionPeriod.current + ); - const { body: endpointMetricsResponse } = endpointData.endpointMetrics as unknown as { - body: EndpointMetricsAggregation; - }; + /** STAGE 1 - Fetch Endpoint Agent Metrics + * + * Reads Endpoint Agent metrics out of the `.ds-metrics-endpoint.metrics` data stream + * and buckets them by Endpoint Agent id and sorts by the top hit. The EP agent will + * report its metrics once per day OR every time a policy change has occured. If + * a metric document(s) exists for an EP agent we map to fleet agent and policy + */ + if (endpointData.endpointMetrics === undefined) { + tlog(logger, `no endpoint metrics to report`); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return 0; + } - if (endpointMetricsResponse.aggregations === undefined) { - tlog(logger, `no endpoint metrics to report`); - return 0; - } + const { body: endpointMetricsResponse } = endpointData.endpointMetrics as unknown as { + body: EndpointMetricsAggregation; + }; - const telemetryUsageCounter = sender.getTelemetryUsageCluster(); - telemetryUsageCounter?.incrementCounter({ - counterName: createUsageCounterLabel( - usageLabelPrefix.concat(['payloads', TELEMETRY_CHANNEL_ENDPOINT_META]) - ), - counterType: 'num_endpoint', - incrementBy: endpointMetricsResponse.aggregations.endpoint_count.value, - }); - - const endpointMetrics = endpointMetricsResponse.aggregations.endpoint_agents.buckets.map( - (epMetrics) => { - return { - endpoint_agent: epMetrics.latest_metrics.hits.hits[0]._source.agent.id, - endpoint_version: epMetrics.latest_metrics.hits.hits[0]._source.agent.version, - endpoint_metrics: epMetrics.latest_metrics.hits.hits[0]._source, - }; + if (endpointMetricsResponse.aggregations === undefined) { + tlog(logger, `no endpoint metrics to report`); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return 0; } - ); - - /** STAGE 2 - Fetch Fleet Agent Config - * - * As the policy id + policy version does not exist on the Endpoint Metrics document - * we need to fetch information about the Fleet Agent and sync the metrics document - * with the Agent's policy data. - * - */ - const agentsResponse = endpointData.fleetAgentsResponse; - - if (agentsResponse === undefined) { - tlog(logger, 'no fleet agent information available'); - return 0; - } - const fleetAgents = agentsResponse.agents.reduce((cache, agent) => { - if (agent.id === DefaultEndpointPolicyIdToIgnore) { + const telemetryUsageCounter = sender.getTelemetryUsageCluster(); + telemetryUsageCounter?.incrementCounter({ + counterName: createUsageCounterLabel( + usageLabelPrefix.concat(['payloads', TELEMETRY_CHANNEL_ENDPOINT_META]) + ), + counterType: 'num_endpoint', + incrementBy: endpointMetricsResponse.aggregations.endpoint_count.value, + }); + + const endpointMetrics = endpointMetricsResponse.aggregations.endpoint_agents.buckets.map( + (epMetrics) => { + return { + endpoint_agent: epMetrics.latest_metrics.hits.hits[0]._source.agent.id, + endpoint_version: epMetrics.latest_metrics.hits.hits[0]._source.agent.version, + endpoint_metrics: epMetrics.latest_metrics.hits.hits[0]._source, + }; + } + ); + + /** STAGE 2 - Fetch Fleet Agent Config + * + * As the policy id + policy version does not exist on the Endpoint Metrics document + * we need to fetch information about the Fleet Agent and sync the metrics document + * with the Agent's policy data. + * + */ + const agentsResponse = endpointData.fleetAgentsResponse; + + if (agentsResponse === undefined) { + tlog(logger, 'no fleet agent information available'); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return 0; + } + + const fleetAgents = agentsResponse.agents.reduce((cache, agent) => { + if (agent.id === DefaultEndpointPolicyIdToIgnore) { + return cache; + } + + if (agent.policy_id !== null && agent.policy_id !== undefined) { + cache.set(agent.id, agent.policy_id); + } + return cache; + }, new Map()); + + const endpointPolicyCache = new Map(); + for (const policyInfo of fleetAgents.values()) { + if ( + policyInfo !== null && + policyInfo !== undefined && + !endpointPolicyCache.has(policyInfo) + ) { + tlog(logger, `policy info exists as ${policyInfo}`); + const agentPolicy = await receiver.fetchPolicyConfigs(policyInfo); + const packagePolicies = agentPolicy?.package_policies; + + if (packagePolicies !== undefined && isPackagePolicyList(packagePolicies)) { + tlog(logger, `package policy exists as ${JSON.stringify(packagePolicies)}`); + packagePolicies + .map((pPolicy) => pPolicy as PolicyData) + .forEach((pPolicy) => { + if ( + pPolicy.inputs[0]?.config !== undefined && + pPolicy.inputs[0]?.config !== null + ) { + pPolicy.inputs.forEach((input) => { + if ( + input.type === FLEET_ENDPOINT_PACKAGE && + input?.config !== undefined && + policyInfo !== undefined + ) { + endpointPolicyCache.set(policyInfo, pPolicy); + } + }); + } + }); + } + } } - if (agent.policy_id !== null && agent.policy_id !== undefined) { - cache.set(agent.id, agent.policy_id); + /** STAGE 3 - Fetch Endpoint Policy Responses + * + * Reads Endpoint Agent policy responses out of the `.ds-metrics-endpoint.policy*` data + * stream and creates a local K/V structure that stores the policy response (V) with + * the Endpoint Agent Id (K). A value will only exist if there has been a endpoint + * enrolled in the last 24 hours OR a policy change has occurred. We only send + * non-successful responses. If the field is null, we assume no responses in + * the last 24h or no failures/warnings in the policy applied. + * + */ + const { body: failedPolicyResponses } = endpointData.epPolicyResponse as unknown as { + body: EndpointPolicyResponseAggregation; + }; + + // If there is no policy responses in the 24h > now then we will continue + const policyResponses = failedPolicyResponses.aggregations + ? failedPolicyResponses.aggregations.policy_responses.buckets.reduce( + (cache, endpointAgentId) => { + const doc = endpointAgentId.latest_response.hits.hits[0]; + cache.set(endpointAgentId.key, doc); + return cache; + }, + new Map() + ) + : new Map(); + + tlog( + logger, + `policy responses exists as ${JSON.stringify(Object.fromEntries(policyResponses))}` + ); + + /** STAGE 4 - Fetch Endpoint Agent Metadata + * + * Reads Endpoint Agent metadata out of the `.ds-metrics-endpoint.metadata` data stream + * and buckets them by Endpoint Agent id and sorts by the top hit. The EP agent will + * report its metadata once per day OR every time a policy change has occured. If + * a metadata document(s) exists for an EP agent we map to fleet agent and policy + */ + if (endpointData.endpointMetadata === undefined) { + tlog(logger, `no endpoint metadata to report`); } - return cache; - }, new Map()); - - const endpointPolicyCache = new Map(); - for (const policyInfo of fleetAgents.values()) { - if ( - policyInfo !== null && - policyInfo !== undefined && - !endpointPolicyCache.has(policyInfo) - ) { - tlog(logger, `policy info exists as ${policyInfo}`); - const agentPolicy = await receiver.fetchPolicyConfigs(policyInfo); - const packagePolicies = agentPolicy?.package_policies; - - if (packagePolicies !== undefined && isPackagePolicyList(packagePolicies)) { - tlog(logger, `package policy exists as ${JSON.stringify(packagePolicies)}`); - packagePolicies - .map((pPolicy) => pPolicy as PolicyData) - .forEach((pPolicy) => { - if (pPolicy.inputs[0]?.config !== undefined && pPolicy.inputs[0]?.config !== null) { - pPolicy.inputs.forEach((input) => { - if ( - input.type === FLEET_ENDPOINT_PACKAGE && - input?.config !== undefined && - policyInfo !== undefined - ) { - endpointPolicyCache.set(policyInfo, pPolicy); - } - }); - } - }); - } + const { body: endpointMetadataResponse } = endpointData.endpointMetadata as unknown as { + body: EndpointMetadataAggregation; + }; + + if (endpointMetadataResponse.aggregations === undefined) { + tlog(logger, `no endpoint metadata to report`); } - } - /** STAGE 3 - Fetch Endpoint Policy Responses - * - * Reads Endpoint Agent policy responses out of the `.ds-metrics-endpoint.policy*` data - * stream and creates a local K/V structure that stores the policy response (V) with - * the Endpoint Agent Id (K). A value will only exist if there has been a endpoint - * enrolled in the last 24 hours OR a policy change has occurred. We only send - * non-successful responses. If the field is null, we assume no responses in - * the last 24h or no failures/warnings in the policy applied. - * - */ - const { body: failedPolicyResponses } = endpointData.epPolicyResponse as unknown as { - body: EndpointPolicyResponseAggregation; - }; - - // If there is no policy responses in the 24h > now then we will continue - const policyResponses = failedPolicyResponses.aggregations - ? failedPolicyResponses.aggregations.policy_responses.buckets.reduce( + const endpointMetadata = + endpointMetadataResponse.aggregations.endpoint_metadata.buckets.reduce( (cache, endpointAgentId) => { - const doc = endpointAgentId.latest_response.hits.hits[0]; + const doc = endpointAgentId.latest_metadata.hits.hits[0]; cache.set(endpointAgentId.key, doc); return cache; }, - new Map() - ) - : new Map(); - - tlog( - logger, - `policy responses exists as ${JSON.stringify(Object.fromEntries(policyResponses))}` - ); - - /** STAGE 4 - Fetch Endpoint Agent Metadata - * - * Reads Endpoint Agent metadata out of the `.ds-metrics-endpoint.metadata` data stream - * and buckets them by Endpoint Agent id and sorts by the top hit. The EP agent will - * report its metadata once per day OR every time a policy change has occured. If - * a metadata document(s) exists for an EP agent we map to fleet agent and policy - */ - if (endpointData.endpointMetadata === undefined) { - tlog(logger, `no endpoint metadata to report`); - } - - const { body: endpointMetadataResponse } = endpointData.endpointMetadata as unknown as { - body: EndpointMetadataAggregation; - }; - - if (endpointMetadataResponse.aggregations === undefined) { - tlog(logger, `no endpoint metadata to report`); - } - - const endpointMetadata = - endpointMetadataResponse.aggregations.endpoint_metadata.buckets.reduce( - (cache, endpointAgentId) => { - const doc = endpointAgentId.latest_metadata.hits.hits[0]; - cache.set(endpointAgentId.key, doc); - return cache; - }, - new Map() + new Map() + ); + tlog( + logger, + `endpoint metadata exists as ${JSON.stringify(Object.fromEntries(endpointMetadata))}` ); - tlog( - logger, - `endpoint metadata exists as ${JSON.stringify(Object.fromEntries(endpointMetadata))}` - ); - /** STAGE 5 - Create the telemetry log records - * - * Iterates through the endpoint metrics documents at STAGE 1 and joins them together - * to form the telemetry log that is sent back to Elastic Security developers to - * make improvements to the product. - * - */ - try { - const telemetryPayloads = endpointMetrics.map((endpoint) => { - let policyConfig = null; - let failedPolicy = null; - let endpointMetadataById = null; - - const fleetAgentId = endpoint.endpoint_metrics.elastic.agent.id; - const endpointAgentId = endpoint.endpoint_agent; - - const policyInformation = fleetAgents.get(fleetAgentId); - if (policyInformation) { - policyConfig = endpointPolicyCache.get(policyInformation) || null; - - if (policyConfig) { - failedPolicy = policyResponses.get(endpointAgentId); + /** STAGE 5 - Create the telemetry log records + * + * Iterates through the endpoint metrics documents at STAGE 1 and joins them together + * to form the telemetry log that is sent back to Elastic Security developers to + * make improvements to the product. + * + */ + try { + const telemetryPayloads = endpointMetrics.map((endpoint) => { + let policyConfig = null; + let failedPolicy = null; + let endpointMetadataById = null; + + const fleetAgentId = endpoint.endpoint_metrics.elastic.agent.id; + const endpointAgentId = endpoint.endpoint_agent; + + const policyInformation = fleetAgents.get(fleetAgentId); + if (policyInformation) { + policyConfig = endpointPolicyCache.get(policyInformation) || null; + + if (policyConfig) { + failedPolicy = policyResponses.get(endpointAgentId); + } } - } - if (endpointMetadata) { - endpointMetadataById = endpointMetadata.get(endpointAgentId); - } + if (endpointMetadata) { + endpointMetadataById = endpointMetadata.get(endpointAgentId); + } - const { - cpu, - memory, - uptime, - documents_volume: documentsVolume, - malicious_behavior_rules: maliciousBehaviorRules, - system_impact: systemImpact, - threads, - event_filter: eventFilter, - } = endpoint.endpoint_metrics.Endpoint.metrics; - const endpointPolicyDetail = extractEndpointPolicyConfig(policyConfig); - if (endpointPolicyDetail) { - endpointPolicyDetail.value = addDefaultAdvancedPolicyConfigSettings( - endpointPolicyDetail.value - ); - } - return { - '@timestamp': taskExecutionPeriod.current, - cluster_uuid: clusterInfo.cluster_uuid, - cluster_name: clusterInfo.cluster_name, - license_id: licenseInfo?.uid, - endpoint_id: endpointAgentId, - endpoint_version: endpoint.endpoint_version, - endpoint_package_version: policyConfig?.package?.version || null, - endpoint_metrics: { - cpu: cpu.endpoint, - memory: memory.endpoint.private, + const { + cpu, + memory, uptime, - documentsVolume, - maliciousBehaviorRules, - systemImpact, + documents_volume: documentsVolume, + malicious_behavior_rules: maliciousBehaviorRules, + system_impact: systemImpact, threads, - eventFilter, - }, - endpoint_meta: { - os: endpoint.endpoint_metrics.host.os, - capabilities: - endpointMetadataById !== null && endpointMetadataById !== undefined - ? endpointMetadataById._source.Endpoint.capabilities - : [], - }, - policy_config: endpointPolicyDetail !== null ? endpointPolicyDetail : {}, - policy_response: - failedPolicy !== null && failedPolicy !== undefined - ? { - agent_policy_status: failedPolicy._source.event.agent_id_status, - manifest_version: - failedPolicy._source.Endpoint.policy.applied.artifacts.global.version, - status: failedPolicy._source.Endpoint.policy.applied.status, - actions: failedPolicy._source.Endpoint.policy.applied.actions - .map((action) => (action.status !== 'success' ? action : null)) - .filter((action) => action !== null), - configuration: failedPolicy._source.Endpoint.configuration, - state: failedPolicy._source.Endpoint.state, - } - : {}, - telemetry_meta: { - metrics_timestamp: endpoint.endpoint_metrics['@timestamp'], - }, - }; - }); - - /** - * STAGE 6 - Send the documents - * - * Send the documents in a batches of maxTelemetryBatch - */ - const batches = batchTelemetryRecords(telemetryPayloads, maxTelemetryBatch); - for (const batch of batches) { - await sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_META, batch); + event_filter: eventFilter, + } = endpoint.endpoint_metrics.Endpoint.metrics; + const endpointPolicyDetail = extractEndpointPolicyConfig(policyConfig); + if (endpointPolicyDetail) { + endpointPolicyDetail.value = addDefaultAdvancedPolicyConfigSettings( + endpointPolicyDetail.value + ); + } + return { + '@timestamp': taskExecutionPeriod.current, + cluster_uuid: clusterInfo.cluster_uuid, + cluster_name: clusterInfo.cluster_name, + license_id: licenseInfo?.uid, + endpoint_id: endpointAgentId, + endpoint_version: endpoint.endpoint_version, + endpoint_package_version: policyConfig?.package?.version || null, + endpoint_metrics: { + cpu: cpu.endpoint, + memory: memory.endpoint.private, + uptime, + documentsVolume, + maliciousBehaviorRules, + systemImpact, + threads, + eventFilter, + }, + endpoint_meta: { + os: endpoint.endpoint_metrics.host.os, + capabilities: + endpointMetadataById !== null && endpointMetadataById !== undefined + ? endpointMetadataById._source.Endpoint.capabilities + : [], + }, + policy_config: endpointPolicyDetail !== null ? endpointPolicyDetail : {}, + policy_response: + failedPolicy !== null && failedPolicy !== undefined + ? { + agent_policy_status: failedPolicy._source.event.agent_id_status, + manifest_version: + failedPolicy._source.Endpoint.policy.applied.artifacts.global.version, + status: failedPolicy._source.Endpoint.policy.applied.status, + actions: failedPolicy._source.Endpoint.policy.applied.actions + .map((action) => (action.status !== 'success' ? action : null)) + .filter((action) => action !== null), + configuration: failedPolicy._source.Endpoint.configuration, + state: failedPolicy._source.Endpoint.state, + } + : {}, + telemetry_meta: { + metrics_timestamp: endpoint.endpoint_metrics['@timestamp'], + }, + }; + }); + + /** + * STAGE 6 - Send the documents + * + * Send the documents in a batches of maxTelemetryBatch + */ + const batches = batchTelemetryRecords(telemetryPayloads, maxTelemetryBatch); + for (const batch of batches) { + await sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_META, batch); + } + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return telemetryPayloads.length; + } catch (err) { + logger.warn(`could not complete endpoint alert telemetry task due to ${err?.message}`); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, false, startTime, err.message), + ]); + return 0; } - return telemetryPayloads.length; } catch (err) { - logger.warn(`could not complete endpoint alert telemetry task due to ${err?.message}`); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, false, startTime, err.message), + ]); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts index 44a6b3cf644f4..33d33924fcf36 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/prebuilt_rule_alerts.ts @@ -10,8 +10,8 @@ import type { ITelemetryEventsSender } from '../sender'; import type { ITelemetryReceiver } from '../receiver'; import type { ESClusterInfo, ESLicense, TelemetryEvent } from '../types'; import type { TaskExecutionPeriod } from '../task'; -import { TELEMETRY_CHANNEL_DETECTION_ALERTS } from '../constants'; -import { batchTelemetryRecords, tlog } from '../helpers'; +import { TELEMETRY_CHANNEL_DETECTION_ALERTS, TASK_METRICS_CHANNEL } from '../constants'; +import { batchTelemetryRecords, tlog, createTaskMetric } from '../helpers'; import { copyAllowlistedFields, prebuiltRuleAllowlistFields } from '../filterlists'; export function createTelemetryPrebuiltRuleAlertsTaskConfig(maxTelemetryBatch: number) { @@ -28,6 +28,8 @@ export function createTelemetryPrebuiltRuleAlertsTaskConfig(maxTelemetryBatch: n sender: ITelemetryEventsSender, taskExecutionPeriod: TaskExecutionPeriod ) => { + const startTime = Date.now(); + const taskName = 'Security Solution - Prebuilt Rule and Elastic ML Alerts Telemetry'; try { const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ receiver.fetchClusterInfo(), @@ -54,6 +56,9 @@ export function createTelemetryPrebuiltRuleAlertsTaskConfig(maxTelemetryBatch: n if (telemetryEvents.length === 0) { tlog(logger, 'no prebuilt rule alerts retrieved'); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); return 0; } @@ -76,10 +81,15 @@ export function createTelemetryPrebuiltRuleAlertsTaskConfig(maxTelemetryBatch: n for (const batch of batches) { await sender.sendOnDemand(TELEMETRY_CHANNEL_DETECTION_ALERTS, batch); } - + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); return enrichedAlerts.length; } catch (err) { logger.error('could not complete prebuilt alerts telemetry task'); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, false, startTime, err.message), + ]); return 0; } }, diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts index a6023d809c6b0..08baef614c1b8 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/security_lists.ts @@ -15,9 +15,10 @@ import { LIST_ENDPOINT_EVENT_FILTER, LIST_TRUSTED_APPLICATION, TELEMETRY_CHANNEL_LISTS, + TASK_METRICS_CHANNEL, } from '../constants'; import type { ESClusterInfo, ESLicense } from '../types'; -import { batchTelemetryRecords, templateExceptionList, tlog } from '../helpers'; +import { batchTelemetryRecords, templateExceptionList, tlog, createTaskMetric } from '../helpers'; import type { ITelemetryEventsSender } from '../sender'; import type { ITelemetryReceiver } from '../receiver'; import type { TaskExecutionPeriod } from '../task'; @@ -36,88 +37,100 @@ export function createTelemetrySecurityListTaskConfig(maxTelemetryBatch: number) sender: ITelemetryEventsSender, taskExecutionPeriod: TaskExecutionPeriod ) => { - let count = 0; + const startTime = Date.now(); + const taskName = 'Security Solution Lists Telemetry'; + try { + let count = 0; - const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ - receiver.fetchClusterInfo(), - receiver.fetchLicenseInfo(), - ]); + const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ + receiver.fetchClusterInfo(), + receiver.fetchLicenseInfo(), + ]); - const clusterInfo = - clusterInfoPromise.status === 'fulfilled' - ? clusterInfoPromise.value - : ({} as ESClusterInfo); - const licenseInfo = - licenseInfoPromise.status === 'fulfilled' - ? licenseInfoPromise.value - : ({} as ESLicense | undefined); - const FETCH_VALUE_LIST_META_DATA_INTERVAL_IN_HOURS = 24; + const clusterInfo = + clusterInfoPromise.status === 'fulfilled' + ? clusterInfoPromise.value + : ({} as ESClusterInfo); + const licenseInfo = + licenseInfoPromise.status === 'fulfilled' + ? licenseInfoPromise.value + : ({} as ESLicense | undefined); + const FETCH_VALUE_LIST_META_DATA_INTERVAL_IN_HOURS = 24; - // Lists Telemetry: Trusted Applications - const trustedApps = await receiver.fetchTrustedApplications(); - if (trustedApps?.data) { - const trustedAppsJson = templateExceptionList( - trustedApps.data, - clusterInfo, - licenseInfo, - LIST_TRUSTED_APPLICATION - ); - tlog(logger, `Trusted Apps: ${trustedAppsJson}`); - count += trustedAppsJson.length; + // Lists Telemetry: Trusted Applications + const trustedApps = await receiver.fetchTrustedApplications(); + if (trustedApps?.data) { + const trustedAppsJson = templateExceptionList( + trustedApps.data, + clusterInfo, + licenseInfo, + LIST_TRUSTED_APPLICATION + ); + tlog(logger, `Trusted Apps: ${trustedAppsJson}`); + count += trustedAppsJson.length; - const batches = batchTelemetryRecords(trustedAppsJson, maxTelemetryBatch); - for (const batch of batches) { - await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); + const batches = batchTelemetryRecords(trustedAppsJson, maxTelemetryBatch); + for (const batch of batches) { + await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); + } } - } - // Lists Telemetry: Endpoint Exceptions + // Lists Telemetry: Endpoint Exceptions - const epExceptions = await receiver.fetchEndpointList(ENDPOINT_LIST_ID); - if (epExceptions?.data) { - const epExceptionsJson = templateExceptionList( - epExceptions.data, - clusterInfo, - licenseInfo, - LIST_ENDPOINT_EXCEPTION - ); - tlog(logger, `EP Exceptions: ${epExceptionsJson}`); - count += epExceptionsJson.length; + const epExceptions = await receiver.fetchEndpointList(ENDPOINT_LIST_ID); + if (epExceptions?.data) { + const epExceptionsJson = templateExceptionList( + epExceptions.data, + clusterInfo, + licenseInfo, + LIST_ENDPOINT_EXCEPTION + ); + tlog(logger, `EP Exceptions: ${epExceptionsJson}`); + count += epExceptionsJson.length; - const batches = batchTelemetryRecords(epExceptionsJson, maxTelemetryBatch); - for (const batch of batches) { - await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); + const batches = batchTelemetryRecords(epExceptionsJson, maxTelemetryBatch); + for (const batch of batches) { + await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); + } } - } - // Lists Telemetry: Endpoint Event Filters + // Lists Telemetry: Endpoint Event Filters - const epFilters = await receiver.fetchEndpointList(ENDPOINT_EVENT_FILTERS_LIST_ID); - if (epFilters?.data) { - const epFiltersJson = templateExceptionList( - epFilters.data, - clusterInfo, - licenseInfo, - LIST_ENDPOINT_EVENT_FILTER - ); - tlog(logger, `EP Event Filters: ${epFiltersJson}`); - count += epFiltersJson.length; + const epFilters = await receiver.fetchEndpointList(ENDPOINT_EVENT_FILTERS_LIST_ID); + if (epFilters?.data) { + const epFiltersJson = templateExceptionList( + epFilters.data, + clusterInfo, + licenseInfo, + LIST_ENDPOINT_EVENT_FILTER + ); + tlog(logger, `EP Event Filters: ${epFiltersJson}`); + count += epFiltersJson.length; - const batches = batchTelemetryRecords(epFiltersJson, maxTelemetryBatch); - for (const batch of batches) { - await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); + const batches = batchTelemetryRecords(epFiltersJson, maxTelemetryBatch); + for (const batch of batches) { + await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, batch); + } } - } - // Value list meta data - const valueListMetaData = await receiver.fetchValueListMetaData( - FETCH_VALUE_LIST_META_DATA_INTERVAL_IN_HOURS - ); - tlog(logger, `Value List Meta Data: ${JSON.stringify(valueListMetaData)}`); - if (valueListMetaData?.total_list_count) { - await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, [valueListMetaData]); + // Value list meta data + const valueListMetaData = await receiver.fetchValueListMetaData( + FETCH_VALUE_LIST_META_DATA_INTERVAL_IN_HOURS + ); + tlog(logger, `Value List Meta Data: ${JSON.stringify(valueListMetaData)}`); + if (valueListMetaData?.total_list_count) { + await sender.sendOnDemand(TELEMETRY_CHANNEL_LISTS, [valueListMetaData]); + } + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return count; + } catch (err) { + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, false, startTime, err.message), + ]); + return 0; } - return count; }, }; } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.test.ts index 7a460caa197d7..16794dfa3f68f 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.test.ts @@ -60,6 +60,5 @@ describe('timeline telemetry task test', () => { expect(mockTelemetryReceiver.buildProcessTree).toHaveBeenCalled(); expect(mockTelemetryReceiver.fetchTimelineEvents).toHaveBeenCalled(); expect(mockTelemetryReceiver.fetchTimelineEndpointAlerts).toHaveBeenCalled(); - expect(mockTelemetryEventsSender.sendOnDemand).not.toHaveBeenCalled(); }); }); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.ts index 8403bbd7f30fd..4fdfc4a726a35 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/timelines.ts @@ -17,9 +17,9 @@ import type { TimelineTelemetryTemplate, TimelineTelemetryEvent, } from '../types'; -import { TELEMETRY_CHANNEL_TIMELINE } from '../constants'; +import { TELEMETRY_CHANNEL_TIMELINE, TASK_METRICS_CHANNEL } from '../constants'; import { resolverEntity } from '../../../endpoint/routes/resolver/entity/utils/build_resolver_entity'; -import { tlog } from '../helpers'; +import { tlog, createTaskMetric } from '../helpers'; export function createTelemetryTimelineTaskConfig() { return { @@ -35,145 +35,159 @@ export function createTelemetryTimelineTaskConfig() { sender: ITelemetryEventsSender, taskExecutionPeriod: TaskExecutionPeriod ) => { - let counter = 0; - - tlog(logger, `Running task: ${taskId}`); - - const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ - receiver.fetchClusterInfo(), - receiver.fetchLicenseInfo(), - ]); - - const clusterInfo = - clusterInfoPromise.status === 'fulfilled' - ? clusterInfoPromise.value - : ({} as ESClusterInfo); - - const licenseInfo = - licenseInfoPromise.status === 'fulfilled' - ? licenseInfoPromise.value - : ({} as ESLicense | undefined); - - const now = moment(); - const startOfDay = now.startOf('day').toISOString(); - const endOfDay = now.endOf('day').toISOString(); - - const baseDocument = { - version: clusterInfo.version?.number, - cluster_name: clusterInfo.cluster_name, - cluster_uuid: clusterInfo.cluster_uuid, - license_uuid: licenseInfo?.uid, - }; - - // Fetch EP Alerts - - const endpointAlerts = await receiver.fetchTimelineEndpointAlerts(3); - - const aggregations = endpointAlerts?.aggregations as unknown as { - endpoint_alert_count: { value: number }; - }; - tlog(logger, `Endpoint alert count: ${aggregations?.endpoint_alert_count}`); - sender.getTelemetryUsageCluster()?.incrementCounter({ - counterName: 'telemetry_endpoint_alert', - counterType: 'endpoint_alert_count', - incrementBy: aggregations?.endpoint_alert_count.value, - }); - - // No EP Alerts -> Nothing to do - if ( - endpointAlerts.hits.hits?.length === 0 || - endpointAlerts.hits.hits?.length === undefined - ) { - tlog(logger, 'no endpoint alerts received. exiting telemetry task.'); - return counter; - } + const startTime = Date.now(); + const taskName = 'Security Solution Timeline telemetry'; + try { + let counter = 0; + + tlog(logger, `Running task: ${taskId}`); + + const [clusterInfoPromise, licenseInfoPromise] = await Promise.allSettled([ + receiver.fetchClusterInfo(), + receiver.fetchLicenseInfo(), + ]); + + const clusterInfo = + clusterInfoPromise.status === 'fulfilled' + ? clusterInfoPromise.value + : ({} as ESClusterInfo); + + const licenseInfo = + licenseInfoPromise.status === 'fulfilled' + ? licenseInfoPromise.value + : ({} as ESLicense | undefined); + + const now = moment(); + const startOfDay = now.startOf('day').toISOString(); + const endOfDay = now.endOf('day').toISOString(); + + const baseDocument = { + version: clusterInfo.version?.number, + cluster_name: clusterInfo.cluster_name, + cluster_uuid: clusterInfo.cluster_uuid, + license_uuid: licenseInfo?.uid, + }; + + // Fetch EP Alerts + + const endpointAlerts = await receiver.fetchTimelineEndpointAlerts(3); + + const aggregations = endpointAlerts?.aggregations as unknown as { + endpoint_alert_count: { value: number }; + }; + tlog(logger, `Endpoint alert count: ${aggregations?.endpoint_alert_count}`); + sender.getTelemetryUsageCluster()?.incrementCounter({ + counterName: 'telemetry_endpoint_alert', + counterType: 'endpoint_alert_count', + incrementBy: aggregations?.endpoint_alert_count.value, + }); + + // No EP Alerts -> Nothing to do + if ( + endpointAlerts.hits.hits?.length === 0 || + endpointAlerts.hits.hits?.length === undefined + ) { + tlog(logger, 'no endpoint alerts received. exiting telemetry task.'); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return counter; + } - // Build process tree for each EP Alert recieved + // Build process tree for each EP Alert recieved - for (const alert of endpointAlerts.hits.hits) { - const eventId = alert._source ? alert._source['event.id'] : 'unknown'; - const alertUUID = alert._source ? alert._source['kibana.alert.uuid'] : 'unknown'; + for (const alert of endpointAlerts.hits.hits) { + const eventId = alert._source ? alert._source['event.id'] : 'unknown'; + const alertUUID = alert._source ? alert._source['kibana.alert.uuid'] : 'unknown'; - const entities = resolverEntity([alert]); + const entities = resolverEntity([alert]); - // Build Tree + // Build Tree - const tree = await receiver.buildProcessTree( - entities[0].id, - entities[0].schema, - startOfDay, - endOfDay - ); + const tree = await receiver.buildProcessTree( + entities[0].id, + entities[0].schema, + startOfDay, + endOfDay + ); - const nodeIds = [] as string[]; - if (Array.isArray(tree)) { - for (const node of tree) { - const nodeId = node?.id.toString(); - nodeIds.push(nodeId); + const nodeIds = [] as string[]; + if (Array.isArray(tree)) { + for (const node of tree) { + const nodeId = node?.id.toString(); + nodeIds.push(nodeId); + } } - } - sender.getTelemetryUsageCluster()?.incrementCounter({ - counterName: 'telemetry_timeline', - counterType: 'timeline_node_count', - incrementBy: nodeIds.length, - }); + sender.getTelemetryUsageCluster()?.incrementCounter({ + counterName: 'telemetry_timeline', + counterType: 'timeline_node_count', + incrementBy: nodeIds.length, + }); - // Fetch event lineage + // Fetch event lineage - const timelineEvents = await receiver.fetchTimelineEvents(nodeIds); - tlog(logger, `Timeline Events: ${JSON.stringify(timelineEvents)}`); - const eventsStore = new Map(); - for (const event of timelineEvents.hits.hits) { - const doc = event._source; + const timelineEvents = await receiver.fetchTimelineEvents(nodeIds); + tlog(logger, `Timeline Events: ${JSON.stringify(timelineEvents)}`); + const eventsStore = new Map(); + for (const event of timelineEvents.hits.hits) { + const doc = event._source; - if (doc !== null && doc !== undefined) { - const entityId = doc?.process?.entity_id?.toString(); - if (entityId !== null && entityId !== undefined) eventsStore.set(entityId, doc); + if (doc !== null && doc !== undefined) { + const entityId = doc?.process?.entity_id?.toString(); + if (entityId !== null && entityId !== undefined) eventsStore.set(entityId, doc); + } } - } - sender.getTelemetryUsageCluster()?.incrementCounter({ - counterName: 'telemetry_timeline', - counterType: 'timeline_event_count', - incrementBy: eventsStore.size, - }); + sender.getTelemetryUsageCluster()?.incrementCounter({ + counterName: 'telemetry_timeline', + counterType: 'timeline_event_count', + incrementBy: eventsStore.size, + }); - // Create telemetry record + // Create telemetry record - const telemetryTimeline: TimelineTelemetryEvent[] = []; - if (Array.isArray(tree)) { - for (const node of tree) { - const id = node.id.toString(); - const event = eventsStore.get(id); + const telemetryTimeline: TimelineTelemetryEvent[] = []; + if (Array.isArray(tree)) { + for (const node of tree) { + const id = node.id.toString(); + const event = eventsStore.get(id); - const timelineTelemetryEvent: TimelineTelemetryEvent = { - ...node, - event, - }; + const timelineTelemetryEvent: TimelineTelemetryEvent = { + ...node, + event, + }; - telemetryTimeline.push(timelineTelemetryEvent); + telemetryTimeline.push(timelineTelemetryEvent); + } } - } - if (telemetryTimeline.length >= 1) { - const record: TimelineTelemetryTemplate = { - '@timestamp': moment().toISOString(), - ...baseDocument, - alert_id: alertUUID, - event_id: eventId, - timeline: telemetryTimeline, - }; - - sender.sendOnDemand(TELEMETRY_CHANNEL_TIMELINE, [record]); - counter += 1; - } else { - tlog(logger, 'no events in timeline'); + if (telemetryTimeline.length >= 1) { + const record: TimelineTelemetryTemplate = { + '@timestamp': moment().toISOString(), + ...baseDocument, + alert_id: alertUUID, + event_id: eventId, + timeline: telemetryTimeline, + }; + + sender.sendOnDemand(TELEMETRY_CHANNEL_TIMELINE, [record]); + counter += 1; + } else { + tlog(logger, 'no events in timeline'); + } } + tlog(logger, `sent ${counter} timelines. concluding timeline task.`); + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, true, startTime), + ]); + return counter; + } catch (err) { + await sender.sendOnDemand(TASK_METRICS_CHANNEL, [ + createTaskMetric(taskName, false, startTime, err.message), + ]); + return 0; } - - tlog(logger, `sent ${counter} timelines. concluding timeline task.`); - return counter; }, }; } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/types.ts b/x-pack/plugins/security_solution/server/lib/telemetry/types.ts index 82b4fde4b5992..3e0d9c1b4e1d2 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/types.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/types.ts @@ -412,3 +412,12 @@ export interface ValueListIndicatorMatchResponseAggregation { vl_used_in_indicator_match_rule_count: { value: number }; }; } + +export interface TaskMetric { + name: string; + passed: boolean; + time_executed_in_ms: number; + start_time: number; + end_time: number; + error_message?: string; +} diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/all_types.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/all_types.ts index 323fe9041e1b6..354ba79a46a56 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/all_types.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/all_types.ts @@ -12,6 +12,7 @@ import { deleteAllAlerts, deleteSignalsIndex, getSecurityTelemetryStats, + removeTimeFieldsFromTelemetryStats, } from '../../../../utils'; import { deleteAllExceptions } from '../../../../../lists_api_integration/utils'; @@ -41,14 +42,43 @@ export default ({ getService }: FtrProviderContext) => { await deleteAllExceptions(supertest, log); }); - it('should have initialized empty/zero values when no rules are running', async () => { + it('should only have task metric values when no rules are running', async () => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); expect(stats).to.eql({ - detection_rules: [], - security_lists: [], - endpoints: [], - diagnostics: [], + detection_rules: [ + [ + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, + ], + ], + security_lists: [ + [ + { + name: 'Security Solution Lists Telemetry', + passed: true, + }, + ], + ], + endpoints: [ + [ + { + name: 'Security Solution Telemetry Endpoint Metrics and Info task', + passed: true, + }, + ], + ], + diagnostics: [ + [ + { + name: 'Security Solution Telemetry Diagnostics task', + passed: true, + }, + ], + ], }); }); }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts index 627faebb2daaa..eb5f5c9a923bb 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/detection_rules.ts @@ -21,6 +21,7 @@ import { getSecurityTelemetryStats, createExceptionList, createExceptionListItem, + removeTimeFieldsFromTelemetryStats, } from '../../../../utils'; import { deleteAllExceptions } from '../../../../../lists_api_integration/utils'; @@ -100,7 +101,15 @@ export default ({ getService }: FtrProviderContext) => { // Get the stats and ensure they're empty await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); - expect(stats.detection_rules).to.eql([]); + removeTimeFieldsFromTelemetryStats(stats); + expect(stats.detection_rules).to.eql([ + [ + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, + ], + ]); }); }); @@ -148,7 +157,15 @@ export default ({ getService }: FtrProviderContext) => { // Get the stats and ensure they're empty await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); - expect(stats.detection_rules).to.eql([]); + removeTimeFieldsFromTelemetryStats(stats); + expect(stats.detection_rules).to.eql([ + [ + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, + ], + ]); }); }); @@ -196,7 +213,15 @@ export default ({ getService }: FtrProviderContext) => { // Get the stats and ensure they're empty await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); - expect(stats.detection_rules).to.eql([]); + removeTimeFieldsFromTelemetryStats(stats); + expect(stats.detection_rules).to.eql([ + [ + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, + ], + ]); }); }); @@ -244,7 +269,15 @@ export default ({ getService }: FtrProviderContext) => { // Get the stats and ensure they're empty await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); - expect(stats.detection_rules).to.eql([]); + removeTimeFieldsFromTelemetryStats(stats); + expect(stats.detection_rules).to.eql([ + [ + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, + ], + ]); }); }); @@ -292,7 +325,15 @@ export default ({ getService }: FtrProviderContext) => { // Get the stats and ensure they're empty await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); - expect(stats.detection_rules).to.eql([]); + removeTimeFieldsFromTelemetryStats(stats); + expect(stats.detection_rules).to.eql([ + [ + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, + ], + ]); }); }); }); @@ -350,7 +391,7 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); - expect(stats.detection_rules).length(1); + expect(stats.detection_rules).length(2); const detectionRule = stats.detection_rules[0][0]; expect(detectionRule['@timestamp']).to.be.a('string'); expect(detectionRule.cluster_uuid).to.be.a('string'); @@ -408,9 +449,10 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const detectionRules = stats.detection_rules .flat() - .map((obj: { detection_rule: any }) => obj.detection_rule); + .map((obj: any) => (obj.passed != null ? obj : obj.detection_rule)); expect(detectionRules).to.eql([ { @@ -428,6 +470,10 @@ export default ({ getService }: FtrProviderContext) => { os_types: [], rule_version: detectionRules[0].rule_version, }, + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, ]); }); }); @@ -479,9 +525,10 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const detectionRules = stats.detection_rules .flat() - .map((obj: { detection_rule: any }) => obj.detection_rule); + .map((obj: any) => (obj.passed != null ? obj : obj.detection_rule)); expect(detectionRules).to.eql([ { @@ -499,6 +546,10 @@ export default ({ getService }: FtrProviderContext) => { os_types: [], rule_version: detectionRules[0].rule_version, }, + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, ]); }); }); @@ -550,9 +601,10 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const detectionRules = stats.detection_rules .flat() - .map((obj: { detection_rule: any }) => obj.detection_rule); + .map((obj: any) => (obj.passed != null ? obj : obj.detection_rule)); expect(detectionRules).to.eql([ { @@ -570,6 +622,10 @@ export default ({ getService }: FtrProviderContext) => { os_types: [], rule_version: detectionRules[0].rule_version, }, + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, ]); }); }); @@ -621,9 +677,10 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const detectionRules = stats.detection_rules .flat() - .map((obj: { detection_rule: any }) => obj.detection_rule); + .map((obj: any) => (obj.passed != null ? obj : obj.detection_rule)); expect(detectionRules).to.eql([ { @@ -641,6 +698,10 @@ export default ({ getService }: FtrProviderContext) => { os_types: [], rule_version: detectionRules[0].rule_version, }, + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, ]); }); }); @@ -692,9 +753,10 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const detectionRules = stats.detection_rules .flat() - .map((obj: { detection_rule: any }) => obj.detection_rule); + .map((obj: any) => (obj.passed != null ? obj : obj.detection_rule)); expect(detectionRules).to.eql([ { @@ -712,6 +774,10 @@ export default ({ getService }: FtrProviderContext) => { os_types: [], rule_version: detectionRules[0].rule_version, }, + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, ]); }); }); @@ -787,11 +853,12 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const detectionRules = stats.detection_rules .flat() - .map((obj: { detection_rule: any }) => obj.detection_rule) + .map((obj: any) => (obj.passed != null ? obj : obj.detection_rule)) .sort((obj1: { entries: { name: number } }, obj2: { entries: { name: number } }) => { - return obj1.entries.name - obj2.entries.name; + return obj1?.entries?.name - obj2?.entries?.name; }); expect(detectionRules).to.eql([ @@ -825,6 +892,10 @@ export default ({ getService }: FtrProviderContext) => { os_types: [], rule_version: detectionRules[1].rule_version, }, + { + name: 'Security Solution Detection Rule Lists Telemetry', + passed: true, + }, ]); }); }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/security_lists.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/security_lists.ts index c56936f016b58..4db09b123d3db 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/security_lists.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group4/telemetry/task_based/security_lists.ts @@ -19,6 +19,7 @@ import { getSecurityTelemetryStats, createExceptionListItem, createExceptionList, + removeTimeFieldsFromTelemetryStats, } from '../../../../utils'; import { deleteAllExceptions } from '../../../../../lists_api_integration/utils'; @@ -72,10 +73,10 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); - + removeTimeFieldsFromTelemetryStats(stats); const trustedApplication = stats.security_lists .flat() - .map((obj: { trusted_application: any }) => obj.trusted_application); + .map((obj: any) => (obj.passed != null ? obj : obj.trusted_application)); expect(trustedApplication).to.eql([ { created_at: trustedApplication[0].created_at, @@ -95,6 +96,10 @@ export default ({ getService }: FtrProviderContext) => { policies: [], }, }, + { + name: 'Security Solution Lists Telemetry', + passed: true, + }, ]); }); }); @@ -138,12 +143,12 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); - + removeTimeFieldsFromTelemetryStats(stats); const trustedApplication = stats.security_lists .flat() - .map((obj: { trusted_application: any }) => obj.trusted_application) + .map((obj: any) => (obj.passed != null ? obj : obj.trusted_application)) .sort((obj1: { entries: { name: number } }, obj2: { entries: { name: number } }) => { - return obj1.entries.name - obj2.entries.name; + return obj1?.entries?.name - obj2?.entries?.name; }); expect(trustedApplication).to.eql([ @@ -183,6 +188,10 @@ export default ({ getService }: FtrProviderContext) => { policies: [], }, }, + { + name: 'Security Solution Lists Telemetry', + passed: true, + }, ]); }); }); @@ -210,9 +219,10 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const securityLists = stats.security_lists .flat() - .map((obj: { endpoint_exception: any }) => obj.endpoint_exception); + .map((obj: any) => (obj.passed != null ? obj : obj.endpoint_exception)); expect(securityLists).to.eql([ { created_at: securityLists[0].created_at, @@ -228,6 +238,10 @@ export default ({ getService }: FtrProviderContext) => { name: ENDPOINT_LIST_ID, os_types: [], }, + { + name: 'Security Solution Lists Telemetry', + passed: true, + }, ]); }); }); @@ -271,11 +285,12 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const securityLists = stats.security_lists .flat() - .map((obj: { endpoint_exception: any }) => obj.endpoint_exception) + .map((obj: any) => (obj.passed != null ? obj : obj.endpoint_exception)) .sort((obj1: { entries: { name: number } }, obj2: { entries: { name: number } }) => { - return obj1.entries.name - obj2.entries.name; + return obj1?.entries?.name - obj2?.entries?.name; }); expect(securityLists).to.eql([ @@ -307,6 +322,10 @@ export default ({ getService }: FtrProviderContext) => { name: ENDPOINT_LIST_ID, os_types: [], }, + { + name: 'Security Solution Lists Telemetry', + passed: true, + }, ]); }); }); @@ -346,9 +365,11 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const endPointEventFilter = stats.security_lists .flat() - .map((obj: { endpoint_event_filter: any }) => obj.endpoint_event_filter); + .map((obj: any) => (obj.passed != null ? obj : obj.endpoint_event_filter)); + expect(endPointEventFilter).to.eql([ { created_at: endPointEventFilter[0].created_at, @@ -364,6 +385,10 @@ export default ({ getService }: FtrProviderContext) => { name: ENDPOINT_EVENT_FILTERS_LIST_ID, os_types: ['linux'], }, + { + name: 'Security Solution Lists Telemetry', + passed: true, + }, ]); }); }); @@ -407,11 +432,12 @@ export default ({ getService }: FtrProviderContext) => { await retry.try(async () => { const stats = await getSecurityTelemetryStats(supertest, log); + removeTimeFieldsFromTelemetryStats(stats); const endPointEventFilter = stats.security_lists .flat() - .map((obj: { endpoint_event_filter: any }) => obj.endpoint_event_filter) + .map((obj: any) => (obj.passed != null ? obj : obj.endpoint_event_filter)) .sort((obj1: { entries: { name: number } }, obj2: { entries: { name: number } }) => { - return obj1.entries.name - obj2.entries.name; + return obj1?.entries?.name - obj2?.entries?.name; }); expect(endPointEventFilter).to.eql([ @@ -443,6 +469,10 @@ export default ({ getService }: FtrProviderContext) => { name: ENDPOINT_EVENT_FILTERS_LIST_ID, os_types: ['macos'], }, + { + name: 'Security Solution Lists Telemetry', + passed: true, + }, ]); }); }); diff --git a/x-pack/test/detection_engine_api_integration/utils/index.ts b/x-pack/test/detection_engine_api_integration/utils/index.ts index 31d13a52f72da..093be64c26d8a 100644 --- a/x-pack/test/detection_engine_api_integration/utils/index.ts +++ b/x-pack/test/detection_engine_api_integration/utils/index.ts @@ -80,6 +80,7 @@ export * from './get_web_hook_action'; export * from './index_event_log_execution_events'; export * from './install_prepackaged_rules'; export * from './refresh_index'; +export * from './remove_time_fields_from_telemetry_stats'; export * from './remove_server_generated_properties'; export * from './remove_server_generated_properties_including_rule_id'; export * from './resolve_simple_rule_output'; diff --git a/x-pack/test/detection_engine_api_integration/utils/remove_time_fields_from_telemetry_stats.ts b/x-pack/test/detection_engine_api_integration/utils/remove_time_fields_from_telemetry_stats.ts new file mode 100644 index 0000000000000..7c0931b4b5ae9 --- /dev/null +++ b/x-pack/test/detection_engine_api_integration/utils/remove_time_fields_from_telemetry_stats.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 { unset } from 'lodash'; + +export const removeTimeFieldsFromTelemetryStats = (stats: any) => { + Object.entries(stats).forEach(([, value]: [unknown, any]) => { + value.forEach((entry: any, i: number) => { + entry.forEach((e: any, j: number) => { + unset(value, `[${i}][${j}].time_executed_in_ms`); + unset(value, `[${i}][${j}].start_time`); + unset(value, `[${i}][${j}].end_time`); + }); + }); + }); +}; From 08e9c63659cbca8a1a0fd34c697864bb0a160fe4 Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Wed, 21 Sep 2022 19:02:00 -0600 Subject: [PATCH 21/36] [Actionable Observability][Metric Threshold Rule] Add histogram support to avg, max, min, sum and percentiles (#139770) --- .../metric_threshold/components/expression_row.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.tsx index 2209e1810a788..2204dd16fd46a 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.tsx +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression_row.tsx @@ -364,7 +364,7 @@ export const aggregationType: { [key: string]: any } = { defaultMessage: 'Average', }), fieldRequired: true, - validNormalizedTypes: ['number'], + validNormalizedTypes: ['number', 'histogram'], value: AGGREGATION_TYPES.AVERAGE, }, max: { @@ -372,7 +372,7 @@ export const aggregationType: { [key: string]: any } = { defaultMessage: 'Max', }), fieldRequired: true, - validNormalizedTypes: ['number', 'date'], + validNormalizedTypes: ['number', 'date', 'histogram'], value: AGGREGATION_TYPES.MAX, }, min: { @@ -380,7 +380,7 @@ export const aggregationType: { [key: string]: any } = { defaultMessage: 'Min', }), fieldRequired: true, - validNormalizedTypes: ['number', 'date'], + validNormalizedTypes: ['number', 'date', 'histogram'], value: AGGREGATION_TYPES.MIN, }, cardinality: { @@ -413,7 +413,7 @@ export const aggregationType: { [key: string]: any } = { }), fieldRequired: false, value: AGGREGATION_TYPES.SUM, - validNormalizedTypes: ['number'], + validNormalizedTypes: ['number', 'histogram'], }, p95: { text: i18n.translate('xpack.infra.metrics.alertFlyout.aggregationText.p95', { @@ -421,7 +421,7 @@ export const aggregationType: { [key: string]: any } = { }), fieldRequired: false, value: AGGREGATION_TYPES.P95, - validNormalizedTypes: ['number'], + validNormalizedTypes: ['number', 'histogram'], }, p99: { text: i18n.translate('xpack.infra.metrics.alertFlyout.aggregationText.p99', { @@ -429,6 +429,6 @@ export const aggregationType: { [key: string]: any } = { }), fieldRequired: false, value: AGGREGATION_TYPES.P99, - validNormalizedTypes: ['number'], + validNormalizedTypes: ['number', 'histogram'], }, }; From da60f57dff0b3ba34377a0eebbfbd87148f522aa Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 21 Sep 2022 20:13:24 -0500 Subject: [PATCH 22/36] [packages] add missing kibana.jsonc files (#141327) --- .github/CODEOWNERS | 4 ++++ packages/BUILD.bazel | 7 +++++++ packages/shared-ux/avatar/user_profile/impl/kibana.jsonc | 7 +++++++ packages/shared-ux/router/impl/kibana.jsonc | 7 +++++++ packages/shared-ux/router/mocks/kibana.jsonc | 7 +++++++ packages/shared-ux/router/types/kibana.jsonc | 7 +++++++ 6 files changed, 39 insertions(+) create mode 100644 packages/shared-ux/avatar/user_profile/impl/kibana.jsonc create mode 100644 packages/shared-ux/router/impl/kibana.jsonc create mode 100644 packages/shared-ux/router/mocks/kibana.jsonc create mode 100644 packages/shared-ux/router/types/kibana.jsonc diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index c78de33572f14..93cf5cc23dde2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -937,6 +937,7 @@ packages/kbn-utility-types-jest @elastic/kibana-operations packages/kbn-utils @elastic/kibana-operations packages/kbn-yarn-lock-validator @elastic/kibana-operations packages/shared-ux/avatar/solution @elastic/shared-ux +packages/shared-ux/avatar/user_profile/impl @elastic/shared-ux packages/shared-ux/button_toolbar @elastic/shared-ux packages/shared-ux/button/exit_full_screen/impl @elastic/shared-ux packages/shared-ux/button/exit_full_screen/mocks @elastic/shared-ux @@ -966,6 +967,9 @@ packages/shared-ux/page/solution_nav @elastic/shared-ux packages/shared-ux/prompt/no_data_views/impl @elastic/shared-ux packages/shared-ux/prompt/no_data_views/mocks @elastic/shared-ux packages/shared-ux/prompt/no_data_views/types @elastic/shared-ux +packages/shared-ux/router/impl @elastic/shared-ux +packages/shared-ux/router/mocks @elastic/shared-ux +packages/shared-ux/router/types @elastic/shared-ux packages/shared-ux/storybook/config @elastic/shared-ux packages/shared-ux/storybook/mock @elastic/shared-ux x-pack/packages/ml/agg_utils @elastic/ml-ui diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 051d0ac9bf27f..56ef73801d5a9 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -281,6 +281,7 @@ filegroup( "//packages/kbn-utils:build", "//packages/kbn-yarn-lock-validator:build", "//packages/shared-ux/avatar/solution:build", + "//packages/shared-ux/avatar/user_profile/impl:build", "//packages/shared-ux/button_toolbar:build", "//packages/shared-ux/button/exit_full_screen/impl:build", "//packages/shared-ux/button/exit_full_screen/mocks:build", @@ -310,6 +311,9 @@ filegroup( "//packages/shared-ux/prompt/no_data_views/impl:build", "//packages/shared-ux/prompt/no_data_views/mocks:build", "//packages/shared-ux/prompt/no_data_views/types:build", + "//packages/shared-ux/router/impl:build", + "//packages/shared-ux/router/mocks:build", + "//packages/shared-ux/router/types:build", "//packages/shared-ux/storybook/config:build", "//packages/shared-ux/storybook/mock:build", "//x-pack/packages/ml/agg_utils:build", @@ -581,6 +585,7 @@ filegroup( "//packages/kbn-utils:build_types", "//packages/kbn-yarn-lock-validator:build_types", "//packages/shared-ux/avatar/solution:build_types", + "//packages/shared-ux/avatar/user_profile/impl:build_types", "//packages/shared-ux/button_toolbar:build_types", "//packages/shared-ux/button/exit_full_screen/impl:build_types", "//packages/shared-ux/button/exit_full_screen/mocks:build_types", @@ -601,6 +606,8 @@ filegroup( "//packages/shared-ux/page/solution_nav:build_types", "//packages/shared-ux/prompt/no_data_views/impl:build_types", "//packages/shared-ux/prompt/no_data_views/mocks:build_types", + "//packages/shared-ux/router/impl:build_types", + "//packages/shared-ux/router/mocks:build_types", "//packages/shared-ux/storybook/config:build_types", "//packages/shared-ux/storybook/mock:build_types", "//x-pack/packages/ml/agg_utils:build_types", diff --git a/packages/shared-ux/avatar/user_profile/impl/kibana.jsonc b/packages/shared-ux/avatar/user_profile/impl/kibana.jsonc new file mode 100644 index 0000000000000..1fab1b9cb7d84 --- /dev/null +++ b/packages/shared-ux/avatar/user_profile/impl/kibana.jsonc @@ -0,0 +1,7 @@ +{ + "type": "shared-common", + "id": "@kbn/shared-ux-avatar-user-profile-components", + "owner": "@elastic/shared-ux", + "runtimeDeps": [], + "typeDeps": [] +} diff --git a/packages/shared-ux/router/impl/kibana.jsonc b/packages/shared-ux/router/impl/kibana.jsonc new file mode 100644 index 0000000000000..77f3eca900702 --- /dev/null +++ b/packages/shared-ux/router/impl/kibana.jsonc @@ -0,0 +1,7 @@ +{ + "type": "shared-common", + "id": "@kbn/shared-ux-router", + "owner": "@elastic/shared-ux", + "runtimeDeps": [], + "typeDeps": [] +} diff --git a/packages/shared-ux/router/mocks/kibana.jsonc b/packages/shared-ux/router/mocks/kibana.jsonc new file mode 100644 index 0000000000000..8f3aef23a2081 --- /dev/null +++ b/packages/shared-ux/router/mocks/kibana.jsonc @@ -0,0 +1,7 @@ +{ + "type": "shared-common", + "id": "@kbn/shared-ux-router-mocks", + "owner": "@elastic/shared-ux", + "runtimeDeps": [], + "typeDeps": [] +} diff --git a/packages/shared-ux/router/types/kibana.jsonc b/packages/shared-ux/router/types/kibana.jsonc new file mode 100644 index 0000000000000..4e328b93d6081 --- /dev/null +++ b/packages/shared-ux/router/types/kibana.jsonc @@ -0,0 +1,7 @@ +{ + "type": "shared-common", + "id": "@kbn/shared-ux-router-types", + "owner": "@elastic/shared-ux", + "runtimeDeps": [], + "typeDeps": [] +} From 85f5544263b7e2b49262705167ac5e7eb33ee058 Mon Sep 17 00:00:00 2001 From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Date: Wed, 21 Sep 2022 22:39:45 -0600 Subject: [PATCH 23/36] [api-docs] Daily api_docs build (#141343) --- api_docs/actions.mdx | 2 +- api_docs/advanced_settings.mdx | 2 +- api_docs/aiops.mdx | 2 +- api_docs/alerting.mdx | 2 +- api_docs/apm.devdocs.json | 8 +- api_docs/apm.mdx | 2 +- api_docs/banners.mdx | 2 +- api_docs/bfetch.mdx | 2 +- api_docs/canvas.mdx | 2 +- api_docs/cases.mdx | 2 +- api_docs/charts.mdx | 2 +- api_docs/cloud.mdx | 2 +- api_docs/cloud_experiments.mdx | 2 +- api_docs/cloud_security_posture.mdx | 2 +- api_docs/console.mdx | 2 +- api_docs/controls.mdx | 2 +- api_docs/core.mdx | 2 +- api_docs/custom_integrations.mdx | 2 +- api_docs/dashboard.mdx | 2 +- api_docs/dashboard_enhanced.mdx | 2 +- api_docs/data.devdocs.json | 4 +- api_docs/data.mdx | 2 +- api_docs/data_query.mdx | 2 +- api_docs/data_search.mdx | 2 +- api_docs/data_view_editor.mdx | 2 +- api_docs/data_view_field_editor.mdx | 2 +- api_docs/data_view_management.mdx | 2 +- api_docs/data_views.mdx | 2 +- api_docs/data_visualizer.mdx | 2 +- api_docs/deprecations_by_api.mdx | 2 +- api_docs/deprecations_by_plugin.mdx | 4 +- api_docs/deprecations_by_team.mdx | 2 +- api_docs/dev_tools.mdx | 2 +- api_docs/discover.mdx | 2 +- api_docs/discover_enhanced.mdx | 2 +- api_docs/embeddable.mdx | 2 +- api_docs/embeddable_enhanced.mdx | 2 +- api_docs/encrypted_saved_objects.mdx | 2 +- api_docs/enterprise_search.mdx | 2 +- api_docs/es_ui_shared.mdx | 2 +- api_docs/event_annotation.mdx | 2 +- api_docs/event_log.mdx | 2 +- api_docs/expression_error.mdx | 2 +- api_docs/expression_gauge.mdx | 2 +- api_docs/expression_heatmap.mdx | 2 +- api_docs/expression_image.mdx | 2 +- api_docs/expression_legacy_metric_vis.mdx | 2 +- api_docs/expression_metric.mdx | 2 +- api_docs/expression_metric_vis.mdx | 2 +- api_docs/expression_partition_vis.mdx | 2 +- api_docs/expression_repeat_image.mdx | 2 +- api_docs/expression_reveal_image.mdx | 2 +- api_docs/expression_shape.mdx | 2 +- api_docs/expression_tagcloud.mdx | 2 +- api_docs/expression_x_y.mdx | 2 +- api_docs/expressions.mdx | 2 +- api_docs/features.mdx | 2 +- api_docs/field_formats.mdx | 2 +- api_docs/file_upload.mdx | 2 +- api_docs/files.devdocs.json | 515 +++++++++++++++++- api_docs/files.mdx | 10 +- api_docs/fleet.mdx | 2 +- api_docs/global_search.mdx | 2 +- api_docs/guided_onboarding.mdx | 2 +- api_docs/home.mdx | 2 +- api_docs/index_lifecycle_management.mdx | 2 +- api_docs/index_management.mdx | 2 +- api_docs/infra.mdx | 2 +- api_docs/inspector.mdx | 2 +- api_docs/interactive_setup.mdx | 2 +- api_docs/kbn_ace.mdx | 2 +- api_docs/kbn_aiops_components.mdx | 2 +- api_docs/kbn_aiops_utils.mdx | 2 +- api_docs/kbn_alerts.mdx | 2 +- api_docs/kbn_analytics.mdx | 2 +- api_docs/kbn_analytics_client.mdx | 2 +- ..._analytics_shippers_elastic_v3_browser.mdx | 2 +- ...n_analytics_shippers_elastic_v3_common.mdx | 2 +- ...n_analytics_shippers_elastic_v3_server.mdx | 2 +- api_docs/kbn_analytics_shippers_fullstory.mdx | 2 +- api_docs/kbn_apm_config_loader.mdx | 2 +- api_docs/kbn_apm_synthtrace.mdx | 2 +- api_docs/kbn_apm_utils.mdx | 2 +- api_docs/kbn_axe_config.mdx | 2 +- api_docs/kbn_chart_icons.mdx | 2 +- api_docs/kbn_ci_stats_core.mdx | 2 +- api_docs/kbn_ci_stats_performance_metrics.mdx | 2 +- api_docs/kbn_ci_stats_reporter.mdx | 2 +- api_docs/kbn_cli_dev_mode.mdx | 2 +- api_docs/kbn_coloring.mdx | 2 +- api_docs/kbn_config.mdx | 2 +- api_docs/kbn_config_mocks.mdx | 2 +- api_docs/kbn_config_schema.mdx | 2 +- .../kbn_content_management_table_list.mdx | 2 +- api_docs/kbn_core_analytics_browser.mdx | 2 +- .../kbn_core_analytics_browser_internal.mdx | 2 +- api_docs/kbn_core_analytics_browser_mocks.mdx | 2 +- api_docs/kbn_core_analytics_server.mdx | 2 +- .../kbn_core_analytics_server_internal.mdx | 2 +- api_docs/kbn_core_analytics_server_mocks.mdx | 2 +- api_docs/kbn_core_application_browser.mdx | 2 +- .../kbn_core_application_browser_internal.mdx | 2 +- .../kbn_core_application_browser_mocks.mdx | 2 +- api_docs/kbn_core_application_common.mdx | 2 +- api_docs/kbn_core_apps_browser_internal.mdx | 2 +- api_docs/kbn_core_apps_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_browser_mocks.mdx | 2 +- api_docs/kbn_core_base_common.mdx | 2 +- api_docs/kbn_core_base_server_internal.mdx | 2 +- api_docs/kbn_core_base_server_mocks.mdx | 2 +- .../kbn_core_capabilities_browser_mocks.mdx | 2 +- api_docs/kbn_core_capabilities_common.mdx | 2 +- api_docs/kbn_core_capabilities_server.mdx | 2 +- .../kbn_core_capabilities_server_mocks.mdx | 2 +- api_docs/kbn_core_chrome_browser.mdx | 2 +- api_docs/kbn_core_chrome_browser_mocks.mdx | 2 +- api_docs/kbn_core_config_server_internal.mdx | 2 +- api_docs/kbn_core_deprecations_browser.mdx | 2 +- ...kbn_core_deprecations_browser_internal.mdx | 2 +- .../kbn_core_deprecations_browser_mocks.mdx | 2 +- api_docs/kbn_core_deprecations_common.mdx | 2 +- api_docs/kbn_core_deprecations_server.mdx | 2 +- .../kbn_core_deprecations_server_internal.mdx | 2 +- .../kbn_core_deprecations_server_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_browser.mdx | 2 +- api_docs/kbn_core_doc_links_browser_mocks.mdx | 2 +- api_docs/kbn_core_doc_links_server.mdx | 2 +- api_docs/kbn_core_doc_links_server_mocks.mdx | 2 +- ...e_elasticsearch_client_server_internal.mdx | 2 +- ...core_elasticsearch_client_server_mocks.mdx | 2 +- api_docs/kbn_core_elasticsearch_server.mdx | 2 +- ...kbn_core_elasticsearch_server_internal.mdx | 2 +- .../kbn_core_elasticsearch_server_mocks.mdx | 2 +- .../kbn_core_environment_server_internal.mdx | 2 +- .../kbn_core_environment_server_mocks.mdx | 2 +- .../kbn_core_execution_context_browser.mdx | 2 +- ...ore_execution_context_browser_internal.mdx | 2 +- ...n_core_execution_context_browser_mocks.mdx | 2 +- .../kbn_core_execution_context_common.mdx | 2 +- .../kbn_core_execution_context_server.mdx | 2 +- ...core_execution_context_server_internal.mdx | 2 +- ...bn_core_execution_context_server_mocks.mdx | 2 +- api_docs/kbn_core_fatal_errors_browser.mdx | 2 +- .../kbn_core_fatal_errors_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_browser.mdx | 2 +- api_docs/kbn_core_http_browser_internal.mdx | 2 +- api_docs/kbn_core_http_browser_mocks.mdx | 2 +- api_docs/kbn_core_http_common.mdx | 2 +- .../kbn_core_http_context_server_mocks.mdx | 2 +- .../kbn_core_http_router_server_internal.mdx | 2 +- .../kbn_core_http_router_server_mocks.mdx | 2 +- api_docs/kbn_core_http_server.mdx | 2 +- api_docs/kbn_core_http_server_internal.mdx | 2 +- api_docs/kbn_core_http_server_mocks.mdx | 2 +- api_docs/kbn_core_i18n_browser.mdx | 2 +- api_docs/kbn_core_i18n_browser_mocks.mdx | 2 +- api_docs/kbn_core_i18n_server.mdx | 2 +- api_docs/kbn_core_i18n_server_internal.mdx | 2 +- api_docs/kbn_core_i18n_server_mocks.mdx | 2 +- .../kbn_core_injected_metadata_browser.mdx | 2 +- ...n_core_injected_metadata_browser_mocks.mdx | 2 +- ...kbn_core_integrations_browser_internal.mdx | 2 +- .../kbn_core_integrations_browser_mocks.mdx | 2 +- api_docs/kbn_core_logging_server.mdx | 2 +- api_docs/kbn_core_logging_server_internal.mdx | 2 +- api_docs/kbn_core_logging_server_mocks.mdx | 2 +- ...ore_metrics_collectors_server_internal.mdx | 2 +- ...n_core_metrics_collectors_server_mocks.mdx | 2 +- api_docs/kbn_core_metrics_server.mdx | 2 +- api_docs/kbn_core_metrics_server_internal.mdx | 2 +- api_docs/kbn_core_metrics_server_mocks.mdx | 2 +- api_docs/kbn_core_mount_utils_browser.mdx | 2 +- api_docs/kbn_core_node_server.mdx | 2 +- api_docs/kbn_core_node_server_internal.mdx | 2 +- api_docs/kbn_core_node_server_mocks.mdx | 2 +- api_docs/kbn_core_notifications_browser.mdx | 2 +- ...bn_core_notifications_browser_internal.mdx | 2 +- .../kbn_core_notifications_browser_mocks.mdx | 2 +- api_docs/kbn_core_overlays_browser.mdx | 2 +- .../kbn_core_overlays_browser_internal.mdx | 2 +- api_docs/kbn_core_overlays_browser_mocks.mdx | 2 +- api_docs/kbn_core_preboot_server.mdx | 2 +- api_docs/kbn_core_preboot_server_mocks.mdx | 2 +- api_docs/kbn_core_rendering_browser_mocks.mdx | 2 +- .../kbn_core_saved_objects_api_browser.mdx | 2 +- .../kbn_core_saved_objects_api_server.mdx | 2 +- ...core_saved_objects_api_server_internal.mdx | 2 +- ...bn_core_saved_objects_api_server_mocks.mdx | 2 +- ...ore_saved_objects_base_server_internal.mdx | 2 +- ...n_core_saved_objects_base_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_browser.mdx | 2 +- ...bn_core_saved_objects_browser_internal.mdx | 2 +- .../kbn_core_saved_objects_browser_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_common.mdx | 2 +- ..._objects_import_export_server_internal.mdx | 2 +- ...ved_objects_import_export_server_mocks.mdx | 2 +- ...aved_objects_migration_server_internal.mdx | 2 +- ...e_saved_objects_migration_server_mocks.mdx | 2 +- api_docs/kbn_core_saved_objects_server.mdx | 2 +- ...kbn_core_saved_objects_server_internal.mdx | 2 +- .../kbn_core_saved_objects_server_mocks.mdx | 2 +- .../kbn_core_saved_objects_utils_server.mdx | 2 +- api_docs/kbn_core_status_common.mdx | 2 +- api_docs/kbn_core_status_common_internal.mdx | 2 +- api_docs/kbn_core_status_server.mdx | 2 +- api_docs/kbn_core_status_server_internal.mdx | 2 +- api_docs/kbn_core_status_server_mocks.mdx | 2 +- ...core_test_helpers_deprecations_getters.mdx | 2 +- ...n_core_test_helpers_http_setup_browser.mdx | 2 +- api_docs/kbn_core_theme_browser.mdx | 2 +- api_docs/kbn_core_theme_browser_internal.mdx | 2 +- api_docs/kbn_core_theme_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_browser.mdx | 2 +- .../kbn_core_ui_settings_browser_internal.mdx | 2 +- .../kbn_core_ui_settings_browser_mocks.mdx | 2 +- api_docs/kbn_core_ui_settings_common.mdx | 2 +- api_docs/kbn_core_ui_settings_server.mdx | 2 +- .../kbn_core_ui_settings_server_internal.mdx | 2 +- .../kbn_core_ui_settings_server_mocks.mdx | 2 +- api_docs/kbn_core_usage_data_server.mdx | 2 +- .../kbn_core_usage_data_server_internal.mdx | 2 +- api_docs/kbn_core_usage_data_server_mocks.mdx | 2 +- api_docs/kbn_crypto.mdx | 2 +- api_docs/kbn_crypto_browser.mdx | 2 +- api_docs/kbn_datemath.mdx | 2 +- api_docs/kbn_dev_cli_errors.mdx | 2 +- api_docs/kbn_dev_cli_runner.mdx | 2 +- api_docs/kbn_dev_proc_runner.mdx | 2 +- api_docs/kbn_dev_utils.mdx | 2 +- api_docs/kbn_doc_links.devdocs.json | 2 +- api_docs/kbn_doc_links.mdx | 2 +- api_docs/kbn_docs_utils.mdx | 2 +- api_docs/kbn_ebt_tools.mdx | 2 +- api_docs/kbn_es_archiver.mdx | 2 +- api_docs/kbn_es_errors.mdx | 2 +- api_docs/kbn_es_query.mdx | 2 +- api_docs/kbn_es_types.mdx | 2 +- api_docs/kbn_eslint_plugin_imports.mdx | 2 +- api_docs/kbn_field_types.mdx | 2 +- api_docs/kbn_find_used_node_modules.mdx | 2 +- api_docs/kbn_generate.mdx | 2 +- api_docs/kbn_get_repo_files.mdx | 2 +- api_docs/kbn_handlebars.mdx | 2 +- api_docs/kbn_hapi_mocks.mdx | 2 +- api_docs/kbn_home_sample_data_card.mdx | 2 +- api_docs/kbn_home_sample_data_tab.mdx | 2 +- api_docs/kbn_i18n.mdx | 2 +- api_docs/kbn_import_resolver.mdx | 2 +- api_docs/kbn_interpreter.mdx | 2 +- api_docs/kbn_io_ts_utils.mdx | 2 +- api_docs/kbn_jest_serializers.mdx | 2 +- api_docs/kbn_kibana_manifest_schema.mdx | 2 +- api_docs/kbn_logging.mdx | 2 +- api_docs/kbn_logging_mocks.mdx | 2 +- api_docs/kbn_managed_vscode_config.mdx | 2 +- api_docs/kbn_mapbox_gl.mdx | 2 +- api_docs/kbn_ml_agg_utils.mdx | 2 +- api_docs/kbn_ml_is_populated_object.mdx | 2 +- api_docs/kbn_ml_string_hash.mdx | 2 +- api_docs/kbn_monaco.mdx | 2 +- api_docs/kbn_optimizer.mdx | 2 +- api_docs/kbn_optimizer_webpack_helpers.mdx | 2 +- ..._performance_testing_dataset_extractor.mdx | 2 +- api_docs/kbn_plugin_generator.mdx | 2 +- api_docs/kbn_plugin_helpers.mdx | 2 +- api_docs/kbn_react_field.mdx | 2 +- api_docs/kbn_repo_source_classifier.mdx | 2 +- api_docs/kbn_rule_data_utils.mdx | 2 +- .../kbn_securitysolution_autocomplete.mdx | 2 +- api_docs/kbn_securitysolution_es_utils.mdx | 2 +- api_docs/kbn_securitysolution_hook_utils.mdx | 2 +- ..._securitysolution_io_ts_alerting_types.mdx | 2 +- .../kbn_securitysolution_io_ts_list_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_types.mdx | 2 +- api_docs/kbn_securitysolution_io_ts_utils.mdx | 2 +- api_docs/kbn_securitysolution_list_api.mdx | 2 +- .../kbn_securitysolution_list_constants.mdx | 2 +- api_docs/kbn_securitysolution_list_hooks.mdx | 2 +- api_docs/kbn_securitysolution_list_utils.mdx | 2 +- api_docs/kbn_securitysolution_rules.mdx | 2 +- api_docs/kbn_securitysolution_t_grid.mdx | 2 +- api_docs/kbn_securitysolution_utils.mdx | 2 +- api_docs/kbn_server_http_tools.mdx | 2 +- api_docs/kbn_server_route_repository.mdx | 2 +- api_docs/kbn_shared_svg.mdx | 2 +- ...ared_ux_avatar_user_profile_components.mdx | 2 +- ...hared_ux_button_exit_full_screen_mocks.mdx | 2 +- api_docs/kbn_shared_ux_button_toolbar.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data.mdx | 2 +- api_docs/kbn_shared_ux_card_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_link_redirect_app_mocks.mdx | 2 +- .../kbn_shared_ux_page_analytics_no_data.mdx | 2 +- ...shared_ux_page_analytics_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_no_data.mdx | 2 +- ...bn_shared_ux_page_kibana_no_data_mocks.mdx | 2 +- .../kbn_shared_ux_page_kibana_template.mdx | 2 +- ...n_shared_ux_page_kibana_template_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data.mdx | 2 +- .../kbn_shared_ux_page_no_data_config.mdx | 2 +- ...bn_shared_ux_page_no_data_config_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_no_data_mocks.mdx | 2 +- api_docs/kbn_shared_ux_page_solution_nav.mdx | 2 +- .../kbn_shared_ux_prompt_no_data_views.mdx | 2 +- ...n_shared_ux_prompt_no_data_views_mocks.mdx | 2 +- api_docs/kbn_shared_ux_router.mdx | 2 +- api_docs/kbn_shared_ux_router_mocks.mdx | 2 +- api_docs/kbn_shared_ux_storybook_config.mdx | 2 +- api_docs/kbn_shared_ux_storybook_mock.mdx | 2 +- api_docs/kbn_shared_ux_utility.mdx | 2 +- api_docs/kbn_some_dev_log.mdx | 2 +- api_docs/kbn_sort_package_json.mdx | 2 +- api_docs/kbn_std.mdx | 2 +- api_docs/kbn_stdio_dev_helpers.mdx | 2 +- api_docs/kbn_storybook.mdx | 2 +- api_docs/kbn_telemetry_tools.mdx | 2 +- api_docs/kbn_test.mdx | 2 +- api_docs/kbn_test_jest_helpers.mdx | 2 +- api_docs/kbn_test_subj_selector.mdx | 2 +- api_docs/kbn_tooling_log.mdx | 2 +- api_docs/kbn_type_summarizer.mdx | 2 +- api_docs/kbn_type_summarizer_core.mdx | 2 +- api_docs/kbn_typed_react_router_config.mdx | 2 +- api_docs/kbn_ui_theme.mdx | 2 +- api_docs/kbn_user_profile_components.mdx | 2 +- api_docs/kbn_utility_types.mdx | 2 +- api_docs/kbn_utility_types_jest.mdx | 2 +- api_docs/kbn_utils.mdx | 2 +- api_docs/kbn_yarn_lock_validator.mdx | 2 +- api_docs/kibana_overview.mdx | 2 +- api_docs/kibana_react.mdx | 2 +- api_docs/kibana_utils.mdx | 2 +- api_docs/kubernetes_security.mdx | 2 +- api_docs/lens.mdx | 2 +- api_docs/license_api_guard.mdx | 2 +- api_docs/license_management.mdx | 2 +- api_docs/licensing.mdx | 2 +- api_docs/lists.mdx | 2 +- api_docs/management.mdx | 2 +- api_docs/maps.mdx | 2 +- api_docs/maps_ems.mdx | 2 +- api_docs/ml.mdx | 2 +- api_docs/monitoring.mdx | 2 +- api_docs/monitoring_collection.mdx | 2 +- api_docs/navigation.mdx | 2 +- api_docs/newsfeed.mdx | 2 +- api_docs/observability.devdocs.json | 121 ++++ api_docs/observability.mdx | 4 +- api_docs/osquery.mdx | 2 +- api_docs/plugin_directory.mdx | 12 +- api_docs/presentation_util.mdx | 2 +- api_docs/profiling.mdx | 2 +- api_docs/remote_clusters.mdx | 2 +- api_docs/reporting.mdx | 2 +- api_docs/rollup.mdx | 2 +- api_docs/rule_registry.mdx | 2 +- api_docs/runtime_fields.mdx | 2 +- api_docs/saved_objects.mdx | 2 +- api_docs/saved_objects_finder.mdx | 2 +- api_docs/saved_objects_management.mdx | 2 +- api_docs/saved_objects_tagging.mdx | 2 +- api_docs/saved_objects_tagging_oss.mdx | 2 +- api_docs/saved_search.mdx | 2 +- api_docs/screenshot_mode.mdx | 2 +- api_docs/screenshotting.mdx | 2 +- api_docs/security.mdx | 2 +- api_docs/security_solution.mdx | 2 +- api_docs/session_view.mdx | 2 +- api_docs/share.mdx | 2 +- api_docs/snapshot_restore.mdx | 2 +- api_docs/spaces.mdx | 2 +- api_docs/stack_alerts.devdocs.json | 2 +- api_docs/stack_alerts.mdx | 2 +- api_docs/stack_connectors.mdx | 2 +- api_docs/task_manager.mdx | 2 +- api_docs/telemetry.mdx | 2 +- api_docs/telemetry_collection_manager.mdx | 2 +- api_docs/telemetry_collection_xpack.mdx | 2 +- api_docs/telemetry_management_section.mdx | 2 +- api_docs/threat_intelligence.mdx | 2 +- api_docs/timelines.mdx | 2 +- api_docs/transform.mdx | 2 +- api_docs/triggers_actions_ui.mdx | 2 +- api_docs/ui_actions.mdx | 2 +- api_docs/ui_actions_enhanced.mdx | 2 +- api_docs/unified_field_list.mdx | 2 +- api_docs/unified_search.devdocs.json | 41 +- api_docs/unified_search.mdx | 4 +- api_docs/unified_search_autocomplete.mdx | 4 +- api_docs/url_forwarding.mdx | 2 +- api_docs/usage_collection.mdx | 2 +- api_docs/ux.mdx | 2 +- api_docs/vis_default_editor.mdx | 2 +- api_docs/vis_type_gauge.mdx | 2 +- api_docs/vis_type_heatmap.mdx | 2 +- api_docs/vis_type_pie.mdx | 2 +- api_docs/vis_type_table.mdx | 2 +- api_docs/vis_type_timelion.mdx | 2 +- api_docs/vis_type_timeseries.mdx | 2 +- api_docs/vis_type_vega.mdx | 2 +- api_docs/vis_type_vislib.mdx | 2 +- api_docs/vis_type_xy.mdx | 2 +- api_docs/visualizations.devdocs.json | 20 + api_docs/visualizations.mdx | 4 +- 403 files changed, 1099 insertions(+), 432 deletions(-) diff --git a/api_docs/actions.mdx b/api_docs/actions.mdx index bdf14bf19ae84..880dc0b122f6a 100644 --- a/api_docs/actions.mdx +++ b/api_docs/actions.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/actions title: "actions" image: https://source.unsplash.com/400x175/?github description: API docs for the actions plugin -date: 2022-09-21 +date: 2022-09-22 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 1dbd552804863..69f9463fb9e2e 100644 --- a/api_docs/advanced_settings.mdx +++ b/api_docs/advanced_settings.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/advancedSettings title: "advancedSettings" image: https://source.unsplash.com/400x175/?github description: API docs for the advancedSettings plugin -date: 2022-09-21 +date: 2022-09-22 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 16ee88902efc4..fd4f21939b6e8 100644 --- a/api_docs/aiops.mdx +++ b/api_docs/aiops.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/aiops title: "aiops" image: https://source.unsplash.com/400x175/?github description: API docs for the aiops plugin -date: 2022-09-21 +date: 2022-09-22 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 3a59a9f336d06..da826f60ffc9c 100644 --- a/api_docs/alerting.mdx +++ b/api_docs/alerting.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/alerting title: "alerting" image: https://source.unsplash.com/400x175/?github description: API docs for the alerting plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'alerting'] --- import alertingObj from './alerting.devdocs.json'; diff --git a/api_docs/apm.devdocs.json b/api_docs/apm.devdocs.json index 1ad2876e6274d..42d291bc57f02 100644 --- a/api_docs/apm.devdocs.json +++ b/api_docs/apm.devdocs.json @@ -196,7 +196,7 @@ "APMPluginSetupDependencies", ") => { config$: ", "Observable", - "; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedServiceMetrics: boolean; searchAggregatedTransactions: ", + "; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", "; telemetryCollectionEnabled: boolean; metricsInterval: number; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }>>; getApmIndices: () => Promise<", "ApmIndicesConfig", @@ -415,7 +415,7 @@ "label": "config", "description": [], "signature": [ - "{ readonly indices: Readonly<{} & { metric: string; error: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedServiceMetrics: boolean; readonly searchAggregatedTransactions: ", + "{ readonly indices: Readonly<{} & { metric: string; error: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }" ], @@ -811,7 +811,7 @@ "label": "APMConfig", "description": [], "signature": [ - "{ readonly indices: Readonly<{} & { metric: string; error: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedServiceMetrics: boolean; readonly searchAggregatedTransactions: ", + "{ readonly indices: Readonly<{} & { metric: string; error: string; span: string; transaction: string; sourcemap: string; onboarding: string; }>; readonly autoCreateApmDataView: boolean; readonly serviceMapEnabled: boolean; readonly serviceMapFingerprintBucketSize: number; readonly serviceMapTraceIdBucketSize: number; readonly serviceMapFingerprintGlobalBucketSize: number; readonly serviceMapTraceIdGlobalBucketSize: number; readonly serviceMapMaxTracesPerRequest: number; readonly ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; readonly searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", "; readonly telemetryCollectionEnabled: boolean; readonly metricsInterval: number; readonly agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }" ], @@ -5618,7 +5618,7 @@ "description": [], "signature": [ "Observable", - "; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedServiceMetrics: boolean; searchAggregatedTransactions: ", + "; autoCreateApmDataView: boolean; serviceMapEnabled: boolean; serviceMapFingerprintBucketSize: number; serviceMapTraceIdBucketSize: number; serviceMapFingerprintGlobalBucketSize: number; serviceMapTraceIdGlobalBucketSize: number; serviceMapMaxTracesPerRequest: number; ui: Readonly<{} & { enabled: boolean; transactionGroupBucketSize: number; maxTraceItems: number; }>; searchAggregatedTransactions: ", "SearchAggregatedTransactionSetting", "; telemetryCollectionEnabled: boolean; metricsInterval: number; agent: Readonly<{} & { migrations: Readonly<{} & { enabled: boolean; }>; }>; }>>" ], diff --git a/api_docs/apm.mdx b/api_docs/apm.mdx index 936fb386563a2..bbd29cd9d6bdf 100644 --- a/api_docs/apm.mdx +++ b/api_docs/apm.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/apm title: "apm" image: https://source.unsplash.com/400x175/?github description: API docs for the apm plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'apm'] --- import apmObj from './apm.devdocs.json'; diff --git a/api_docs/banners.mdx b/api_docs/banners.mdx index 9f93e0cf30bad..7f66666be6ed8 100644 --- a/api_docs/banners.mdx +++ b/api_docs/banners.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/banners title: "banners" image: https://source.unsplash.com/400x175/?github description: API docs for the banners plugin -date: 2022-09-21 +date: 2022-09-22 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 03ef60650c287..2667ba38a0f73 100644 --- a/api_docs/bfetch.mdx +++ b/api_docs/bfetch.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/bfetch title: "bfetch" image: https://source.unsplash.com/400x175/?github description: API docs for the bfetch plugin -date: 2022-09-21 +date: 2022-09-22 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 e1070b82be030..4661b73c4cef5 100644 --- a/api_docs/canvas.mdx +++ b/api_docs/canvas.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/canvas title: "canvas" image: https://source.unsplash.com/400x175/?github description: API docs for the canvas plugin -date: 2022-09-21 +date: 2022-09-22 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 9c1f56437d048..2601c456b45e1 100644 --- a/api_docs/cases.mdx +++ b/api_docs/cases.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cases title: "cases" image: https://source.unsplash.com/400x175/?github description: API docs for the cases plugin -date: 2022-09-21 +date: 2022-09-22 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 496b2c6c79551..806f99fc1dd39 100644 --- a/api_docs/charts.mdx +++ b/api_docs/charts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/charts title: "charts" image: https://source.unsplash.com/400x175/?github description: API docs for the charts plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'charts'] --- import chartsObj from './charts.devdocs.json'; diff --git a/api_docs/cloud.mdx b/api_docs/cloud.mdx index 58a63e62dd73a..0a73a5a20eec9 100644 --- a/api_docs/cloud.mdx +++ b/api_docs/cloud.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloud title: "cloud" image: https://source.unsplash.com/400x175/?github description: API docs for the cloud plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'cloud'] --- import cloudObj from './cloud.devdocs.json'; diff --git a/api_docs/cloud_experiments.mdx b/api_docs/cloud_experiments.mdx index f80478c49dede..8cb4e1537763e 100644 --- a/api_docs/cloud_experiments.mdx +++ b/api_docs/cloud_experiments.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudExperiments title: "cloudExperiments" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudExperiments plugin -date: 2022-09-21 +date: 2022-09-22 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 8e2501623ac24..e2848bff600e0 100644 --- a/api_docs/cloud_security_posture.mdx +++ b/api_docs/cloud_security_posture.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/cloudSecurityPosture title: "cloudSecurityPosture" image: https://source.unsplash.com/400x175/?github description: API docs for the cloudSecurityPosture plugin -date: 2022-09-21 +date: 2022-09-22 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 5d4888478dedf..b99308ac7643d 100644 --- a/api_docs/console.mdx +++ b/api_docs/console.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/console title: "console" image: https://source.unsplash.com/400x175/?github description: API docs for the console plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'console'] --- import consoleObj from './console.devdocs.json'; diff --git a/api_docs/controls.mdx b/api_docs/controls.mdx index 51aa262c87e5a..4427f251a9ef3 100644 --- a/api_docs/controls.mdx +++ b/api_docs/controls.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/controls title: "controls" image: https://source.unsplash.com/400x175/?github description: API docs for the controls plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'controls'] --- import controlsObj from './controls.devdocs.json'; diff --git a/api_docs/core.mdx b/api_docs/core.mdx index a5cd7b55e96a4..413a21a58e12e 100644 --- a/api_docs/core.mdx +++ b/api_docs/core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/core title: "core" image: https://source.unsplash.com/400x175/?github description: API docs for the core plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'core'] --- import coreObj from './core.devdocs.json'; diff --git a/api_docs/custom_integrations.mdx b/api_docs/custom_integrations.mdx index cc8febab951ca..db608cbbc805b 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: 2022-09-21 +date: 2022-09-22 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 a1e2f06b410e5..8a21209e990fb 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: 2022-09-21 +date: 2022-09-22 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 ed8980fc7c838..ef500bb63d28d 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'dashboardEnhanced'] --- import dashboardEnhancedObj from './dashboard_enhanced.devdocs.json'; diff --git a/api_docs/data.devdocs.json b/api_docs/data.devdocs.json index f2850615238c6..d8e572383857c 100644 --- a/api_docs/data.devdocs.json +++ b/api_docs/data.devdocs.json @@ -11419,11 +11419,11 @@ }, { "plugin": "stackAlerts", - "path": "x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx" + "path": "x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx" }, { "plugin": "stackAlerts", - "path": "x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx" + "path": "x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx" }, { "plugin": "stackAlerts", diff --git a/api_docs/data.mdx b/api_docs/data.mdx index cb7c49f026491..3a8209067815f 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: 2022-09-21 +date: 2022-09-22 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 dfc44a7ebf77d..661eef503c692 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: 2022-09-21 +date: 2022-09-22 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 fa49792d2181c..4801005b8e955 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: 2022-09-21 +date: 2022-09-22 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 15d7ddfaff816..bec2047cd26a0 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: 2022-09-21 +date: 2022-09-22 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 cd3ddbce16f08..a07ba6097b88f 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: 2022-09-21 +date: 2022-09-22 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 706182af7954b..4619af2e25aa8 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: 2022-09-21 +date: 2022-09-22 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 95d0e05ecf2ab..7a8fd54baad3a 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: 2022-09-21 +date: 2022-09-22 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 73e19b646e6f6..e7c4937c65f86 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: 2022-09-21 +date: 2022-09-22 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 26c1133aa166d..c834b151512de 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 33ca134222c20..5b36d18efade8 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -690,7 +690,7 @@ migrates to using the Kibana Privilege model: https://github.com/elastic/kibana/ | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [rule_type.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/alert_types/es_query/rule_type.test.ts#:~:text=fetch), [rule_type.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/alert_types/es_query/rule_type.test.ts#:~:text=fetch) | - | -| | [entity_index_expression.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx#:~:text=indexPatterns), [boundary_index_expression.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns) | - | +| | [boundary_index_expression.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/boundary_index_expression.tsx#:~:text=indexPatterns), [entity_index_expression.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/expressions/entity_index_expression.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns), [index.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/geo_containment/query_builder/index.tsx#:~:text=indexPatterns) | - | | | [expression.tsx](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/public/alert_types/threshold/expression.tsx#:~:text=fieldFormats) | - | | | [fetch_search_source_query.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/alert_types/es_query/lib/fetch_search_source_query.ts#:~:text=fetch), [rule_type.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/alert_types/es_query/rule_type.test.ts#:~:text=fetch), [rule_type.test.ts](https://github.com/elastic/kibana/tree/main/x-pack/plugins/stack_alerts/server/alert_types/es_query/rule_type.test.ts#:~:text=fetch) | - | diff --git a/api_docs/deprecations_by_team.mdx b/api_docs/deprecations_by_team.mdx index a7dc1bdec8678..7d2110b109555 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- diff --git a/api_docs/dev_tools.mdx b/api_docs/dev_tools.mdx index 08b245fb26f43..cb50c61bce67d 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: 2022-09-21 +date: 2022-09-22 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 22482b37187c2..ad00f12b57cf8 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: 2022-09-21 +date: 2022-09-22 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 e29728560aab4..694a717b00ea4 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'discoverEnhanced'] --- import discoverEnhancedObj from './discover_enhanced.devdocs.json'; diff --git a/api_docs/embeddable.mdx b/api_docs/embeddable.mdx index 2f5fbce453b35..cd86fe18bd9c8 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: 2022-09-21 +date: 2022-09-22 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 57604fa09d9cc..a3ea1b1190f83 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: 2022-09-21 +date: 2022-09-22 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 10e8ab28d577a..08cb65de4ffb1 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: 2022-09-21 +date: 2022-09-22 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 d21f75ff234d8..69819eb7b668c 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: 2022-09-21 +date: 2022-09-22 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 799b9e84cc1fd..1e0dae9b242e7 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: 2022-09-21 +date: 2022-09-22 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 b856ac4924147..32e9439e61b31 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: 2022-09-21 +date: 2022-09-22 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 12011c049c6f6..32bf0c0ec8138 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'eventLog'] --- import eventLogObj from './event_log.devdocs.json'; diff --git a/api_docs/expression_error.mdx b/api_docs/expression_error.mdx index 04fb06c8c96d4..ce92668b511a0 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: 2022-09-21 +date: 2022-09-22 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 d0b10885cf2b7..7c7a8804ab79f 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: 2022-09-21 +date: 2022-09-22 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 de91bc5178131..1927d1ba583e9 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: 2022-09-21 +date: 2022-09-22 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 1cc9d08db5a90..50164ed6d0dc8 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: 2022-09-21 +date: 2022-09-22 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 9fcf50bff28ef..04246f0e5bd22 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: 2022-09-21 +date: 2022-09-22 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 bc16b14f88d03..6226327af0e0b 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: 2022-09-21 +date: 2022-09-22 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 7b72a487826e6..6240f18c0ce55 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: 2022-09-21 +date: 2022-09-22 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 c219691750f84..633b28f5cb989 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: 2022-09-21 +date: 2022-09-22 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 6929d4d65ff1c..783dcdff3412b 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: 2022-09-21 +date: 2022-09-22 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 cf8447fa6e554..2e2068e4bd83b 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: 2022-09-21 +date: 2022-09-22 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 b86adf33d39e5..0950fff727a5f 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: 2022-09-21 +date: 2022-09-22 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 3fe265b6ba374..e9d5af42e5be2 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: 2022-09-21 +date: 2022-09-22 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 c017cb7f59f51..f83d943cbcd24 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: 2022-09-21 +date: 2022-09-22 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 8bd22f5dbc372..e186179b019e0 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: 2022-09-21 +date: 2022-09-22 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 fb97fac6d9a73..f917d8d7d9967 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: 2022-09-21 +date: 2022-09-22 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 02113ea2e591b..171e1798f6ecf 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: 2022-09-21 +date: 2022-09-22 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 3a28e7c492bf3..b89efdc3b0f69 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'fileUpload'] --- import fileUploadObj from './file_upload.devdocs.json'; diff --git a/api_docs/files.devdocs.json b/api_docs/files.devdocs.json index faee578b74688..69eb98792d527 100644 --- a/api_docs/files.devdocs.json +++ b/api_docs/files.devdocs.json @@ -2,7 +2,133 @@ "id": "files", "client": { "classes": [], - "functions": [], + "functions": [ + { + "parentPluginId": "files", + "id": "def-public.FilesContext", + "type": "Function", + "tags": [], + "label": "FilesContext", + "description": [], + "signature": [ + "({ children }: { children?: React.ReactNode; }) => JSX.Element" + ], + "path": "x-pack/plugins/files/public/components/context.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "files", + "id": "def-public.FilesContext.$1", + "type": "Object", + "tags": [], + "label": "{ children }", + "description": [], + "signature": [ + "{ children?: React.ReactNode; }" + ], + "path": "x-pack/plugins/files/public/components/context.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "files", + "id": "def-public.Image", + "type": "Function", + "tags": [ + "note" + ], + "label": "Image", + "description": [ + "\nA viewport-aware component that displays an image. This component is a very\nthin wrapper around the img tag.\n" + ], + "signature": [ + "React.ForwardRefExoticComponent<", + { + "pluginId": "files", + "scope": "public", + "docId": "kibFilesPluginApi", + "section": "def-public.Props", + "text": "Props" + }, + " & React.RefAttributes>" + ], + "path": "x-pack/plugins/files/public/components/image/image.tsx", + "deprecated": false, + "trackAdoption": false, + "returnComment": [], + "children": [ + { + "parentPluginId": "files", + "id": "def-public.Image.$1", + "type": "Uncategorized", + "tags": [], + "label": "props", + "description": [], + "signature": [ + "P" + ], + "path": "node_modules/@types/react/index.d.ts", + "deprecated": false, + "trackAdoption": false + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "files", + "id": "def-public.UploadFile", + "type": "Function", + "tags": [], + "label": "UploadFile", + "description": [], + "signature": [ + "(props: ", + { + "pluginId": "files", + "scope": "public", + "docId": "kibFilesPluginApi", + "section": "def-public.Props", + "text": "Props" + }, + ") => JSX.Element" + ], + "path": "x-pack/plugins/files/public/components/upload_file/index.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "files", + "id": "def-public.UploadFile.$1", + "type": "Object", + "tags": [], + "label": "props", + "description": [], + "signature": [ + { + "pluginId": "files", + "scope": "public", + "docId": "kibFilesPluginApi", + "section": "def-public.Props", + "text": "Props" + }, + "" + ], + "path": "x-pack/plugins/files/public/components/upload_file/index.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], "interfaces": [ { "parentPluginId": "files", @@ -62,7 +188,7 @@ "- create file args" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -97,7 +223,7 @@ "- delete file args" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -140,7 +266,7 @@ "- get file by ID args" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -191,7 +317,7 @@ "- list files args" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -234,7 +360,7 @@ "- update file args" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -252,7 +378,7 @@ "\nStream the contents of the file to Kibana server for storage.\n" ], "signature": [ - "(args: { body: unknown; } & { id: string; } & { kind: string; }) => Promise<{ ok: true; size: number; }>" + "(args: { body: unknown; } & { id: string; } & { selfDestructOnAbort?: boolean | undefined; } & { kind: string; } & { abortSignal?: AbortSignal | undefined; }) => Promise<{ ok: true; size: number; }>" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -269,7 +395,7 @@ "- upload file args" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -304,7 +430,7 @@ "- download file args" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -398,7 +524,7 @@ "- File share arguments" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -433,7 +559,7 @@ "- File unshare arguments" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -476,7 +602,7 @@ "- Get file share arguments" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -527,7 +653,7 @@ "- Get file share arguments" ], "signature": [ - "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; }" + "E[\"inputs\"][\"body\"] & E[\"inputs\"][\"params\"] & E[\"inputs\"][\"query\"] & { kind: string; } & ExtraArgs" ], "path": "x-pack/plugins/files/public/types.ts", "deprecated": false, @@ -621,6 +747,270 @@ } ], "initialIsOpen": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props", + "type": "Interface", + "tags": [], + "label": "Props", + "description": [], + "signature": [ + { + "pluginId": "files", + "scope": "public", + "docId": "kibFilesPluginApi", + "section": "def-public.Props", + "text": "Props" + }, + " extends React.ImgHTMLAttributes" + ], + "path": "x-pack/plugins/files/public/components/image/image.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "files", + "id": "def-public.Props.src", + "type": "string", + "tags": [], + "label": "src", + "description": [], + "path": "x-pack/plugins/files/public/components/image/image.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props.alt", + "type": "string", + "tags": [], + "label": "alt", + "description": [], + "path": "x-pack/plugins/files/public/components/image/image.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props.onFirstVisible", + "type": "Function", + "tags": [], + "label": "onFirstVisible", + "description": [ + "\nEmits when the image first becomes visible" + ], + "signature": [ + "(() => void) | undefined" + ], + "path": "x-pack/plugins/files/public/components/image/image.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [], + "returnComment": [] + } + ], + "initialIsOpen": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props", + "type": "Interface", + "tags": [], + "label": "Props", + "description": [ + "\nUploadFile component props" + ], + "signature": [ + { + "pluginId": "files", + "scope": "public", + "docId": "kibFilesPluginApi", + "section": "def-public.Props", + "text": "Props" + }, + "" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "files", + "id": "def-public.Props.kind", + "type": "Uncategorized", + "tags": [], + "label": "kind", + "description": [ + "\nA file kind that should be registered during plugin startup. See {@link FileServiceStart}." + ], + "signature": [ + "Kind" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props.client", + "type": "Object", + "tags": [], + "label": "client", + "description": [ + "\nA files client that will be used process uploads." + ], + "signature": [ + { + "pluginId": "files", + "scope": "public", + "docId": "kibFilesPluginApi", + "section": "def-public.FilesClient", + "text": "FilesClient" + } + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props.allowClear", + "type": "CompoundType", + "tags": [ + "note" + ], + "label": "allowClear", + "description": [ + "\nAllow users to clear a file after uploading.\n" + ], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props.immediate", + "type": "CompoundType", + "tags": [], + "label": "immediate", + "description": [ + "\nStart uploading the file as soon as it is provided\nby the user." + ], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props.meta", + "type": "Object", + "tags": [], + "label": "meta", + "description": [ + "\nMetadata that you want to associate with any uploaded files" + ], + "signature": [ + "Record | undefined" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props.allowRepeatedUploads", + "type": "CompoundType", + "tags": [ + "default" + ], + "label": "allowRepeatedUploads", + "description": [ + "\nWhether this component should display a \"done\" state after processing an\nupload or return to the initial state to allow for another upload.\n" + ], + "signature": [ + "boolean | undefined" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.Props.onDone", + "type": "Function", + "tags": [], + "label": "onDone", + "description": [ + "\nCalled when the an upload process fully completes" + ], + "signature": [ + "(files: UploadedFile[]) => void" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "files", + "id": "def-public.Props.onDone.$1", + "type": "Array", + "tags": [], + "label": "files", + "description": [], + "signature": [ + "UploadedFile[]" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + }, + { + "parentPluginId": "files", + "id": "def-public.Props.onError", + "type": "Function", + "tags": [], + "label": "onError", + "description": [ + "\nCalled when an error occurs during upload" + ], + "signature": [ + "((e: Error) => void) | undefined" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "files", + "id": "def-public.Props.onError.$1", + "type": "Object", + "tags": [], + "label": "e", + "description": [], + "signature": [ + "Error" + ], + "path": "x-pack/plugins/files/public/components/upload_file/upload_file.tsx", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "initialIsOpen": false } ], "enums": [], @@ -762,7 +1152,7 @@ "section": "def-common.FileJSON", "text": "FileJSON" }, - "; }>; upload: (arg: Omit<{ body: unknown; } & { id: string; } & { kind: string; }, \"kind\">) => Promise<{ ok: true; size: number; }>; download: (arg: Omit<{ id: string; fileName?: string | undefined; } & { kind: string; }, \"kind\">) => Promise; getDownloadHref: (arg: Omit<", + "; }>; upload: (arg: Omit<{ body: unknown; } & { id: string; } & { selfDestructOnAbort?: boolean | undefined; } & { kind: string; } & { abortSignal?: AbortSignal | undefined; }, \"kind\">) => Promise<{ ok: true; size: number; }>; download: (arg: Omit<{ id: string; fileName?: string | undefined; } & { kind: string; }, \"kind\">) => Promise; getDownloadHref: (arg: Omit<", { "pluginId": "files", "scope": "common", @@ -835,6 +1225,95 @@ } ], "objects": [], + "setup": { + "parentPluginId": "files", + "id": "def-public.FilesSetup", + "type": "Interface", + "tags": [], + "label": "FilesSetup", + "description": [ + "\nPublic setup-phase contract" + ], + "path": "x-pack/plugins/files/public/plugin.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "files", + "id": "def-public.FilesSetup.filesClientFactory", + "type": "Object", + "tags": [], + "label": "filesClientFactory", + "description": [ + "\nA factory for creating an {@link FilesClient} instance. This requires a\nregistered {@link FileKind}." + ], + "signature": [ + { + "pluginId": "files", + "scope": "public", + "docId": "kibFilesPluginApi", + "section": "def-public.FilesClientFactory", + "text": "FilesClientFactory" + } + ], + "path": "x-pack/plugins/files/public/plugin.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "files", + "id": "def-public.FilesSetup.registerFileKind", + "type": "Function", + "tags": [], + "label": "registerFileKind", + "description": [ + "\nRegister a {@link FileKind} which allows for specifying details about the files\nthat will be uploaded.\n" + ], + "signature": [ + "(fileKind: ", + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileKind", + "text": "FileKind" + }, + ") => void" + ], + "path": "x-pack/plugins/files/public/plugin.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "files", + "id": "def-public.FilesSetup.registerFileKind.$1", + "type": "Object", + "tags": [], + "label": "fileKind", + "description": [ + "- the file kind to register" + ], + "signature": [ + { + "pluginId": "files", + "scope": "common", + "docId": "kibFilesPluginApi", + "section": "def-common.FileKind", + "text": "FileKind" + } + ], + "path": "x-pack/plugins/files/public/plugin.ts", + "deprecated": false, + "trackAdoption": false, + "isRequired": true + } + ], + "returnComment": [] + } + ], + "lifecycle": "setup", + "initialIsOpen": true + }, "start": { "parentPluginId": "files", "id": "def-public.FilesStart", @@ -843,13 +1322,15 @@ "label": "FilesStart", "description": [], "signature": [ + "{ filesClientFactory: ", { "pluginId": "files", "scope": "public", "docId": "kibFilesPluginApi", - "section": "def-public.FilesSetup", - "text": "FilesSetup" - } + "section": "def-public.FilesClientFactory", + "text": "FilesClientFactory" + }, + "; }" ], "path": "x-pack/plugins/files/public/plugin.ts", "deprecated": false, diff --git a/api_docs/files.mdx b/api_docs/files.mdx index bb3bd2bbcff56..ea2cf22087412 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'files'] --- import filesObj from './files.devdocs.json'; @@ -21,13 +21,19 @@ Contact [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/tea | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 240 | 0 | 6 | 2 | +| 263 | 0 | 15 | 2 | ## Client +### Setup + + ### Start +### Functions + + ### Interfaces diff --git a/api_docs/fleet.mdx b/api_docs/fleet.mdx index 07f8d74f9c842..deaa296249ab3 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: 2022-09-21 +date: 2022-09-22 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 c5034da58e5a1..0aae391e045d8 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: 2022-09-21 +date: 2022-09-22 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 fe535e96c2df8..c1d48c0989a34 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'guidedOnboarding'] --- import guidedOnboardingObj from './guided_onboarding.devdocs.json'; diff --git a/api_docs/home.mdx b/api_docs/home.mdx index 1c29739eb6bb6..20dac194b7666 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'home'] --- import homeObj from './home.devdocs.json'; diff --git a/api_docs/index_lifecycle_management.mdx b/api_docs/index_lifecycle_management.mdx index 501b570f5d017..ea1e351b8eca7 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: 2022-09-21 +date: 2022-09-22 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 c01e2fd84fcd7..14dbc7f48fedb 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: 2022-09-21 +date: 2022-09-22 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 8a0e939a8ed2b..e9ee4c12f506d 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: 2022-09-21 +date: 2022-09-22 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 b0b1c0aba0443..83ec164aa79e6 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: 2022-09-21 +date: 2022-09-22 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 32e01d93df529..475c42ddf450b 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: 2022-09-21 +date: 2022-09-22 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 376fd853d73aa..efdce690d2247 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: 2022-09-21 +date: 2022-09-22 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 dc1ee35a57b69..26ee28f0d5116 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: 2022-09-21 +date: 2022-09-22 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 b87509e3cc43f..047d85e585bb0 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/aiops-utils'] --- import kbnAiopsUtilsObj from './kbn_aiops_utils.devdocs.json'; diff --git a/api_docs/kbn_alerts.mdx b/api_docs/kbn_alerts.mdx index 0d305dac2e069..711dca1d69319 100644 --- a/api_docs/kbn_alerts.mdx +++ b/api_docs/kbn_alerts.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-alerts title: "@kbn/alerts" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/alerts plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/alerts'] --- import kbnAlertsObj from './kbn_alerts.devdocs.json'; diff --git a/api_docs/kbn_analytics.mdx b/api_docs/kbn_analytics.mdx index 873c79fa16586..f2d1444eddc39 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: 2022-09-21 +date: 2022-09-22 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 a4f4547481fd4..c4b2f07e35477 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: 2022-09-21 +date: 2022-09-22 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 382a8ad33ef27..66f9a16b7e217 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: 2022-09-21 +date: 2022-09-22 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 e1eccc8fdb940..3ec92012afe72 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: 2022-09-21 +date: 2022-09-22 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 dac62dbfa13f6..6081a36a42fdc 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: 2022-09-21 +date: 2022-09-22 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 2f3a2e4b6e791..ffb73d2b3cbbc 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/analytics-shippers-fullstory'] --- import kbnAnalyticsShippersFullstoryObj from './kbn_analytics_shippers_fullstory.devdocs.json'; diff --git a/api_docs/kbn_apm_config_loader.mdx b/api_docs/kbn_apm_config_loader.mdx index 948d34bfbcbd4..145d493a2664f 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: 2022-09-21 +date: 2022-09-22 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 92e27ecd44c61..8670cc5eb9306 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/apm-synthtrace'] --- import kbnApmSynthtraceObj from './kbn_apm_synthtrace.devdocs.json'; diff --git a/api_docs/kbn_apm_utils.mdx b/api_docs/kbn_apm_utils.mdx index 5901d75a22dfe..791dbb286d079 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: 2022-09-21 +date: 2022-09-22 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 3d141045316e9..c240caf2e87dd 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/axe-config'] --- import kbnAxeConfigObj from './kbn_axe_config.devdocs.json'; diff --git a/api_docs/kbn_chart_icons.mdx b/api_docs/kbn_chart_icons.mdx index c4bf743890b27..6e1955e64d291 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: 2022-09-21 +date: 2022-09-22 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 e80b8d319443f..548d3a429b221 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: 2022-09-21 +date: 2022-09-22 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 dcf4e1168cda0..f71fdfc630e12 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: 2022-09-21 +date: 2022-09-22 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 b0d2e856b602b..6a78799b95ef2 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: 2022-09-21 +date: 2022-09-22 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 af88a7a61ecaf..92b6b367bc9ff 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/cli-dev-mode'] --- import kbnCliDevModeObj from './kbn_cli_dev_mode.devdocs.json'; diff --git a/api_docs/kbn_coloring.mdx b/api_docs/kbn_coloring.mdx index d179dd6f56b8d..235779d14f01d 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: 2022-09-21 +date: 2022-09-22 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 610cf11db4ce2..754221c503859 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: 2022-09-21 +date: 2022-09-22 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 9796cc2ef31a2..85bc4f51eec07 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: 2022-09-21 +date: 2022-09-22 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 be242a54c53a0..cb3f886dd7e36 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/config-schema'] --- import kbnConfigSchemaObj from './kbn_config_schema.devdocs.json'; diff --git a/api_docs/kbn_content_management_table_list.mdx b/api_docs/kbn_content_management_table_list.mdx index d36ee3d0a04b8..f9b256a70ba39 100644 --- a/api_docs/kbn_content_management_table_list.mdx +++ b/api_docs/kbn_content_management_table_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-content-management-table-list title: "@kbn/content-management-table-list" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/content-management-table-list plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/content-management-table-list'] --- import kbnContentManagementTableListObj from './kbn_content_management_table_list.devdocs.json'; diff --git a/api_docs/kbn_core_analytics_browser.mdx b/api_docs/kbn_core_analytics_browser.mdx index 92f03112a75e2..6ffaa576b57fe 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: 2022-09-21 +date: 2022-09-22 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 5ee4fe180b1a6..3966c5e685595 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: 2022-09-21 +date: 2022-09-22 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 ddab8a6da8ba5..de23002284e5c 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: 2022-09-21 +date: 2022-09-22 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 3cf2b1c781613..c4777e8cf10ee 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: 2022-09-21 +date: 2022-09-22 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 1978fd217005e..f89a0fcf9a39a 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: 2022-09-21 +date: 2022-09-22 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 f921a117aa1ac..9c41e734fcb99 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: 2022-09-21 +date: 2022-09-22 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 27c1ae53f78c0..0cea1dc774c2a 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: 2022-09-21 +date: 2022-09-22 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 2fef5d62c1be4..cfae804acde4e 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: 2022-09-21 +date: 2022-09-22 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 fd1a6a7790662..8de77b355c88a 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: 2022-09-21 +date: 2022-09-22 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 e323813393c86..9cb6865cfc80d 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: 2022-09-21 +date: 2022-09-22 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 8e7baa413c2d9..21a8ec5b98cf7 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: 2022-09-21 +date: 2022-09-22 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 37560d75caaa7..30982dcb656d0 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: 2022-09-21 +date: 2022-09-22 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_base_browser_mocks.mdx b/api_docs/kbn_core_base_browser_mocks.mdx index b3de07059b8b3..9e5b655ab4d8f 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: 2022-09-21 +date: 2022-09-22 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 bccffa5f3169b..2ae5b314e3ab7 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: 2022-09-21 +date: 2022-09-22 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 2d70af69f3207..5de0d422641c3 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: 2022-09-21 +date: 2022-09-22 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 92b87e2784eb8..f54426285ba57 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: 2022-09-21 +date: 2022-09-22 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 36b71dc6bbf18..3307668b79611 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: 2022-09-21 +date: 2022-09-22 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 8840046d85094..f5bb2de27d66d 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: 2022-09-21 +date: 2022-09-22 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 d829790191100..97d5a26685f3a 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: 2022-09-21 +date: 2022-09-22 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 ea0cddb465a58..ece7b5cdbf4fe 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: 2022-09-21 +date: 2022-09-22 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 47c38a7c769e9..2a4053b22f8f0 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: 2022-09-21 +date: 2022-09-22 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 28553cc4442de..66bc99d5a3e6a 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: 2022-09-21 +date: 2022-09-22 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 e3121dd71a4c5..a3818855fb04c 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: 2022-09-21 +date: 2022-09-22 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_deprecations_browser.mdx b/api_docs/kbn_core_deprecations_browser.mdx index 51ab765a1ebfd..f9d1268dfac82 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: 2022-09-21 +date: 2022-09-22 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 2aca3e87366d5..22cd35d5bd484 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: 2022-09-21 +date: 2022-09-22 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 1de746416ab97..b4f237ef1b22f 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: 2022-09-21 +date: 2022-09-22 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 a8eba9d98e241..60166d8b9529b 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: 2022-09-21 +date: 2022-09-22 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 df85327dc4356..e133115b93e4e 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: 2022-09-21 +date: 2022-09-22 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 a90ff68ad7816..19749a36a463f 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: 2022-09-21 +date: 2022-09-22 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 8970c1fb4c739..a0793ce78d4cc 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: 2022-09-21 +date: 2022-09-22 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 ca61cd3b1df6c..ed3da76740aa1 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: 2022-09-21 +date: 2022-09-22 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 593f2f23e1172..f7b43d5d2e357 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: 2022-09-21 +date: 2022-09-22 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 1b6fc98e5aaa8..7554694a7e97e 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: 2022-09-21 +date: 2022-09-22 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 58d6dab3192fc..f4bde1777de85 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: 2022-09-21 +date: 2022-09-22 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 bdaea106a91d2..28b7898bfeacc 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: 2022-09-21 +date: 2022-09-22 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 82dfdc3bf2116..d6a769f16193d 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: 2022-09-21 +date: 2022-09-22 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 53c51781010a0..05d63bea9feff 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: 2022-09-21 +date: 2022-09-22 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 a8b0c0db5b795..0c7d773da623c 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: 2022-09-21 +date: 2022-09-22 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 aa122cf8c7e6e..14f381a2ebf56 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: 2022-09-21 +date: 2022-09-22 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 a22516bdc6e0e..0cfbea89cd0c5 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: 2022-09-21 +date: 2022-09-22 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 a51d321654147..741db5f261f88 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: 2022-09-21 +date: 2022-09-22 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 458d203e20aa7..0c91019f2e6b9 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: 2022-09-21 +date: 2022-09-22 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 cc444c3d5b8ca..ae8cf6e8b9770 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: 2022-09-21 +date: 2022-09-22 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 3bc9d80c72a18..d5db7822402e6 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: 2022-09-21 +date: 2022-09-22 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 d29a114050dbf..3825cd5ba57fe 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: 2022-09-21 +date: 2022-09-22 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 4509eb592b397..7e445c7f999d7 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: 2022-09-21 +date: 2022-09-22 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 af698072a94ca..77f5a3959fbe7 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: 2022-09-21 +date: 2022-09-22 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 eb5d40300ed87..901253890c7e9 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: 2022-09-21 +date: 2022-09-22 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 4cff04d98dc26..deaa4702f705c 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: 2022-09-21 +date: 2022-09-22 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 721ea0c3945d9..140d9132ec2c0 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: 2022-09-21 +date: 2022-09-22 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 415f15276d937..b0c9c4220e7f5 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: 2022-09-21 +date: 2022-09-22 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 6db848c711182..e3a0724e0dcb9 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: 2022-09-21 +date: 2022-09-22 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 573f8733da5b5..fcbeeaa6e9627 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: 2022-09-21 +date: 2022-09-22 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 b883779a793a0..f7102c3ec16e0 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: 2022-09-21 +date: 2022-09-22 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 d18c50836ba87..e60af9f5d9eab 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: 2022-09-21 +date: 2022-09-22 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_router_server_internal.mdx b/api_docs/kbn_core_http_router_server_internal.mdx index 3d126a078dc71..e8d711e575cc6 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: 2022-09-21 +date: 2022-09-22 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 faa4e8f8e4e0d..5352c783a9b45 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-http-router-server-mocks'] --- import kbnCoreHttpRouterServerMocksObj from './kbn_core_http_router_server_mocks.devdocs.json'; diff --git a/api_docs/kbn_core_http_server.mdx b/api_docs/kbn_core_http_server.mdx index d2614fafeaf5f..8e81de35d50fb 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: 2022-09-21 +date: 2022-09-22 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 9051a0bf0b52e..9fe6811754183 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: 2022-09-21 +date: 2022-09-22 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 c9419dbd572a9..a0cf2e4ffbfa1 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: 2022-09-21 +date: 2022-09-22 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 b1dba4af85762..56c0f34c4227e 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: 2022-09-21 +date: 2022-09-22 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 b67a590ecfa75..78b7a706f203d 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: 2022-09-21 +date: 2022-09-22 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 2dd6083d4293f..6965e9b7a4328 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: 2022-09-21 +date: 2022-09-22 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 ae5f69bf3d5bf..63c27ceafd0c2 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: 2022-09-21 +date: 2022-09-22 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 b16d6e10e8725..3064d37b2b764 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: 2022-09-21 +date: 2022-09-22 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.mdx b/api_docs/kbn_core_injected_metadata_browser.mdx index a1c0750d2f77b..fc9a42796ed91 100644 --- a/api_docs/kbn_core_injected_metadata_browser.mdx +++ b/api_docs/kbn_core_injected_metadata_browser.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-injected-metadata-browser title: "@kbn/core-injected-metadata-browser" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-injected-metadata-browser plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-injected-metadata-browser'] --- import kbnCoreInjectedMetadataBrowserObj from './kbn_core_injected_metadata_browser.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 c733e3cc061a7..c1c9212ced012 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: 2022-09-21 +date: 2022-09-22 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 cc3c1aae43229..676f01fc2cf5b 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: 2022-09-21 +date: 2022-09-22 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 f303a7a2bce56..c693554b5408d 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: 2022-09-21 +date: 2022-09-22 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_logging_server.mdx b/api_docs/kbn_core_logging_server.mdx index 500ece47590d2..11c07ea3a463d 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: 2022-09-21 +date: 2022-09-22 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 34db9ddb92aa6..1d4b36eb97b55 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: 2022-09-21 +date: 2022-09-22 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 8736af0225f13..244a90780255a 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: 2022-09-21 +date: 2022-09-22 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 f1ff3c7382729..95b139093f28d 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: 2022-09-21 +date: 2022-09-22 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 9aebf6bfe65fa..0464c4b38c300 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: 2022-09-21 +date: 2022-09-22 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 d9ab077872da7..93cf2d5749ca3 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: 2022-09-21 +date: 2022-09-22 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 bd4671af281c4..225a82aa4be21 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: 2022-09-21 +date: 2022-09-22 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 22cc5dac4f43d..49bcb201c222a 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: 2022-09-21 +date: 2022-09-22 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 cfe0c1672a0ac..e114e2af0b6bc 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: 2022-09-21 +date: 2022-09-22 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 d6f58108da44a..a1ce5e75dfdad 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: 2022-09-21 +date: 2022-09-22 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 5aa0b5bf3138c..04163a37acbf9 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: 2022-09-21 +date: 2022-09-22 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 59e3b1e657613..4f794d1bce300 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: 2022-09-21 +date: 2022-09-22 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 a17faa06bcc22..11a6a77f6a8b1 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: 2022-09-21 +date: 2022-09-22 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 6b5aaa33c88c7..12bc341027894 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: 2022-09-21 +date: 2022-09-22 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 daf8186f94e4f..effecee9ba65b 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: 2022-09-21 +date: 2022-09-22 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 7a5eff7a76390..2e03ba6fcc3ed 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: 2022-09-21 +date: 2022-09-22 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 8c8a72aa73172..7fba986174a28 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: 2022-09-21 +date: 2022-09-22 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 ec24423b0c296..4c463966e38b2 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: 2022-09-21 +date: 2022-09-22 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_preboot_server.mdx b/api_docs/kbn_core_preboot_server.mdx index e6385a2a75836..e6d5f7d5a1811 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: 2022-09-21 +date: 2022-09-22 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 0c8abfaa31f78..bc67c83d3d8ae 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: 2022-09-21 +date: 2022-09-22 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 98ee357d65bf7..c02b5f7e8791c 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: 2022-09-21 +date: 2022-09-22 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_saved_objects_api_browser.mdx b/api_docs/kbn_core_saved_objects_api_browser.mdx index a5933775d7f23..8fcc6aac79dd3 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: 2022-09-21 +date: 2022-09-22 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 48aef5d9e3a5a..853fc6b82e6f5 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: 2022-09-21 +date: 2022-09-22 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_internal.mdx b/api_docs/kbn_core_saved_objects_api_server_internal.mdx index 8f7fe0f6163f2..e53441bfc1185 100644 --- a/api_docs/kbn_core_saved_objects_api_server_internal.mdx +++ b/api_docs/kbn_core_saved_objects_api_server_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-saved-objects-api-server-internal title: "@kbn/core-saved-objects-api-server-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-saved-objects-api-server-internal plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-saved-objects-api-server-internal'] --- import kbnCoreSavedObjectsApiServerInternalObj from './kbn_core_saved_objects_api_server_internal.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 738cbc10225ea..a17b5a1953925 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: 2022-09-21 +date: 2022-09-22 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 d4874ff125c9d..473834ecc1707 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: 2022-09-21 +date: 2022-09-22 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 6bf81edf60447..c9b9a87273772 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: 2022-09-21 +date: 2022-09-22 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 f631627c7c671..ef40536890d3c 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: 2022-09-21 +date: 2022-09-22 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 f8d2a00000ad6..d66e50e0cd43b 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: 2022-09-21 +date: 2022-09-22 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 b2429c7efea6a..dd1720b80cd2a 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: 2022-09-21 +date: 2022-09-22 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 6942d08a8a361..d0e65f194f45f 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: 2022-09-21 +date: 2022-09-22 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 80a176a289a2b..2c5eb3d91f286 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: 2022-09-21 +date: 2022-09-22 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 87fd03b5794a6..0ae0cd612b849 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: 2022-09-21 +date: 2022-09-22 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 f5c4c8c690179..301aa937001db 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: 2022-09-21 +date: 2022-09-22 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 f2562939d3214..91302dc2f4ad0 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: 2022-09-21 +date: 2022-09-22 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 dca63daba9785..d2bdf0f51e9fe 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: 2022-09-21 +date: 2022-09-22 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 015215fa5039e..f323cae307882 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: 2022-09-21 +date: 2022-09-22 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 36d189e120cd8..82a4ce2a7aac4 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: 2022-09-21 +date: 2022-09-22 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 5900ab2e01897..5bac274913abd 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: 2022-09-21 +date: 2022-09-22 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 410b3389b9ef6..8686d9c3536a9 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: 2022-09-21 +date: 2022-09-22 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 250cb345b9a21..f20257486b238 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: 2022-09-21 +date: 2022-09-22 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 9e062fe408eec..f562a422f61aa 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: 2022-09-21 +date: 2022-09-22 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 448c81ec4b79a..9db2c460e004e 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: 2022-09-21 +date: 2022-09-22 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 3593f09e53c79..6906d65c39af0 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: 2022-09-21 +date: 2022-09-22 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 c1ea683699773..e825685ecdd41 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: 2022-09-21 +date: 2022-09-22 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 90c31ad1d6e85..375edb77fda06 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: 2022-09-21 +date: 2022-09-22 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_theme_browser.mdx b/api_docs/kbn_core_theme_browser.mdx index 11ed64d22dcc7..dd58b41f7aebe 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: 2022-09-21 +date: 2022-09-22 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_internal.mdx b/api_docs/kbn_core_theme_browser_internal.mdx index 5cb8a68077a19..61e989baa7c20 100644 --- a/api_docs/kbn_core_theme_browser_internal.mdx +++ b/api_docs/kbn_core_theme_browser_internal.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-core-theme-browser-internal title: "@kbn/core-theme-browser-internal" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/core-theme-browser-internal plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/core-theme-browser-internal'] --- import kbnCoreThemeBrowserInternalObj from './kbn_core_theme_browser_internal.devdocs.json'; diff --git a/api_docs/kbn_core_theme_browser_mocks.mdx b/api_docs/kbn_core_theme_browser_mocks.mdx index 8b8c6e62c6fc1..5c93551750307 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: 2022-09-21 +date: 2022-09-22 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 8c4774f561e62..799e715ef6f35 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: 2022-09-21 +date: 2022-09-22 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 729aa317ec334..8b1be60494682 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: 2022-09-21 +date: 2022-09-22 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 095a8324b79c3..93c0682c786c0 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: 2022-09-21 +date: 2022-09-22 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 bd961f3cd990a..31025c9fac7de 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: 2022-09-21 +date: 2022-09-22 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 71f72e035cb74..7ac444b7ef812 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: 2022-09-21 +date: 2022-09-22 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 657ac74105e43..f7a68e1a00588 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: 2022-09-21 +date: 2022-09-22 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 50887b10d7a0d..4dca929c1363c 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: 2022-09-21 +date: 2022-09-22 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 0c74acc01304f..b10ab2782c488 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: 2022-09-21 +date: 2022-09-22 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 8e592b7f85eee..90e9bca0ae863 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: 2022-09-21 +date: 2022-09-22 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 f0a28f0875ed9..d6e1d8246e70b 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: 2022-09-21 +date: 2022-09-22 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_crypto.mdx b/api_docs/kbn_crypto.mdx index 28faa9e162e77..5baa0d9007a3b 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: 2022-09-21 +date: 2022-09-22 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 46c98951488ae..04e8a2a5ad66d 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/crypto-browser'] --- import kbnCryptoBrowserObj from './kbn_crypto_browser.devdocs.json'; diff --git a/api_docs/kbn_datemath.mdx b/api_docs/kbn_datemath.mdx index aa7809f7eb2e1..6a636d981544d 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/datemath'] --- import kbnDatemathObj from './kbn_datemath.devdocs.json'; diff --git a/api_docs/kbn_dev_cli_errors.mdx b/api_docs/kbn_dev_cli_errors.mdx index 1843be33150fa..98354b22dd3f0 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: 2022-09-21 +date: 2022-09-22 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 17b48fee7a458..7812305c5e84d 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: 2022-09-21 +date: 2022-09-22 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 5df40a7588976..e66f3d2941b8d 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: 2022-09-21 +date: 2022-09-22 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 5340deeed61b7..b90ddfe887f5e 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/dev-utils'] --- import kbnDevUtilsObj from './kbn_dev_utils.devdocs.json'; diff --git a/api_docs/kbn_doc_links.devdocs.json b/api_docs/kbn_doc_links.devdocs.json index b8d975b8f5814..c48ba82c33d21 100644 --- a/api_docs/kbn_doc_links.devdocs.json +++ b/api_docs/kbn_doc_links.devdocs.json @@ -658,7 +658,7 @@ "label": "observability", "description": [], "signature": [ - "{ readonly guide: string; readonly infrastructureThreshold: string; readonly logsThreshold: string; readonly metricsThreshold: string; readonly monitorStatus: string; readonly monitorUptime: string; readonly tlsCertificate: string; readonly uptimeDurationAnomaly: string; readonly monitorLogs: string; readonly analyzeMetrics: string; readonly monitorUptimeSynthetics: string; readonly userExperience: string; readonly createAlerts: string; }" + "{ readonly guide: string; readonly infrastructureThreshold: string; readonly logsThreshold: string; readonly metricsThreshold: string; readonly monitorStatus: string; readonly monitorUptime: string; readonly tlsCertificate: string; readonly uptimeDurationAnomaly: string; readonly monitorLogs: string; readonly analyzeMetrics: string; readonly monitorUptimeSynthetics: string; readonly userExperience: string; readonly createAlerts: string; readonly syntheticsCommandReference: string; }" ], "path": "packages/kbn-doc-links/src/types.ts", "deprecated": false, diff --git a/api_docs/kbn_doc_links.mdx b/api_docs/kbn_doc_links.mdx index 4590efe64c129..ea57e416a51d9 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: 2022-09-21 +date: 2022-09-22 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 e074495e15334..08d82611db4c2 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/docs-utils'] --- import kbnDocsUtilsObj from './kbn_docs_utils.devdocs.json'; diff --git a/api_docs/kbn_ebt_tools.mdx b/api_docs/kbn_ebt_tools.mdx index 79dcf4c12fdba..90d36c669fdac 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ebt-tools'] --- import kbnEbtToolsObj from './kbn_ebt_tools.devdocs.json'; diff --git a/api_docs/kbn_es_archiver.mdx b/api_docs/kbn_es_archiver.mdx index bf0588c4f99c1..3309781c13f31 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: 2022-09-21 +date: 2022-09-22 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 7ae016edcfb59..866fc7615a3e7 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: 2022-09-21 +date: 2022-09-22 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 06994c389d718..5c9a1fe11d91a 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: 2022-09-21 +date: 2022-09-22 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 95466ada26028..9141040ca4c36 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: 2022-09-21 +date: 2022-09-22 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 7f2a5f8ffbca4..6ab866bd44dd1 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/eslint-plugin-imports'] --- import kbnEslintPluginImportsObj from './kbn_eslint_plugin_imports.devdocs.json'; diff --git a/api_docs/kbn_field_types.mdx b/api_docs/kbn_field_types.mdx index 94177dc5aa243..8310f90111603 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: 2022-09-21 +date: 2022-09-22 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 44625438cd032..822e97678f09b 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: 2022-09-21 +date: 2022-09-22 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_generate.mdx b/api_docs/kbn_generate.mdx index af968a0d6c12b..5f39a5ed34eb1 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/generate'] --- import kbnGenerateObj from './kbn_generate.devdocs.json'; diff --git a/api_docs/kbn_get_repo_files.mdx b/api_docs/kbn_get_repo_files.mdx index eb3041437f858..3277b35b8d4a1 100644 --- a/api_docs/kbn_get_repo_files.mdx +++ b/api_docs/kbn_get_repo_files.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-get-repo-files title: "@kbn/get-repo-files" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/get-repo-files plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/get-repo-files'] --- import kbnGetRepoFilesObj from './kbn_get_repo_files.devdocs.json'; diff --git a/api_docs/kbn_handlebars.mdx b/api_docs/kbn_handlebars.mdx index ea945e927f03b..ef29d0fa81189 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: 2022-09-21 +date: 2022-09-22 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 5d79694335b6b..041357a77e22b 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/hapi-mocks'] --- import kbnHapiMocksObj from './kbn_hapi_mocks.devdocs.json'; diff --git a/api_docs/kbn_home_sample_data_card.mdx b/api_docs/kbn_home_sample_data_card.mdx index 94506cf8d9909..20f96872d286b 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: 2022-09-21 +date: 2022-09-22 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 0d4b974929b83..cbe688254ef8d 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: 2022-09-21 +date: 2022-09-22 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 bf4c70817d7bc..38dd4fd120884 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/i18n'] --- import kbnI18nObj from './kbn_i18n.devdocs.json'; diff --git a/api_docs/kbn_import_resolver.mdx b/api_docs/kbn_import_resolver.mdx index d051acb699996..6e0f1031ba7a6 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/import-resolver'] --- import kbnImportResolverObj from './kbn_import_resolver.devdocs.json'; diff --git a/api_docs/kbn_interpreter.mdx b/api_docs/kbn_interpreter.mdx index 7d0955caeb361..940a58f4154dc 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: 2022-09-21 +date: 2022-09-22 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 b6c9a79910594..e8b8fa5d82554 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: 2022-09-21 +date: 2022-09-22 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 4ed4996625614..fa7ba1ee6795a 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/jest-serializers'] --- import kbnJestSerializersObj from './kbn_jest_serializers.devdocs.json'; diff --git a/api_docs/kbn_kibana_manifest_schema.mdx b/api_docs/kbn_kibana_manifest_schema.mdx index e1edaaac04cc2..3181dee87f7db 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/kibana-manifest-schema'] --- import kbnKibanaManifestSchemaObj from './kbn_kibana_manifest_schema.devdocs.json'; diff --git a/api_docs/kbn_logging.mdx b/api_docs/kbn_logging.mdx index b8e4bbc6d85d7..30f74050e31a9 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: 2022-09-21 +date: 2022-09-22 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 cdf7e9493bfde..bc64637c8f1a6 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: 2022-09-21 +date: 2022-09-22 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 3f07937de52fe..e6ead9f8174da 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/managed-vscode-config'] --- import kbnManagedVscodeConfigObj from './kbn_managed_vscode_config.devdocs.json'; diff --git a/api_docs/kbn_mapbox_gl.mdx b/api_docs/kbn_mapbox_gl.mdx index bc63c5e56f04c..7003f5277fc39 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/mapbox-gl'] --- import kbnMapboxGlObj from './kbn_mapbox_gl.devdocs.json'; diff --git a/api_docs/kbn_ml_agg_utils.mdx b/api_docs/kbn_ml_agg_utils.mdx index 20d206ee85420..a0ecdade3f9e6 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: 2022-09-21 +date: 2022-09-22 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_is_populated_object.mdx b/api_docs/kbn_ml_is_populated_object.mdx index f03e2c0dd1368..32da79b32c407 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: 2022-09-21 +date: 2022-09-22 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_string_hash.mdx b/api_docs/kbn_ml_string_hash.mdx index f5c6ec4dab20c..7a92565583d64 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ml-string-hash'] --- import kbnMlStringHashObj from './kbn_ml_string_hash.devdocs.json'; diff --git a/api_docs/kbn_monaco.mdx b/api_docs/kbn_monaco.mdx index 4a2b7d251d645..e108034ba2c2d 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/monaco'] --- import kbnMonacoObj from './kbn_monaco.devdocs.json'; diff --git a/api_docs/kbn_optimizer.mdx b/api_docs/kbn_optimizer.mdx index 9dec2e2d12388..98b48440df6fd 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: 2022-09-21 +date: 2022-09-22 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 3ecb10b8ce84a..9d676c1c06397 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/optimizer-webpack-helpers'] --- import kbnOptimizerWebpackHelpersObj from './kbn_optimizer_webpack_helpers.devdocs.json'; diff --git a/api_docs/kbn_performance_testing_dataset_extractor.mdx b/api_docs/kbn_performance_testing_dataset_extractor.mdx index 629055ccc04e7..b4483ef89d466 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: 2022-09-21 +date: 2022-09-22 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 f2e631ec8cd4b..0e8047259ac54 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: 2022-09-21 +date: 2022-09-22 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 b7141c78f3cf9..725c12f183891 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/plugin-helpers'] --- import kbnPluginHelpersObj from './kbn_plugin_helpers.devdocs.json'; diff --git a/api_docs/kbn_react_field.mdx b/api_docs/kbn_react_field.mdx index 5a9f1942a5bd6..6f4a984b14a3a 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/react-field'] --- import kbnReactFieldObj from './kbn_react_field.devdocs.json'; diff --git a/api_docs/kbn_repo_source_classifier.mdx b/api_docs/kbn_repo_source_classifier.mdx index 0e6aab2d83377..5f00051849f1c 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/repo-source-classifier'] --- import kbnRepoSourceClassifierObj from './kbn_repo_source_classifier.devdocs.json'; diff --git a/api_docs/kbn_rule_data_utils.mdx b/api_docs/kbn_rule_data_utils.mdx index c4061ab88aac1..c1a782c141bc6 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/rule-data-utils'] --- import kbnRuleDataUtilsObj from './kbn_rule_data_utils.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_autocomplete.mdx b/api_docs/kbn_securitysolution_autocomplete.mdx index fd9731c4d32f5..d5e955d1f2595 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/securitysolution-autocomplete'] --- import kbnSecuritysolutionAutocompleteObj from './kbn_securitysolution_autocomplete.devdocs.json'; diff --git a/api_docs/kbn_securitysolution_es_utils.mdx b/api_docs/kbn_securitysolution_es_utils.mdx index ec574df2ac420..77bceec83858e 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: 2022-09-21 +date: 2022-09-22 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_hook_utils.mdx b/api_docs/kbn_securitysolution_hook_utils.mdx index 060150aec0633..b7856995a8108 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: 2022-09-21 +date: 2022-09-22 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 1c47b09302c0e..bc4e23e2e983d 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: 2022-09-21 +date: 2022-09-22 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 343773fc6961f..82e3fb0ae468c 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: 2022-09-21 +date: 2022-09-22 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 5b6f8c7121eb2..a0d2052ae7794 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: 2022-09-21 +date: 2022-09-22 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 d91fd25457476..8117732d57ad9 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: 2022-09-21 +date: 2022-09-22 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 47970932a1793..c403a28913447 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: 2022-09-21 +date: 2022-09-22 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 34e695f21aeea..a3ba38ac91210 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: 2022-09-21 +date: 2022-09-22 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 e58504680e2cf..e59220c83f958 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: 2022-09-21 +date: 2022-09-22 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 a87cfd6fe0973..b77cb1ff96d10 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: 2022-09-21 +date: 2022-09-22 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 ff535c6f560d9..c1d3390dd76b6 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: 2022-09-21 +date: 2022-09-22 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 5df5c3218e6a1..778caf257464d 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: 2022-09-21 +date: 2022-09-22 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 fc58053025b36..d326fdb690acd 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: 2022-09-21 +date: 2022-09-22 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 1af486fce1c5e..25471b3d51cd0 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: 2022-09-21 +date: 2022-09-22 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 b743139813871..dfbc5720c2a3a 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/server-route-repository'] --- import kbnServerRouteRepositoryObj from './kbn_server_route_repository.devdocs.json'; diff --git a/api_docs/kbn_shared_svg.mdx b/api_docs/kbn_shared_svg.mdx index 78782a2742f93..793150d936933 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: 2022-09-21 +date: 2022-09-22 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_user_profile_components.mdx b/api_docs/kbn_shared_ux_avatar_user_profile_components.mdx index 9d1ce452077a0..e1daf06b3b274 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: 2022-09-21 +date: 2022-09-22 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_mocks.mdx b/api_docs/kbn_shared_ux_button_exit_full_screen_mocks.mdx index 86f562d4bb410..a4cf83db9324e 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: 2022-09-21 +date: 2022-09-22 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 534731ed2ed6c..8658ea40c1995 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: 2022-09-21 +date: 2022-09-22 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 3b9307fe75198..0dc7d8de76359 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: 2022-09-21 +date: 2022-09-22 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 d8a57acd59459..35914b6d9b59d 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: 2022-09-21 +date: 2022-09-22 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_link_redirect_app_mocks.mdx b/api_docs/kbn_shared_ux_link_redirect_app_mocks.mdx index 29650e5ed8646..a2b9f784ff86e 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: 2022-09-21 +date: 2022-09-22 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_page_analytics_no_data.mdx b/api_docs/kbn_shared_ux_page_analytics_no_data.mdx index 9962da3b57786..bb96516fa0fbd 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: 2022-09-21 +date: 2022-09-22 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 f5e9eec99917c..d804aea444daa 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: 2022-09-21 +date: 2022-09-22 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 2123307bc9e97..31a07313d1af3 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: 2022-09-21 +date: 2022-09-22 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 e09c5179542e1..4f57dbfd4399d 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: 2022-09-21 +date: 2022-09-22 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 17b290a187bd0..673c8bb7bb567 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: 2022-09-21 +date: 2022-09-22 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 0624865a7cb3e..135bb6bd1caad 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: 2022-09-21 +date: 2022-09-22 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 5a3f2d93ec15d..3fd6fad8f1a41 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: 2022-09-21 +date: 2022-09-22 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 158d91473e56c..6334f26246c3b 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: 2022-09-21 +date: 2022-09-22 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 8f4d8b0219143..e737f1156e683 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: 2022-09-21 +date: 2022-09-22 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 fe62493020308..196d53a7ba389 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: 2022-09-21 +date: 2022-09-22 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 c95da8b4cc92f..b49adcd6ea044 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: 2022-09-21 +date: 2022-09-22 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 655e11aa964bf..a25944fdb2882 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: 2022-09-21 +date: 2022-09-22 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 db40292785ab2..54f45ccf3da49 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: 2022-09-21 +date: 2022-09-22 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_router.mdx b/api_docs/kbn_shared_ux_router.mdx index 5824ea5c73c58..7de045590c6f7 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: 2022-09-21 +date: 2022-09-22 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 8ec6570a0220e..f65e964f0848a 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: 2022-09-21 +date: 2022-09-22 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 d9814c190f09f..81fb8c51ac022 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: 2022-09-21 +date: 2022-09-22 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 6744b6d0e1dcd..8cb95096540e5 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: 2022-09-21 +date: 2022-09-22 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 c3d29d99df19d..23c2afad25bf7 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/shared-ux-utility'] --- import kbnSharedUxUtilityObj from './kbn_shared_ux_utility.devdocs.json'; diff --git a/api_docs/kbn_some_dev_log.mdx b/api_docs/kbn_some_dev_log.mdx index 80d98d2a35ebe..aae68b0778949 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/some-dev-log'] --- import kbnSomeDevLogObj from './kbn_some_dev_log.devdocs.json'; diff --git a/api_docs/kbn_sort_package_json.mdx b/api_docs/kbn_sort_package_json.mdx index e149b42881f92..a0578b5514cd2 100644 --- a/api_docs/kbn_sort_package_json.mdx +++ b/api_docs/kbn_sort_package_json.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-sort-package-json title: "@kbn/sort-package-json" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/sort-package-json plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/sort-package-json'] --- import kbnSortPackageJsonObj from './kbn_sort_package_json.devdocs.json'; diff --git a/api_docs/kbn_std.mdx b/api_docs/kbn_std.mdx index 349e5920113d0..7e7f3747c59ee 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: 2022-09-21 +date: 2022-09-22 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 99f2f0c8664b2..5a733985a17a5 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: 2022-09-21 +date: 2022-09-22 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 8c97882f6aa61..f0012bc98f817 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: 2022-09-21 +date: 2022-09-22 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 83166d900d2ed..b7f2429457b19 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: 2022-09-21 +date: 2022-09-22 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 9230fac245d35..9dd5c24776896 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: 2022-09-21 +date: 2022-09-22 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 1e3817ccdee9f..5e84097dcef14 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: 2022-09-21 +date: 2022-09-22 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 53a5a76b85ff3..b6729e8555502 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/test-subj-selector'] --- import kbnTestSubjSelectorObj from './kbn_test_subj_selector.devdocs.json'; diff --git a/api_docs/kbn_tooling_log.mdx b/api_docs/kbn_tooling_log.mdx index 054c0285c637d..8d30e51ee9228 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/tooling-log'] --- import kbnToolingLogObj from './kbn_tooling_log.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer.mdx b/api_docs/kbn_type_summarizer.mdx index afa19269f8816..94e15ec19c237 100644 --- a/api_docs/kbn_type_summarizer.mdx +++ b/api_docs/kbn_type_summarizer.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer title: "@kbn/type-summarizer" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer'] --- import kbnTypeSummarizerObj from './kbn_type_summarizer.devdocs.json'; diff --git a/api_docs/kbn_type_summarizer_core.mdx b/api_docs/kbn_type_summarizer_core.mdx index 8c4e404667da3..1abf7a1158dc8 100644 --- a/api_docs/kbn_type_summarizer_core.mdx +++ b/api_docs/kbn_type_summarizer_core.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/kbn-type-summarizer-core title: "@kbn/type-summarizer-core" image: https://source.unsplash.com/400x175/?github description: API docs for the @kbn/type-summarizer-core plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/type-summarizer-core'] --- import kbnTypeSummarizerCoreObj from './kbn_type_summarizer_core.devdocs.json'; diff --git a/api_docs/kbn_typed_react_router_config.mdx b/api_docs/kbn_typed_react_router_config.mdx index 805990c966ba5..0c95e31f10e68 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: 2022-09-21 +date: 2022-09-22 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_theme.mdx b/api_docs/kbn_ui_theme.mdx index 64654b10b3002..a6871ad14be19 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/ui-theme'] --- import kbnUiThemeObj from './kbn_ui_theme.devdocs.json'; diff --git a/api_docs/kbn_user_profile_components.mdx b/api_docs/kbn_user_profile_components.mdx index e4d20bc32a22e..d996627374c01 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: 2022-09-21 +date: 2022-09-22 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 a2ab571bf69fa..2ceeeae778cfe 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: 2022-09-21 +date: 2022-09-22 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 0767b1a144f7e..4e1ba1953d065 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: 2022-09-21 +date: 2022-09-22 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 c937c340e4433..eb5beac7065ff 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', '@kbn/utils'] --- import kbnUtilsObj from './kbn_utils.devdocs.json'; diff --git a/api_docs/kbn_yarn_lock_validator.mdx b/api_docs/kbn_yarn_lock_validator.mdx index 64f290c135730..4667f30cbf1f4 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: 2022-09-21 +date: 2022-09-22 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 da1c2cc403976..34c0d11826ba1 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: 2022-09-21 +date: 2022-09-22 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 79b13332456d4..97f3a78ded925 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: 2022-09-21 +date: 2022-09-22 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 676f396e38cc2..deafbf79b1aed 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: 2022-09-21 +date: 2022-09-22 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 97372d71d53fb..7665687eeeb21 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: 2022-09-21 +date: 2022-09-22 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 3d5eb7fe015f6..76385b837391c 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: 2022-09-21 +date: 2022-09-22 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 3f990bbcb20d0..c56a3ae4b8e16 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: 2022-09-21 +date: 2022-09-22 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 9e7dc24aae0e2..e68b7f3ca1944 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: 2022-09-21 +date: 2022-09-22 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 c16ee014aeeb8..ea9fad5915ad3 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: 2022-09-21 +date: 2022-09-22 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 619cdab0943f7..c63719ad85397 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'lists'] --- import listsObj from './lists.devdocs.json'; diff --git a/api_docs/management.mdx b/api_docs/management.mdx index 4850104f76366..b5bc104a0ce60 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: 2022-09-21 +date: 2022-09-22 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 57b107d6beadb..5fcfd0203431c 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: 2022-09-21 +date: 2022-09-22 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 90a09544d07e7..9cc6b1a542f2f 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: 2022-09-21 +date: 2022-09-22 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 e430f45966c72..0a43ee6b4356d 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: 2022-09-21 +date: 2022-09-22 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 167becc10bb92..7e9bbc61325bd 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: 2022-09-21 +date: 2022-09-22 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 5046f23612945..a2551bb06b839 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: 2022-09-21 +date: 2022-09-22 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 b7f3142a5db26..d832b2f6ba19a 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: 2022-09-21 +date: 2022-09-22 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 80dc9cea35aa6..448efa7620ec5 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'newsfeed'] --- import newsfeedObj from './newsfeed.devdocs.json'; diff --git a/api_docs/observability.devdocs.json b/api_docs/observability.devdocs.json index 9720b4db69b1f..4fae8b05f4e6a 100644 --- a/api_docs/observability.devdocs.json +++ b/api_docs/observability.devdocs.json @@ -8860,6 +8860,112 @@ } ] }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableServiceMetrics", + "type": "Object", + "tags": [], + "label": "[enableServiceMetrics]", + "description": [], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false, + "children": [ + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableServiceMetrics.category", + "type": "Array", + "tags": [], + "label": "category", + "description": [], + "signature": [ + "string[]" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableServiceMetrics.name", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableServiceMetrics.value", + "type": "boolean", + "tags": [], + "label": "value", + "description": [], + "signature": [ + "false" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableServiceMetrics.description", + "type": "string", + "tags": [], + "label": "description", + "description": [], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableServiceMetrics.schema", + "type": "Object", + "tags": [], + "label": "schema", + "description": [], + "signature": [ + "Type", + "" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableServiceMetrics.requiresPageReload", + "type": "boolean", + "tags": [], + "label": "requiresPageReload", + "description": [], + "signature": [ + "true" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "observability", + "id": "def-server.uiSettings.enableServiceMetrics.showInLabs", + "type": "boolean", + "tags": [], + "label": "showInLabs", + "description": [], + "signature": [ + "true" + ], + "path": "x-pack/plugins/observability/server/ui_settings.ts", + "deprecated": false, + "trackAdoption": false + } + ] + }, { "parentPluginId": "observability", "id": "def-server.uiSettings.apmServiceInventoryOptimizedSorting", @@ -10117,6 +10223,21 @@ "trackAdoption": false, "initialIsOpen": false }, + { + "parentPluginId": "observability", + "id": "def-common.enableServiceMetrics", + "type": "string", + "tags": [], + "label": "enableServiceMetrics", + "description": [], + "signature": [ + "\"observability:apmEnableServiceMetrics\"" + ], + "path": "x-pack/plugins/observability/common/ui_settings_keys.ts", + "deprecated": false, + "trackAdoption": false, + "initialIsOpen": false + }, { "parentPluginId": "observability", "id": "def-common.maxSuggestions", diff --git a/api_docs/observability.mdx b/api_docs/observability.mdx index e4a65ba5f33e7..636feb22aad94 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'observability'] --- import observabilityObj from './observability.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Observability UI](https://github.com/orgs/elastic/teams/observability-u | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 519 | 2 | 515 | 30 | +| 528 | 2 | 524 | 30 | ## Client diff --git a/api_docs/osquery.mdx b/api_docs/osquery.mdx index f87b8903f184c..55d8f562dfe26 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: 2022-09-21 +date: 2022-09-22 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 9bc3e41f6b9e1..baf9b97b47850 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana'] --- @@ -21,7 +21,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 31334 | 180 | 21000 | 980 | +| 31370 | 180 | 21022 | 981 | ## Plugin Directory @@ -80,7 +80,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 222 | 0 | 95 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 5 | 249 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 62 | 0 | 62 | 2 | -| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 240 | 0 | 6 | 2 | +| | [@elastic/kibana-app-services](https://github.com/orgs/elastic/teams/team:AppServicesUx) | File upload, download, sharing, and serving over HTTP implementation in Kibana. | 263 | 0 | 15 | 2 | | | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 986 | 3 | 886 | 17 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | @@ -115,7 +115,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 34 | 0 | 34 | 2 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | -| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 519 | 2 | 515 | 30 | +| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 528 | 2 | 524 | 30 | | | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 21 | 0 | 21 | 3 | | painlessLab | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 243 | 2 | 187 | 12 | @@ -156,7 +156,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds UI Actions service to Kibana | 132 | 0 | 91 | 11 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends UI Actions plugin with more functionality | 206 | 0 | 142 | 9 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | Contains functionality for the field list which can be integrated into apps | 61 | 0 | 59 | 2 | -| | [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 122 | 2 | 96 | 16 | +| | [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-services) | Contains all the key functionality of Kibana's unified search experience.Contains all the key functionality of Kibana's unified search experience. | 125 | 2 | 99 | 17 | | upgradeAssistant | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | urlDrilldown | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds drilldown implementations to Kibana | 0 | 0 | 0 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 12 | 0 | 12 | 0 | @@ -175,7 +175,7 @@ tags: ['contributor', 'dev', 'apidocs', 'kibana'] | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the vega visualization. Is the elastic version of vega and vega-lite libraries. | 2 | 0 | 2 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and heatmap charts. We want to replace them with elastic-charts. | 26 | 0 | 25 | 1 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 53 | 0 | 50 | 5 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 630 | 12 | 601 | 14 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 631 | 12 | 602 | 14 | | watcher | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | ## Package Directory diff --git a/api_docs/presentation_util.mdx b/api_docs/presentation_util.mdx index 5c1ba3fbe59be..b870cf5f14637 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: 2022-09-21 +date: 2022-09-22 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 aa3a5a11aa480..8fb8adca44d0f 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: 2022-09-21 +date: 2022-09-22 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 c20d0362bae48..ed97b5d7991c2 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: 2022-09-21 +date: 2022-09-22 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 b58df3eacde86..932bb602229a1 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: 2022-09-21 +date: 2022-09-22 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 8f47f3dda1591..7df9a27986349 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: 2022-09-21 +date: 2022-09-22 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 1e009c82de870..8a0dbdd763edc 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: 2022-09-21 +date: 2022-09-22 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 bf84cc9fa0b90..21f55bfde44f8 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: 2022-09-21 +date: 2022-09-22 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 8fb8ea0d3c2b7..0d3a66da043f4 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: 2022-09-21 +date: 2022-09-22 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 c9b068a72abff..35098620fec44 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: 2022-09-21 +date: 2022-09-22 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 a93096c35f284..8f802bca47dd3 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: 2022-09-21 +date: 2022-09-22 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 5c0f411010392..2ee5a06e9512f 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: 2022-09-21 +date: 2022-09-22 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 9eccbd9ed489d..d690ce3f16ec2 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: 2022-09-21 +date: 2022-09-22 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 6f35997066953..613210385f877 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: 2022-09-21 +date: 2022-09-22 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 e66c9d7da18f5..185e146c2db95 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: 2022-09-21 +date: 2022-09-22 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 a09ddaab21afb..51927a493f916 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'screenshotting'] --- import screenshottingObj from './screenshotting.devdocs.json'; diff --git a/api_docs/security.mdx b/api_docs/security.mdx index fedcffb1b25d5..415b526e0b26c 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'security'] --- import securityObj from './security.devdocs.json'; diff --git a/api_docs/security_solution.mdx b/api_docs/security_solution.mdx index 60d6c667f7c91..15e420b2b0182 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'securitySolution'] --- import securitySolutionObj from './security_solution.devdocs.json'; diff --git a/api_docs/session_view.mdx b/api_docs/session_view.mdx index 408b96cf182b1..b4ef6d48c46bf 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: 2022-09-21 +date: 2022-09-22 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 e0a7355048af7..b8e64fb777735 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: 2022-09-21 +date: 2022-09-22 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 e4f72340d087e..594c05507252c 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: 2022-09-21 +date: 2022-09-22 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 98cb1380a3503..07430e37fe600 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'spaces'] --- import spacesObj from './spaces.devdocs.json'; diff --git a/api_docs/stack_alerts.devdocs.json b/api_docs/stack_alerts.devdocs.json index 209dcb93ef3a1..3850659e8a4d7 100644 --- a/api_docs/stack_alerts.devdocs.json +++ b/api_docs/stack_alerts.devdocs.json @@ -63,7 +63,7 @@ "signature": [ "\"stackAlerts\"" ], - "path": "x-pack/plugins/stack_alerts/common/index.ts", + "path": "x-pack/plugins/stack_alerts/common/constants.ts", "deprecated": false, "trackAdoption": false, "initialIsOpen": false diff --git a/api_docs/stack_alerts.mdx b/api_docs/stack_alerts.mdx index 0d23909034ae8..90bbd271763c1 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: 2022-09-21 +date: 2022-09-22 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 8b250938595f7..ed1fa872c8a04 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: 2022-09-21 +date: 2022-09-22 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 d33ad32bec354..b3cb07fff0933 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: 2022-09-21 +date: 2022-09-22 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 d170306872998..b23d2d1888173 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: 2022-09-21 +date: 2022-09-22 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 6f9d668fb6cea..226591c004f88 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: 2022-09-21 +date: 2022-09-22 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 ed6b7e61717c5..08f903b0515f4 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: 2022-09-21 +date: 2022-09-22 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 7ad0996faeb49..75afad06122f6 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'telemetryManagementSection'] --- import telemetryManagementSectionObj from './telemetry_management_section.devdocs.json'; diff --git a/api_docs/threat_intelligence.mdx b/api_docs/threat_intelligence.mdx index 341dca64a770b..c0d37bafaf0f7 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: 2022-09-21 +date: 2022-09-22 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 ef634330a3c39..12818ccc00767 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: 2022-09-21 +date: 2022-09-22 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 d4370cbd83025..2c93efb7ba04b 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: 2022-09-21 +date: 2022-09-22 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 6c8003d4f5dfd..9959fc8d580d4 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: 2022-09-21 +date: 2022-09-22 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 146259f72f7bb..215ab9ab7a5a3 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: 2022-09-21 +date: 2022-09-22 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 427db15b1b3ad..bb4305309d371 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'uiActionsEnhanced'] --- import uiActionsEnhancedObj from './ui_actions_enhanced.devdocs.json'; diff --git a/api_docs/unified_field_list.mdx b/api_docs/unified_field_list.mdx index 4d489503da198..117b0750b9d78 100644 --- a/api_docs/unified_field_list.mdx +++ b/api_docs/unified_field_list.mdx @@ -8,7 +8,7 @@ slug: /kibana-dev-docs/api/unifiedFieldList title: "unifiedFieldList" image: https://source.unsplash.com/400x175/?github description: API docs for the unifiedFieldList plugin -date: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedFieldList'] --- import unifiedFieldListObj from './unified_field_list.devdocs.json'; diff --git a/api_docs/unified_search.devdocs.json b/api_docs/unified_search.devdocs.json index 4d5026322ffbb..89093ced7129d 100644 --- a/api_docs/unified_search.devdocs.json +++ b/api_docs/unified_search.devdocs.json @@ -366,7 +366,7 @@ }, " | undefined; textBasedLanguageModeErrors?: Error[] | undefined; onTextBasedSavedAndExit?: (({ onSave }: ", "OnSaveTextLanguageQueryProps", - ") => void) | undefined; showSubmitButton?: boolean | undefined; suggestionsSize?: ", + ") => void) | undefined; showSubmitButton?: boolean | undefined; submitButtonStyle?: \"auto\" | \"full\" | \"iconOnly\" | undefined; suggestionsSize?: ", "SuggestionsListSize", " | undefined; isScreenshotMode?: boolean | undefined; onFiltersUpdated?: ((filters: ", "Filter", @@ -1030,6 +1030,20 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.IUnifiedSearchPluginServices.docLinks", + "type": "Object", + "tags": [], + "label": "docLinks", + "description": [], + "signature": [ + "DocLinksStart" + ], + "path": "src/plugins/unified_search/public/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "unifiedSearch", "id": "def-public.IUnifiedSearchPluginServices.data", @@ -1470,6 +1484,31 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QueryStringInputProps.appName", + "type": "string", + "tags": [], + "label": "appName", + "description": [], + "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx", + "deprecated": false, + "trackAdoption": false + }, + { + "parentPluginId": "unifiedSearch", + "id": "def-public.QueryStringInputProps.deps", + "type": "Object", + "tags": [], + "label": "deps", + "description": [], + "signature": [ + "QueryStringInputDependencies" + ], + "path": "src/plugins/unified_search/public/query_string_input/query_string_input.tsx", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "unifiedSearch", "id": "def-public.QueryStringInputProps.nonKqlMode", diff --git a/api_docs/unified_search.mdx b/api_docs/unified_search.mdx index 67b3d84096fc4..69b4ac2504553 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch'] --- import unifiedSearchObj from './unified_search.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-servic | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 122 | 2 | 96 | 16 | +| 125 | 2 | 99 | 17 | ## Client diff --git a/api_docs/unified_search_autocomplete.mdx b/api_docs/unified_search_autocomplete.mdx index 9d8991e0ea45d..929d32a836b61 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'unifiedSearch.autocomplete'] --- import unifiedSearchAutocompleteObj from './unified_search_autocomplete.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Unified Search](https://github.com/orgs/elastic/teams/kibana-app-servic | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 122 | 2 | 96 | 16 | +| 125 | 2 | 99 | 17 | ## Client diff --git a/api_docs/url_forwarding.mdx b/api_docs/url_forwarding.mdx index 46e7ae60e2614..ccf74575df120 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: 2022-09-21 +date: 2022-09-22 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 a6dfb697d8c5a..a736d4d52eba8 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: 2022-09-21 +date: 2022-09-22 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 c281ebdbd88df..03f35c432a9f8 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: 2022-09-21 +date: 2022-09-22 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 800fbabeaf203..7f07f304187fc 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: 2022-09-21 +date: 2022-09-22 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 f574152d0a191..ba53a8580fdff 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: 2022-09-21 +date: 2022-09-22 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 625d6628b13cf..46fbb7e99329f 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: 2022-09-21 +date: 2022-09-22 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 6bd851dad3a56..680635f94e279 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: 2022-09-21 +date: 2022-09-22 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 8c8bad65b3868..eae6da767fea5 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: 2022-09-21 +date: 2022-09-22 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 9037c2163f3d5..7fdec24dd1ac8 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: 2022-09-21 +date: 2022-09-22 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 69e98952c0f79..1de3ded2cdc39 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: 2022-09-21 +date: 2022-09-22 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 7f049ea5d969d..4c4ad09221dec 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: 2022-09-21 +date: 2022-09-22 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 83c0958ab36ce..ca416be51f23c 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: 2022-09-21 +date: 2022-09-22 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 51b71c88e6a10..b8bc8c502fb16 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visTypeXy'] --- import visTypeXyObj from './vis_type_xy.devdocs.json'; diff --git a/api_docs/visualizations.devdocs.json b/api_docs/visualizations.devdocs.json index f4ce7d07d4c8f..f9d7be383b81f 100644 --- a/api_docs/visualizations.devdocs.json +++ b/api_docs/visualizations.devdocs.json @@ -2546,6 +2546,26 @@ "deprecated": false, "trackAdoption": false }, + { + "parentPluginId": "visualizations", + "id": "def-public.EditorRenderProps.unifiedSearch", + "type": "Object", + "tags": [], + "label": "unifiedSearch", + "description": [], + "signature": [ + { + "pluginId": "unifiedSearch", + "scope": "public", + "docId": "kibUnifiedSearchPluginApi", + "section": "def-public.UnifiedSearchPublicPluginStart", + "text": "UnifiedSearchPublicPluginStart" + } + ], + "path": "src/plugins/visualizations/public/visualize_app/types.ts", + "deprecated": false, + "trackAdoption": false + }, { "parentPluginId": "visualizations", "id": "def-public.EditorRenderProps.linked", diff --git a/api_docs/visualizations.mdx b/api_docs/visualizations.mdx index 90b1267c266a9..4fd3e74a04cf9 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: 2022-09-21 +date: 2022-09-22 tags: ['contributor', 'dev', 'apidocs', 'kibana', 'visualizations'] --- import visualizationsObj from './visualizations.devdocs.json'; @@ -21,7 +21,7 @@ Contact [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 630 | 12 | 601 | 14 | +| 631 | 12 | 602 | 14 | ## Client From 3433f5d112d1e7737edd3dcef7ce57224c3ac535 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Thu, 22 Sep 2022 08:52:48 +0200 Subject: [PATCH 24/36] [Fleet] Force unenroll in Agent activity (#141208) * fix for force unenroll * fixed tests * fixed checks, solve for one more edge case: only updating unenroll actions that do not have results yet * added more tests * added try catch * updated description on flyout Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../fleet/common/types/models/agent.ts | 8 +- .../components/agent_activity_flyout.tsx | 7 +- .../server/services/agents/action.mock.ts | 2 + .../server/services/agents/action_status.ts | 11 +- .../fleet/server/services/agents/actions.ts | 37 ++++- .../server/services/agents/unenroll.test.ts | 134 ++++++++++++++- .../fleet/server/services/agents/unenroll.ts | 7 +- .../services/agents/unenroll_action_runner.ts | 154 ++++++++++++++---- .../preconfiguration/reset_agent_policies.ts | 2 +- 9 files changed, 311 insertions(+), 51 deletions(-) diff --git a/x-pack/plugins/fleet/common/types/models/agent.ts b/x-pack/plugins/fleet/common/types/models/agent.ts index 7415ad01ee0c9..809e32c78c1b8 100644 --- a/x-pack/plugins/fleet/common/types/models/agent.ts +++ b/x-pack/plugins/fleet/common/types/models/agent.ts @@ -30,7 +30,13 @@ export type AgentStatus = export type SimplifiedAgentStatus = 'healthy' | 'unhealthy' | 'updating' | 'offline' | 'inactive'; -export type AgentActionType = 'UNENROLL' | 'UPGRADE' | 'SETTINGS' | 'POLICY_REASSIGN' | 'CANCEL'; +export type AgentActionType = + | 'UNENROLL' + | 'UPGRADE' + | 'SETTINGS' + | 'POLICY_REASSIGN' + | 'CANCEL' + | 'FORCE_UNENROLL'; type FleetServerAgentComponentStatusTuple = typeof FleetServerAgentComponentStatuses; export type FleetServerAgentComponentStatus = FleetServerAgentComponentStatusTuple[number]; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.tsx index e0cc1ae984671..a2fdf6d145d55 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agents/agent_list_page/components/agent_activity_flyout.tsx @@ -143,7 +143,7 @@ export const AgentActivityFlyout: React.FunctionComponent<{ body={ } /> @@ -238,6 +238,11 @@ const actionNames: { completedText: 'unenrolled', cancelledText: 'unenrollment', }, + FORCE_UNENROLL: { + inProgressText: 'Force unenrolling', + completedText: 'force unenrolled', + cancelledText: 'force unenrollment', + }, CANCEL: { inProgressText: 'Cancelling', completedText: 'cancelled', cancelledText: '' }, ACTION: { inProgressText: 'Actioning', completedText: 'actioned', cancelledText: 'action' }, }; diff --git a/x-pack/plugins/fleet/server/services/agents/action.mock.ts b/x-pack/plugins/fleet/server/services/agents/action.mock.ts index 015914a1016cc..8d0bcb8b4ee4e 100644 --- a/x-pack/plugins/fleet/server/services/agents/action.mock.ts +++ b/x-pack/plugins/fleet/server/services/agents/action.mock.ts @@ -124,6 +124,8 @@ export function createClientMock() { }; }); + esClientMock.search.mockResolvedValue({ hits: { hits: [] } } as any); + return { soClient: soClientMock, esClient: esClientMock, diff --git a/x-pack/plugins/fleet/server/services/agents/action_status.ts b/x-pack/plugins/fleet/server/services/agents/action_status.ts index 2f5e6ff80cd9e..0db6d6db9d86c 100644 --- a/x-pack/plugins/fleet/server/services/agents/action_status.ts +++ b/x-pack/plugins/fleet/server/services/agents/action_status.ts @@ -36,7 +36,7 @@ export async function getActionStatuses( size: 0, aggs: { ack_counts: { - terms: { field: 'action_id' }, + terms: { field: 'action_id', size: actions.length || 10 }, aggs: { max_timestamp: { max: { field: '@timestamp' } }, }, @@ -61,7 +61,7 @@ export async function getActionStatuses( const nbAgentsAck = matchingBucket?.doc_count ?? 0; const completionTime = (matchingBucket?.max_timestamp as any)?.value_as_string; const nbAgentsActioned = action.nbAgentsActioned || action.nbAgentsActionCreated; - const complete = nbAgentsAck === nbAgentsActioned; + const complete = nbAgentsAck >= nbAgentsActioned; const cancelledAction = cancelledActions.find((a) => a.actionId === action.actionId); let errorCount = 0; @@ -161,13 +161,6 @@ async function _getActions( }, }, ], - must: [ - { - exists: { - field: 'agents', - }, - }, - ], }, }, body: { diff --git a/x-pack/plugins/fleet/server/services/agents/actions.ts b/x-pack/plugins/fleet/server/services/agents/actions.ts index f215e6dffee7e..20cb2fb94e51d 100644 --- a/x-pack/plugins/fleet/server/services/agents/actions.ts +++ b/x-pack/plugins/fleet/server/services/agents/actions.ts @@ -106,7 +106,7 @@ export async function bulkCreateAgentActionResults( results: Array<{ actionId: string; agentId: string; - error: string; + error?: string; }> ): Promise { if (results.length === 0) { @@ -164,6 +164,41 @@ export async function getAgentActions(esClient: ElasticsearchClient, actionId: s })); } +export async function getUnenrollAgentActions( + esClient: ElasticsearchClient +): Promise { + const res = await esClient.search({ + index: AGENT_ACTIONS_INDEX, + query: { + bool: { + must: [ + { + term: { + type: 'UNENROLL', + }, + }, + { + exists: { + field: 'agents', + }, + }, + { + range: { + expiration: { gte: new Date().toISOString() }, + }, + }, + ], + }, + }, + size: SO_SEARCH_LIMIT, + }); + + return res.hits.hits.map((hit) => ({ + ...hit._source, + id: hit._id, + })); +} + export async function cancelAgentAction(esClient: ElasticsearchClient, actionId: string) { const res = await esClient.search({ index: AGENT_ACTIONS_INDEX, diff --git a/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts b/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts index f3bbb2036954f..d96e8b89d2fc1 100644 --- a/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts +++ b/x-pack/plugins/fleet/server/services/agents/unenroll.test.ts @@ -6,6 +6,8 @@ */ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; +import { AGENT_ACTIONS_INDEX } from '../../../common'; + import { HostedAgentPolicyRestrictionRelatedError } from '../../errors'; import { invalidateAPIKeys } from '../api_keys'; @@ -13,8 +15,10 @@ import { appContextService } from '../app_context'; import { createAppContextStartContractMock } from '../../mocks'; +import type { Agent } from '../../types'; + import { unenrollAgent, unenrollAgents } from './unenroll'; -import { invalidateAPIKeysForAgents } from './unenroll_action_runner'; +import { invalidateAPIKeysForAgents, isAgentUnenrolled } from './unenroll_action_runner'; import { createClientMock } from './action.mock'; jest.mock('../api_keys'); @@ -137,6 +141,78 @@ describe('unenrollAgents (plural)', () => { expect(calledWithActionResults.body?.[1] as any).toEqual(expectedObject); }); + it('force unenroll updates in progress unenroll actions', async () => { + const { soClient, esClient, agentInRegularDoc, agentInRegularDoc2 } = createClientMock(); + esClient.search.mockReset(); + esClient.search.mockImplementation((request) => + Promise.resolve( + request?.index === AGENT_ACTIONS_INDEX + ? ({ + hits: { + hits: [ + { + _source: { + agents: ['agent-in-regular-policy'], + action_id: 'other-action', + }, + }, + ], + }, + } as any) + : { hits: { hits: [] } } + ) + ); + + const idsToUnenroll = [agentInRegularDoc._id, agentInRegularDoc2._id]; + await unenrollAgents(soClient, esClient, { + agentIds: idsToUnenroll, + revoke: true, + }); + + expect(esClient.bulk.mock.calls.length).toEqual(3); + const bulkBody = (esClient.bulk.mock.calls[1][0] as estypes.BulkRequest)?.body?.[1] as any; + expect(bulkBody.agent_id).toEqual(agentInRegularDoc._id); + expect(bulkBody.action_id).toEqual('other-action'); + }); + + it('force unenroll should not update completed unenroll actions', async () => { + const { soClient, esClient, agentInRegularDoc, agentInRegularDoc2 } = createClientMock(); + esClient.search.mockReset(); + esClient.search.mockImplementation((request) => + Promise.resolve( + request?.index === AGENT_ACTIONS_INDEX + ? ({ + hits: { + hits: [ + { + _source: { + agents: ['agent-in-regular-policy'], + action_id: 'other-action1', + }, + }, + ], + }, + } as any) + : { + hits: { + hits: [ + { _source: { action_id: 'other-action1', agent_id: 'agent-in-regular-policy' } }, + ], + }, + } + ) + ); + + const idsToUnenroll = [agentInRegularDoc._id, agentInRegularDoc2._id]; + await unenrollAgents(soClient, esClient, { + agentIds: idsToUnenroll, + revoke: true, + }); + + // agent and force unenroll results updated, no other action results + expect(esClient.bulk.mock.calls.length).toEqual(2); + }); + it('cannot unenroll from a hosted agent policy with revoke=true', async () => { const { soClient, esClient, agentInHostedDoc, agentInRegularDoc, agentInRegularDoc2 } = createClientMock(); @@ -165,7 +241,7 @@ describe('unenrollAgents (plural)', () => { // calls ES update with correct values const onlyRegular = [agentInRegularDoc._id, agentInRegularDoc2._id]; - const calledWith = esClient.bulk.mock.calls[0][0]; + const calledWith = esClient.bulk.mock.calls[2][0]; const ids = (calledWith as estypes.BulkRequest)?.body ?.filter((i: any) => i.update !== undefined) .map((i: any) => i.update._id); @@ -176,6 +252,21 @@ describe('unenrollAgents (plural)', () => { for (const doc of docs!) { expect(doc).toHaveProperty('unenrolled_at'); } + + const errorResults = esClient.bulk.mock.calls[1][0]; + const errorIds = (errorResults as estypes.BulkRequest)?.body + ?.filter((i: any) => i.agent_id) + .map((i: any) => i.agent_id); + expect(errorIds).toEqual([agentInHostedDoc._id]); + + const actionResults = esClient.bulk.mock.calls[0][0]; + const resultIds = (actionResults as estypes.BulkRequest)?.body + ?.filter((i: any) => i.agent_id) + .map((i: any) => i.agent_id); + expect(resultIds).toEqual(onlyRegular); + + const action = esClient.create.mock.calls[0][0] as any; + expect(action.body.type).toEqual('FORCE_UNENROLL'); }); it('can unenroll from hosted agent policy with force=true', async () => { @@ -226,7 +317,7 @@ describe('unenrollAgents (plural)', () => { ]); // calls ES update with correct values - const calledWith = esClient.bulk.mock.calls[0][0]; + const calledWith = esClient.bulk.mock.calls[1][0]; const ids = (calledWith as estypes.BulkRequest)?.body ?.filter((i: any) => i.update !== undefined) .map((i: any) => i.update._id); @@ -237,6 +328,15 @@ describe('unenrollAgents (plural)', () => { for (const doc of docs!) { expect(doc).toHaveProperty('unenrolled_at'); } + + const actionResults = esClient.bulk.mock.calls[0][0]; + const resultIds = (actionResults as estypes.BulkRequest)?.body + ?.filter((i: any) => i.agent_id) + .map((i: any) => i.agent_id); + expect(resultIds).toEqual(idsToUnenroll); + + const action = esClient.create.mock.calls[0][0] as any; + expect(action.body.type).toEqual('FORCE_UNENROLL'); }); }); @@ -270,3 +370,31 @@ describe('invalidateAPIKeysForAgents', () => { ]); }); }); + +describe('isAgentUnenrolled', () => { + it('should return true if revoke and unenrolled_at set', () => { + expect(isAgentUnenrolled({ unenrolled_at: '2022-09-21' } as Agent, true)).toBe(true); + }); + + it('should return false if revoke and unenrolled_at null', () => { + expect( + isAgentUnenrolled({ unenrolled_at: null, unenrollment_started_at: '2022-09-21' } as any, true) + ).toBe(false); + }); + + it('should return true if unenrolled_at set', () => { + expect(isAgentUnenrolled({ unenrolled_at: '2022-09-21' } as Agent)).toBe(true); + }); + + it('should return true if unenrollment_started_at set and unenrolled_at null', () => { + expect( + isAgentUnenrolled({ unenrolled_at: null, unenrollment_started_at: '2022-09-21' } as any) + ).toBe(true); + }); + + it('should return false if unenrollment_started_at null and unenrolled_at null', () => { + expect(isAgentUnenrolled({ unenrolled_at: null, unenrollment_started_at: null } as any)).toBe( + false + ); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/agents/unenroll.ts b/x-pack/plugins/fleet/server/services/agents/unenroll.ts index 941e1260894b4..f7c49f3efcf1c 100644 --- a/x-pack/plugins/fleet/server/services/agents/unenroll.ts +++ b/x-pack/plugins/fleet/server/services/agents/unenroll.ts @@ -7,6 +7,8 @@ import type { ElasticsearchClient, SavedObjectsClientContract } from '@kbn/core/server'; +import uuid from 'uuid'; + import type { Agent, BulkActionResult } from '../../types'; import { HostedAgentPolicyRestrictionRelatedError } from '../../errors'; import { SO_SEARCH_LIMIT } from '../../constants'; @@ -20,6 +22,7 @@ import { invalidateAPIKeysForAgents, UnenrollActionRunner, unenrollBatch, + updateActionsForForceUnenroll, } from './unenroll_action_runner'; async function unenrollAgentIsAllowed( @@ -50,7 +53,7 @@ export async function unenrollAgent( await unenrollAgentIsAllowed(soClient, esClient, agentId); } if (options?.revoke) { - return forceUnenrollAgent(soClient, esClient, agentId); + return forceUnenrollAgent(esClient, agentId); } const now = new Date().toISOString(); await createAgentAction(esClient, { @@ -102,7 +105,6 @@ export async function unenrollAgents( } export async function forceUnenrollAgent( - soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, agentIdOrAgent: string | Agent ) { @@ -116,4 +118,5 @@ export async function forceUnenrollAgent( active: false, unenrolled_at: new Date().toISOString(), }); + await updateActionsForForceUnenroll(esClient, [agent.id], uuid(), 1); } diff --git a/x-pack/plugins/fleet/server/services/agents/unenroll_action_runner.ts b/x-pack/plugins/fleet/server/services/agents/unenroll_action_runner.ts index 70cfcece227ba..dfa7fac5e0e4c 100644 --- a/x-pack/plugins/fleet/server/services/agents/unenroll_action_runner.ts +++ b/x-pack/plugins/fleet/server/services/agents/unenroll_action_runner.ts @@ -7,9 +7,13 @@ import uuid from 'uuid'; import type { SavedObjectsClientContract, ElasticsearchClient } from '@kbn/core/server'; +import { intersection } from 'lodash'; + +import { AGENT_ACTIONS_RESULTS_INDEX } from '../../../common'; + import type { Agent, BulkActionResult } from '../../types'; -import { HostedAgentPolicyRestrictionRelatedError } from '../../errors'; +import { FleetError, HostedAgentPolicyRestrictionRelatedError } from '../../errors'; import { invalidateAPIKeys } from '../api_keys'; @@ -18,7 +22,11 @@ import { appContextService } from '../app_context'; import { ActionRunner } from './action_runner'; import { errorsToResults, bulkUpdateAgents } from './crud'; -import { bulkCreateAgentActionResults, createAgentAction } from './actions'; +import { + bulkCreateAgentActionResults, + createAgentAction, + getUnenrollAgentActions, +} from './actions'; import { getHostedPolicies, isHostedAgent } from './hosted_agent'; import { BulkActionTaskType } from './bulk_actions_resolver'; @@ -36,6 +44,13 @@ export class UnenrollActionRunner extends ActionRunner { } } +export function isAgentUnenrolled(agent: Agent, revoke?: boolean): boolean { + return Boolean( + (revoke && agent.unenrolled_at) || + (!revoke && (agent.unenrollment_started_at || agent.unenrolled_at)) + ); +} + export async function unenrollBatch( soClient: SavedObjectsClientContract, esClient: ElasticsearchClient, @@ -48,23 +63,16 @@ export async function unenrollBatch( }, skipSuccess?: boolean ): Promise<{ items: BulkActionResult[] }> { - // Filter to those not already unenrolled, or unenrolling - const agentsEnrolled = givenAgents.filter((agent) => { - if (options.revoke) { - return !agent.unenrolled_at; - } - return !agent.unenrollment_started_at && !agent.unenrolled_at; - }); - - const hostedPolicies = await getHostedPolicies(soClient, agentsEnrolled); - + const hostedPolicies = await getHostedPolicies(soClient, givenAgents); const outgoingErrors: Record = {}; // And which are allowed to unenroll const agentsToUpdate = options.force - ? agentsEnrolled - : agentsEnrolled.reduce((agents, agent) => { - if (isHostedAgent(hostedPolicies, agent)) { + ? givenAgents + : givenAgents.reduce((agents, agent) => { + if (isAgentUnenrolled(agent, options.revoke)) { + outgoingErrors[agent.id] = new FleetError(`Agent ${agent.id} already unenrolled`); + } else if (isHostedAgent(hostedPolicies, agent)) { outgoingErrors[agent.id] = new HostedAgentPolicyRestrictionRelatedError( `Cannot unenroll ${agent.id} from a hosted agent policy ${agent.policy_id}` ); @@ -76,39 +84,43 @@ export async function unenrollBatch( const actionId = options.actionId ?? uuid(); const errorCount = Object.keys(outgoingErrors).length; - const total = options.total ?? agentsToUpdate.length + errorCount; + const total = options.total ?? givenAgents.length; + + const agentIds = agentsToUpdate.map((agent) => agent.id); const now = new Date().toISOString(); if (options.revoke) { // Get all API keys that need to be invalidated await invalidateAPIKeysForAgents(agentsToUpdate); + + await updateActionsForForceUnenroll(esClient, agentIds, actionId, total); } else { // Create unenroll action for each agent await createAgentAction(esClient, { id: actionId, - agents: agentsToUpdate.map((agent) => agent.id), + agents: agentIds, created_at: now, type: 'UNENROLL', total, }); + } - if (errorCount > 0) { - appContextService - .getLogger() - .info( - `Skipping ${errorCount} agents, as failed validation (cannot unenroll from a hosted policy)` - ); - - // writing out error result for those agents that failed validation, so the action is not going to stay in progress forever - await bulkCreateAgentActionResults( - esClient, - Object.keys(outgoingErrors).map((agentId) => ({ - agentId, - actionId, - error: outgoingErrors[agentId].message, - })) + if (errorCount > 0) { + appContextService + .getLogger() + .info( + `Skipping ${errorCount} agents, as failed validation (cannot unenroll from a hosted policy or already unenrolled)` ); - } + + // writing out error result for those agents that failed validation, so the action is not going to stay in progress forever + await bulkCreateAgentActionResults( + esClient, + Object.keys(outgoingErrors).map((agentId) => ({ + agentId, + actionId, + error: outgoingErrors[agentId].message, + })) + ); } // Update the necessary agents @@ -126,6 +138,82 @@ export async function unenrollBatch( }; } +export async function updateActionsForForceUnenroll( + esClient: ElasticsearchClient, + agentIds: string[], + actionId: string, + total: number +) { + // creating an unenroll so that force unenroll shows up in activity + await createAgentAction(esClient, { + id: actionId, + agents: [], + created_at: new Date().toISOString(), + type: 'FORCE_UNENROLL', + total, + }); + await bulkCreateAgentActionResults( + esClient, + agentIds.map((agentId) => ({ + agentId, + actionId, + })) + ); + + // updating action results for those agents that are there in a pending unenroll action + const unenrollActions = await getUnenrollAgentActions(esClient); + for (const action of unenrollActions) { + const commonAgents = intersection(action.agents, agentIds); + if (commonAgents.length > 0) { + // filtering out agents with action results + const agentsToUpdate = await getAgentsWithoutActionResults( + esClient, + action.action_id!, + commonAgents + ); + if (agentsToUpdate.length > 0) { + await bulkCreateAgentActionResults( + esClient, + agentsToUpdate.map((agentId) => ({ + agentId, + actionId: action.action_id!, + })) + ); + } + } + } +} + +async function getAgentsWithoutActionResults( + esClient: ElasticsearchClient, + actionId: string, + commonAgents: string[] +): Promise { + try { + const res = await esClient.search({ + index: AGENT_ACTIONS_RESULTS_INDEX, + query: { + bool: { + must: [{ term: { action_id: actionId } }, { terms: { agent_id: commonAgents } }], + }, + }, + size: commonAgents.length, + }); + const agentsToUpdate = commonAgents.filter( + (agentId) => !res.hits.hits.find((hit) => (hit._source as any)?.agent_id === agentId) + ); + return agentsToUpdate; + } catch (err) { + if (err.statusCode === 404) { + // .fleet-actions-results does not yet exist + appContextService.getLogger().debug(err); + } else { + throw err; + } + } + return commonAgents; +} + export async function invalidateAPIKeysForAgents(agents: Agent[]) { const apiKeys = agents.reduce((keys, agent) => { if (agent.access_api_key_id) { diff --git a/x-pack/plugins/fleet/server/services/preconfiguration/reset_agent_policies.ts b/x-pack/plugins/fleet/server/services/preconfiguration/reset_agent_policies.ts index 6d456a01d551f..9375c3d82b7cb 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration/reset_agent_policies.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration/reset_agent_policies.ts @@ -163,7 +163,7 @@ async function _deleteExistingData( // Delete if (agents.length > 0) { logger.info(`Force unenrolling ${agents.length} agents`); - await pMap(agents, (agent) => forceUnenrollAgent(soClient, esClient, agent.id), { + await pMap(agents, (agent) => forceUnenrollAgent(esClient, agent.id), { concurrency: 20, }); } From 6f1be65f1e0c1c034073410e874219744d8df617 Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Thu, 22 Sep 2022 09:22:24 +0200 Subject: [PATCH 25/36] :white_check_mark: add more unit tests for the annotation type switch operation (#141241) --- .../annotations_config_panel/index.test.tsx | 212 ++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/annotations_config_panel/index.test.tsx b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/annotations_config_panel/index.test.tsx index 049823e3361ce..c852759a97aa8 100644 --- a/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/annotations_config_panel/index.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/xy/xy_config_panel/annotations_config_panel/index.test.tsx @@ -372,6 +372,218 @@ describe('AnnotationsPanel', () => { ); }); + test('should avoid to retain specific manual configurations when switching to query based annotations', () => { + const state = testState(); + const indexPattern = createMockedIndexPattern(); + state.layers[0] = { + annotations: [customLineStaticAnnotation], + layerId: 'annotation', + layerType: 'annotations', + ignoreGlobalFilters: true, + indexPatternId: indexPattern.id, + }; + const frameMock = createMockFramePublicAPI({ + datasourceLayers: {}, + dataViews: createMockDataViewsState({ + indexPatterns: { [indexPattern.id]: indexPattern }, + }), + }); + + const setState = jest.fn(); + + const component = mount( + + ); + + act(() => { + component + .find(`[data-test-subj="lns-xyAnnotation-placementType"]`) + .find(EuiButtonGroup) + .prop('onChange')!('lens_xyChart_annotation_query'); + }); + component.update(); + + expect(setState).toHaveBeenCalledWith( + expect.objectContaining({ + layers: [ + expect.objectContaining({ + annotations: [ + expect.objectContaining({ + key: expect.not.objectContaining({ timestamp: expect.any('string') }), + }), + ], + }), + ], + }) + ); + }); + + test('should avoid to retain range manual configurations when switching to query based annotations', () => { + const state = testState(); + const indexPattern = createMockedIndexPattern(); + state.layers[0] = { + annotations: [ + { + color: 'red', + icon: 'triangle', + id: 'ann1', + type: 'manual', + isHidden: undefined, + key: { + endTimestamp: '2022-03-21T10:49:00.000Z', + timestamp: '2022-03-18T08:25:00.000Z', + type: 'range', + }, + label: 'Event range', + lineStyle: 'dashed', + lineWidth: 3, + }, + ], + layerId: 'annotation', + layerType: 'annotations', + ignoreGlobalFilters: true, + indexPatternId: indexPattern.id, + }; + const frameMock = createMockFramePublicAPI({ + datasourceLayers: {}, + dataViews: createMockDataViewsState({ + indexPatterns: { [indexPattern.id]: indexPattern }, + }), + }); + + const setState = jest.fn(); + + const component = mount( + + ); + + act(() => { + component + .find(`[data-test-subj="lns-xyAnnotation-placementType"]`) + .find(EuiButtonGroup) + .prop('onChange')!('lens_xyChart_annotation_query'); + }); + component.update(); + + expect(setState).toHaveBeenCalledWith( + expect.objectContaining({ + layers: [ + expect.objectContaining({ + annotations: [ + expect.objectContaining({ label: expect.not.stringContaining('Event range') }), + ], + }), + ], + }) + ); + }); + + test('should set a default tiemstamp when switching from query based to manual annotations', () => { + const state = testState(); + const indexPattern = createMockedIndexPattern(); + state.layers[0] = { + annotations: [ + { + color: 'red', + icon: 'triangle', + id: 'ann1', + type: 'query', + isHidden: undefined, + timeField: 'timestamp', + key: { + type: 'point_in_time', + }, + label: 'Query based event', + lineStyle: 'dashed', + lineWidth: 3, + filter: { type: 'kibana_query', query: '', language: 'kuery' }, + }, + ], + layerId: 'annotation', + layerType: 'annotations', + indexPatternId: indexPattern.id, + ignoreGlobalFilters: true, + }; + const frameMock = createMockFramePublicAPI({ + datasourceLayers: {}, + dataViews: createMockDataViewsState({ + indexPatterns: { [indexPattern.id]: indexPattern }, + }), + }); + + const setState = jest.fn(); + + const component = mount( + + ); + + act(() => { + component + .find(`[data-test-subj="lns-xyAnnotation-placementType"]`) + .find(EuiButtonGroup) + .prop('onChange')!('lens_xyChart_annotation_manual'); + }); + component.update(); + + expect(setState).toHaveBeenCalledWith( + expect.objectContaining({ + layers: [ + expect.objectContaining({ + annotations: [ + expect.objectContaining({ + key: { type: 'point_in_time', timestamp: expect.any(String) }, + }), + ], + }), + ], + }) + ); + + // also check query specific props are not carried over + expect(setState).toHaveBeenCalledWith( + expect.objectContaining({ + layers: [ + expect.objectContaining({ + annotations: [expect.not.objectContaining({ timeField: 'timestamp' })], + }), + ], + }) + ); + }); + test('should fallback to the first date field available in the dataView if not time-based', () => { const state = testState(); const indexPattern = createMockedIndexPattern({ timeFieldName: '' }); From 2bc9b77e9c24fdb901991f7ed9eb5e13869754b9 Mon Sep 17 00:00:00 2001 From: Gloria Hornero Date: Thu, 22 Sep 2022 09:48:35 +0200 Subject: [PATCH 26/36] [Security Solution] Removes flakiness from pinned filters and adds code owners (#141269) --- .github/CODEOWNERS | 1 + .../security_solution/cypress/e2e/filters/pinned_filters.cy.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 93cf5cc23dde2..4d9b0f55c880f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -418,6 +418,7 @@ x-pack/examples/files_example @elastic/kibana-app-services /x-pack/plugins/security_solution/common/search_strategy/security_solution/user @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/cypress/e2e/cases @elastic/security-threat-hunting-explore +/x-pack/plugins/security_solution/cypress/e2e/filters @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/cypress/e2e/host_details @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/cypress/e2e/hosts @elastic/security-threat-hunting-explore /x-pack/plugins/security_solution/cypress/e2e/network @elastic/security-threat-hunting-explore diff --git a/x-pack/plugins/security_solution/cypress/e2e/filters/pinned_filters.cy.ts b/x-pack/plugins/security_solution/cypress/e2e/filters/pinned_filters.cy.ts index 91d99f790e31b..b152dbd7157bd 100644 --- a/x-pack/plugins/security_solution/cypress/e2e/filters/pinned_filters.cy.ts +++ b/x-pack/plugins/security_solution/cypress/e2e/filters/pinned_filters.cy.ts @@ -17,10 +17,12 @@ import { openKibanaNavigation, } from '../../tasks/kibana_navigation'; import { ALERTS_PAGE } from '../../screens/kibana_navigation'; +import { postDataView } from '../../tasks/common'; describe('pinned filters', () => { before(() => { login(); + postDataView('audit*'); }); it('show pinned filters on security', () => { From 50b3b57d9e28eca15d934f351ddeb9de5e1bc31b Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 22 Sep 2022 03:06:46 -0500 Subject: [PATCH 27/36] [ftr] add first-class support for playwrite journeys (#140680) * [ftr] add first-class support for playwrite journeys * [CI] Auto-commit changed files from 'node scripts/generate codeowners' * fix jest test * remove ability to customize kibana server args, if we need it we can add it back * remove dev dir that doesn't exist * fix typo * prevent duplicated array converstion logic by sharing flag reader * remove destructuring of option * fix scalability config and config_path import * fix start_servers args and tests * include simple readme * fix jest tests and support build re-use when changes are just to jest tests Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .buildkite/ftr_configs.yml | 16 +- .buildkite/pipelines/performance/daily.yml | 12 +- .buildkite/pull_requests.json | 7 +- .../functional/performance_playwright.sh | 79 ++-- .../scalability_dataset_extraction.sh | 23 +- .eslintrc.js | 1 + .github/CODEOWNERS | 4 + dev_docs/operations/operations_landing.mdx | 1 + package.json | 8 + packages/BUILD.bazel | 8 + packages/kbn-dev-cli-runner/index.ts | 1 + packages/kbn-dev-cli-runner/src/flags.ts | 6 +- .../src/flags_reader.test.ts | 344 +++++++++++++++ .../kbn-dev-cli-runner/src/flags_reader.ts | 267 ++++++++++++ packages/kbn-dev-cli-runner/src/run.ts | 10 +- .../src/run_with_commands.test.ts | 2 + .../src/run_with_commands.ts | 9 +- .../kbn-failed-test-reporter-cli/BUILD.bazel | 145 +++++++ .../kbn-failed-test-reporter-cli/README.md | 3 + .../failed_tests_reporter/README.md | 0 .../__fixtures__/cypress_report.xml | 0 .../__fixtures__/ftr_report.xml | 0 .../__fixtures__/index.ts | 0 .../__fixtures__/jest_report.xml | 0 .../__fixtures__/mocha_report.xml | 0 .../add_messages_to_report.test.ts | 0 .../add_messages_to_report.ts | 0 .../buildkite_metadata.ts | 0 .../failed_tests_reporter/es_config | 0 .../existing_failed_test_issues.test.ts | 0 .../existing_failed_test_issues.ts | 0 .../failed_tests_reporter_cli.ts | 208 +++++++++ .../get_failures.test.ts | 0 .../failed_tests_reporter/get_failures.ts | 0 .../failed_tests_reporter/github_api.ts | 0 .../issue_metadata.test.ts | 0 .../failed_tests_reporter/issue_metadata.ts | 0 .../report_failure.test.ts | 0 .../failed_tests_reporter/report_failure.ts | 0 .../report_failures_to_es.ts | 0 .../report_failures_to_file.ts | 199 +++++++++ ...report_failures_to_file_html_template.html | 0 .../report_metadata.test.ts | 0 .../failed_tests_reporter/report_metadata.ts | 0 .../failed_tests_reporter/test_report.ts | 21 + .../index.ts | 2 +- .../jest.config.js} | 9 +- .../kbn-failed-test-reporter-cli/kibana.jsonc | 8 + .../kbn-failed-test-reporter-cli/package.json | 7 + .../tsconfig.json | 17 + .../BUILD.bazel | 127 ++++++ .../README.md | 3 + .../index.ts | 21 + .../jest.config.js | 13 + .../kibana.jsonc | 8 + .../package.json | 7 + .../services/all.ts | 19 + .../services/es.ts | 7 +- .../services/es_archiver.ts | 22 +- .../services/ftr_provider_context.ts | 16 + .../kibana_server/extend_es_archiver.ts | 0 .../services/kibana_server/index.ts | 0 .../services/kibana_server/kibana_server.ts | 16 +- .../services/retry/index.ts | 0 .../services/retry/retry.ts | 2 +- .../services/retry/retry_for_success.ts | 0 .../services/retry/retry_for_truthy.ts | 0 .../tsconfig.json | 17 + .../kbn-ftr-screenshot-filename/BUILD.bazel | 125 ++++++ .../kbn-ftr-screenshot-filename/README.md | 3 + .../ftr_screenshot_filename.ts | 15 + packages/kbn-ftr-screenshot-filename/index.ts | 11 + .../jest.config.js | 13 + .../kbn-ftr-screenshot-filename/kibana.jsonc | 8 + .../kbn-ftr-screenshot-filename/package.json | 7 + .../kbn-ftr-screenshot-filename/tsconfig.json | 17 + packages/kbn-journeys/BUILD.bazel | 134 ++++++ packages/kbn-journeys/README.mdx | 32 ++ packages/kbn-journeys/index.ts | 15 + packages/kbn-journeys/jest.config.js | 13 + packages/kbn-journeys/journey/journey.ts | 125 ++++++ .../kbn-journeys/journey/journey_config.ts | 155 +++++++ .../journey/journey_ftr_config.ts | 127 ++++++ .../journey/journey_ftr_harness.ts | 410 ++++++++++++++++++ .../journey/journey_screenshots.ts | 128 ++++++ packages/kbn-journeys/kibana.jsonc | 8 + packages/kbn-journeys/package.json | 7 + packages/kbn-journeys/services/auth.ts | 85 ++++ .../kbn-journeys}/services/input_delays.ts | 10 +- packages/kbn-journeys/services/kibana_url.ts | 60 +++ packages/kbn-journeys/tsconfig.json | 17 + .../BUILD.bazel | 2 +- .../src/cli.ts | 82 ++-- .../src/types.ts | 16 +- packages/kbn-test/BUILD.bazel | 2 + packages/kbn-test/index.ts | 20 +- .../report_failures_to_file.ts | 167 ------- .../run_failed_tests_reporter_cli.ts | 210 --------- .../src/functional_test_runner/cli.ts | 98 ++--- .../fake_mocha_types.ts | 1 + .../functional_test_runner.ts | 82 ++-- .../lib/config/config.test.ts | 1 + .../lib/config/config.ts | 17 +- ...ig_file.test.ts => config_loading.test.ts} | 2 +- .../lib/config/config_loading.ts | 182 ++++++++ .../lib/config/index.ts | 3 +- .../lib/config/read_config_file.ts | 101 ----- .../lib/config/schema.ts | 59 +-- .../functional_test_runner/lib/es_version.ts | 4 + .../src/functional_test_runner/lib/index.ts | 2 +- .../lib/mocha/load_test_files.js | 89 ---- .../lib/mocha/load_tests.ts | 120 +++++ .../lib/mocha/reporter/reporter.js | 1 + .../mocha/{setup_mocha.js => setup_mocha.ts} | 54 ++- .../functional_test_runner/public_types.ts | 7 + .../run_tests/__snapshots__/args.test.js.snap | 332 -------------- .../functional_tests/cli/run_tests/args.js | 193 --------- .../cli/run_tests/args.test.js | 142 ------ .../src/functional_tests/cli/run_tests/cli.js | 27 -- .../__snapshots__/args.test.js.snap | 141 ------ .../cli/start_servers/args.js | 130 ------ .../cli/start_servers/args.test.js | 110 ----- .../functional_tests/cli/start_servers/cli.js | 26 -- .../lib/__snapshots__/run_cli.test.js.snap | 26 -- .../src/functional_tests/lib/index.ts | 4 +- .../{test_helpers.ts => lib/logs_dir.ts} | 14 +- .../src/functional_tests/lib/run_cli.test.js | 122 ------ .../src/functional_tests/lib/run_cli.ts | 57 --- .../src/functional_tests/lib/run_ftr.ts | 130 +----- .../functional_tests/lib/run_kibana_server.ts | 24 +- .../src/functional_tests/run_tests/cli.ts | 36 ++ .../functional_tests/run_tests/flags.test.ts | 151 +++++++ .../src/functional_tests/run_tests/flags.ts | 89 ++++ .../src/functional_tests/run_tests/index.ts | 10 + .../functional_tests/run_tests/run_tests.ts | 116 +++++ .../src/functional_tests/start_servers/cli.ts | 34 ++ .../start_servers/flags.test.ts | 54 +++ .../functional_tests/start_servers/flags.ts | 50 +++ .../functional_tests/start_servers/index.ts | 10 + .../start_servers/start_servers.ts | 82 ++++ .../kbn-test/src/functional_tests/tasks.ts | 230 ---------- .../src/mocha/junit_report_generation.js | 2 + .../src/mocha/junit_report_generation.test.js | 1 + scripts/functional_tests_server.js | 2 +- scripts/report_failed_tests.js | 2 +- src/dev/typescript/projects.ts | 1 + test/common/services/bsearch.ts | 89 ++-- test/common/services/index.ts | 14 +- .../services/common/failure_debugging.ts | 12 +- .../ecommerce_sample_data/data.json.gz | Bin .../ecommerce_sample_data/mappings.json | 0 .../reporting_dashboard/data.json.gz | Bin .../reporting_dashboard/mappings.json | 0 .../journeys/data_stress_test_lens.ts | 18 + .../journeys/ecommerce_dashboard.ts | 56 +++ .../performance/journeys/flight_dashboard.ts | 68 +++ x-pack/performance/journeys/login.ts | 44 ++ .../journeys/many_fields_discover.ts | 25 ++ .../journeys/promotion_tracking_dashboard.ts | 55 +++ .../journeys/web_logs_dashboard.ts | 56 +++ .../promotion_tracking_dashboard.json | 0 .../kbn_archives/reporting_dashboard.json | 0 x-pack/performance/services/toasts.ts | 34 ++ x-pack/performance/tsconfig.json | 11 + x-pack/{test => }/performance/utils.ts | 10 +- x-pack/scripts/functional_tests_server.js | 2 +- x-pack/test/common/ftr_provider_context.ts | 3 +- x-pack/test/common/services/bsearch_secure.ts | 77 ++-- x-pack/test/common/services/index.ts | 4 +- .../page_objects/infra_logs_page.ts | 1 - .../test_utils.ts | 2 +- .../test/performance/journeys/base.config.ts | 95 ---- .../journeys/data_stress_test_lens/config.ts | 47 -- .../data_stress_test_lens.ts | 37 -- .../journeys/ecommerce_dashboard/config.ts | 43 -- .../ecommerce_dashboard.ts | 61 --- .../journeys/flight_dashboard/config.ts | 43 -- .../flight_dashboard/flight_dashboard.ts | 76 ---- .../test/performance/journeys/login/config.ts | 66 --- .../test/performance/journeys/login/login.ts | 42 -- .../journeys/many_fields_discover/config.ts | 47 -- .../many_fields_discover.ts | 41 -- .../promotion_tracking_dashboard/config.ts | 70 --- .../promotion_tracking_dashboard.ts | 62 --- .../journeys/web_logs_dashboard/config.ts | 43 -- .../web_logs_dashboard/web_logs_dashboard.ts | 61 --- x-pack/test/performance/page_objects.ts | 8 - x-pack/test/performance/scalability/config.ts | 109 ----- x-pack/test/performance/services/auth.ts | 62 --- x-pack/test/performance/services/index.ts | 21 - .../test/performance/services/performance.ts | 306 ------------- x-pack/test/scalability/config.ts | 69 +++ .../ftr_provider_context.ts | 6 +- .../{performance => }/scalability/runner.ts | 2 +- .../tests/audit/file_wrapper.ts | 2 +- .../services/es_archiver.js | 2 +- yarn.lock | 32 ++ 197 files changed, 4828 insertions(+), 4096 deletions(-) create mode 100644 packages/kbn-dev-cli-runner/src/flags_reader.test.ts create mode 100644 packages/kbn-dev-cli-runner/src/flags_reader.ts create mode 100644 packages/kbn-failed-test-reporter-cli/BUILD.bazel create mode 100644 packages/kbn-failed-test-reporter-cli/README.md rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/README.md (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/__fixtures__/cypress_report.xml (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/__fixtures__/ftr_report.xml (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/__fixtures__/index.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/__fixtures__/jest_report.xml (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/__fixtures__/mocha_report.xml (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/add_messages_to_report.test.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/add_messages_to_report.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/buildkite_metadata.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/es_config (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/existing_failed_test_issues.test.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/existing_failed_test_issues.ts (100%) create mode 100644 packages/kbn-failed-test-reporter-cli/failed_tests_reporter/failed_tests_reporter_cli.ts rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/get_failures.test.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/get_failures.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/github_api.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/issue_metadata.test.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/issue_metadata.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/report_failure.test.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/report_failure.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/report_failures_to_es.ts (100%) create mode 100644 packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file.ts rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/report_failures_to_file_html_template.html (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/report_metadata.test.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/report_metadata.ts (100%) rename packages/{kbn-test/src => kbn-failed-test-reporter-cli}/failed_tests_reporter/test_report.ts (84%) rename packages/{kbn-test/src/failed_tests_reporter => kbn-failed-test-reporter-cli}/index.ts (82%) rename packages/{kbn-test/src/functional_tests/cli/index.js => kbn-failed-test-reporter-cli/jest.config.js} (56%) create mode 100644 packages/kbn-failed-test-reporter-cli/kibana.jsonc create mode 100644 packages/kbn-failed-test-reporter-cli/package.json create mode 100644 packages/kbn-failed-test-reporter-cli/tsconfig.json create mode 100644 packages/kbn-ftr-common-functional-services/BUILD.bazel create mode 100644 packages/kbn-ftr-common-functional-services/README.md create mode 100644 packages/kbn-ftr-common-functional-services/index.ts create mode 100644 packages/kbn-ftr-common-functional-services/jest.config.js create mode 100644 packages/kbn-ftr-common-functional-services/kibana.jsonc create mode 100644 packages/kbn-ftr-common-functional-services/package.json create mode 100644 packages/kbn-ftr-common-functional-services/services/all.ts rename test/common/services/elasticsearch.ts => packages/kbn-ftr-common-functional-services/services/es.ts (75%) rename {test/common => packages/kbn-ftr-common-functional-services}/services/es_archiver.ts (61%) create mode 100644 packages/kbn-ftr-common-functional-services/services/ftr_provider_context.ts rename {test/common => packages/kbn-ftr-common-functional-services}/services/kibana_server/extend_es_archiver.ts (100%) rename {test/common => packages/kbn-ftr-common-functional-services}/services/kibana_server/index.ts (100%) rename {test/common => packages/kbn-ftr-common-functional-services}/services/kibana_server/kibana_server.ts (69%) rename {test/common => packages/kbn-ftr-common-functional-services}/services/retry/index.ts (100%) rename {test/common => packages/kbn-ftr-common-functional-services}/services/retry/retry.ts (96%) rename {test/common => packages/kbn-ftr-common-functional-services}/services/retry/retry_for_success.ts (100%) rename {test/common => packages/kbn-ftr-common-functional-services}/services/retry/retry_for_truthy.ts (100%) create mode 100644 packages/kbn-ftr-common-functional-services/tsconfig.json create mode 100644 packages/kbn-ftr-screenshot-filename/BUILD.bazel create mode 100644 packages/kbn-ftr-screenshot-filename/README.md create mode 100644 packages/kbn-ftr-screenshot-filename/ftr_screenshot_filename.ts create mode 100644 packages/kbn-ftr-screenshot-filename/index.ts create mode 100644 packages/kbn-ftr-screenshot-filename/jest.config.js create mode 100644 packages/kbn-ftr-screenshot-filename/kibana.jsonc create mode 100644 packages/kbn-ftr-screenshot-filename/package.json create mode 100644 packages/kbn-ftr-screenshot-filename/tsconfig.json create mode 100644 packages/kbn-journeys/BUILD.bazel create mode 100644 packages/kbn-journeys/README.mdx create mode 100644 packages/kbn-journeys/index.ts create mode 100644 packages/kbn-journeys/jest.config.js create mode 100644 packages/kbn-journeys/journey/journey.ts create mode 100644 packages/kbn-journeys/journey/journey_config.ts create mode 100644 packages/kbn-journeys/journey/journey_ftr_config.ts create mode 100644 packages/kbn-journeys/journey/journey_ftr_harness.ts create mode 100644 packages/kbn-journeys/journey/journey_screenshots.ts create mode 100644 packages/kbn-journeys/kibana.jsonc create mode 100644 packages/kbn-journeys/package.json create mode 100644 packages/kbn-journeys/services/auth.ts rename {x-pack/test/performance => packages/kbn-journeys}/services/input_delays.ts (69%) create mode 100644 packages/kbn-journeys/services/kibana_url.ts create mode 100644 packages/kbn-journeys/tsconfig.json delete mode 100644 packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts delete mode 100644 packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts rename packages/kbn-test/src/functional_test_runner/lib/config/{read_config_file.test.ts => config_loading.test.ts} (97%) create mode 100644 packages/kbn-test/src/functional_test_runner/lib/config/config_loading.ts delete mode 100644 packages/kbn-test/src/functional_test_runner/lib/config/read_config_file.ts delete mode 100644 packages/kbn-test/src/functional_test_runner/lib/mocha/load_test_files.js create mode 100644 packages/kbn-test/src/functional_test_runner/lib/mocha/load_tests.ts rename packages/kbn-test/src/functional_test_runner/lib/mocha/{setup_mocha.js => setup_mocha.ts} (59%) delete mode 100644 packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/args.test.js.snap delete mode 100644 packages/kbn-test/src/functional_tests/cli/run_tests/args.js delete mode 100644 packages/kbn-test/src/functional_tests/cli/run_tests/args.test.js delete mode 100644 packages/kbn-test/src/functional_tests/cli/run_tests/cli.js delete mode 100644 packages/kbn-test/src/functional_tests/cli/start_servers/__snapshots__/args.test.js.snap delete mode 100644 packages/kbn-test/src/functional_tests/cli/start_servers/args.js delete mode 100644 packages/kbn-test/src/functional_tests/cli/start_servers/args.test.js delete mode 100644 packages/kbn-test/src/functional_tests/cli/start_servers/cli.js delete mode 100644 packages/kbn-test/src/functional_tests/lib/__snapshots__/run_cli.test.js.snap rename packages/kbn-test/src/functional_tests/{test_helpers.ts => lib/logs_dir.ts} (52%) delete mode 100644 packages/kbn-test/src/functional_tests/lib/run_cli.test.js delete mode 100644 packages/kbn-test/src/functional_tests/lib/run_cli.ts create mode 100644 packages/kbn-test/src/functional_tests/run_tests/cli.ts create mode 100644 packages/kbn-test/src/functional_tests/run_tests/flags.test.ts create mode 100644 packages/kbn-test/src/functional_tests/run_tests/flags.ts create mode 100644 packages/kbn-test/src/functional_tests/run_tests/index.ts create mode 100644 packages/kbn-test/src/functional_tests/run_tests/run_tests.ts create mode 100644 packages/kbn-test/src/functional_tests/start_servers/cli.ts create mode 100644 packages/kbn-test/src/functional_tests/start_servers/flags.test.ts create mode 100644 packages/kbn-test/src/functional_tests/start_servers/flags.ts create mode 100644 packages/kbn-test/src/functional_tests/start_servers/index.ts create mode 100644 packages/kbn-test/src/functional_tests/start_servers/start_servers.ts delete mode 100644 packages/kbn-test/src/functional_tests/tasks.ts rename x-pack/{test => }/performance/es_archives/ecommerce_sample_data/data.json.gz (100%) rename x-pack/{test => }/performance/es_archives/ecommerce_sample_data/mappings.json (100%) rename x-pack/{test => }/performance/es_archives/reporting_dashboard/data.json.gz (100%) rename x-pack/{test => }/performance/es_archives/reporting_dashboard/mappings.json (100%) create mode 100644 x-pack/performance/journeys/data_stress_test_lens.ts create mode 100644 x-pack/performance/journeys/ecommerce_dashboard.ts create mode 100644 x-pack/performance/journeys/flight_dashboard.ts create mode 100644 x-pack/performance/journeys/login.ts create mode 100644 x-pack/performance/journeys/many_fields_discover.ts create mode 100644 x-pack/performance/journeys/promotion_tracking_dashboard.ts create mode 100644 x-pack/performance/journeys/web_logs_dashboard.ts rename x-pack/{test => }/performance/kbn_archives/promotion_tracking_dashboard.json (100%) rename x-pack/{test => }/performance/kbn_archives/reporting_dashboard.json (100%) create mode 100644 x-pack/performance/services/toasts.ts create mode 100644 x-pack/performance/tsconfig.json rename x-pack/{test => }/performance/utils.ts (67%) delete mode 100644 x-pack/test/performance/journeys/base.config.ts delete mode 100644 x-pack/test/performance/journeys/data_stress_test_lens/config.ts delete mode 100644 x-pack/test/performance/journeys/data_stress_test_lens/data_stress_test_lens.ts delete mode 100644 x-pack/test/performance/journeys/ecommerce_dashboard/config.ts delete mode 100644 x-pack/test/performance/journeys/ecommerce_dashboard/ecommerce_dashboard.ts delete mode 100644 x-pack/test/performance/journeys/flight_dashboard/config.ts delete mode 100644 x-pack/test/performance/journeys/flight_dashboard/flight_dashboard.ts delete mode 100644 x-pack/test/performance/journeys/login/config.ts delete mode 100644 x-pack/test/performance/journeys/login/login.ts delete mode 100644 x-pack/test/performance/journeys/many_fields_discover/config.ts delete mode 100644 x-pack/test/performance/journeys/many_fields_discover/many_fields_discover.ts delete mode 100644 x-pack/test/performance/journeys/promotion_tracking_dashboard/config.ts delete mode 100644 x-pack/test/performance/journeys/promotion_tracking_dashboard/promotion_tracking_dashboard.ts delete mode 100644 x-pack/test/performance/journeys/web_logs_dashboard/config.ts delete mode 100644 x-pack/test/performance/journeys/web_logs_dashboard/web_logs_dashboard.ts delete mode 100644 x-pack/test/performance/page_objects.ts delete mode 100644 x-pack/test/performance/scalability/config.ts delete mode 100644 x-pack/test/performance/services/auth.ts delete mode 100644 x-pack/test/performance/services/index.ts delete mode 100644 x-pack/test/performance/services/performance.ts create mode 100644 x-pack/test/scalability/config.ts rename x-pack/test/{performance => scalability}/ftr_provider_context.ts (79%) rename x-pack/test/{performance => }/scalability/runner.ts (95%) diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml index 3fd459ffc64c1..ebaeb6c3692b7 100644 --- a/.buildkite/ftr_configs.yml +++ b/.buildkite/ftr_configs.yml @@ -56,7 +56,7 @@ disabled: - x-pack/test/fleet_packages/config.ts # Scalability testing config that we run in its own pipeline - - x-pack/test/performance/scalability/config.ts + - x-pack/test/scalability/config.ts defaultQueue: 'n2-4-spot' enabled: @@ -267,10 +267,10 @@ enabled: - x-pack/test/ui_capabilities/spaces_only/config.ts - x-pack/test/upgrade_assistant_integration/config.js - x-pack/test/usage_collection/config.ts - - x-pack/test/performance/journeys/ecommerce_dashboard/config.ts - - x-pack/test/performance/journeys/flight_dashboard/config.ts - - x-pack/test/performance/journeys/login/config.ts - - x-pack/test/performance/journeys/many_fields_discover/config.ts - - x-pack/test/performance/journeys/promotion_tracking_dashboard/config.ts - - x-pack/test/performance/journeys/web_logs_dashboard/config.ts - - x-pack/test/performance/journeys/data_stress_test_lens/config.ts + - x-pack/performance/journeys/ecommerce_dashboard.ts + - x-pack/performance/journeys/flight_dashboard.ts + - x-pack/performance/journeys/login.ts + - x-pack/performance/journeys/many_fields_discover.ts + - x-pack/performance/journeys/promotion_tracking_dashboard.ts + - x-pack/performance/journeys/web_logs_dashboard.ts + - x-pack/performance/journeys/data_stress_test_lens.ts diff --git a/.buildkite/pipelines/performance/daily.yml b/.buildkite/pipelines/performance/daily.yml index 3e0a813adce49..10f137a5c5088 100644 --- a/.buildkite/pipelines/performance/daily.yml +++ b/.buildkite/pipelines/performance/daily.yml @@ -1,19 +1,19 @@ steps: - - label: ':male-mechanic::skin-tone-2: Pre-Build' + - label: '👨‍🔧 Pre-Build' command: .buildkite/scripts/lifecycle/pre_build.sh agents: queue: kibana-default - wait - - label: ':factory_worker: Build Kibana Distribution and Plugins' + - label: '🧑‍🏭 Build Kibana Distribution and Plugins' command: .buildkite/scripts/steps/build_kibana.sh agents: queue: c2-16 key: build if: "build.env('KIBANA_BUILD_ID') == null || build.env('KIBANA_BUILD_ID') == ''" - - label: ':muscle: Performance Tests with Playwright config' + - label: '💪 Performance Tests with Playwright config' command: .buildkite/scripts/steps/functional/performance_playwright.sh agents: queue: kb-static-ubuntu @@ -21,13 +21,13 @@ steps: key: tests timeout_in_minutes: 60 - - label: ':shipit: Performance Tests dataset extraction for scalability benchmarking' + - label: '🚢 Performance Tests dataset extraction for scalability benchmarking' command: .buildkite/scripts/steps/functional/scalability_dataset_extraction.sh agents: queue: n2-2 depends_on: tests - - label: ':chart_with_upwards_trend: Report performance metrics to ci-stats' + - label: '📈 Report performance metrics to ci-stats' command: .buildkite/scripts/steps/functional/report_performance_metrics.sh agents: queue: n2-2 @@ -36,7 +36,7 @@ steps: - wait: ~ continue_on_failure: true - - label: ':male_superhero::skin-tone-2: Post-Build' + - label: '🦸 Post-Build' command: .buildkite/scripts/lifecycle/post_build.sh agents: queue: kibana-default diff --git a/.buildkite/pull_requests.json b/.buildkite/pull_requests.json index 1c6e1ae3ce7bc..027c2de8bf915 100644 --- a/.buildkite/pull_requests.json +++ b/.buildkite/pull_requests.json @@ -42,7 +42,12 @@ "kibana_versions_check": true, "kibana_build_reuse": true, "kibana_build_reuse_pipeline_slugs": ["kibana-pull-request", "kibana-on-merge"], - "kibana_build_reuse_regexes": ["^test/", "^x-pack/test/"] + "kibana_build_reuse_regexes": [ + "^test/", + "^x-pack/test/", + "/__snapshots__/", + "\\.test\\.(ts|tsx|js|jsx)" + ] } ] } diff --git a/.buildkite/scripts/steps/functional/performance_playwright.sh b/.buildkite/scripts/steps/functional/performance_playwright.sh index adab313e4c382..cdf2e449f7a6b 100644 --- a/.buildkite/scripts/steps/functional/performance_playwright.sh +++ b/.buildkite/scripts/steps/functional/performance_playwright.sh @@ -4,16 +4,33 @@ set -euo pipefail source .buildkite/scripts/common/util.sh +is_test_execution_step + .buildkite/scripts/bootstrap.sh # These tests are running on static workers so we have to make sure we delete previous build of Kibana rm -rf "$KIBANA_BUILD_LOCATION" .buildkite/scripts/download_build_artifacts.sh -echo --- Run Performance Tests with Playwright config +echo "--- 🦺 Starting Elasticsearch" node scripts/es snapshot& +export esPid=$! +trap 'kill ${esPid}' EXIT -esPid=$! +export TEST_ES_URL=http://elastic:changeme@localhost:9200 +export TEST_ES_DISABLE_STARTUP=true + +# Pings the es server every second for up to 2 minutes until it is green +curl \ + --fail \ + --silent \ + --retry 120 \ + --retry-delay 1 \ + --retry-connrefused \ + -XGET "${TEST_ES_URL}/_cluster/health?wait_for_nodes=>=1&wait_for_status=yellow" \ + > /dev/null + +echo "✅ ES is ready and will continue to run in the background" # unset env vars defined in other parts of CI for automatic APM collection of # Kibana. We manage APM config in our FTR config and performance service, and @@ -29,39 +46,27 @@ unset ELASTIC_APM_SERVER_URL unset ELASTIC_APM_SECRET_TOKEN unset ELASTIC_APM_GLOBAL_LABELS - -export TEST_ES_URL=http://elastic:changeme@localhost:9200 -export TEST_ES_DISABLE_STARTUP=true - -# Pings the es server every seconds 2 mins until it is status is green -curl --retry 120 \ - --retry-delay 1 \ - --retry-all-errors \ - -I -XGET "${TEST_ES_URL}/_cluster/health?wait_for_nodes=>=1&wait_for_status=yellow" - -journeys=("login" "ecommerce_dashboard" "flight_dashboard" "web_logs_dashboard" "promotion_tracking_dashboard" "many_fields_discover" "data_stress_test_lens") - -for i in "${journeys[@]}"; do - echo "JOURNEY[${i}] is running" - - export TEST_PERFORMANCE_PHASE=WARMUP - export JOURNEY_NAME="${i}" - - checks-reporter-with-killswitch "Run Performance Tests with Playwright Config (Journey:${i},Phase: WARMUP)" \ - node scripts/functional_tests \ - --config "x-pack/test/performance/journeys/${i}/config.ts" \ - --kibana-install-dir "$KIBANA_BUILD_LOCATION" \ - --debug \ - --bail - - export TEST_PERFORMANCE_PHASE=TEST - - checks-reporter-with-killswitch "Run Performance Tests with Playwright Config (Journey:${i},Phase: TEST)" \ - node scripts/functional_tests \ - --config "x-pack/test/performance/journeys/${i}/config.ts" \ - --kibana-install-dir "$KIBANA_BUILD_LOCATION" \ - --debug \ - --bail +for journey in x-pack/performance/journeys/*; do + set +e + + phases=("WARMUP" "TEST") + for phase in "${phases[@]}"; do + echo "--- $journey - $phase" + + export TEST_PERFORMANCE_PHASE="$phase" + node scripts/functional_tests \ + --config "$journey" \ + --kibana-install-dir "$KIBANA_BUILD_LOCATION" \ + --debug \ + --bail + + status=$? + if [ $status -ne 0 ]; then + echo "^^^ +++" + echo "❌ FTR failed with status code: $status" + exit 1 + fi + done + + set -e done - -kill "$esPid" diff --git a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh index a8711c8d2f58a..a2b81f538b92b 100755 --- a/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh +++ b/.buildkite/scripts/steps/functional/scalability_dataset_extraction.sh @@ -15,19 +15,16 @@ OUTPUT_DIR="${KIBANA_DIR}/${OUTPUT_REL}" .buildkite/scripts/bootstrap.sh echo "--- Extract APM metrics" -scalabilityJourneys=("login" "ecommerce_dashboard" "flight_dashboard" "web_logs_dashboard" "promotion_tracking_dashboard" "many_fields_discover") - -for i in "${scalabilityJourneys[@]}"; do - JOURNEY_NAME="${i}" - echo "Looking for JOURNEY=${JOURNEY_NAME} and BUILD_ID=${BUILD_ID} in APM traces" - - node scripts/extract_performance_testing_dataset \ - --config "x-pack/test/performance/journeys/${i}/config.ts" \ - --buildId "${BUILD_ID}" \ - --es-url "${ES_SERVER_URL}" \ - --es-username "${USER_FROM_VAULT}" \ - --es-password "${PASS_FROM_VAULT}" \ - --without-static-resources +for journey in x-pack/performance/journeys/*; do + echo "Looking for journey=${journey} and BUILD_ID=${BUILD_ID} in APM traces" + + node scripts/extract_performance_testing_dataset \ + --config "${journey}" \ + --buildId "${BUILD_ID}" \ + --es-url "${ES_SERVER_URL}" \ + --es-username "${USER_FROM_VAULT}" \ + --es-password "${PASS_FROM_VAULT}" \ + --without-static-resources done echo "--- Creating scalability dataset in ${OUTPUT_REL}" diff --git a/.eslintrc.js b/.eslintrc.js index c36e8b5e7e668..df107348cfafc 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -178,6 +178,7 @@ const DEV_PATTERNS = [ 'x-pack/{dev-tools,tasks,scripts,test,build_chromium}/**/*', 'x-pack/plugins/*/server/scripts/**/*', 'x-pack/plugins/fleet/cypress', + 'x-pack/performance/**/*', ]; /** Restricted imports with suggested alternatives */ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 4d9b0f55c880f..dc7a6270638c8 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -861,9 +861,12 @@ packages/kbn-eslint-plugin-disable @elastic/kibana-operations packages/kbn-eslint-plugin-eslint @elastic/kibana-operations packages/kbn-eslint-plugin-imports @elastic/kibana-operations packages/kbn-expect @elastic/kibana-operations +packages/kbn-failed-test-reporter-cli @elastic/kibana-operations packages/kbn-field-types @elastic/kibana-app-services packages/kbn-find-used-node-modules @elastic/kibana-operations packages/kbn-flot-charts @elastic/kibana-operations +packages/kbn-ftr-common-functional-services @elastic/kibana-operations +packages/kbn-ftr-screenshot-filename @elastic/kibana-operations packages/kbn-generate @elastic/kibana-operations packages/kbn-get-repo-files @elastic/kibana-operations packages/kbn-handlebars @elastic/kibana-security @@ -874,6 +877,7 @@ packages/kbn-import-resolver @elastic/kibana-operations packages/kbn-interpreter @elastic/kibana-app-services packages/kbn-io-ts-utils @elastic/apm-ui packages/kbn-jest-serializers @elastic/kibana-operations +packages/kbn-journeys @elastic/kibana-operations packages/kbn-kibana-manifest-schema @elastic/kibana-operations packages/kbn-logging @elastic/kibana-core packages/kbn-logging-mocks @elastic/kibana-core diff --git a/dev_docs/operations/operations_landing.mdx b/dev_docs/operations/operations_landing.mdx index 88e4be9eb93a3..9004141255f58 100644 --- a/dev_docs/operations/operations_landing.mdx +++ b/dev_docs/operations/operations_landing.mdx @@ -26,6 +26,7 @@ layout: landing { pageId: "kibDevDocsOpsWritingStableFunctionalTests" }, { pageId: "kibDevDocsOpsFlakyTestRunner" }, { pageId: "kibDevDocsOpsCiStats" }, + { pageId: "kibDevDocsOpsJourneys" }, ]} /> diff --git a/package.json b/package.json index c257e1a46fc9a..7c8a27447d4c0 100644 --- a/package.json +++ b/package.json @@ -702,11 +702,15 @@ "@kbn/eslint-plugin-eslint": "link:bazel-bin/packages/kbn-eslint-plugin-eslint", "@kbn/eslint-plugin-imports": "link:bazel-bin/packages/kbn-eslint-plugin-imports", "@kbn/expect": "link:bazel-bin/packages/kbn-expect", + "@kbn/failed-test-reporter-cli": "link:bazel-bin/packages/kbn-failed-test-reporter-cli", "@kbn/find-used-node-modules": "link:bazel-bin/packages/kbn-find-used-node-modules", + "@kbn/ftr-common-functional-services": "link:bazel-bin/packages/kbn-ftr-common-functional-services", + "@kbn/ftr-screenshot-filename": "link:bazel-bin/packages/kbn-ftr-screenshot-filename", "@kbn/generate": "link:bazel-bin/packages/kbn-generate", "@kbn/get-repo-files": "link:bazel-bin/packages/kbn-get-repo-files", "@kbn/import-resolver": "link:bazel-bin/packages/kbn-import-resolver", "@kbn/jest-serializers": "link:bazel-bin/packages/kbn-jest-serializers", + "@kbn/journeys": "link:bazel-bin/packages/kbn-journeys", "@kbn/kibana-manifest-schema": "link:bazel-bin/packages/kbn-kibana-manifest-schema", "@kbn/managed-vscode-config": "link:bazel-bin/packages/kbn-managed-vscode-config", "@kbn/managed-vscode-config-cli": "link:bazel-bin/packages/kbn-managed-vscode-config-cli", @@ -1017,8 +1021,11 @@ "@types/kbn__es-types": "link:bazel-bin/packages/kbn-es-types/npm_module_types", "@types/kbn__eslint-plugin-disable": "link:bazel-bin/packages/kbn-eslint-plugin-disable/npm_module_types", "@types/kbn__eslint-plugin-imports": "link:bazel-bin/packages/kbn-eslint-plugin-imports/npm_module_types", + "@types/kbn__failed-test-reporter-cli": "link:bazel-bin/packages/kbn-failed-test-reporter-cli/npm_module_types", "@types/kbn__field-types": "link:bazel-bin/packages/kbn-field-types/npm_module_types", "@types/kbn__find-used-node-modules": "link:bazel-bin/packages/kbn-find-used-node-modules/npm_module_types", + "@types/kbn__ftr-common-functional-services": "link:bazel-bin/packages/kbn-ftr-common-functional-services/npm_module_types", + "@types/kbn__ftr-screenshot-filename": "link:bazel-bin/packages/kbn-ftr-screenshot-filename/npm_module_types", "@types/kbn__generate": "link:bazel-bin/packages/kbn-generate/npm_module_types", "@types/kbn__get-repo-files": "link:bazel-bin/packages/kbn-get-repo-files/npm_module_types", "@types/kbn__handlebars": "link:bazel-bin/packages/kbn-handlebars/npm_module_types", @@ -1032,6 +1039,7 @@ "@types/kbn__interpreter": "link:bazel-bin/packages/kbn-interpreter/npm_module_types", "@types/kbn__io-ts-utils": "link:bazel-bin/packages/kbn-io-ts-utils/npm_module_types", "@types/kbn__jest-serializers": "link:bazel-bin/packages/kbn-jest-serializers/npm_module_types", + "@types/kbn__journeys": "link:bazel-bin/packages/kbn-journeys/npm_module_types", "@types/kbn__kbn-ci-stats-performance-metrics": "link:bazel-bin/packages/kbn-kbn-ci-stats-performance-metrics/npm_module_types", "@types/kbn__kibana-manifest-schema": "link:bazel-bin/packages/kbn-kibana-manifest-schema/npm_module_types", "@types/kbn__logging": "link:bazel-bin/packages/kbn-logging/npm_module_types", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 56ef73801d5a9..d6994772c9ef2 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -204,9 +204,12 @@ filegroup( "//packages/kbn-eslint-plugin-eslint:build", "//packages/kbn-eslint-plugin-imports:build", "//packages/kbn-expect:build", + "//packages/kbn-failed-test-reporter-cli:build", "//packages/kbn-field-types:build", "//packages/kbn-find-used-node-modules:build", "//packages/kbn-flot-charts:build", + "//packages/kbn-ftr-common-functional-services:build", + "//packages/kbn-ftr-screenshot-filename:build", "//packages/kbn-generate:build", "//packages/kbn-get-repo-files:build", "//packages/kbn-handlebars:build", @@ -217,6 +220,7 @@ filegroup( "//packages/kbn-interpreter:build", "//packages/kbn-io-ts-utils:build", "//packages/kbn-jest-serializers:build", + "//packages/kbn-journeys:build", "//packages/kbn-kibana-manifest-schema:build", "//packages/kbn-logging:build", "//packages/kbn-logging-mocks:build", @@ -514,8 +518,11 @@ filegroup( "//packages/kbn-es-types:build_types", "//packages/kbn-eslint-plugin-disable:build_types", "//packages/kbn-eslint-plugin-imports:build_types", + "//packages/kbn-failed-test-reporter-cli:build_types", "//packages/kbn-field-types:build_types", "//packages/kbn-find-used-node-modules:build_types", + "//packages/kbn-ftr-common-functional-services:build_types", + "//packages/kbn-ftr-screenshot-filename:build_types", "//packages/kbn-generate:build_types", "//packages/kbn-get-repo-files:build_types", "//packages/kbn-handlebars:build_types", @@ -526,6 +533,7 @@ filegroup( "//packages/kbn-interpreter:build_types", "//packages/kbn-io-ts-utils:build_types", "//packages/kbn-jest-serializers:build_types", + "//packages/kbn-journeys:build_types", "//packages/kbn-kibana-manifest-schema:build_types", "//packages/kbn-logging:build_types", "//packages/kbn-logging-mocks:build_types", diff --git a/packages/kbn-dev-cli-runner/index.ts b/packages/kbn-dev-cli-runner/index.ts index aa56ab0e976ce..0bc2b64c64d7c 100644 --- a/packages/kbn-dev-cli-runner/index.ts +++ b/packages/kbn-dev-cli-runner/index.ts @@ -9,4 +9,5 @@ export * from './src/run'; export * from './src/run_with_commands'; export * from './src/flags'; +export * from './src/flags_reader'; export type { CleanupTask } from './src/cleanup'; diff --git a/packages/kbn-dev-cli-runner/src/flags.ts b/packages/kbn-dev-cli-runner/src/flags.ts index 919da586f7ba6..595205c3e0333 100644 --- a/packages/kbn-dev-cli-runner/src/flags.ts +++ b/packages/kbn-dev-cli-runner/src/flags.ts @@ -53,6 +53,10 @@ export function mergeFlagOptions(global: FlagOptions = {}, local: FlagOptions = }; } +export const DEFAULT_FLAG_ALIASES = { + v: 'verbose', +}; + export function getFlags( argv: string[], flagOptions: RunOptions['flags'] = {}, @@ -67,7 +71,7 @@ export function getFlags( boolean: [...(flagOptions.boolean || []), ...logLevelFlags, 'help'], alias: { ...flagOptions.alias, - v: 'verbose', + ...DEFAULT_FLAG_ALIASES, }, default: flagOptions.default, unknown: (name: string) => { diff --git a/packages/kbn-dev-cli-runner/src/flags_reader.test.ts b/packages/kbn-dev-cli-runner/src/flags_reader.test.ts new file mode 100644 index 0000000000000..bef3339c5b27a --- /dev/null +++ b/packages/kbn-dev-cli-runner/src/flags_reader.test.ts @@ -0,0 +1,344 @@ +/* + * 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 { createAbsolutePathSerializer } from '@kbn/jest-serializers'; + +import { getFlags } from './flags'; +import { FlagsReader } from './flags_reader'; + +const FLAGS = { + string: 'string', + astring: ['foo', 'bar'], + num: '1234', + bool: true, + missing: undefined, +}; + +const basic = new FlagsReader(FLAGS); + +expect.addSnapshotSerializer(createAbsolutePathSerializer()); + +describe('#string()', () => { + it('returns a single string, regardless of flag count', () => { + expect(basic.string('string')).toMatchInlineSnapshot(`"string"`); + expect(basic.string('astring')).toBe(FLAGS.astring.at(-1)); + }); + + it('returns undefined when flag is missing', () => { + expect(basic.string('missing')).toMatchInlineSnapshot(`undefined`); + }); + + it('throws for non-string flags', () => { + expect(() => basic.string('bool')).toThrowErrorMatchingInlineSnapshot( + `"expected --bool to be a string"` + ); + }); + + describe('required version', () => { + it('throws when flag is missing', () => { + expect(() => basic.requiredString('missing')).toThrowErrorMatchingInlineSnapshot( + `"missing required flag --missing"` + ); + }); + }); +}); + +describe('#arrayOfStrings()', () => { + it('returns an array of strings for string flags, regardless of count', () => { + expect(basic.arrayOfStrings('string')).toMatchInlineSnapshot(` + Array [ + "string", + ] + `); + expect(basic.arrayOfStrings('astring')).toMatchInlineSnapshot(` + Array [ + "foo", + "bar", + ] + `); + }); + + it('returns undefined when flag is missing', () => { + expect(basic.arrayOfStrings('missing')).toMatchInlineSnapshot(`undefined`); + }); + + it('throws for non-string flags', () => { + expect(() => basic.arrayOfStrings('bool')).toThrowErrorMatchingInlineSnapshot( + `"expected --bool to be a string"` + ); + }); + + describe('required version', () => { + it('throws when flag is missing', () => { + expect(() => basic.requiredArrayOfStrings('missing')).toThrowErrorMatchingInlineSnapshot( + `"missing required flag --missing"` + ); + }); + }); +}); + +describe('#enum()', () => { + it('validates that values match options', () => { + expect(basic.enum('string', ['a', 'string', 'b'])).toMatchInlineSnapshot(`"string"`); + expect(basic.enum('missing', ['a', 'b'])).toMatchInlineSnapshot(`undefined`); + expect(() => basic.enum('string', ['a', 'b'])).toThrowErrorMatchingInlineSnapshot( + `"invalid --string, expected one of \\"a\\", \\"b\\""` + ); + }); +}); + +describe('#path()', () => { + it('parses the string to an absolute path based on CWD', () => { + expect(basic.path('string')).toMatchInlineSnapshot(`/string`); + expect(basic.path('missing')).toMatchInlineSnapshot(`undefined`); + }); + + describe('required version', () => { + it('throws if the flag is missing', () => { + expect(() => basic.requiredPath('missing')).toThrowErrorMatchingInlineSnapshot( + `"missing required flag --missing"` + ); + }); + }); + + describe('array version', () => { + it('parses a list of paths', () => { + expect(basic.arrayOfPaths('astring')).toMatchInlineSnapshot(` + Array [ + /foo, + /bar, + ] + `); + }); + + describe('required version', () => { + it('throws if the flag is missing', () => { + expect(() => basic.requiredArrayOfPaths('missing')).toThrowErrorMatchingInlineSnapshot( + `"missing required flag --missing"` + ); + }); + }); + }); +}); + +describe('#number()', () => { + it('parses strings as numbers', () => { + expect(basic.number('num')).toMatchInlineSnapshot(`1234`); + expect(basic.number('missing')).toMatchInlineSnapshot(`undefined`); + expect(() => basic.number('bool')).toThrowErrorMatchingInlineSnapshot( + `"expected --bool to be a string"` + ); + expect(() => basic.number('string')).toThrowErrorMatchingInlineSnapshot( + `"unable to parse --string value [string] as a number"` + ); + expect(() => basic.number('astring')).toThrowErrorMatchingInlineSnapshot( + `"unable to parse --astring value [bar] as a number"` + ); + }); + + describe('required version', () => { + it('throws if the flag is missing', () => { + expect(() => basic.requiredNumber('missing')).toThrowErrorMatchingInlineSnapshot( + `"missing required flag --missing"` + ); + }); + }); +}); + +describe('#boolean()', () => { + it('ensures flag is boolean, requires value', () => { + expect(basic.boolean('bool')).toMatchInlineSnapshot(`true`); + expect(() => basic.boolean('missing')).toThrowErrorMatchingInlineSnapshot( + `"expected --missing to be a boolean"` + ); + expect(() => basic.boolean('string')).toThrowErrorMatchingInlineSnapshot( + `"expected --string to be a boolean"` + ); + expect(() => basic.boolean('astring')).toThrowErrorMatchingInlineSnapshot( + `"expected --astring to be a boolean"` + ); + }); +}); + +describe('#getPositionals()', () => { + it('returns all positional arguments in flags', () => { + const flags = new FlagsReader({ + ...FLAGS, + _: ['a', 'b', 'c'], + }); + + expect(flags.getPositionals()).toMatchInlineSnapshot(` + Array [ + "a", + "b", + "c", + ] + `); + }); + + it('handles missing _ flag', () => { + const flags = new FlagsReader({}); + expect(flags.getPositionals()).toMatchInlineSnapshot(`Array []`); + }); +}); + +describe('#getUnused()', () => { + it('returns a map of all unused flags', () => { + const flags = new FlagsReader({ + a: '1', + b: '2', + c: '3', + }); + + expect(flags.getUnused()).toMatchInlineSnapshot(` + Map { + "a" => "1", + "b" => "2", + "c" => "3", + } + `); + + flags.number('a'); + flags.number('b'); + + expect(flags.getUnused()).toMatchInlineSnapshot(` + Map { + "c" => "3", + } + `); + }); + + it('ignores the default flags which are forced on commands', () => { + const rawFlags = getFlags(['--a=1'], { + string: ['a'], + }); + + const flags = new FlagsReader(rawFlags, { + aliases: { + v: 'verbose', + }, + }); + + expect(flags.getUnused()).toMatchInlineSnapshot(` + Map { + "a" => "1", + } + `); + flags.number('a'); + expect(flags.getUnused()).toMatchInlineSnapshot(`Map {}`); + }); + + it('treats aliased flags as used', () => { + const flags = new FlagsReader( + { + f: true, + force: true, + v: true, + verbose: true, + }, + { + aliases: { + f: 'force', + v: 'verbose', + }, + } + ); + + expect(flags.getUnused()).toMatchInlineSnapshot(` + Map { + "f" => true, + "force" => true, + } + `); + flags.boolean('force'); + expect(flags.getUnused()).toMatchInlineSnapshot(`Map {}`); + flags.boolean('v'); + expect(flags.getUnused()).toMatchInlineSnapshot(`Map {}`); + }); + + it('treats failed reads as "uses"', () => { + const flags = new FlagsReader({ a: 'b' }); + + expect(flags.getUnused()).toMatchInlineSnapshot(` + Map { + "a" => "b", + } + `); + expect(() => flags.number('a')).toThrowError(); + expect(flags.getUnused()).toMatchInlineSnapshot(`Map {}`); + }); +}); + +describe('#getUsed()', () => { + it('returns a map of all used flags', () => { + const flags = new FlagsReader({ + a: '1', + b: '2', + c: '3', + }); + + expect(flags.getUsed()).toMatchInlineSnapshot(`Map {}`); + + flags.number('a'); + flags.number('b'); + + expect(flags.getUsed()).toMatchInlineSnapshot(` + Map { + "a" => "1", + "b" => "2", + } + `); + }); + + it('treats aliases flags as used', () => { + const flags = new FlagsReader( + { + f: true, + force: true, + v: true, + verbose: true, + }, + { + aliases: { + f: 'force', + v: 'verbose', + }, + } + ); + + expect(flags.getUsed()).toMatchInlineSnapshot(`Map {}`); + flags.boolean('force'); + expect(flags.getUsed()).toMatchInlineSnapshot(` + Map { + "force" => true, + "f" => true, + } + `); + flags.boolean('v'); + expect(flags.getUsed()).toMatchInlineSnapshot(` + Map { + "force" => true, + "f" => true, + "v" => true, + "verbose" => true, + } + `); + }); + + it('treats failed reads as "uses"', () => { + const flags = new FlagsReader({ a: 'b' }); + + expect(flags.getUsed()).toMatchInlineSnapshot(`Map {}`); + expect(() => flags.number('a')).toThrowError(); + expect(flags.getUsed()).toMatchInlineSnapshot(` + Map { + "a" => "b", + } + `); + }); +}); diff --git a/packages/kbn-dev-cli-runner/src/flags_reader.ts b/packages/kbn-dev-cli-runner/src/flags_reader.ts new file mode 100644 index 0000000000000..156f1a4fba32b --- /dev/null +++ b/packages/kbn-dev-cli-runner/src/flags_reader.ts @@ -0,0 +1,267 @@ +/* + * 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 Path from 'path'; + +import { createFlagError } from '@kbn/dev-cli-errors'; +import { LOG_LEVEL_FLAGS } from '@kbn/tooling-log'; + +type FlagValue = string | string[] | boolean; +const FORCED_FLAGS = new Set([...LOG_LEVEL_FLAGS.map((l) => l.name), 'help']); + +const makeAbsolute = (rel: string) => Path.resolve(process.cwd(), rel); + +const nonUndefinedValues = (e: [string, FlagValue | undefined]): e is [string, FlagValue] => + e[1] !== undefined; + +export class FlagsReader { + private readonly used: Map; + private readonly unused: Map; + private readonly _: string[]; + private readonly aliasMap: Map; + + constructor( + flags: Record, + private readonly opts?: { aliases?: Record } + ) { + this.used = new Map(); + this.unused = new Map( + Object.entries(flags) + .filter(nonUndefinedValues) + .filter((e) => e[0] !== 'unexpected') + ); + this.aliasMap = new Map( + Object.entries(this.opts?.aliases ?? []).flatMap(([a, b]) => [ + [a, b], + [b, a], + ]) + ); + + this._ = this.arrayOfStrings('_') ?? []; + } + + private use(key: string) { + const alias = this.aliasMap.get(key); + + const used = this.used.get(key); + if (used !== undefined) { + return used; + } + + const unused = this.unused.get(key); + if (unused !== undefined) { + this.used.set(key, unused); + this.unused.delete(key); + + if (alias !== undefined) { + this.used.set(alias, unused); + this.unused.delete(alias); + } + } + + return unused; + } + + /** + * Read a string flag that supports multiple instances into an array of strings. If the + * flag is only passed once an array with a single item will be returned. If the flag is not + * passed then undefined will be returned. + */ + arrayOfStrings(key: string) { + const value = this.use(key); + + switch (typeof value) { + case 'boolean': + throw createFlagError(`expected --${key} to be a string`); + case 'string': + return value ? [value] : []; + default: + return value; + } + } + + /** + * Same as #arrayOfStrings() except when the flag is not passed a "flag error" is thrown telling + * the user that the flag is required and shows them the help text. + */ + requiredArrayOfStrings(key: string) { + const value = this.arrayOfStrings(key); + if (value === undefined) { + throw createFlagError(`missing required flag --${key}`); + } + return value; + } + + /** + * Read the value of a string flag. If the flag is passed multiple times the last value is returned. If + * the flag is not passed then undefined is returned. + */ + string(key: string) { + const value = this.use(key); + + switch (typeof value) { + case 'undefined': + return undefined; + case 'string': + return value || undefined; // convert "" to undefined + case 'object': + const last = value.at(-1); + if (last === undefined) { + throw createFlagError(`expected --${key} to be a string`); + } + return last || undefined; // convert "" to undefined + default: + throw createFlagError(`expected --${key} to be a string`); + } + } + + /** + * Same as #string() except when the flag is passed it is validated against a list + * of valid values + */ + enum(key: string, values: readonly T[]) { + const value = this.string(key); + if (value === undefined) { + return; + } + + if (values.includes(value as T)) { + return value as T; + } + + throw createFlagError(`invalid --${key}, expected one of "${values.join('", "')}"`); + } + + /** + * Same as #string() except when a flag is not passed a "flag error" is thrown telling the user + * that the flag is required and shows them the help text. + */ + requiredString(key: string) { + const value = this.string(key); + if (value === undefined) { + throw createFlagError(`missing required flag --${key}`); + } + return value; + } + + /** + * Same as #string(), except that when there is a value for the string it is resolved to an + * absolute path based on the current working directory + */ + path(key: string) { + const value = this.string(key); + if (value !== undefined) { + return makeAbsolute(value); + } + } + + /** + * Same as #requiredString() except that values are converted to absolute paths based on the + * current working directory + */ + requiredPath(key: string) { + return makeAbsolute(this.requiredString(key)); + } + + /** + * Same as #arrayOfStrings(), except that when there are values they are resolved to + * absolute paths based on the current working directory + */ + arrayOfPaths(key: string) { + const value = this.arrayOfStrings(key); + if (value !== undefined) { + return value.map(makeAbsolute); + } + } + + /** + * Same as #requiredArrayOfStrings(), except that values are resolved to absolute paths + * based on the current working directory + */ + requiredArrayOfPaths(key: string) { + return this.requiredArrayOfStrings(key).map(makeAbsolute); + } + + /** + * Parsed the provided flag as a number, if the value does not parse to a valid number + * using Number.parseFloat() then a "flag error" is thrown. If the flag is not passed + * undefined is returned. + */ + number(key: string) { + const value = this.string(key); + if (value === undefined) { + return; + } + + const num = Number.parseFloat(value); + if (Number.isNaN(num)) { + throw createFlagError(`unable to parse --${key} value [${value}] as a number`); + } + + return num; + } + + /** + * Same as #number() except that when the flag is missing a "flag error" is thrown + */ + requiredNumber(key: string) { + const value = this.number(key); + if (value === undefined) { + throw createFlagError(`missing required flag --${key}`); + } + return value; + } + + /** + * Read a boolean flag value, if the flag is properly defined as a "boolean" in the run options + * then the value will always be a boolean, defaulting to `false`, so there is no need for an + * optional/requiredBoolean() method. + */ + boolean(key: string) { + const value = this.use(key); + if (typeof value !== 'boolean') { + throw createFlagError(`expected --${key} to be a boolean`); + } + return value; + } + + /** + * Get the positional arguments passed, includes any values that are not associated with + * a specific --flag + */ + getPositionals() { + return this._.slice(0); + } + + /** + * Returns all of the unused flags. When a flag is read via any of the key-specific methods + * the key is marked as "used" and this method will return a map of just the flags which + * have not been used yet (excluding the default flags like --debug, --verbose, and --help) + */ + getUnused() { + return new Map( + [...this.unused.entries()].filter(([key]) => { + const alias = this.aliasMap.get(key); + if (alias !== undefined && FORCED_FLAGS.has(alias)) { + return false; + } + + return !FORCED_FLAGS.has(key); + }) + ); + } + + /** + * Returns all of the used flags. When a flag is read via any of the key-specific methods + * the key is marked as "used" and from then on this method will return a map including that + * and any other key used by these methods. + */ + getUsed() { + return new Map(this.used); + } +} diff --git a/packages/kbn-dev-cli-runner/src/run.ts b/packages/kbn-dev-cli-runner/src/run.ts index bbccfdde564f8..08457caaebfd4 100644 --- a/packages/kbn-dev-cli-runner/src/run.ts +++ b/packages/kbn-dev-cli-runner/src/run.ts @@ -10,7 +10,8 @@ import { pickLevelFromFlags, ToolingLog, LogLevel } from '@kbn/tooling-log'; import { ProcRunner, withProcRunner } from '@kbn/dev-proc-runner'; import { createFlagError } from '@kbn/dev-cli-errors'; -import { Flags, getFlags, FlagOptions } from './flags'; +import { Flags, getFlags, FlagOptions, DEFAULT_FLAG_ALIASES } from './flags'; +import { FlagsReader } from './flags_reader'; import { getHelp } from './help'; import { CleanupTask, Cleanup } from './cleanup'; import { Metrics, MetricsMeta } from './metrics'; @@ -21,6 +22,7 @@ export interface RunContext { procRunner: ProcRunner; statsMeta: MetricsMeta; addCleanupTask: (task: CleanupTask) => void; + flagsReader: FlagsReader; } export type RunFn = (context: RunContext) => Promise | void; @@ -71,6 +73,12 @@ export async function run(fn: RunFn, options: RunOptions = {}) { procRunner, statsMeta: metrics.meta, addCleanupTask: cleanup.add.bind(cleanup), + flagsReader: new FlagsReader(flags, { + aliases: { + ...options.flags?.alias, + ...DEFAULT_FLAG_ALIASES, + }, + }), }); }); } catch (error) { diff --git a/packages/kbn-dev-cli-runner/src/run_with_commands.test.ts b/packages/kbn-dev-cli-runner/src/run_with_commands.test.ts index c740087b40c30..329e858b08f5e 100644 --- a/packages/kbn-dev-cli-runner/src/run_with_commands.test.ts +++ b/packages/kbn-dev-cli-runner/src/run_with_commands.test.ts @@ -9,6 +9,7 @@ import { ToolingLog, ToolingLogCollectingWriter } from '@kbn/tooling-log'; import { ProcRunner } from '@kbn/dev-proc-runner'; +import { FlagsReader } from './flags_reader'; import { RunWithCommands } from './run_with_commands'; const testLog = new ToolingLog(); @@ -44,6 +45,7 @@ it('extends the context using extendContext()', async () => { expect(context).toEqual({ log: expect.any(ToolingLog), flags: expect.any(Object), + flagsReader: expect.any(FlagsReader), addCleanupTask: expect.any(Function), procRunner: expect.any(ProcRunner), statsMeta: expect.any(Map), diff --git a/packages/kbn-dev-cli-runner/src/run_with_commands.ts b/packages/kbn-dev-cli-runner/src/run_with_commands.ts index 94b167671d21b..ff93f29f4c631 100644 --- a/packages/kbn-dev-cli-runner/src/run_with_commands.ts +++ b/packages/kbn-dev-cli-runner/src/run_with_commands.ts @@ -11,7 +11,8 @@ import { withProcRunner } from '@kbn/dev-proc-runner'; import { createFlagError } from '@kbn/dev-cli-errors'; import { RunContext, RunOptions } from './run'; -import { getFlags, FlagOptions, mergeFlagOptions } from './flags'; +import { getFlags, FlagOptions, mergeFlagOptions, DEFAULT_FLAG_ALIASES } from './flags'; +import { FlagsReader } from './flags_reader'; import { Cleanup } from './cleanup'; import { getHelpForAllCommands, getCommandLevelHelp } from './help'; import { Metrics } from './metrics'; @@ -116,6 +117,12 @@ export class RunWithCommands { procRunner, statsMeta: metrics.meta, addCleanupTask: cleanup.add.bind(cleanup), + flagsReader: new FlagsReader(commandFlags, { + aliases: { + ...commandFlagOptions.alias, + ...DEFAULT_FLAG_ALIASES, + }, + }), }; const extendedContext = { diff --git a/packages/kbn-failed-test-reporter-cli/BUILD.bazel b/packages/kbn-failed-test-reporter-cli/BUILD.bazel new file mode 100644 index 0000000000000..a3ae8903169a3 --- /dev/null +++ b/packages/kbn-failed-test-reporter-cli/BUILD.bazel @@ -0,0 +1,145 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "kbn-failed-test-reporter-cli" +PKG_REQUIRE_NAME = "@kbn/failed-test-reporter-cli" + +SOURCE_FILES = glob( + [ + "**/*.ts", + "**/*.html", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__/**", + "**/integration_tests/**", + "**/mocks/**", + "**/scripts/**", + "**/storybook/**", + "**/test_fixtures/**", + "**/test_helpers/**", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ +] + +# In this array place dependencies necessary to build the types, which will include the +# :npm_module_types target of other packages and packages from NPM, including @types/* +# packages. +# +# To reference the types for another package use: +# "//repo/relative/path/to/package:npm_module_types" +# eg. "//packages/kbn-utils:npm_module_types" +# +# References to NPM packages work the same as RUNTIME_DEPS +TYPES_DEPS = [ + "//packages/kbn-utils:npm_module_types", + "//packages/kbn-ci-stats-reporter:npm_module_types", + "//packages/kbn-dev-cli-runner:npm_module_types", + "//packages/kbn-dev-cli-errors:npm_module_types", + "//packages/kbn-dev-utils:npm_module_types", + "//packages/kbn-tooling-log:npm_module_types", + "//packages/kbn-ftr-screenshot-filename:npm_module_types", + "//packages/kbn-jest-serializers:npm_module_types", + "//packages/kbn-journeys:npm_module_types", + "@npm//@elastic/elasticsearch", + "@npm//@types/node", + "@npm//@types/he", + "@npm//@types/jest", + "@npm//@types/strip-ansi", + "@npm//@types/normalize-path", + "@npm//@types/xml2js", + "@npm//axios", + "@npm//dedent", + "@npm//globby", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), + additional_args = [ + "--copy-files" + ], +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-failed-test-reporter-cli/README.md b/packages/kbn-failed-test-reporter-cli/README.md new file mode 100644 index 0000000000000..d577a58dfb856 --- /dev/null +++ b/packages/kbn-failed-test-reporter-cli/README.md @@ -0,0 +1,3 @@ +# @kbn/failed-test-reporter-cli + +Empty package generated by @kbn/generate diff --git a/packages/kbn-test/src/failed_tests_reporter/README.md b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/README.md similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/README.md rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/README.md diff --git a/packages/kbn-test/src/failed_tests_reporter/__fixtures__/cypress_report.xml b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/cypress_report.xml similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/__fixtures__/cypress_report.xml rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/cypress_report.xml diff --git a/packages/kbn-test/src/failed_tests_reporter/__fixtures__/ftr_report.xml b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/ftr_report.xml similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/__fixtures__/ftr_report.xml rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/ftr_report.xml diff --git a/packages/kbn-test/src/failed_tests_reporter/__fixtures__/index.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/index.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/__fixtures__/index.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/index.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/__fixtures__/jest_report.xml b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/jest_report.xml similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/__fixtures__/jest_report.xml rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/jest_report.xml diff --git a/packages/kbn-test/src/failed_tests_reporter/__fixtures__/mocha_report.xml b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/mocha_report.xml similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/__fixtures__/mocha_report.xml rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/__fixtures__/mocha_report.xml diff --git a/packages/kbn-test/src/failed_tests_reporter/add_messages_to_report.test.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/add_messages_to_report.test.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/add_messages_to_report.test.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/add_messages_to_report.test.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/add_messages_to_report.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/add_messages_to_report.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/add_messages_to_report.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/add_messages_to_report.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/buildkite_metadata.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/buildkite_metadata.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/buildkite_metadata.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/buildkite_metadata.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/es_config b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/es_config similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/es_config rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/es_config diff --git a/packages/kbn-test/src/failed_tests_reporter/existing_failed_test_issues.test.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/existing_failed_test_issues.test.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/existing_failed_test_issues.test.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/existing_failed_test_issues.test.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/existing_failed_test_issues.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/existing_failed_test_issues.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/existing_failed_test_issues.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/existing_failed_test_issues.ts diff --git a/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/failed_tests_reporter_cli.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/failed_tests_reporter_cli.ts new file mode 100644 index 0000000000000..b105b6d80ac37 --- /dev/null +++ b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/failed_tests_reporter_cli.ts @@ -0,0 +1,208 @@ +/* + * 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 Path from 'path'; + +import { REPO_ROOT } from '@kbn/utils'; +import { run } from '@kbn/dev-cli-runner'; +import { createFailError, createFlagError } from '@kbn/dev-cli-errors'; +import { CiStatsReporter } from '@kbn/ci-stats-reporter'; +import globby from 'globby'; +import normalize from 'normalize-path'; + +import { getFailures } from './get_failures'; +import { GithubApi } from './github_api'; +import { updateFailureIssue, createFailureIssue } from './report_failure'; +import { readTestReport, getRootMetadata } from './test_report'; +import { addMessagesToReport } from './add_messages_to_report'; +import { getReportMessageIter } from './report_metadata'; +import { reportFailuresToEs } from './report_failures_to_es'; +import { reportFailuresToFile } from './report_failures_to_file'; +import { getBuildkiteMetadata } from './buildkite_metadata'; +import { ExistingFailedTestIssues } from './existing_failed_test_issues'; + +const DEFAULT_PATTERNS = [Path.resolve(REPO_ROOT, 'target/junit/**/*.xml')]; +const DISABLE_MISSING_TEST_REPORT_ERRORS = + process.env.DISABLE_MISSING_TEST_REPORT_ERRORS === 'true'; + +run( + async ({ log, flags }) => { + const indexInEs = flags['index-errors']; + + let updateGithub = flags['github-update']; + if (updateGithub && !process.env.GITHUB_TOKEN) { + throw createFailError( + 'GITHUB_TOKEN environment variable must be set, otherwise use --no-github-update flag' + ); + } + + let branch: string = ''; + if (updateGithub) { + let isPr = false; + + if (process.env.BUILDKITE === 'true') { + branch = process.env.BUILDKITE_BRANCH || ''; + isPr = process.env.BUILDKITE_PULL_REQUEST === 'true'; + updateGithub = process.env.REPORT_FAILED_TESTS_TO_GITHUB === 'true'; + } else { + // JOB_NAME is formatted as `elastic+kibana+7.x` in some places and `elastic+kibana+7.x/JOB=kibana-intake,node=immutable` in others + const jobNameSplit = (process.env.JOB_NAME || '').split(/\+|\//); + branch = jobNameSplit.length >= 3 ? jobNameSplit[2] : process.env.GIT_BRANCH || ''; + isPr = !!process.env.ghprbPullId; + + const isMainOrVersion = branch === 'main' || branch.match(/^\d+\.(x|\d+)$/); + if (!isMainOrVersion || isPr) { + log.info('Failure issues only created on main/version branch jobs'); + updateGithub = false; + } + } + + if (!branch) { + throw createFailError( + 'Unable to determine originating branch from job name or other environment variables' + ); + } + } + + const githubApi = new GithubApi({ + log, + token: process.env.GITHUB_TOKEN, + dryRun: !updateGithub, + }); + + const bkMeta = getBuildkiteMetadata(); + + try { + const buildUrl = flags['build-url'] || (updateGithub ? '' : 'http://buildUrl'); + if (typeof buildUrl !== 'string' || !buildUrl) { + throw createFlagError('Missing --build-url or process.env.BUILD_URL'); + } + + const patterns = (flags._.length ? flags._ : DEFAULT_PATTERNS).map((p) => + normalize(Path.resolve(p)) + ); + log.info('Searching for reports at', patterns); + const reportPaths = await globby(patterns, { + absolute: true, + }); + + if (!reportPaths.length && DISABLE_MISSING_TEST_REPORT_ERRORS) { + // it is fine for code coverage to not have test results + return; + } + + if (!reportPaths.length) { + throw createFailError(`Unable to find any junit reports with patterns [${patterns}]`); + } + + log.info('found', reportPaths.length, 'junit reports', reportPaths); + + const existingIssues = new ExistingFailedTestIssues(log); + for (const reportPath of reportPaths) { + const report = await readTestReport(reportPath); + const messages = Array.from(getReportMessageIter(report)); + const failures = getFailures(report); + + await existingIssues.loadForFailures(failures); + + if (indexInEs) { + await reportFailuresToEs(log, failures); + } + + for (const failure of failures) { + const pushMessage = (msg: string) => { + messages.push({ + classname: failure.classname, + name: failure.name, + message: msg, + }); + }; + + if (failure.likelyIrrelevant) { + pushMessage( + 'Failure is likely irrelevant' + + (updateGithub ? ', so an issue was not created or updated' : '') + ); + continue; + } + + const existingIssue = existingIssues.getForFailure(failure); + if (existingIssue) { + const { newBody, newCount } = await updateFailureIssue( + buildUrl, + existingIssue, + githubApi, + branch + ); + const url = existingIssue.github.htmlUrl; + existingIssue.github.body = newBody; + failure.githubIssue = url; + failure.failureCount = updateGithub ? newCount : newCount - 1; + pushMessage(`Test has failed ${newCount - 1} times on tracked branches: ${url}`); + if (updateGithub) { + pushMessage(`Updated existing issue: ${url} (fail count: ${newCount})`); + } + continue; + } + + const newIssue = await createFailureIssue(buildUrl, failure, githubApi, branch); + existingIssues.addNewlyCreated(failure, newIssue); + pushMessage('Test has not failed recently on tracked branches'); + if (updateGithub) { + pushMessage(`Created new issue: ${newIssue.html_url}`); + failure.githubIssue = newIssue.html_url; + } + failure.failureCount = updateGithub ? 1 : 0; + } + + // mutates report to include messages and writes updated report to disk + await addMessagesToReport({ + report, + messages, + log, + reportPath, + dryRun: !flags['report-update'], + }); + + await reportFailuresToFile(log, failures, bkMeta, getRootMetadata(report)); + } + } finally { + await CiStatsReporter.fromEnv(log).metrics([ + { + group: 'github api request count', + id: `failed test reporter`, + value: githubApi.getRequestCount(), + meta: Object.fromEntries( + Object.entries(bkMeta).map( + ([k, v]) => [`buildkite${k[0].toUpperCase()}${k.slice(1)}`, v] as const + ) + ), + }, + ]); + } + }, + { + description: `a cli that opens issues or updates existing issues based on junit reports`, + flags: { + boolean: ['github-update', 'report-update'], + string: ['build-url'], + default: { + 'github-update': true, + 'report-update': true, + 'index-errors': true, + 'build-url': process.env.BUILD_URL, + }, + help: ` + --no-github-update Execute the CLI without writing to Github + --no-report-update Execute the CLI without writing to the JUnit reports + --no-index-errors Execute the CLI without indexing failures into Elasticsearch + --build-url URL of the failed build, defaults to process.env.BUILD_URL + `, + }, + } +); diff --git a/packages/kbn-test/src/failed_tests_reporter/get_failures.test.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/get_failures.test.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/get_failures.test.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/get_failures.test.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/get_failures.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/get_failures.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/get_failures.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/get_failures.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/github_api.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/github_api.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/github_api.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/github_api.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/issue_metadata.test.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/issue_metadata.test.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/issue_metadata.test.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/issue_metadata.test.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/issue_metadata.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/issue_metadata.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/issue_metadata.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/issue_metadata.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/report_failure.test.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failure.test.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/report_failure.test.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failure.test.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/report_failure.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failure.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/report_failure.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failure.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/report_failures_to_es.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_es.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/report_failures_to_es.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_es.ts diff --git a/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file.ts new file mode 100644 index 0000000000000..d34df80f3d0a8 --- /dev/null +++ b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file.ts @@ -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 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 Path from 'path'; +import Fs from 'fs'; +import { createHash } from 'crypto'; + +import globby from 'globby'; +import { ToolingLog } from '@kbn/tooling-log'; +import { REPO_ROOT } from '@kbn/utils'; +import { escape } from 'he'; +import { FtrScreenshotFilename } from '@kbn/ftr-screenshot-filename'; +import { JourneyScreenshots } from '@kbn/journeys'; + +import { BuildkiteMetadata } from './buildkite_metadata'; +import { TestFailure } from './get_failures'; + +interface JourneyMeta { + journeyName: string; +} +function getJourneyMetadata(rootMeta: Record): JourneyMeta | undefined { + const { journeyName } = rootMeta; + if (typeof journeyName === 'string') { + return { journeyName }; + } + + return undefined; +} + +async function getJourneySnapshotHtml(log: ToolingLog, journeyMeta: JourneyMeta) { + let screenshots; + try { + screenshots = await JourneyScreenshots.load(journeyMeta.journeyName); + } catch (error) { + log.error(`Failed to load journey screenshots: ${error.message}`); + return ''; + } + + return [ + '
', + '
Steps
', + ...screenshots.get().flatMap(({ title, path }) => { + const base64 = Fs.readFileSync(path, 'base64'); + + return [ + `

${escape(title)}

`, + ``, + ]; + }), + '
', + ].join('\n'); +} + +let _allScreenshotsCache: Array<{ path: string; name: string }> | undefined; +function getAllScreenshots(log: ToolingLog) { + return (_allScreenshotsCache ??= findAllScreenshots(log)); +} +function findAllScreenshots(log: ToolingLog) { + try { + return globby + .sync( + [ + 'test/functional/**/screenshots/failure/*.png', + 'x-pack/test/functional/**/screenshots/failure/*.png', + ], + { + cwd: REPO_ROOT, + absolute: true, + } + ) + .map((path) => ({ + path, + name: Path.basename(path, Path.extname(path)), + })); + } catch (error) { + log.error(`Failed to find screenshots: ${error.message}`); + return []; + } +} + +function getFtrScreenshotHtml(log: ToolingLog, failureName: string) { + return getAllScreenshots(log) + .filter((s) => s.name.startsWith(FtrScreenshotFilename.create(failureName, { ext: false }))) + .map((s) => { + const base64 = Fs.readFileSync(s.path).toString('base64'); + return ``; + }) + .join('\n'); +} + +export async function reportFailuresToFile( + log: ToolingLog, + failures: TestFailure[], + bkMeta: BuildkiteMetadata, + rootMeta: Record +) { + if (!failures?.length) { + return; + } + + const journeyMeta = getJourneyMetadata(rootMeta); + + // Jest could, in theory, fail 1000s of tests and write 1000s of failures + // So let's just write files for the first 20 + for (const failure of failures.slice(0, 20)) { + const hash = createHash('md5').update(failure.name).digest('hex'); + const filenameBase = `${ + process.env.BUILDKITE_JOB_ID ? process.env.BUILDKITE_JOB_ID + '_' : '' + }${hash}`; + const dir = Path.join('target', 'test_failures'); + + const failureLog = [ + ['Test:', '-----', failure.classname, failure.name, ''], + ['Failure:', '--------', failure.failure], + failure['system-out'] ? ['', 'Standard Out:', '-------------', failure['system-out']] : [], + ] + .flat() + .join('\n'); + + const failureJSON = JSON.stringify( + { + ...failure, + hash, + buildId: bkMeta.buildId, + jobId: bkMeta.jobId, + url: bkMeta.url, + jobUrl: bkMeta.jobUrl, + jobName: bkMeta.jobName, + }, + null, + 2 + ); + + const failureHTML = Fs.readFileSync( + require.resolve('./report_failures_to_file_html_template.html') + ) + .toString() + .replace('$TITLE', escape(failure.name)) + .replace( + '$MAIN', + ` + ${failure.classname + .split('.') + .map((part) => `
${escape(part.replace('·', '.'))}
`) + .join('')} +
+

${escape(failure.name)}

+

+ + Failures in tracked branches: ${ + failure.failureCount || 0 + } + ${ + failure.githubIssue + ? `
${escape( + failure.githubIssue + )}` + : '' + } +
+

+ ${ + bkMeta.jobUrl + ? `

+ + Buildkite Job
+ ${escape(bkMeta.jobUrl)} +
+

` + : '' + } +
${escape(failure.failure)}
+ ${ + journeyMeta + ? await getJourneySnapshotHtml(log, journeyMeta) + : getFtrScreenshotHtml(log, failure.name) + } + ${ + failure['system-out'] + ? ` +
Stdout
+
${escape(failure['system-out'] || '')}
+ ` + : '' + } + ` + ); + + Fs.mkdirSync(dir, { recursive: true }); + Fs.writeFileSync(Path.join(dir, `${filenameBase}.log`), failureLog, 'utf8'); + Fs.writeFileSync(Path.join(dir, `${filenameBase}.html`), failureHTML, 'utf8'); + Fs.writeFileSync(Path.join(dir, `${filenameBase}.json`), failureJSON, 'utf8'); + } +} diff --git a/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file_html_template.html similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_failures_to_file_html_template.html diff --git a/packages/kbn-test/src/failed_tests_reporter/report_metadata.test.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_metadata.test.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/report_metadata.test.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_metadata.test.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/report_metadata.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_metadata.ts similarity index 100% rename from packages/kbn-test/src/failed_tests_reporter/report_metadata.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/report_metadata.ts diff --git a/packages/kbn-test/src/failed_tests_reporter/test_report.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/test_report.ts similarity index 84% rename from packages/kbn-test/src/failed_tests_reporter/test_report.ts rename to packages/kbn-failed-test-reporter-cli/failed_tests_reporter/test_report.ts index 9c83d77b19a99..e70aa44a2a088 100644 --- a/packages/kbn-test/src/failed_tests_reporter/test_report.ts +++ b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/test_report.ts @@ -35,6 +35,8 @@ export interface TestSuite { failures: string; /* number of skipped tests as a string */ skipped: string; + /* optional JSON encoded metadata */ + 'metadata-json'?: string; }; testcase?: TestCase[]; } @@ -93,3 +95,22 @@ export function* makeFailedTestCaseIter(report: TestReport) { yield testCase as FailedTestCase; } } + +export function getRootMetadata(report: TestReport): Record { + const json = + ('testsuites' in report + ? report.testsuites?.testsuite?.[0]?.$?.['metadata-json'] + : report.testsuite?.$?.['metadata-json']) ?? '{}'; + + try { + const obj = JSON.parse(json); + + if (typeof obj === 'object' && obj !== null) { + return obj; + } + + return {}; + } catch { + return {}; + } +} diff --git a/packages/kbn-test/src/failed_tests_reporter/index.ts b/packages/kbn-failed-test-reporter-cli/index.ts similarity index 82% rename from packages/kbn-test/src/failed_tests_reporter/index.ts rename to packages/kbn-failed-test-reporter-cli/index.ts index b750cf44348e1..999da20da72f5 100644 --- a/packages/kbn-test/src/failed_tests_reporter/index.ts +++ b/packages/kbn-failed-test-reporter-cli/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export { runFailedTestsReporterCli } from './run_failed_tests_reporter_cli'; +import './failed_tests_reporter/failed_tests_reporter_cli'; diff --git a/packages/kbn-test/src/functional_tests/cli/index.js b/packages/kbn-failed-test-reporter-cli/jest.config.js similarity index 56% rename from packages/kbn-test/src/functional_tests/cli/index.js rename to packages/kbn-failed-test-reporter-cli/jest.config.js index 9721d70d12262..eb33f488f9e84 100644 --- a/packages/kbn-test/src/functional_tests/cli/index.js +++ b/packages/kbn-failed-test-reporter-cli/jest.config.js @@ -6,7 +6,8 @@ * Side Public License, v 1. */ -export { runTestsCli } from './run_tests/cli'; -export { processOptions as processRunTestsCliOptions } from './run_tests/args'; -export { startServersCli } from './start_servers/cli'; -export { processOptions as processStartServersCliOptions } from './start_servers/args'; +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../..', + roots: ['/packages/kbn-failed-test-reporter-cli'], +}; diff --git a/packages/kbn-failed-test-reporter-cli/kibana.jsonc b/packages/kbn-failed-test-reporter-cli/kibana.jsonc new file mode 100644 index 0000000000000..dfaa875e12735 --- /dev/null +++ b/packages/kbn-failed-test-reporter-cli/kibana.jsonc @@ -0,0 +1,8 @@ +{ + "type": "shared-common", + "id": "@kbn/failed-test-reporter-cli", + "owner": "@elastic/kibana-operations", + "devOnly": true, + "runtimeDeps": [], + "typeDeps": [], +} diff --git a/packages/kbn-failed-test-reporter-cli/package.json b/packages/kbn-failed-test-reporter-cli/package.json new file mode 100644 index 0000000000000..daf9a58cd77d7 --- /dev/null +++ b/packages/kbn-failed-test-reporter-cli/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/failed-test-reporter-cli", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/kbn-failed-test-reporter-cli/tsconfig.json b/packages/kbn-failed-test-reporter-cli/tsconfig.json new file mode 100644 index 0000000000000..81935b1385550 --- /dev/null +++ b/packages/kbn-failed-test-reporter-cli/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "**/*.ts", + ] +} diff --git a/packages/kbn-ftr-common-functional-services/BUILD.bazel b/packages/kbn-ftr-common-functional-services/BUILD.bazel new file mode 100644 index 0000000000000..8085c75af4af1 --- /dev/null +++ b/packages/kbn-ftr-common-functional-services/BUILD.bazel @@ -0,0 +1,127 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "kbn-ftr-common-functional-services" +PKG_REQUIRE_NAME = "@kbn/ftr-common-functional-services" + +SOURCE_FILES = glob( + [ + "**/*.ts", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__/**", + "**/integration_tests/**", + "**/mocks/**", + "**/scripts/**", + "**/storybook/**", + "**/test_fixtures/**", + "**/test_helpers/**", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ +] + +# In this array place dependencies necessary to build the types, which will include the +# :npm_module_types target of other packages and packages from NPM, including @types/* +# packages. +# +# To reference the types for another package use: +# "//repo/relative/path/to/package:npm_module_types" +# eg. "//packages/kbn-utils:npm_module_types" +# +# References to NPM packages work the same as RUNTIME_DEPS +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "//packages/kbn-tooling-log:npm_module_types", + "//packages/kbn-es-archiver:npm_module_types", + "//packages/kbn-test:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-ftr-common-functional-services/README.md b/packages/kbn-ftr-common-functional-services/README.md new file mode 100644 index 0000000000000..a2438327a62f7 --- /dev/null +++ b/packages/kbn-ftr-common-functional-services/README.md @@ -0,0 +1,3 @@ +# @kbn/ftr-common-functional-services + +A collection of very common services used by all functional FTR configs, moved to a package so that we can start putting FTR configs in packages. \ No newline at end of file diff --git a/packages/kbn-ftr-common-functional-services/index.ts b/packages/kbn-ftr-common-functional-services/index.ts new file mode 100644 index 0000000000000..950a860f7553f --- /dev/null +++ b/packages/kbn-ftr-common-functional-services/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ProvidedType } from '@kbn/test'; +export { services as commonFunctionalServices } from './services/all'; + +import { KibanaServerProvider } from './services/kibana_server'; +export type KibanaServer = ProvidedType; + +export { RetryService } from './services/retry'; + +import { EsArchiverProvider } from './services/es_archiver'; +export type EsArchiver = ProvidedType; + +import { EsProvider } from './services/es'; +export type Es = ProvidedType; diff --git a/packages/kbn-ftr-common-functional-services/jest.config.js b/packages/kbn-ftr-common-functional-services/jest.config.js new file mode 100644 index 0000000000000..1831bdb22630d --- /dev/null +++ b/packages/kbn-ftr-common-functional-services/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../..', + roots: ['/packages/kbn-ftr-common-functional-services'], +}; diff --git a/packages/kbn-ftr-common-functional-services/kibana.jsonc b/packages/kbn-ftr-common-functional-services/kibana.jsonc new file mode 100644 index 0000000000000..5ceecdcda8610 --- /dev/null +++ b/packages/kbn-ftr-common-functional-services/kibana.jsonc @@ -0,0 +1,8 @@ +{ + "type": "shared-common", + "id": "@kbn/ftr-common-functional-services", + "owner": "@elastic/kibana-operations", + "devOnly": true, + "runtimeDeps": [], + "typeDeps": [], +} diff --git a/packages/kbn-ftr-common-functional-services/package.json b/packages/kbn-ftr-common-functional-services/package.json new file mode 100644 index 0000000000000..642a5a39c7141 --- /dev/null +++ b/packages/kbn-ftr-common-functional-services/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/ftr-common-functional-services", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/kbn-ftr-common-functional-services/services/all.ts b/packages/kbn-ftr-common-functional-services/services/all.ts new file mode 100644 index 0000000000000..14019caaa582c --- /dev/null +++ b/packages/kbn-ftr-common-functional-services/services/all.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { EsArchiverProvider } from './es_archiver'; +import { EsProvider } from './es'; +import { KibanaServerProvider } from './kibana_server'; +import { RetryService } from './retry'; + +export const services = { + es: EsProvider, + kibanaServer: KibanaServerProvider, + esArchiver: EsArchiverProvider, + retry: RetryService, +}; diff --git a/test/common/services/elasticsearch.ts b/packages/kbn-ftr-common-functional-services/services/es.ts similarity index 75% rename from test/common/services/elasticsearch.ts rename to packages/kbn-ftr-common-functional-services/services/es.ts index 2f19bfe9105d0..fe9aafbf10736 100644 --- a/test/common/services/elasticsearch.ts +++ b/packages/kbn-ftr-common-functional-services/services/es.ts @@ -9,12 +9,9 @@ import { Client } from '@elastic/elasticsearch'; import { systemIndicesSuperuser, createEsClientForFtrConfig } from '@kbn/test'; -import { FtrProviderContext } from '../ftr_provider_context'; +import { FtrProviderContext } from './ftr_provider_context'; -/* - registers Kibana-specific @elastic/elasticsearch client instance. - */ -export function ElasticsearchProvider({ getService }: FtrProviderContext): Client { +export function EsProvider({ getService }: FtrProviderContext): Client { const config = getService('config'); return createEsClientForFtrConfig(config, { diff --git a/test/common/services/es_archiver.ts b/packages/kbn-ftr-common-functional-services/services/es_archiver.ts similarity index 61% rename from test/common/services/es_archiver.ts rename to packages/kbn-ftr-common-functional-services/services/es_archiver.ts index 865c2ba4b4434..8a81297bf1784 100644 --- a/test/common/services/es_archiver.ts +++ b/packages/kbn-ftr-common-functional-services/services/es_archiver.ts @@ -7,17 +7,15 @@ */ import { EsArchiver } from '@kbn/es-archiver'; -import { FtrProviderContext } from '../ftr_provider_context'; -import * as KibanaServer from './kibana_server'; +import { FtrProviderContext } from './ftr_provider_context'; +import { extendEsArchiver } from './kibana_server'; export function EsArchiverProvider({ getService }: FtrProviderContext): EsArchiver { const config = getService('config'); const client = getService('es'); - const lifecycle = getService('lifecycle'); const log = getService('log'); const kibanaServer = getService('kibanaServer'); const retry = getService('retry'); - const esArchives: string[] = config.get('testData.esArchives'); const esArchiver = new EsArchiver({ client, @@ -25,26 +23,12 @@ export function EsArchiverProvider({ getService }: FtrProviderContext): EsArchiv kbnClient: kibanaServer, }); - KibanaServer.extendEsArchiver({ + extendEsArchiver({ esArchiver, kibanaServer, retry, defaults: config.get('uiSettings.defaults'), }); - if (esArchives.length) { - lifecycle.beforeTests.add(async () => { - for (const archive of esArchives) { - await esArchiver.load(archive); - } - }); - - lifecycle.cleanup.add(async () => { - for (const archive of esArchives) { - await esArchiver.unload(archive); - } - }); - } - return esArchiver; } diff --git a/packages/kbn-ftr-common-functional-services/services/ftr_provider_context.ts b/packages/kbn-ftr-common-functional-services/services/ftr_provider_context.ts new file mode 100644 index 0000000000000..979658fbd8edd --- /dev/null +++ b/packages/kbn-ftr-common-functional-services/services/ftr_provider_context.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 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 { GenericFtrProviderContext, GenericFtrService } from '@kbn/test'; + +import type { services } from './all'; + +type Services = typeof services; + +export type FtrProviderContext = GenericFtrProviderContext; +export class FtrService extends GenericFtrService {} diff --git a/test/common/services/kibana_server/extend_es_archiver.ts b/packages/kbn-ftr-common-functional-services/services/kibana_server/extend_es_archiver.ts similarity index 100% rename from test/common/services/kibana_server/extend_es_archiver.ts rename to packages/kbn-ftr-common-functional-services/services/kibana_server/extend_es_archiver.ts diff --git a/test/common/services/kibana_server/index.ts b/packages/kbn-ftr-common-functional-services/services/kibana_server/index.ts similarity index 100% rename from test/common/services/kibana_server/index.ts rename to packages/kbn-ftr-common-functional-services/services/kibana_server/index.ts diff --git a/test/common/services/kibana_server/kibana_server.ts b/packages/kbn-ftr-common-functional-services/services/kibana_server/kibana_server.ts similarity index 69% rename from test/common/services/kibana_server/kibana_server.ts rename to packages/kbn-ftr-common-functional-services/services/kibana_server/kibana_server.ts index 182b289ed1d8e..bdfc42670f18b 100644 --- a/test/common/services/kibana_server/kibana_server.ts +++ b/packages/kbn-ftr-common-functional-services/services/kibana_server/kibana_server.ts @@ -9,7 +9,7 @@ import Url from 'url'; import { KbnClient } from '@kbn/test'; -import { FtrProviderContext } from '../../ftr_provider_context'; +import { FtrProviderContext } from '../ftr_provider_context'; export function KibanaServerProvider({ getService }: FtrProviderContext): KbnClient { const log = getService('log'); @@ -17,7 +17,6 @@ export function KibanaServerProvider({ getService }: FtrProviderContext): KbnCli const lifecycle = getService('lifecycle'); const url = Url.format(config.get('servers.kibana')); const defaults = config.get('uiSettings.defaults'); - const kbnArchives: string[] = config.get('testData.kbnArchives'); const kbn = new KbnClient({ log, @@ -32,18 +31,5 @@ export function KibanaServerProvider({ getService }: FtrProviderContext): KbnCli }); } - if (kbnArchives.length) { - lifecycle.beforeTests.add(async () => { - for (const archive of kbnArchives) { - await kbn.importExport.load(archive); - } - }); - lifecycle.cleanup.add(async () => { - for (const archive of kbnArchives) { - await kbn.importExport.unload(archive); - } - }); - } - return kbn; } diff --git a/test/common/services/retry/index.ts b/packages/kbn-ftr-common-functional-services/services/retry/index.ts similarity index 100% rename from test/common/services/retry/index.ts rename to packages/kbn-ftr-common-functional-services/services/retry/index.ts diff --git a/test/common/services/retry/retry.ts b/packages/kbn-ftr-common-functional-services/services/retry/retry.ts similarity index 96% rename from test/common/services/retry/retry.ts rename to packages/kbn-ftr-common-functional-services/services/retry/retry.ts index 5c823e256ddc8..231a829225dbc 100644 --- a/test/common/services/retry/retry.ts +++ b/packages/kbn-ftr-common-functional-services/services/retry/retry.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { FtrService } from '../../ftr_provider_context'; +import { FtrService } from '../ftr_provider_context'; import { retryForSuccess } from './retry_for_success'; import { retryForTruthy } from './retry_for_truthy'; diff --git a/test/common/services/retry/retry_for_success.ts b/packages/kbn-ftr-common-functional-services/services/retry/retry_for_success.ts similarity index 100% rename from test/common/services/retry/retry_for_success.ts rename to packages/kbn-ftr-common-functional-services/services/retry/retry_for_success.ts diff --git a/test/common/services/retry/retry_for_truthy.ts b/packages/kbn-ftr-common-functional-services/services/retry/retry_for_truthy.ts similarity index 100% rename from test/common/services/retry/retry_for_truthy.ts rename to packages/kbn-ftr-common-functional-services/services/retry/retry_for_truthy.ts diff --git a/packages/kbn-ftr-common-functional-services/tsconfig.json b/packages/kbn-ftr-common-functional-services/tsconfig.json new file mode 100644 index 0000000000000..81935b1385550 --- /dev/null +++ b/packages/kbn-ftr-common-functional-services/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "**/*.ts", + ] +} diff --git a/packages/kbn-ftr-screenshot-filename/BUILD.bazel b/packages/kbn-ftr-screenshot-filename/BUILD.bazel new file mode 100644 index 0000000000000..5cbd3e2c87ac7 --- /dev/null +++ b/packages/kbn-ftr-screenshot-filename/BUILD.bazel @@ -0,0 +1,125 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "kbn-ftr-screenshot-filename" +PKG_REQUIRE_NAME = "@kbn/ftr-screenshot-filename" + +SOURCE_FILES = glob( + [ + "**/*.ts", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__/**", + "**/integration_tests/**", + "**/mocks/**", + "**/scripts/**", + "**/storybook/**", + "**/test_fixtures/**", + "**/test_helpers/**", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ +] + +# In this array place dependencies necessary to build the types, which will include the +# :npm_module_types target of other packages and packages from NPM, including @types/* +# packages. +# +# To reference the types for another package use: +# "//repo/relative/path/to/package:npm_module_types" +# eg. "//packages/kbn-utils:npm_module_types" +# +# References to NPM packages work the same as RUNTIME_DEPS +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/jest", + "@npm//tslib", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-ftr-screenshot-filename/README.md b/packages/kbn-ftr-screenshot-filename/README.md new file mode 100644 index 0000000000000..faf5d4b994e50 --- /dev/null +++ b/packages/kbn-ftr-screenshot-filename/README.md @@ -0,0 +1,3 @@ +# @kbn/ftr-screenshot-filename + +A simple package that exposes a helper function for generating a unique screenshot filename that can be found by `node scripts/failed_test_reporter`. diff --git a/packages/kbn-ftr-screenshot-filename/ftr_screenshot_filename.ts b/packages/kbn-ftr-screenshot-filename/ftr_screenshot_filename.ts new file mode 100644 index 0000000000000..2cce021d50826 --- /dev/null +++ b/packages/kbn-ftr-screenshot-filename/ftr_screenshot_filename.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createHash } from 'crypto'; + +export function create(fullTitle: string, opts?: { ext?: boolean }) { + const truncatedName = fullTitle.replaceAll(/[^ a-zA-Z0-9-]+/g, '').slice(0, 80); + const failureNameHash = createHash('sha256').update(fullTitle).digest('hex'); + return `${truncatedName}-${failureNameHash}${opts?.ext === false ? '' : `.png`}`; +} diff --git a/packages/kbn-ftr-screenshot-filename/index.ts b/packages/kbn-ftr-screenshot-filename/index.ts new file mode 100644 index 0000000000000..2911989659805 --- /dev/null +++ b/packages/kbn-ftr-screenshot-filename/index.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import * as FtrScreenshotFilename from './ftr_screenshot_filename'; + +export { FtrScreenshotFilename }; diff --git a/packages/kbn-ftr-screenshot-filename/jest.config.js b/packages/kbn-ftr-screenshot-filename/jest.config.js new file mode 100644 index 0000000000000..0ab6eb759a1dd --- /dev/null +++ b/packages/kbn-ftr-screenshot-filename/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../..', + roots: ['/packages/kbn-ftr-screenshot-filename'], +}; diff --git a/packages/kbn-ftr-screenshot-filename/kibana.jsonc b/packages/kbn-ftr-screenshot-filename/kibana.jsonc new file mode 100644 index 0000000000000..61ce39de5a622 --- /dev/null +++ b/packages/kbn-ftr-screenshot-filename/kibana.jsonc @@ -0,0 +1,8 @@ +{ + "type": "shared-common", + "id": "@kbn/ftr-screenshot-filename", + "owner": "@elastic/kibana-operations", + "devOnly": true, + "runtimeDeps": [], + "typeDeps": [], +} diff --git a/packages/kbn-ftr-screenshot-filename/package.json b/packages/kbn-ftr-screenshot-filename/package.json new file mode 100644 index 0000000000000..8e3a9b1e57db4 --- /dev/null +++ b/packages/kbn-ftr-screenshot-filename/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/ftr-screenshot-filename", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/kbn-ftr-screenshot-filename/tsconfig.json b/packages/kbn-ftr-screenshot-filename/tsconfig.json new file mode 100644 index 0000000000000..81935b1385550 --- /dev/null +++ b/packages/kbn-ftr-screenshot-filename/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [ + "jest", + "node" + ] + }, + "include": [ + "**/*.ts", + ] +} diff --git a/packages/kbn-journeys/BUILD.bazel b/packages/kbn-journeys/BUILD.bazel new file mode 100644 index 0000000000000..cfadfb4b8b4b7 --- /dev/null +++ b/packages/kbn-journeys/BUILD.bazel @@ -0,0 +1,134 @@ +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") + +PKG_DIRNAME = "kbn-journeys" +PKG_REQUIRE_NAME = "@kbn/journeys" + +SOURCE_FILES = glob( + [ + "**/*.ts", + ], + exclude = [ + "**/*.config.js", + "**/*.mock.*", + "**/*.test.*", + "**/*.stories.*", + "**/__snapshots__/**", + "**/integration_tests/**", + "**/mocks/**", + "**/scripts/**", + "**/storybook/**", + "**/test_fixtures/**", + "**/test_helpers/**", + ], +) + +SRCS = SOURCE_FILES + +filegroup( + name = "srcs", + srcs = SRCS, +) + +NPM_MODULE_EXTRA_FILES = [ + "package.json", +] + +# In this array place runtime dependencies, including other packages and NPM packages +# which must be available for this code to run. +# +# To reference other packages use: +# "//repo/relative/path/to/package" +# eg. "//packages/kbn-utils" +# +# To reference a NPM package use: +# "@npm//name-of-package" +# eg. "@npm//lodash" +RUNTIME_DEPS = [ +] + +# In this array place dependencies necessary to build the types, which will include the +# :npm_module_types target of other packages and packages from NPM, including @types/* +# packages. +# +# To reference the types for another package use: +# "//repo/relative/path/to/package:npm_module_types" +# eg. "//packages/kbn-utils:npm_module_types" +# +# References to NPM packages work the same as RUNTIME_DEPS +TYPES_DEPS = [ + "@npm//@types/node", + "@npm//@types/mocha", + "@npm//playwright", + "@npm//uuid", + "@npm//axios", + "@npm//callsites", + "@npm//rxjs", + "@npm//elastic-apm-node", + "//packages/kbn-ftr-common-functional-services:npm_module_types", + "//packages/kbn-ftr-screenshot-filename:npm_module_types", + "//packages/kbn-test:npm_module_types", + "//packages/kbn-utils:npm_module_types", +] + +jsts_transpiler( + name = "target_node", + srcs = SRCS, + build_pkg_name = package_name(), +) + +ts_config( + name = "tsconfig", + src = "tsconfig.json", + deps = [ + "//:tsconfig.base.json", + "//:tsconfig.bazel.json", + ], +) + +ts_project( + name = "tsc_types", + args = ['--pretty'], + srcs = SRCS, + deps = TYPES_DEPS, + declaration = True, + declaration_map = True, + emit_declaration_only = True, + out_dir = "target_types", + tsconfig = ":tsconfig", +) + +js_library( + name = PKG_DIRNAME, + srcs = NPM_MODULE_EXTRA_FILES, + deps = RUNTIME_DEPS + [":target_node"], + package_name = PKG_REQUIRE_NAME, + visibility = ["//visibility:public"], +) + +pkg_npm( + name = "npm_module", + deps = [":" + PKG_DIRNAME], +) + +filegroup( + name = "build", + srcs = [":npm_module"], + visibility = ["//visibility:public"], +) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [":npm_module_types"], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-journeys/README.mdx b/packages/kbn-journeys/README.mdx new file mode 100644 index 0000000000000..506b5eb21a9e5 --- /dev/null +++ b/packages/kbn-journeys/README.mdx @@ -0,0 +1,32 @@ +--- +id: kibDevDocsOpsJourneys +slug: /kibana-dev-docs/ops/journeys +title: Journeys +description: A new style of functional test, focused on performance testing for now +tags: ['kibana', 'dev', 'contributor', 'operations', 'performance', 'functional', 'testing'] +--- + +Journeys are a slightly newer take on Functional Tests, currently powered by [playwright](https://playwright.dev/docs). + +A Journey is a single pathway through Kibana and looks something like this: + +```ts +import { Journey } from '@kbn/journeys'; +import { subj } from '@kbn/test-subj-selector'; + +export const journey = new Journey({ + esArchives: [ ... ], + kbnArchives: [ ... ], + scalabilitySetup: { ... }, +}) + .step('Go to Discover Page', async ({ page, kbnUrl }) => { + await page.goto(kbnUrl.get(`/app/discover`)); + await page.waitForSelector(subj('discoverDocTable')); + }) + + .step('Expand the first document', async ({ page }) => { + const expandButtons = page.locator(subj('docTableExpandToggleColumn')); + await expandButtons.first().click(); + await page.locator('text="Expanded document"'); + }); +``` \ No newline at end of file diff --git a/packages/kbn-journeys/index.ts b/packages/kbn-journeys/index.ts new file mode 100644 index 0000000000000..cc4c10c685d1c --- /dev/null +++ b/packages/kbn-journeys/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { JourneyConfig } from './journey/journey_config'; +export type { ScalabilityAction, ScalabilitySetup } from './journey/journey_config'; + +export { Journey } from './journey/journey'; +export type { Step } from './journey/journey'; + +export { JourneyScreenshots } from './journey/journey_screenshots'; diff --git a/packages/kbn-journeys/jest.config.js b/packages/kbn-journeys/jest.config.js new file mode 100644 index 0000000000000..3d4735db3ddf8 --- /dev/null +++ b/packages/kbn-journeys/jest.config.js @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +module.exports = { + preset: '@kbn/test/jest_node', + rootDir: '../..', + roots: ['/packages/kbn-journeys'], +}; diff --git a/packages/kbn-journeys/journey/journey.ts b/packages/kbn-journeys/journey/journey.ts new file mode 100644 index 0000000000000..c399db0ba91c4 --- /dev/null +++ b/packages/kbn-journeys/journey/journey.ts @@ -0,0 +1,125 @@ +/* + * 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 { inspect } from 'util'; + +import { Page } from 'playwright'; +import callsites from 'callsites'; +import { ToolingLog } from '@kbn/tooling-log'; +import { FtrConfigProvider } from '@kbn/test'; +import { FtrProviderContext } from '@kbn/ftr-common-functional-services'; + +import { Auth } from '../services/auth'; +import { InputDelays } from '../services/input_delays'; +import { KibanaUrl } from '../services/kibana_url'; + +import { JourneyFtrHarness } from './journey_ftr_harness'; +import { makeFtrConfigProvider } from './journey_ftr_config'; +import { JourneyConfig, JourneyConfigOptions } from './journey_config'; + +export interface BaseStepCtx { + page: Page; + log: ToolingLog; + inputDelays: InputDelays; + kbnUrl: KibanaUrl; +} + +export type AnyStep = Step<{}>; + +export interface Step { + name: string; + index: number; + fn(ctx: BaseStepCtx & CtxExt): Promise; +} + +const CONFIG_PROVIDER_CACHE = new WeakMap, FtrConfigProvider>(); + +export class Journey { + static convertToFtrConfigProvider(journey: Journey) { + const cached = CONFIG_PROVIDER_CACHE.get(journey); + if (cached) { + return cached; + } + + const provider = makeFtrConfigProvider(journey.config, journey.#steps); + CONFIG_PROVIDER_CACHE.set(journey, provider); + return provider; + } + + /** + * Load a journey from a file path + */ + static async load(path: string) { + let m; + try { + m = await import(path); + } catch (error) { + throw new Error(`Unable to load file: ${path}`); + } + + if (!m || !m.journey) { + throw new Error(`[${path}] is not a journey`); + } + + const journey = m.journey; + if (journey instanceof Journey) { + return journey; + } + + const dbg = inspect(journey); + throw new Error(`[${path}] does not export a Journey like it should, received ${dbg}`); + } + + #steps: Array> = []; + + config: JourneyConfig; + + /** + * Create a Journey which should be exported from a file in the + * x-pack/performance/journeys directory. + */ + constructor(opts?: JourneyConfigOptions) { + const path = callsites().at(1)?.getFileName(); + + if (!path) { + throw new Error('unable to determine path of journey config file'); + } + + this.config = new JourneyConfig(path, opts); + } + + /** + * Define a step of this Journey. Steps are only separated from each other + * to aid in reading/debuging the journey and reading it's logging output. + * + * If a journey fails, a failure report will be created with a screenshot + * at the point of failure as well as a screenshot at the end of every + * step. + */ + step(name: string, fn: (ctx: BaseStepCtx & CtxExt) => Promise) { + this.#steps.push({ + name, + index: this.#steps.length, + fn, + }); + + return this; + } + + /** called by FTR to setup tests */ + protected testProvider({ getService }: FtrProviderContext) { + new JourneyFtrHarness( + getService('log'), + getService('config'), + getService('esArchiver'), + getService('kibanaServer'), + new Auth(getService('config'), getService('log'), getService('kibanaServer')), + this.config + ).initMochaSuite(this.#steps); + } +} diff --git a/packages/kbn-journeys/journey/journey_config.ts b/packages/kbn-journeys/journey/journey_config.ts new file mode 100644 index 0000000000000..e23b2a748fbe7 --- /dev/null +++ b/packages/kbn-journeys/journey/journey_config.ts @@ -0,0 +1,155 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import Path from 'path'; + +import { REPO_ROOT } from '@kbn/utils'; + +import { BaseStepCtx } from './journey'; + +export interface RampConcurrentUsersAction { + action: 'rampConcurrentUsers'; + /** + * Duration strings must be formatted as string that starts with an integer and + * ends with either "m" or "s" for minutes and seconds, respectively + * + * eg: "1m" or "30s" + */ + duration: string; + minUsersCount: number; + maxUsersCount: number; +} + +export interface ConstantConcurrentUsersAction { + action: 'constantConcurrentUsers'; + /** + * Duration strings must be formatted as string that starts with an integer and + * ends with either "m" or "s" for minutes and seconds, respectively + * + * eg: "1m" or "30s" + */ + duration: string; + userCount: number; +} + +export type ScalabilityAction = RampConcurrentUsersAction | ConstantConcurrentUsersAction; + +export interface ScalabilitySetup { + /** + * Duration strings must be formatted as string that starts with an integer and + * ends with either "m" or "s" for minutes and seconds, respectively + * + * eg: "1m" or "30s" + */ + maxDuration: string; + warmup: ScalabilityAction[]; + test: ScalabilityAction[]; +} + +export interface JourneyConfigOptions { + /** + * Set to `true` to skip this journey. should probably be preceded + * by a link to a Github issue where the reasoning for why this was + * skipped and not just deleted is outlined. + */ + skipped?: boolean; + /** + * Scalability configuration used to customize automatically generated + * scalability tests. For now chat with Dima/Operations if you want to + * use this option. + */ + scalabilitySetup?: ScalabilitySetup; + /** + * These labels will be attached to all APM data created when running + * this journey. + */ + extraApmLabels?: Record; + /** + * A list of kbnArchives which will be automatically loaded/unloaded + * for this journey. + */ + kbnArchives?: string[]; + /** + * A list of esArchives which will be automatically loaded/unloaded + * for this journey. + */ + esArchives?: string[]; + /** + * By default the API is used to get a cookie that can be used for all + * navigation requests to Kibana, so that we don't ever see the login + * screen. Set this to `false` to disable this behavior. + */ + skipAutoLogin?: boolean; + /** + * Use this to extend the context provided to each step. This function + * is called with the default context and returns an object that will + * be merged with the default context provided to each step function. + */ + extendContext?: (ctx: BaseStepCtx) => CtxExt; +} + +export class JourneyConfig { + #opts: JourneyConfigOptions; + #path: string; + #name: string; + + constructor(path: string, opts: JourneyConfigOptions = {}) { + this.#path = path; + this.#name = Path.basename(this.#path, Path.extname(this.#path)); + this.#opts = opts; + } + + getEsArchives() { + return this.#opts.esArchives ?? []; + } + + getKbnArchives() { + return this.#opts.kbnArchives ?? []; + } + + isXpack() { + return this.getRepoRelPath().split(Path.sep).at(0) === 'x-pack'; + } + + getExtraApmLabels() { + return this.#opts.extraApmLabels ? { ...this.#opts.extraApmLabels } : {}; + } + + getRepoRelPath() { + return Path.relative(REPO_ROOT, this.getPath()); + } + + getPath() { + return this.#path; + } + + getName() { + return this.#name; + } + + shouldAutoLogin() { + return !this.#opts.skipAutoLogin; + } + + isSkipped() { + return !!this.#opts.skipped; + } + + getScalabilityConfig() { + return this.#opts.scalabilitySetup; + } + + getExtendedStepCtx(ctx: BaseStepCtx): BaseStepCtx & CtxExt { + const ext = this.#opts.extendContext ?? (() => ({} as CtxExt)); + + return { + ...ctx, + ...ext(ctx), + }; + } +} diff --git a/packages/kbn-journeys/journey/journey_ftr_config.ts b/packages/kbn-journeys/journey/journey_ftr_config.ts new file mode 100644 index 0000000000000..392ad69b63ba1 --- /dev/null +++ b/packages/kbn-journeys/journey/journey_ftr_config.ts @@ -0,0 +1,127 @@ +/* + * 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 Path from 'path'; + +import { v4 as uuidV4 } from 'uuid'; +import { REPO_ROOT } from '@kbn/utils'; +import { FtrConfigProviderContext, FtrConfigProvider } from '@kbn/test'; +import { commonFunctionalServices } from '@kbn/ftr-common-functional-services'; + +import { AnyStep } from './journey'; +import { JourneyConfig } from './journey_config'; + +// These "secret" values are intentionally written in the source. We would make the APM server accept anonymous traffic if we could +const APM_SERVER_URL = 'https://kibana-ops-e2e-perf.apm.us-central1.gcp.cloud.es.io:443'; +const APM_PUBLIC_TOKEN = 'CTs9y3cvcfq13bQqsB'; + +export function makeFtrConfigProvider( + config: JourneyConfig, + steps: AnyStep[] +): FtrConfigProvider { + return async ({ readConfigFile }: FtrConfigProviderContext) => { + const baseConfig = ( + await readConfigFile( + Path.resolve( + REPO_ROOT, + config.isXpack() + ? 'x-pack/test/functional/config.base.js' + : 'test/functional/config.base.js' + ) + ) + ).getAll(); + + const testBuildId = process.env.BUILDKITE_BUILD_ID ?? `local-${uuidV4()}`; + const testJobId = process.env.BUILDKITE_JOB_ID ?? `local-${uuidV4()}`; + const prId = process.env.GITHUB_PR_NUMBER + ? Number.parseInt(process.env.GITHUB_PR_NUMBER, 10) + : undefined; + + if (Number.isNaN(prId)) { + throw new Error('invalid GITHUB_PR_NUMBER environment variable'); + } + + const telemetryLabels: Record = { + branch: process.env.BUILDKITE_BRANCH, + ciBuildId: process.env.BUILDKITE_BUILD_ID, + ciBuildJobId: process.env.BUILDKITE_JOB_ID, + ciBuildNumber: Number(process.env.BUILDKITE_BUILD_NUMBER) || 0, + gitRev: process.env.BUILDKITE_COMMIT, + isPr: prId !== undefined, + ...(prId !== undefined ? { prId } : {}), + ciBuildName: process.env.BUILDKITE_PIPELINE_SLUG, + journeyName: config.getName(), + }; + + return { + ...baseConfig, + + mochaOpts: { + ...baseConfig.mochaOpts, + bail: true, + }, + + services: commonFunctionalServices, + pageObjects: {}, + + servicesRequiredForTestAnalysis: ['performance', 'journeyConfig'], + + junit: { + reportName: `Journey: ${config.getName()}`, + metadata: { + journeyName: config.getName(), + stepNames: steps.map((s) => s.name), + }, + }, + + kbnTestServer: { + ...baseConfig.kbnTestServer, + // delay shutdown by 15 seconds to ensure that APM can report the data it collects during test execution + delayShutdown: 15_000, + + serverArgs: [ + ...baseConfig.kbnTestServer.serverArgs, + `--telemetry.optIn=${process.env.TEST_PERFORMANCE_PHASE === 'TEST'}`, + `--telemetry.labels=${JSON.stringify(telemetryLabels)}`, + '--csp.strict=false', + '--csp.warnLegacyBrowsers=false', + ], + + env: { + ELASTIC_APM_ACTIVE: process.env.TEST_PERFORMANCE_PHASE ? 'true' : 'false', + ELASTIC_APM_CONTEXT_PROPAGATION_ONLY: 'false', + ELASTIC_APM_ENVIRONMENT: process.env.CI ? 'ci' : 'development', + ELASTIC_APM_TRANSACTION_SAMPLE_RATE: '1.0', + ELASTIC_APM_SERVER_URL: APM_SERVER_URL, + ELASTIC_APM_SECRET_TOKEN: APM_PUBLIC_TOKEN, + // capture request body for both errors and request transactions + // https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html#capture-body + ELASTIC_APM_CAPTURE_BODY: 'all', + // capture request headers + // https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html#capture-headers + ELASTIC_APM_CAPTURE_HEADERS: true, + // request body with bigger size will be trimmed. + // 300_000 is the default of the APM server. + // for a body with larger size, we might need to reconfigure the APM server to increase the limit. + // https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html#long-field-max-length + ELASTIC_APM_LONG_FIELD_MAX_LENGTH: 300_000, + ELASTIC_APM_GLOBAL_LABELS: Object.entries({ + ...config.getExtraApmLabels(), + testJobId, + testBuildId, + journeyName: config.getName(), + ftrConfig: config.getRepoRelPath(), + performancePhase: process.env.TEST_PERFORMANCE_PHASE, + }) + .flatMap(([key, value]) => (value == null ? [] : `${key}=${value}`)) + .join(','), + }, + }, + }; + }; +} diff --git a/packages/kbn-journeys/journey/journey_ftr_harness.ts b/packages/kbn-journeys/journey/journey_ftr_harness.ts new file mode 100644 index 0000000000000..672b14f0e1a85 --- /dev/null +++ b/packages/kbn-journeys/journey/journey_ftr_harness.ts @@ -0,0 +1,410 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import Url from 'url'; +import { inspect, format } from 'util'; +import { setTimeout } from 'timers/promises'; + +import * as Rx from 'rxjs'; +import apmNode from 'elastic-apm-node'; +import playwright, { ChromiumBrowser, Page, BrowserContext, CDPSession, Request } from 'playwright'; +import { asyncMap, asyncForEach } from '@kbn/std'; +import { ToolingLog } from '@kbn/tooling-log'; +import { Config } from '@kbn/test'; +import { EsArchiver, KibanaServer } from '@kbn/ftr-common-functional-services'; + +import { Auth } from '../services/auth'; +import { getInputDelays } from '../services/input_delays'; +import { KibanaUrl } from '../services/kibana_url'; + +import type { Step, AnyStep } from './journey'; +import type { JourneyConfig } from './journey_config'; +import { JourneyScreenshots } from './journey_screenshots'; + +export class JourneyFtrHarness { + private readonly screenshots: JourneyScreenshots; + + constructor( + private readonly log: ToolingLog, + private readonly config: Config, + private readonly esArchiver: EsArchiver, + private readonly kibanaServer: KibanaServer, + private readonly auth: Auth, + private readonly journeyConfig: JourneyConfig + ) { + this.screenshots = new JourneyScreenshots(this.journeyConfig.getName()); + } + + private browser: ChromiumBrowser | undefined; + private page: Page | undefined; + private client: CDPSession | undefined; + private context: BrowserContext | undefined; + private currentSpanStack: Array = []; + private currentTransaction: apmNode.Transaction | undefined | null = undefined; + + private pageTeardown$ = new Rx.Subject(); + private telemetryTrackerSubs = new Map(); + + private apm: apmNode.Agent | null = null; + + private async setupApm() { + const kbnTestServerEnv = this.config.get(`kbnTestServer.env`); + + this.apm = apmNode.start({ + serviceName: 'functional test runner', + environment: process.env.CI ? 'ci' : 'development', + active: kbnTestServerEnv.ELASTIC_APM_ACTIVE !== 'false', + serverUrl: kbnTestServerEnv.ELASTIC_APM_SERVER_URL, + secretToken: kbnTestServerEnv.ELASTIC_APM_SECRET_TOKEN, + globalLabels: kbnTestServerEnv.ELASTIC_APM_GLOBAL_LABELS, + transactionSampleRate: kbnTestServerEnv.ELASTIC_APM_TRANSACTION_SAMPLE_RATE, + logger: { + warn: (...args: any[]) => { + this.log.warning('APM WARN', ...args); + }, + info: (...args: any[]) => { + this.log.info('APM INFO', ...args); + }, + fatal: (...args: any[]) => { + this.log.error(format('APM FATAL', ...args)); + }, + error: (...args: any[]) => { + this.log.error(format('APM ERROR', ...args)); + }, + debug: (...args: any[]) => { + this.log.debug('APM DEBUG', ...args); + }, + trace: (...args: any[]) => { + this.log.verbose('APM TRACE', ...args); + }, + }, + }); + + if (this.currentTransaction) { + throw new Error(`Transaction exist, end prev transaction ${this.currentTransaction?.name}`); + } + + this.currentTransaction = this.apm?.startTransaction( + `Journey: ${this.journeyConfig.getName()}`, + 'performance' + ); + } + + private async setupBrowserAndPage() { + const browser = await this.getBrowserInstance(); + this.context = await browser.newContext({ bypassCSP: true }); + + if (this.journeyConfig.shouldAutoLogin()) { + const cookie = await this.auth.login({ username: 'elastic', password: 'changeme' }); + await this.context.addCookies([cookie]); + } + + this.page = await this.context.newPage(); + + if (!process.env.NO_BROWSER_LOG) { + this.page.on('console', this.onConsoleEvent); + } + + await this.sendCDPCommands(this.context, this.page); + + this.trackTelemetryRequests(this.page); + await this.interceptBrowserRequests(this.page); + } + + private async onSetup() { + await Promise.all([ + this.setupApm(), + this.setupBrowserAndPage(), + asyncForEach(this.journeyConfig.getEsArchives(), async (esArchive) => { + await this.esArchiver.load(esArchive); + }), + asyncForEach(this.journeyConfig.getKbnArchives(), async (kbnArchive) => { + await this.kibanaServer.importExport.load(kbnArchive); + }), + ]); + } + + private async tearDownBrowserAndPage() { + if (this.page) { + const telemetryTracker = this.telemetryTrackerSubs.get(this.page); + this.telemetryTrackerSubs.delete(this.page); + + if (telemetryTracker && !telemetryTracker.closed) { + this.log.info(`Waiting for telemetry requests, including starting within next 3 secs`); + this.pageTeardown$.next(this.page); + await new Promise((resolve) => telemetryTracker.add(resolve)); + } + + this.log.info('destroying page'); + await this.client?.detach(); + await this.page.close(); + await this.context?.close(); + } + + if (this.browser) { + this.log.info('closing browser'); + await this.browser.close(); + } + } + + private async teardownApm() { + if (!this.apm) { + return; + } + + if (this.currentTransaction) { + this.currentTransaction.end('Success'); + this.currentTransaction = undefined; + } + + const apmStarted = this.apm.isStarted(); + // @ts-expect-error + const apmActive = apmStarted && this.apm._conf.active; + + if (!apmActive) { + this.log.warning('APM is not active'); + return; + } + + this.log.info('Flushing APM'); + await new Promise((resolve) => this.apm?.flush(() => resolve())); + // wait for the HTTP request that apm.flush() starts, which we + // can't track but hope it is started within 3 seconds, node will stay + // alive for active requests + // https://github.com/elastic/apm-agent-nodejs/issues/2088 + await setTimeout(3000); + } + + private async onTeardown() { + await Promise.all([ + this.tearDownBrowserAndPage(), + this.teardownApm(), + asyncForEach(this.journeyConfig.getEsArchives(), async (esArchive) => { + await this.esArchiver.unload(esArchive); + }), + asyncForEach(this.journeyConfig.getKbnArchives(), async (kbnArchive) => { + await this.kibanaServer.importExport.unload(kbnArchive); + }), + ]); + } + + private async onStepSuccess(step: AnyStep) { + if (!this.page) { + return; + } + + await this.screenshots.addSuccess(step, await this.page.screenshot()); + } + + private async onStepError(step: AnyStep, err: Error) { + if (this.currentTransaction) { + this.currentTransaction.end(`Failure ${err.message}`); + this.currentTransaction = undefined; + } + + if (this.page) { + await this.screenshots.addError(step, await this.page.screenshot()); + } + } + + private async withSpan(name: string, type: string | undefined, block: () => Promise) { + if (!this.currentTransaction) { + return await block(); + } + + const span = this.apm?.startSpan(name, type ?? null, { + childOf: this.currentTransaction, + }); + if (!span) { + return await block(); + } + + try { + this.currentSpanStack.unshift(span); + const result = await block(); + span.setOutcome('success'); + span.end(); + return result; + } catch (error) { + span.setOutcome('failure'); + span.end(); + throw error; + } finally { + if (span !== this.currentSpanStack.shift()) { + // eslint-disable-next-line no-unsafe-finally + throw new Error('span stack mismatch'); + } + } + } + + private getCurrentTraceparent() { + return (this.currentSpanStack.length ? this.currentSpanStack[0] : this.currentTransaction) + ?.traceparent; + } + + private async getBrowserInstance() { + if (this.browser) { + return this.browser; + } + return await this.withSpan('Browser creation', 'setup', async () => { + const headless = !!(process.env.TEST_BROWSER_HEADLESS || process.env.CI); + this.browser = await playwright.chromium.launch({ headless, timeout: 60_000 }); + return this.browser; + }); + } + + private async sendCDPCommands(context: BrowserContext, page: Page) { + const client = await context.newCDPSession(page); + + await client.send('Network.clearBrowserCache'); + await client.send('Network.setCacheDisabled', { cacheDisabled: true }); + await client.send('Network.emulateNetworkConditions', { + latency: 100, + downloadThroughput: 750_000, + uploadThroughput: 750_000, + offline: false, + }); + + return client; + } + + private telemetryTrackerCount = 0; + + private trackTelemetryRequests(page: Page) { + const id = ++this.telemetryTrackerCount; + + const requestFailure$ = Rx.fromEvent(page, 'requestfailed'); + const requestSuccess$ = Rx.fromEvent(page, 'requestfinished'); + const request$ = Rx.fromEvent(page, 'request').pipe( + Rx.takeUntil( + this.pageTeardown$.pipe( + Rx.first((p) => p === page), + Rx.delay(3000) + // If EBT client buffers: + // Rx.mergeMap(async () => { + // await page.waitForFunction(() => { + // // return window.kibana_ebt_client.buffer_size == 0 + // }); + // }) + ) + ), + Rx.mergeMap((request) => { + if (!request.url().includes('telemetry-staging.elastic.co')) { + return Rx.EMPTY; + } + + this.log.debug(`Waiting for telemetry request #${id} to complete`); + return Rx.merge(requestFailure$, requestSuccess$).pipe( + Rx.first((r) => r === request), + Rx.tap({ + complete: () => this.log.debug(`Telemetry request #${id} complete`), + }) + ); + }) + ); + + this.telemetryTrackerSubs.set(page, request$.subscribe()); + } + + private async interceptBrowserRequests(page: Page) { + await page.route('**', async (route, request) => { + const headers = await request.allHeaders(); + const traceparent = this.getCurrentTraceparent(); + if (traceparent && request.isNavigationRequest()) { + await route.continue({ headers: { traceparent, ...headers } }); + } else { + await route.continue(); + } + }); + } + + #_ctx?: Record; + private getCtx() { + if (this.#_ctx) { + return this.#_ctx; + } + + const page = this.page; + + if (!page) { + throw new Error('performance service is not properly initialized'); + } + + this.#_ctx = this.journeyConfig.getExtendedStepCtx({ + page, + log: this.log, + inputDelays: getInputDelays(), + kbnUrl: new KibanaUrl( + new URL( + Url.format({ + protocol: this.config.get('servers.kibana.protocol'), + hostname: this.config.get('servers.kibana.hostname'), + port: this.config.get('servers.kibana.port'), + }) + ) + ), + }); + + return this.#_ctx; + } + + public initMochaSuite(steps: Array>) { + const journeyName = this.journeyConfig.getName(); + + (this.journeyConfig.isSkipped() ? describe.skip : describe)(`Journey[${journeyName}]`, () => { + before(async () => await this.onSetup()); + after(async () => await this.onTeardown()); + + for (const step of steps) { + it(step.name, async () => { + await this.withSpan(`step: ${step.name}`, 'step', async () => { + try { + await step.fn(this.getCtx()); + await this.onStepSuccess(step); + } catch (e) { + const error = new Error(`Step [${step.name}] failed: ${e.message}`); + error.stack = e.stack; + await this.onStepError(step, error); + throw error; // Rethrow error if step fails otherwise it is silently passing + } + }); + }); + } + }); + } + + private onConsoleEvent = async (message: playwright.ConsoleMessage) => { + try { + const { url, lineNumber, columnNumber } = message.location(); + const location = `${url}:${lineNumber}:${columnNumber}`; + + const args = await asyncMap(message.args(), (handle) => handle.jsonValue()); + const text = args.length + ? args.map((arg) => (typeof arg === 'string' ? arg : inspect(arg, false, null))).join(' ') + : message.text(); + + if ( + url.includes('kbn-ui-shared-deps-npm.dll.js') && + text.includes('moment construction falls') + ) { + // ignore errors from moment about constructing dates with invalid formats + return; + } + + const type = message.type(); + const method = type === 'debug' ? type : type === 'warning' ? 'error' : 'info'; + const name = type === 'warning' ? 'error' : 'log'; + this.log[method](`[console.${name}] @ ${location}:\n${text}`); + } catch (error) { + const dbg = inspect(message); + this.log.error( + `Error interpreting browser console.log:\nerror:${error.message}\nmessage:\n${dbg}` + ); + } + }; +} diff --git a/packages/kbn-journeys/journey/journey_screenshots.ts b/packages/kbn-journeys/journey/journey_screenshots.ts new file mode 100644 index 0000000000000..8cd36444ef7ee --- /dev/null +++ b/packages/kbn-journeys/journey/journey_screenshots.ts @@ -0,0 +1,128 @@ +/* + * 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 Path from 'path'; +import Fsp from 'fs/promises'; + +import * as Rx from 'rxjs'; +import { REPO_ROOT } from '@kbn/utils'; +import { FtrScreenshotFilename } from '@kbn/ftr-screenshot-filename'; + +import type { AnyStep } from './journey'; + +interface StepShot { + type: 'success' | 'failure'; + title: string; + filename: string; +} + +interface Manifest { + steps: StepShot[]; +} + +const isObj = (v: unknown): v is Record => typeof v === 'object' && v !== null; +const isString = (v: unknown): v is string => typeof v === 'string'; +const isStepShot = (v: unknown): v is StepShot => + isObj(v) && + (v.type === 'success' || v.type === 'failure') && + isString(v.title) && + isString(v.filename); + +const write = async (path: string, content: string | Buffer) => { + await Fsp.mkdir(Path.dirname(path), { recursive: true }); + await Fsp.writeFile(path, content); +}; + +export class JourneyScreenshots { + static async load(journeyName: string) { + const screenshots = new JourneyScreenshots(journeyName); + + const json = await Fsp.readFile(screenshots.#manifestPath, 'utf8'); + const manifest = JSON.parse(json); + + if (!isObj(manifest)) { + throw new Error('invalid manifest, json parsed but not to an object'); + } + + const { steps } = manifest; + + if (!Array.isArray(steps) || !steps.every(isStepShot)) { + throw new Error('invalid manifest, steps must be an array of StepShot objects'); + } + + screenshots.#manifest = { steps }; + return screenshots; + } + + readonly #dir: string; + readonly #manifestPath: string; + + #manifest: Manifest = { + steps: [], + }; + + constructor(journeyName: string) { + this.#dir = Path.resolve(REPO_ROOT, 'data/journey_screenshots', journeyName); + this.#manifestPath = Path.resolve(this.#dir, 'manifest.json'); + } + + readonly #isLocked = new Rx.BehaviorSubject(false); + async lock(fn: () => Promise) { + if (this.#isLocked.getValue()) { + do { + await Rx.firstValueFrom(this.#isLocked.pipe(Rx.skip(1))); + } while (this.#isLocked.getValue()); + } + + try { + this.#isLocked.next(true); + await fn(); + } finally { + this.#isLocked.next(false); + } + } + + async addError(step: AnyStep, screenshot: Buffer) { + await this.lock(async () => { + const filename = FtrScreenshotFilename.create(`${step.index}-${step.name}-failure`); + this.#manifest.steps.push({ + type: 'failure', + title: `Step #${step.index + 1}: ${step.name} - FAILED`, + filename, + }); + + await Promise.all([ + write(Path.resolve(this.#dir, 'manifest.json'), JSON.stringify(this.#manifest)), + write(Path.resolve(this.#dir, filename), screenshot), + ]); + }); + } + + async addSuccess(step: AnyStep, screenshot: Buffer) { + await this.lock(async () => { + const filename = FtrScreenshotFilename.create(`${step.index}-${step.name}`); + this.#manifest.steps.push({ + type: 'success', + title: `Step #${step.index + 1}: ${step.name} - DONE`, + filename, + }); + + await Promise.all([ + write(Path.resolve(this.#dir, 'manifest.json'), JSON.stringify(this.#manifest)), + write(Path.resolve(this.#dir, filename), screenshot), + ]); + }); + } + + get() { + return this.#manifest.steps.map((stepShot) => ({ + ...stepShot, + path: Path.resolve(this.#dir, stepShot.filename), + })); + } +} diff --git a/packages/kbn-journeys/kibana.jsonc b/packages/kbn-journeys/kibana.jsonc new file mode 100644 index 0000000000000..ab8a15547c158 --- /dev/null +++ b/packages/kbn-journeys/kibana.jsonc @@ -0,0 +1,8 @@ +{ + "type": "shared-common", + "id": "@kbn/journeys", + "owner": "@elastic/kibana-operations", + "devOnly": true, + "runtimeDeps": [], + "typeDeps": [], +} diff --git a/packages/kbn-journeys/package.json b/packages/kbn-journeys/package.json new file mode 100644 index 0000000000000..06920a5ebd241 --- /dev/null +++ b/packages/kbn-journeys/package.json @@ -0,0 +1,7 @@ +{ + "name": "@kbn/journeys", + "private": true, + "version": "1.0.0", + "main": "./target_node/index.js", + "license": "SSPL-1.0 OR Elastic License 2.0" +} diff --git a/packages/kbn-journeys/services/auth.ts b/packages/kbn-journeys/services/auth.ts new file mode 100644 index 0000000000000..b8c68a9fbb09c --- /dev/null +++ b/packages/kbn-journeys/services/auth.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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import Url from 'url'; +import { format } from 'util'; + +import axios, { AxiosResponse } from 'axios'; +import { ToolingLog } from '@kbn/tooling-log'; +import { Config } from '@kbn/test'; +import { KibanaServer } from '@kbn/ftr-common-functional-services'; + +export interface Credentials { + username: string; + password: string; +} + +function extractCookieValue(authResponse: AxiosResponse) { + return authResponse.headers['set-cookie']?.[0].toString().split(';')[0].split('sid=')[1] ?? ''; +} +export class Auth { + constructor( + private readonly config: Config, + private readonly log: ToolingLog, + private readonly kibanaServer: KibanaServer + ) {} + + public async login({ username, password }: Credentials) { + const baseUrl = new URL( + Url.format({ + protocol: this.config.get('servers.kibana.protocol'), + hostname: this.config.get('servers.kibana.hostname'), + port: this.config.get('servers.kibana.port'), + }) + ); + + const loginUrl = new URL('/internal/security/login', baseUrl); + const provider = baseUrl.hostname === 'localhost' ? 'basic' : 'cloud-basic'; + + this.log.info('fetching auth cookie from', loginUrl.href); + const authResponse = await axios.request({ + url: loginUrl.href, + method: 'post', + data: { + providerType: 'basic', + providerName: provider, + currentURL: new URL('/login?next=%2F', baseUrl).href, + params: { username, password }, + }, + headers: { + 'content-type': 'application/json', + 'kbn-version': await this.kibanaServer.version.get(), + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + }, + validateStatus: () => true, + maxRedirects: 0, + }); + + const cookie = extractCookieValue(authResponse); + if (cookie) { + this.log.info('captured auth cookie'); + } else { + this.log.error( + format('unable to determine auth cookie from response', { + status: `${authResponse.status} ${authResponse.statusText}`, + body: authResponse.data, + headers: authResponse.headers, + }) + ); + + throw new Error(`failed to determine auth cookie`); + } + + return { + name: 'sid', + value: cookie, + url: baseUrl.href, + }; + } +} diff --git a/x-pack/test/performance/services/input_delays.ts b/packages/kbn-journeys/services/input_delays.ts similarity index 69% rename from x-pack/test/performance/services/input_delays.ts rename to packages/kbn-journeys/services/input_delays.ts index 483974cb9802d..5f66b26f0f36d 100644 --- a/x-pack/test/performance/services/input_delays.ts +++ b/packages/kbn-journeys/services/input_delays.ts @@ -1,10 +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. + * 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. */ -interface InputDelays { + +export interface InputDelays { TYPING: number; MOUSE_CLICK: number; } @@ -20,7 +22,7 @@ const PROFILES: Record = { }, }; -export function InputDelaysProvider(): InputDelays { +export function getInputDelays(): InputDelays { const profile = PROFILES[process.env.INPUT_DELAY_PROFILE ?? 'user']; if (!profile) { diff --git a/packages/kbn-journeys/services/kibana_url.ts b/packages/kbn-journeys/services/kibana_url.ts new file mode 100644 index 0000000000000..d9c54ccfe3c37 --- /dev/null +++ b/packages/kbn-journeys/services/kibana_url.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export interface PathOptions { + /** + * Query string parameters + */ + params?: Record; + /** + * The hash value of the URL + */ + hash?: string; +} + +export class KibanaUrl { + #baseUrl: URL; + + constructor(baseUrl: URL) { + this.#baseUrl = baseUrl; + } + + /** + * Get an absolute URL based on Kibana's URL + * @param rel relative url, resolved relative to Kibana's url + * @param options optional modifications to apply to the URL + */ + get(rel?: string, options?: PathOptions) { + const url = new URL(rel ?? '/', this.#baseUrl); + + if (options?.params) { + for (const [key, value] of Object.entries(options.params)) { + url.searchParams.set(key, value); + } + } + + if (options?.hash !== undefined) { + url.hash = options.hash; + } + + return url.href; + } + + /** + * Get the URL for an app + * @param appName name of the app to get the URL for + * @param options optional modifications to apply to the URL + */ + app(appName: string, options?: PathOptions) { + return this.get(`/app/${appName}`, options); + } + + toString() { + return this.#baseUrl.href; + } +} diff --git a/packages/kbn-journeys/tsconfig.json b/packages/kbn-journeys/tsconfig.json new file mode 100644 index 0000000000000..f4d18db9ffafa --- /dev/null +++ b/packages/kbn-journeys/tsconfig.json @@ -0,0 +1,17 @@ +{ + "extends": "../../tsconfig.bazel.json", + "compilerOptions": { + "declaration": true, + "declarationMap": true, + "emitDeclarationOnly": true, + "outDir": "target_types", + "stripInternal": false, + "types": [ + "mocha", + "node" + ] + }, + "include": [ + "**/*.ts", + ] +} diff --git a/packages/kbn-performance-testing-dataset-extractor/BUILD.bazel b/packages/kbn-performance-testing-dataset-extractor/BUILD.bazel index 479e494bf3b54..53782e9cfbd08 100644 --- a/packages/kbn-performance-testing-dataset-extractor/BUILD.bazel +++ b/packages/kbn-performance-testing-dataset-extractor/BUILD.bazel @@ -66,8 +66,8 @@ RUNTIME_DEPS = [ TYPES_DEPS = [ "//packages/kbn-dev-cli-errors:npm_module_types", "//packages/kbn-dev-cli-runner:npm_module_types", - "//packages/kbn-test:npm_module_types", "//packages/kbn-tooling-log:npm_module_types", + "//packages/kbn-journeys:npm_module_types", "@npm//@elastic/elasticsearch", "@npm//@types/node", "@npm//@types/jest", diff --git a/packages/kbn-performance-testing-dataset-extractor/src/cli.ts b/packages/kbn-performance-testing-dataset-extractor/src/cli.ts index 435f87bcd5818..f2e88addd63fe 100644 --- a/packages/kbn-performance-testing-dataset-extractor/src/cli.ts +++ b/packages/kbn-performance-testing-dataset-extractor/src/cli.ts @@ -12,16 +12,13 @@ * *************************************************************/ +import path from 'path'; + import { run } from '@kbn/dev-cli-runner'; import { createFlagError } from '@kbn/dev-cli-errors'; -import { EsVersion, readConfigFile } from '@kbn/test'; -import path from 'path'; -import { extractor } from './extractor'; -import { ScalabilitySetup, TestData } from './types'; +import { Journey } from '@kbn/journeys'; -interface Vars { - [key: string]: string; -} +import { extractor } from './extractor'; export async function runExtractor() { run( @@ -50,63 +47,46 @@ export async function runExtractor() { throw createFlagError('--es-password must be defined'); } + const withoutStaticResources = !!flags['without-static-resources'] || false; + const buildId = flags.buildId; + if (buildId && typeof buildId !== 'string') { + throw createFlagError('--buildId must be a string'); + } + if (!buildId) { + throw createFlagError('--buildId must be defined'); + } + const configPath = flags.config; if (typeof configPath !== 'string') { throw createFlagError('--config must be a string'); } - const config = await readConfigFile(log, EsVersion.getDefault(), path.resolve(configPath)); - - const scalabilitySetup: ScalabilitySetup = config.get('scalabilitySetup'); + const journey = await Journey.load(path.resolve(configPath)); + const scalabilitySetup = journey.config.getScalabilityConfig(); if (!scalabilitySetup) { log.warning( `'scalabilitySetup' is not defined in config file, output file for Kibana scalability run won't be generated` ); } - const testData: TestData = config.get('testData'); - - const env = config.get(`kbnTestServer.env`); - if ( - typeof env !== 'object' || - typeof env.ELASTIC_APM_GLOBAL_LABELS !== 'string' || - !env.ELASTIC_APM_GLOBAL_LABELS.includes('journeyName=') - ) { - log.error( - `'journeyName' must be defined in config file: - - env: { - ...config.kbnTestServer.env, - ELASTIC_APM_GLOBAL_LABELS: Object.entries({ - journeyName: , - }) - },` - ); - return; - } - - const envVars: Vars = env.ELASTIC_APM_GLOBAL_LABELS.split(',').reduce( - (acc: Vars, pair: string) => { - const [key, value] = pair.split('='); - return { ...acc, [key]: value }; - }, - {} - ); - const journeyName = envVars.journeyName; - - const buildId = flags.buildId; - if (buildId && typeof buildId !== 'string') { - throw createFlagError('--buildId must be a string'); - } - if (!buildId) { - throw createFlagError('--buildId must be defined'); - } - - const withoutStaticResources = !!flags['without-static-resources'] || false; + const testData = { + esArchives: journey.config.getEsArchives(), + kbnArchives: journey.config.getKbnArchives(), + }; return extractor({ - param: { journeyName, scalabilitySetup, testData, buildId, withoutStaticResources }, - client: { baseURL, username, password }, + param: { + journeyName: journey.config.getName(), + scalabilitySetup, + testData, + buildId, + withoutStaticResources, + }, + client: { + baseURL, + username, + password, + }, log, }); }, diff --git a/packages/kbn-performance-testing-dataset-extractor/src/types.ts b/packages/kbn-performance-testing-dataset-extractor/src/types.ts index 69df8a5fd490c..3b7eb1a356adf 100644 --- a/packages/kbn-performance-testing-dataset-extractor/src/types.ts +++ b/packages/kbn-performance-testing-dataset-extractor/src/types.ts @@ -7,6 +7,7 @@ */ import { ToolingLog } from '@kbn/tooling-log'; +import { ScalabilitySetup } from '@kbn/journeys'; export interface Request { transactionId: string; @@ -31,19 +32,6 @@ export interface Stream { requests: T[]; } -export interface InjectionStep { - action: string; - minUsersCount?: number; - maxUsersCount: number; - duration: string; -} - -export interface ScalabilitySetup { - warmup: InjectionStep[]; - test: InjectionStep[]; - maxDuration: string; -} - export interface TestData { kbnArchives?: string[]; esArchives?: string[]; @@ -52,7 +40,7 @@ export interface TestData { export interface CLIParams { param: { journeyName: string; - scalabilitySetup: ScalabilitySetup; + scalabilitySetup?: ScalabilitySetup; testData: TestData; buildId: string; withoutStaticResources: boolean; diff --git a/packages/kbn-test/BUILD.bazel b/packages/kbn-test/BUILD.bazel index a51766a8f6c63..1deca3a0f6d07 100644 --- a/packages/kbn-test/BUILD.bazel +++ b/packages/kbn-test/BUILD.bazel @@ -99,6 +99,7 @@ TYPES_DEPS = [ "//packages/kbn-tooling-log:npm_module_types", "//packages/kbn-bazel-packages:npm_module_types", "//packages/kbn-get-repo-files:npm_module_types", + "//packages/kbn-ftr-screenshot-filename:npm_module_types", "@npm//@elastic/elasticsearch", "@npm//@jest/console", "@npm//@jest/reporters", @@ -116,6 +117,7 @@ TYPES_DEPS = [ "@npm//jest-snapshot", "@npm//redux", "@npm//rxjs", + "@npm//playwright", "@npm//xmlbuilder", "@npm//@types/archiver", "@npm//@types/chance", diff --git a/packages/kbn-test/index.ts b/packages/kbn-test/index.ts index befdf3f3d3a9b..8d1b3cefde463 100644 --- a/packages/kbn-test/index.ts +++ b/packages/kbn-test/index.ts @@ -6,23 +6,13 @@ * Side Public License, v 1. */ -// @internal -import { - runTestsCli, - processRunTestsCliOptions, - startServersCli, - processStartServersCliOptions, - // @ts-ignore not typed yet -} from './src/functional_tests/cli'; - export { KbnClientRequesterError } from './src/kbn_client/kbn_client_requester_error'; // @internal -export { runTestsCli, processRunTestsCliOptions, startServersCli, processStartServersCliOptions }; +export { startServersCli, startServers } from './src/functional_tests/start_servers'; -// @ts-ignore not typed yet // @internal -export { runTests, startServers } from './src/functional_tests/tasks'; +export { runTestsCli, runTests } from './src/functional_tests/run_tests'; export { getKibanaCliArg, getKibanaCliLoggers } from './src/functional_tests/lib/kibana_cli_args'; @@ -48,15 +38,9 @@ export { systemIndicesSuperuser, } from './src/kbn'; -export { readConfigFile } from './src/functional_test_runner/lib/config/read_config_file'; - -export { runFtrCli } from './src/functional_test_runner/cli'; - // @internal export { setupJUnitReportGeneration, escapeCdata } from './src/mocha'; -export { runFailedTestsReporterCli } from './src/failed_tests_reporter'; - export { CI_PARALLEL_PROCESS_PREFIX } from './src/ci_parallel_process_prefix'; export * from './src/functional_test_runner'; diff --git a/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts b/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts deleted file mode 100644 index 9336c40d35bdb..0000000000000 --- a/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { createHash } from 'crypto'; -import { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'fs'; -import { join, basename, resolve } from 'path'; - -import { ToolingLog } from '@kbn/tooling-log'; -import { REPO_ROOT } from '@kbn/utils'; -import { escape } from 'he'; - -import { BuildkiteMetadata } from './buildkite_metadata'; -import { TestFailure } from './get_failures'; - -const findScreenshots = (dirPath: string, allScreenshots: string[] = []) => { - const files = readdirSync(dirPath); - - for (const file of files) { - if (statSync(join(dirPath, file)).isDirectory()) { - if (file.match(/node_modules/)) { - continue; - } - - allScreenshots = findScreenshots(join(dirPath, file), allScreenshots); - } else { - const fullPath = join(dirPath, file); - if (fullPath.match(/screenshots\/failure\/.+\.png$/)) { - allScreenshots.push(fullPath); - } - } - } - - return allScreenshots; -}; - -export function reportFailuresToFile( - log: ToolingLog, - failures: TestFailure[], - bkMeta: BuildkiteMetadata -) { - if (!failures?.length) { - return; - } - - let screenshots: string[]; - try { - screenshots = [ - ...findScreenshots(join(REPO_ROOT, 'test', 'functional')), - ...findScreenshots(join(REPO_ROOT, 'x-pack', 'test', 'functional')), - ]; - } catch (e) { - log.error(e as Error); - screenshots = []; - } - - const screenshotsByName: Record = {}; - for (const screenshot of screenshots) { - const [name] = basename(screenshot).split('.'); - screenshotsByName[name] = screenshot; - } - - // Jest could, in theory, fail 1000s of tests and write 1000s of failures - // So let's just write files for the first 20 - for (const failure of failures.slice(0, 20)) { - const hash = createHash('md5').update(failure.name).digest('hex'); - const filenameBase = `${ - process.env.BUILDKITE_JOB_ID ? process.env.BUILDKITE_JOB_ID + '_' : '' - }${hash}`; - const dir = join('target', 'test_failures'); - - const failureLog = [ - ['Test:', '-----', failure.classname, failure.name, ''], - ['Failure:', '--------', failure.failure], - failure['system-out'] ? ['', 'Standard Out:', '-------------', failure['system-out']] : [], - ] - .flat() - .join('\n'); - - const failureJSON = JSON.stringify( - { - ...failure, - hash, - buildId: bkMeta.buildId, - jobId: bkMeta.jobId, - url: bkMeta.url, - jobUrl: bkMeta.jobUrl, - jobName: bkMeta.jobName, - }, - null, - 2 - ); - - let screenshot = ''; - const truncatedName = failure.name.replace(/([^ a-zA-Z0-9-]+)/g, '_').slice(0, 80); - const failureNameHash = createHash('sha256').update(failure.name).digest('hex'); - const screenshotName = `${truncatedName}-${failureNameHash}`; - - if (screenshotsByName[screenshotName]) { - try { - screenshot = readFileSync(screenshotsByName[screenshotName]).toString('base64'); - } catch (e) { - log.error(e as Error); - } - } - - const screenshotHtml = screenshot - ? `` - : ''; - - const failureHTML = readFileSync( - resolve( - REPO_ROOT, - 'packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html' - ) - ) - .toString() - .replace('$TITLE', escape(failure.name)) - .replace( - '$MAIN', - ` - ${failure.classname - .split('.') - .map((part) => `
${escape(part.replace('·', '.'))}
`) - .join('')} -
-

${escape(failure.name)}

-

- - Failures in tracked branches: ${ - failure.failureCount || 0 - } - ${ - failure.githubIssue - ? `
${escape( - failure.githubIssue - )}` - : '' - } -
-

- ${ - bkMeta.jobUrl - ? `

- - Buildkite Job
- ${escape(bkMeta.jobUrl)} -
-

` - : '' - } -
${escape(failure.failure)}
- ${screenshotHtml} -
${escape(failure['system-out'] || '')}
- ` - ); - - mkdirSync(dir, { recursive: true }); - writeFileSync(join(dir, `${filenameBase}.log`), failureLog, 'utf8'); - writeFileSync(join(dir, `${filenameBase}.html`), failureHTML, 'utf8'); - writeFileSync(join(dir, `${filenameBase}.json`), failureJSON, 'utf8'); - } -} diff --git a/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts b/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts deleted file mode 100644 index 5702372aab7be..0000000000000 --- a/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import Path from 'path'; - -import { REPO_ROOT } from '@kbn/utils'; -import { run } from '@kbn/dev-cli-runner'; -import { createFailError, createFlagError } from '@kbn/dev-cli-errors'; -import { CiStatsReporter } from '@kbn/ci-stats-reporter'; -import globby from 'globby'; -import normalize from 'normalize-path'; - -import { getFailures } from './get_failures'; -import { GithubApi } from './github_api'; -import { updateFailureIssue, createFailureIssue } from './report_failure'; -import { readTestReport } from './test_report'; -import { addMessagesToReport } from './add_messages_to_report'; -import { getReportMessageIter } from './report_metadata'; -import { reportFailuresToEs } from './report_failures_to_es'; -import { reportFailuresToFile } from './report_failures_to_file'; -import { getBuildkiteMetadata } from './buildkite_metadata'; -import { ExistingFailedTestIssues } from './existing_failed_test_issues'; - -const DEFAULT_PATTERNS = [Path.resolve(REPO_ROOT, 'target/junit/**/*.xml')]; -const DISABLE_MISSING_TEST_REPORT_ERRORS = - process.env.DISABLE_MISSING_TEST_REPORT_ERRORS === 'true'; - -export function runFailedTestsReporterCli() { - run( - async ({ log, flags }) => { - const indexInEs = flags['index-errors']; - - let updateGithub = flags['github-update']; - if (updateGithub && !process.env.GITHUB_TOKEN) { - throw createFailError( - 'GITHUB_TOKEN environment variable must be set, otherwise use --no-github-update flag' - ); - } - - let branch: string = ''; - if (updateGithub) { - let isPr = false; - - if (process.env.BUILDKITE === 'true') { - branch = process.env.BUILDKITE_BRANCH || ''; - isPr = process.env.BUILDKITE_PULL_REQUEST === 'true'; - updateGithub = process.env.REPORT_FAILED_TESTS_TO_GITHUB === 'true'; - } else { - // JOB_NAME is formatted as `elastic+kibana+7.x` in some places and `elastic+kibana+7.x/JOB=kibana-intake,node=immutable` in others - const jobNameSplit = (process.env.JOB_NAME || '').split(/\+|\//); - branch = jobNameSplit.length >= 3 ? jobNameSplit[2] : process.env.GIT_BRANCH || ''; - isPr = !!process.env.ghprbPullId; - - const isMainOrVersion = branch === 'main' || branch.match(/^\d+\.(x|\d+)$/); - if (!isMainOrVersion || isPr) { - log.info('Failure issues only created on main/version branch jobs'); - updateGithub = false; - } - } - - if (!branch) { - throw createFailError( - 'Unable to determine originating branch from job name or other environment variables' - ); - } - } - - const githubApi = new GithubApi({ - log, - token: process.env.GITHUB_TOKEN, - dryRun: !updateGithub, - }); - - const bkMeta = getBuildkiteMetadata(); - - try { - const buildUrl = flags['build-url'] || (updateGithub ? '' : 'http://buildUrl'); - if (typeof buildUrl !== 'string' || !buildUrl) { - throw createFlagError('Missing --build-url or process.env.BUILD_URL'); - } - - const patterns = (flags._.length ? flags._ : DEFAULT_PATTERNS).map((p) => - normalize(Path.resolve(p)) - ); - log.info('Searching for reports at', patterns); - const reportPaths = await globby(patterns, { - absolute: true, - }); - - if (!reportPaths.length && DISABLE_MISSING_TEST_REPORT_ERRORS) { - // it is fine for code coverage to not have test results - return; - } - - if (!reportPaths.length) { - throw createFailError(`Unable to find any junit reports with patterns [${patterns}]`); - } - - log.info('found', reportPaths.length, 'junit reports', reportPaths); - - const existingIssues = new ExistingFailedTestIssues(log); - for (const reportPath of reportPaths) { - const report = await readTestReport(reportPath); - const messages = Array.from(getReportMessageIter(report)); - const failures = getFailures(report); - - await existingIssues.loadForFailures(failures); - - if (indexInEs) { - await reportFailuresToEs(log, failures); - } - - for (const failure of failures) { - const pushMessage = (msg: string) => { - messages.push({ - classname: failure.classname, - name: failure.name, - message: msg, - }); - }; - - if (failure.likelyIrrelevant) { - pushMessage( - 'Failure is likely irrelevant' + - (updateGithub ? ', so an issue was not created or updated' : '') - ); - continue; - } - - const existingIssue = existingIssues.getForFailure(failure); - if (existingIssue) { - const { newBody, newCount } = await updateFailureIssue( - buildUrl, - existingIssue, - githubApi, - branch - ); - const url = existingIssue.github.htmlUrl; - existingIssue.github.body = newBody; - failure.githubIssue = url; - failure.failureCount = updateGithub ? newCount : newCount - 1; - pushMessage(`Test has failed ${newCount - 1} times on tracked branches: ${url}`); - if (updateGithub) { - pushMessage(`Updated existing issue: ${url} (fail count: ${newCount})`); - } - continue; - } - - const newIssue = await createFailureIssue(buildUrl, failure, githubApi, branch); - existingIssues.addNewlyCreated(failure, newIssue); - pushMessage('Test has not failed recently on tracked branches'); - if (updateGithub) { - pushMessage(`Created new issue: ${newIssue.html_url}`); - failure.githubIssue = newIssue.html_url; - } - failure.failureCount = updateGithub ? 1 : 0; - } - - // mutates report to include messages and writes updated report to disk - await addMessagesToReport({ - report, - messages, - log, - reportPath, - dryRun: !flags['report-update'], - }); - - reportFailuresToFile(log, failures, bkMeta); - } - } finally { - await CiStatsReporter.fromEnv(log).metrics([ - { - group: 'github api request count', - id: `failed test reporter`, - value: githubApi.getRequestCount(), - meta: Object.fromEntries( - Object.entries(bkMeta).map( - ([k, v]) => [`buildkite${k[0].toUpperCase()}${k.slice(1)}`, v] as const - ) - ), - }, - ]); - } - }, - { - description: `a cli that opens issues or updates existing issues based on junit reports`, - flags: { - boolean: ['github-update', 'report-update'], - string: ['build-url'], - default: { - 'github-update': true, - 'report-update': true, - 'index-errors': true, - 'build-url': process.env.BUILD_URL, - }, - help: ` - --no-github-update Execute the CLI without writing to Github - --no-report-update Execute the CLI without writing to the JUnit reports - --no-index-errors Execute the CLI without indexing failures into Elasticsearch - --build-url URL of the failed build, defaults to process.env.BUILD_URL - `, - }, - } - ); -} diff --git a/packages/kbn-test/src/functional_test_runner/cli.ts b/packages/kbn-test/src/functional_test_runner/cli.ts index de20c93c39995..dfd1edc1d8fc4 100644 --- a/packages/kbn-test/src/functional_test_runner/cli.ts +++ b/packages/kbn-test/src/functional_test_runner/cli.ts @@ -9,26 +9,15 @@ import Path from 'path'; import { inspect } from 'util'; -import { run, Flags } from '@kbn/dev-cli-runner'; +import { run } from '@kbn/dev-cli-runner'; import { createFlagError } from '@kbn/dev-cli-errors'; import { ToolingLog } from '@kbn/tooling-log'; import { getTimeReporter } from '@kbn/ci-stats-reporter'; import exitHook from 'exit-hook'; +import { readConfigFile, EsVersion } from './lib'; import { FunctionalTestRunner } from './functional_test_runner'; -const makeAbsolutePath = (v: string) => Path.resolve(process.cwd(), v); -const toArray = (v: string | string[]) => ([] as string[]).concat(v || []); -const parseInstallDir = (flags: Flags) => { - const flag = flags['kibana-install-dir']; - - if (typeof flag !== 'string' && flag !== undefined) { - throw createFlagError('--kibana-install-dir must be a string or not defined'); - } - - return flag ? makeAbsolutePath(flag) : undefined; -}; - export function runFtrCli() { const runStartTime = Date.now(); const toolingLog = new ToolingLog({ @@ -37,52 +26,49 @@ export function runFtrCli() { }); const reportTime = getTimeReporter(toolingLog, 'scripts/functional_test_runner'); run( - async ({ flags, log }) => { - const esVersion = flags['es-version'] || undefined; // convert "" to undefined - if (esVersion !== undefined && typeof esVersion !== 'string') { - throw createFlagError('expected --es-version to be a string'); + async ({ flagsReader, log }) => { + const esVersionInput = flagsReader.string('es-version'); + + const configPaths = [ + ...(flagsReader.arrayOfStrings('config') ?? []), + ...(flagsReader.arrayOfStrings('journey') ?? []), + ].map((rel) => Path.resolve(rel)); + if (configPaths.length !== 1) { + throw createFlagError(`Expected there to be exactly one --config/--journey flag`); } - const configRel = flags.config; - if (typeof configRel !== 'string' || !configRel) { - throw createFlagError('--config is required'); - } - const configPath = makeAbsolutePath(configRel); - - const functionalTestRunner = new FunctionalTestRunner( - log, - configPath, - { - mochaOpts: { - bail: flags.bail, - dryRun: flags['dry-run'], - grep: flags.grep || undefined, - invert: flags.invert, - }, - kbnTestServer: { - installDir: parseInstallDir(flags), - }, - suiteFiles: { - include: toArray(flags.include as string | string[]).map(makeAbsolutePath), - exclude: toArray(flags.exclude as string | string[]).map(makeAbsolutePath), - }, - suiteTags: { - include: toArray(flags['include-tag'] as string | string[]), - exclude: toArray(flags['exclude-tag'] as string | string[]), - }, - updateBaselines: flags.updateBaselines || flags.u, - updateSnapshots: flags.updateSnapshots || flags.u, + const esVersion = esVersionInput ? new EsVersion(esVersionInput) : EsVersion.getDefault(); + const settingOverrides = { + mochaOpts: { + bail: flagsReader.boolean('bail'), + dryRun: flagsReader.boolean('dry-run'), + grep: flagsReader.string('grep'), + invert: flagsReader.boolean('invert'), }, - esVersion - ); + kbnTestServer: { + installDir: flagsReader.path('kibana-install-dir'), + }, + suiteFiles: { + include: flagsReader.arrayOfPaths('include') ?? [], + exclude: flagsReader.arrayOfPaths('exclude') ?? [], + }, + suiteTags: { + include: flagsReader.arrayOfStrings('include-tag') ?? [], + exclude: flagsReader.arrayOfStrings('exclude-tag') ?? [], + }, + updateBaselines: flagsReader.boolean('updateBaselines') || flagsReader.boolean('u'), + updateSnapshots: flagsReader.boolean('updateSnapshots') || flagsReader.boolean('u'), + }; + + const config = await readConfigFile(log, esVersion, configPaths[0], settingOverrides); - await functionalTestRunner.readConfigFile(); + const functionalTestRunner = new FunctionalTestRunner(log, config, esVersion); - if (flags.throttle) { + if (flagsReader.boolean('throttle')) { process.env.TEST_THROTTLE_NETWORK = '1'; } - if (flags.headless) { + if (flagsReader.boolean('headless')) { process.env.TEST_BROWSER_HEADLESS = '1'; } @@ -95,7 +81,7 @@ export function runFtrCli() { await reportTime(runStartTime, 'total', { success: false, err: err.message, - ...flags, + ...Object.fromEntries(flagsReader.getUsed().entries()), }); log.indent(-log.getIndent()); log.error(err); @@ -103,7 +89,7 @@ export function runFtrCli() { } else { await reportTime(runStartTime, 'total', { success: true, - ...flags, + ...Object.fromEntries(flagsReader.getUsed().entries()), }); } @@ -118,7 +104,7 @@ export function runFtrCli() { exitHook(teardown); try { - if (flags['test-stats']) { + if (flagsReader.boolean('test-stats')) { process.stderr.write( JSON.stringify(await functionalTestRunner.getTestStats(), null, 2) + '\n' ); @@ -139,6 +125,7 @@ export function runFtrCli() { flags: { string: [ 'config', + 'journey', 'grep', 'include', 'exclude', @@ -159,7 +146,8 @@ export function runFtrCli() { 'dry-run', ], help: ` - --config=path path to a config file + --config=path path to a config file (either this or --journey is required) + --journey=path path to a journey file (either this or --config is required) --bail stop tests after the first failure --grep pattern used to select which tests to run --invert invert grep to exclude tests diff --git a/packages/kbn-test/src/functional_test_runner/fake_mocha_types.ts b/packages/kbn-test/src/functional_test_runner/fake_mocha_types.ts index 506b6f139f736..17e9663e33883 100644 --- a/packages/kbn-test/src/functional_test_runner/fake_mocha_types.ts +++ b/packages/kbn-test/src/functional_test_runner/fake_mocha_types.ts @@ -15,6 +15,7 @@ import { EventEmitter } from 'events'; export interface Suite { + currentTest?: Test; suites: Suite[]; tests: Test[]; title: string; diff --git a/packages/kbn-test/src/functional_test_runner/functional_test_runner.ts b/packages/kbn-test/src/functional_test_runner/functional_test_runner.ts index 4e549e960dc26..11f99abfa6fbf 100644 --- a/packages/kbn-test/src/functional_test_runner/functional_test_runner.ts +++ b/packages/kbn-test/src/functional_test_runner/functional_test_runner.ts @@ -14,7 +14,6 @@ import { REPO_ROOT } from '@kbn/utils'; import { Suite, Test } from './fake_mocha_types'; import { Lifecycle, - readConfigFile, ProviderCollection, Providers, readProviderSpec, @@ -32,8 +31,7 @@ export class FunctionalTestRunner { private readonly esVersion: EsVersion; constructor( private readonly log: ToolingLog, - private readonly configFile: string, - private readonly configOverrides: any, + private readonly config: Config, esVersion?: string | EsVersion ) { this.esVersion = @@ -47,8 +45,8 @@ export class FunctionalTestRunner { async run(abortSignal?: AbortSignal) { const testStats = await this.getTestStats(); - return await this.runHarness(async (config, lifecycle, coreProviders) => { - SuiteTracker.startTracking(lifecycle, this.configFile); + return await this.runHarness(async (lifecycle, coreProviders) => { + SuiteTracker.startTracking(lifecycle, this.config.path); const realServices = !testStats || (testStats.testCount > 0 && testStats.nonSkippedTestCount > 0); @@ -56,19 +54,19 @@ export class FunctionalTestRunner { const providers = realServices ? new ProviderCollection(this.log, [ ...coreProviders, - ...readProviderSpec('Service', config.get('services')), - ...readProviderSpec('PageObject', config.get('pageObjects')), + ...readProviderSpec('Service', this.config.get('services')), + ...readProviderSpec('PageObject', this.config.get('pageObjects')), ]) - : this.getStubProviderCollection(config, coreProviders); + : this.getStubProviderCollection(coreProviders); if (realServices) { if (providers.hasService('es')) { - await this.validateEsVersion(config); + await this.validateEsVersion(); } await providers.loadAll(); } - const customTestRunner = config.get('testRunner'); + const customTestRunner = this.config.get('testRunner'); if (customTestRunner) { this.log.warning( 'custom test runner defined, ignoring all mocha/suite/filtering related options' @@ -78,7 +76,7 @@ export class FunctionalTestRunner { let reporter; let reporterOptions; - if (config.get('mochaOpts.dryRun')) { + if (this.config.get('mochaOpts.dryRun')) { // override default reporter for dryRun results const targetFile = Path.resolve(REPO_ROOT, 'target/functional-tests/dryRunOutput.json'); reporter = 'json'; @@ -88,22 +86,22 @@ export class FunctionalTestRunner { this.log.info(`Dry run results will be stored in ${targetFile}`); } - const mocha = await setupMocha( + const mocha = await setupMocha({ lifecycle, - this.log, - config, + log: this.log, + config: this.config, providers, - this.esVersion, + esVersion: this.esVersion, reporter, - reporterOptions - ); + reporterOptions, + }); // there's a bug in mocha's dry run, see https://github.com/mochajs/mocha/issues/4838 // until we can update to a mocha version where this is fixed, we won't actually // execute the mocha dry run but simulate it by reading the suites and tests of // the mocha object and writing a report file with similar structure to the json report // (just leave out some execution details like timing, retry and erros) - if (config.get('mochaOpts.dryRun')) { + if (this.config.get('mochaOpts.dryRun')) { return this.simulateMochaDryRun(mocha); } @@ -123,8 +121,8 @@ export class FunctionalTestRunner { }); } - private async validateEsVersion(config: Config) { - const es = createEsClientForFtrConfig(config); + private async validateEsVersion() { + const es = createEsClientForFtrConfig(this.config); let esInfo; try { @@ -151,13 +149,19 @@ export class FunctionalTestRunner { } async getTestStats() { - return await this.runHarness(async (config, lifecycle, coreProviders) => { - if (config.get('testRunner')) { + return await this.runHarness(async (lifecycle, coreProviders) => { + if (this.config.get('testRunner')) { return; } - const providers = this.getStubProviderCollection(config, coreProviders); - const mocha = await setupMocha(lifecycle, this.log, config, providers, this.esVersion); + const providers = this.getStubProviderCollection(coreProviders); + const mocha = await setupMocha({ + lifecycle, + log: this.log, + config: this.config, + providers, + esVersion: this.esVersion, + }); const queue = new Set([mocha.suite]); const allTests: Test[] = []; @@ -178,7 +182,7 @@ export class FunctionalTestRunner { }); } - private getStubProviderCollection(config: Config, coreProviders: Providers) { + private getStubProviderCollection(coreProviders: Providers) { // when we want to load the tests but not actually run anything we can // use stubbed providers which allow mocha to do it's thing without taking // too much time @@ -206,32 +210,30 @@ export class FunctionalTestRunner { ...coreProviders, ...readStubbedProviderSpec( 'Service', - config.get('services'), - config.get('servicesRequiredForTestAnalysis') + this.config.get('services'), + this.config.get('servicesRequiredForTestAnalysis') ), - ...readStubbedProviderSpec('PageObject', config.get('pageObjects'), []), + ...readStubbedProviderSpec('PageObject', this.config.get('pageObjects'), []), ]); } private async runHarness( - handler: (config: Config, lifecycle: Lifecycle, coreProviders: Providers) => Promise + handler: (lifecycle: Lifecycle, coreProviders: Providers) => Promise ): Promise { let runErrorOccurred = false; const lifecycle = new Lifecycle(this.log); try { - const config = await this.readConfigFile(); - this.log.debug('Config loaded'); - if ( - (!config.get('testFiles') || config.get('testFiles').length === 0) && - !config.get('testRunner') + this.config.module.type !== 'journey' && + (!this.config.get('testFiles') || this.config.get('testFiles').length === 0) && + !this.config.get('testRunner') ) { throw new Error('No tests defined.'); } const dockerServers = new DockerServersService( - config.get('dockerServers'), + this.config.get('dockerServers'), this.log, lifecycle ); @@ -240,13 +242,13 @@ export class FunctionalTestRunner { const coreProviders = readProviderSpec('Service', { lifecycle: () => lifecycle, log: () => this.log, - config: () => config, + config: () => this.config, dockerServers: () => dockerServers, esVersion: () => this.esVersion, - dedicatedTaskRunner: () => new DedicatedTaskRunner(config, this.log), + dedicatedTaskRunner: () => new DedicatedTaskRunner(this.config, this.log), }); - return await handler(config, lifecycle, coreProviders); + return await handler(lifecycle, coreProviders); } catch (runError) { runErrorOccurred = true; throw runError; @@ -265,10 +267,6 @@ export class FunctionalTestRunner { } } - public async readConfigFile() { - return await readConfigFile(this.log, this.esVersion, this.configFile, this.configOverrides); - } - simulateMochaDryRun(mocha: any) { interface TestEntry { file: string; diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/config.test.ts b/packages/kbn-test/src/functional_test_runner/lib/config/config.test.ts index d551e7a884b41..f55a68d3e025c 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/config.test.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/config.test.ts @@ -23,6 +23,7 @@ describe('Config', () => { }, primary: true, path: process.cwd(), + module: {} as any, }); expect(config.has('services.foo')).toEqual(true); diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/config.ts b/packages/kbn-test/src/functional_test_runner/lib/config/config.ts index d6248b9628e73..6fa2f2acc9046 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/config.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/config.ts @@ -10,6 +10,7 @@ import { Schema } from 'joi'; import { cloneDeepWith, get, has, toPath } from 'lodash'; import { schema } from './schema'; +import { ConfigModule } from './config_loading'; const $values = Symbol('values'); @@ -17,25 +18,27 @@ interface Options { settings?: Record; primary?: boolean; path: string; + module: ConfigModule; } export class Config { public readonly path: string; + public readonly module: ConfigModule; private [$values]: Record; constructor(options: Options) { - const { settings = {}, primary = false, path = null } = options || {}; - - if (!path) { + if (!options.path) { throw new TypeError('path is a required option'); } - this.path = path; - const { error, value } = schema.validate(settings, { + this.path = options.path; + this.module = options.module; + + const { error, value } = schema.validate(options.settings, { abortEarly: false, context: { - primary: !!primary, - path, + primary: !!options?.primary, + path: options.path, }, }); diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/read_config_file.test.ts b/packages/kbn-test/src/functional_test_runner/lib/config/config_loading.test.ts similarity index 97% rename from packages/kbn-test/src/functional_test_runner/lib/config/read_config_file.test.ts rename to packages/kbn-test/src/functional_test_runner/lib/config/config_loading.test.ts index 29b723dae7195..a5ccac5edea81 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/read_config_file.test.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/config_loading.test.ts @@ -7,7 +7,7 @@ */ import { ToolingLog } from '@kbn/tooling-log'; -import { readConfigFile } from './read_config_file'; +import { readConfigFile } from './config_loading'; import { Config } from './config'; import { EsVersion } from '../es_version'; diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/config_loading.ts b/packages/kbn-test/src/functional_test_runner/lib/config/config_loading.ts new file mode 100644 index 0000000000000..cfa2cabec4dfc --- /dev/null +++ b/packages/kbn-test/src/functional_test_runner/lib/config/config_loading.ts @@ -0,0 +1,182 @@ +/* + * 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 Path from 'path'; +import { ToolingLog } from '@kbn/tooling-log'; +import { defaultsDeep } from 'lodash'; +import { createFlagError, createFailError } from '@kbn/dev-cli-errors'; +import { REPO_ROOT } from '@kbn/utils'; + +import { FtrConfigProvider, GenericFtrProviderContext } from '../../public_types'; +import { Config } from './config'; +import { EsVersion } from '../es_version'; +import { FTR_CONFIGS_MANIFEST_REL, FTR_CONFIGS_MANIFEST_PATHS } from './ftr_configs_manifest'; + +interface LoadSettingsOptions { + path: string; + settingOverrides: any; + primary: boolean; +} + +interface Journey { + config: { + isSkipped(): boolean; + }; + testProvider(ctx: GenericFtrProviderContext): void; +} + +export type ConfigModule = + | { + type: 'config'; + path: string; + provider: FtrConfigProvider; + } + | { + type: 'journey'; + path: string; + provider: FtrConfigProvider; + journey: Journey; + }; + +async function getConfigModule({ + path, + primary, +}: { + path: string; + primary: boolean; +}): Promise { + let resolvedPath; + try { + resolvedPath = require.resolve(path); + } catch (error) { + if (error.code === 'MODULE_NOT_FOUND') { + throw createFlagError(`Unable to find config file [${path}]`); + } + throw error; + } + + if ( + primary && + !FTR_CONFIGS_MANIFEST_PATHS.includes(resolvedPath) && + !resolvedPath.includes(`${Path.sep}__fixtures__${Path.sep}`) + ) { + const rel = Path.relative(REPO_ROOT, resolvedPath); + throw createFlagError( + `Refusing to load FTR Config at [${rel}] which is not listed in [${FTR_CONFIGS_MANIFEST_REL}]. All FTR Config files must be listed there, use the "enabled" key if the FTR Config should be run on automatically on PR CI, or the "disabled" key if it is run manually or by a special job.` + ); + } + + // eslint-disable-next-line @typescript-eslint/no-var-requires + const exports = require(resolvedPath); + const defaultExport = exports.__esModule ? exports.default : exports; + if (typeof defaultExport === 'function') { + return { + type: 'config', + path: resolvedPath, + provider: defaultExport, + }; + } + + const { journey } = exports; + if ( + !journey.constructor || + typeof journey.constructor !== 'function' || + journey.constructor.name !== 'Journey' + ) { + const rel = Path.relative(process.cwd(), resolvedPath); + throw createFailError( + `"journey" export in journey at [${rel}] is not a valid instance of Journey` + ); + } + + return { + type: 'journey', + path: resolvedPath, + provider: journey.constructor.convertToFtrConfigProvider(journey), + journey, + }; +} + +const cache = new WeakMap>(); +async function executeConfigModule( + log: ToolingLog, + esVersion: EsVersion, + options: LoadSettingsOptions, + module: ConfigModule +): Promise { + const cached = cache.get(module.provider); + + if (cached) { + return defaultsDeep({}, options.settingOverrides, await cached); + } + + log.debug(`Loading config file from ${Path.relative(process.cwd(), options.path)}`); + const settings: Promise = module.provider({ + log, + esVersion, + async readConfigFile(p: string) { + const childModule = await getConfigModule({ + primary: false, + path: p, + }); + + return new Config({ + settings: await executeConfigModule( + log, + esVersion, + { + path: childModule.path, + settingOverrides: {}, + primary: false, + }, + childModule + ), + primary: false, + path: p, + module: childModule, + }); + }, + }); + + cache.set(module.provider, Promise.resolve(settings)); + + return defaultsDeep({}, options.settingOverrides, await settings); +} + +const ident = (vars: T) => vars; + +export async function readConfigFile( + log: ToolingLog, + esVersion: EsVersion, + path: string, + settingOverrides: any = {}, + extendSettings: (vars: any) => any = ident +) { + const module = await getConfigModule({ + primary: true, + path, + }); + + return new Config({ + settings: extendSettings( + await executeConfigModule( + log, + esVersion, + { + path, + settingOverrides, + primary: true, + }, + module + ) + ), + primary: true, + path, + module, + }); +} diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/index.ts b/packages/kbn-test/src/functional_test_runner/lib/config/index.ts index a1f22e215307d..f0fa7e9989c86 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/index.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/index.ts @@ -7,5 +7,6 @@ */ export { Config } from './config'; -export { readConfigFile } from './read_config_file'; +export { readConfigFile } from './config_loading'; +export type { ConfigModule } from './config_loading'; export { runCheckFtrConfigsCli } from './run_check_ftr_configs_cli'; diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/read_config_file.ts b/packages/kbn-test/src/functional_test_runner/lib/config/read_config_file.ts deleted file mode 100644 index 142e5c9da9b3b..0000000000000 --- a/packages/kbn-test/src/functional_test_runner/lib/config/read_config_file.ts +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import Path from 'path'; -import { ToolingLog } from '@kbn/tooling-log'; -import { defaultsDeep } from 'lodash'; -import { createFlagError } from '@kbn/dev-cli-errors'; -import { REPO_ROOT } from '@kbn/utils'; - -import { Config } from './config'; -import { EsVersion } from '../es_version'; -import { FTR_CONFIGS_MANIFEST_REL, FTR_CONFIGS_MANIFEST_PATHS } from './ftr_configs_manifest'; - -const cache = new WeakMap(); - -async function getSettingsFromFile( - log: ToolingLog, - esVersion: EsVersion, - options: { - path: string; - settingOverrides: any; - primary: boolean; - } -) { - let resolvedPath; - try { - resolvedPath = require.resolve(options.path); - } catch (error) { - if (error.code === 'MODULE_NOT_FOUND') { - throw createFlagError(`Unable to find config file [${options.path}]`); - } - - throw error; - } - - if ( - options.primary && - !FTR_CONFIGS_MANIFEST_PATHS.includes(resolvedPath) && - !resolvedPath.includes(`${Path.sep}__fixtures__${Path.sep}`) - ) { - const rel = Path.relative(REPO_ROOT, resolvedPath); - throw createFlagError( - `Refusing to load FTR Config at [${rel}] which is not listed in [${FTR_CONFIGS_MANIFEST_REL}]. All FTR Config files must be listed there, use the "enabled" key if the FTR Config should be run on automatically on PR CI, or the "disabled" key if it is run manually or by a special job.` - ); - } - - const configModule = require(resolvedPath); // eslint-disable-line @typescript-eslint/no-var-requires - const configProvider = configModule.__esModule ? configModule.default : configModule; - - if (!cache.has(configProvider)) { - log.debug('Loading config file from %j', resolvedPath); - cache.set( - configProvider, - configProvider({ - log, - esVersion, - async readConfigFile(p: string, o: any) { - return new Config({ - settings: await getSettingsFromFile(log, esVersion, { - path: p, - settingOverrides: o, - primary: false, - }), - primary: false, - path: p, - }); - }, - }) - ); - } - - const settingsWithDefaults: any = defaultsDeep( - {}, - options.settingOverrides, - await cache.get(configProvider)! - ); - - return settingsWithDefaults; -} - -export async function readConfigFile( - log: ToolingLog, - esVersion: EsVersion, - path: string, - settingOverrides: any = {} -) { - return new Config({ - settings: await getSettingsFromFile(log, esVersion, { - path, - settingOverrides, - primary: true, - }), - primary: true, - path, - }); -} diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts index 7e7ba9e26eb48..ce44dd3cc0496 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/schema.ts @@ -14,7 +14,6 @@ import type { CustomHelpers } from 'joi'; // valid pattern for ID // enforced camel-case identifiers for consistency const ID_PATTERN = /^[a-zA-Z0-9_]+$/; -const SCALABILITY_DURATION_PATTERN = /^[1-9]\d{0,}[m|s]$/; // it will search both --inspect and --inspect-brk const INSPECTING = !!process.execArgv.find((arg) => arg.includes('--inspect')); @@ -164,6 +163,7 @@ export const schema = Joi.object() .keys({ enabled: Joi.boolean().default(!!process.env.CI && !process.env.DISABLE_JUNIT_REPORTER), reportName: Joi.string(), + metadata: Joi.object().unknown(true).default(), }) .default(), @@ -267,63 +267,6 @@ export const schema = Joi.object() }) .default(), - /** - * Optional settings to list test data archives, that will be loaded during the 'beforeTests' - * lifecycle phase and unloaded during the 'cleanup' lifecycle phase. - */ - testData: Joi.object() - .keys({ - kbnArchives: Joi.array().items(Joi.string()).default([]), - esArchives: Joi.array().items(Joi.string()).default([]), - }) - .default(), - - /** - * Optional settings to enable scalability testing for single user performance journey. - * If defined, 'scalabilitySetup' must include 'warmup' and 'test' stage array, - * 'maxDuration', e.g. '10m' to limit execution time to 10 minutes. - * Each stage must include 'action', 'duration' and 'maxUsersCount'. - * In addition, 'rampConcurrentUsers' requires 'minUsersCount' to ramp users from - * min to max within provided time duration. - */ - scalabilitySetup: Joi.object() - .keys({ - warmup: Joi.array() - .items( - Joi.object().keys({ - action: Joi.string() - .valid('constantConcurrentUsers', 'rampConcurrentUsers') - .required(), - duration: Joi.string().pattern(SCALABILITY_DURATION_PATTERN).required(), - minUsersCount: Joi.number().when('action', { - is: 'rampConcurrentUsers', - then: Joi.number().required().less(Joi.ref('maxUsersCount')), - otherwise: Joi.forbidden(), - }), - maxUsersCount: Joi.number().required().greater(0), - }) - ) - .required(), - test: Joi.array() - .items( - Joi.object().keys({ - action: Joi.string() - .valid('constantConcurrentUsers', 'rampConcurrentUsers') - .required(), - duration: Joi.string().pattern(SCALABILITY_DURATION_PATTERN).required(), - minUsersCount: Joi.number().when('action', { - is: 'rampConcurrentUsers', - then: Joi.number().required().less(Joi.ref('maxUsersCount')), - otherwise: Joi.forbidden(), - }), - maxUsersCount: Joi.number().required().greater(0), - }) - ) - .required(), - maxDuration: Joi.string().pattern(SCALABILITY_DURATION_PATTERN).required(), - }) - .optional(), - // settings for the kibanaServer.uiSettings module uiSettings: Joi.object() .keys({ diff --git a/packages/kbn-test/src/functional_test_runner/lib/es_version.ts b/packages/kbn-test/src/functional_test_runner/lib/es_version.ts index 8b3acde47a4dc..976a2c417c747 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/es_version.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/es_version.ts @@ -11,6 +11,10 @@ import { kibanaPackageJson } from '@kbn/utils'; export class EsVersion { static getDefault() { + if (typeof jest === 'object' && jest) { + return new EsVersion('9.9.9'); + } + // example: https://storage.googleapis.com/kibana-ci-es-snapshots-daily/8.0.0/manifest-latest-verified.json const manifestUrl = process.env.ES_SNAPSHOT_MANIFEST; if (manifestUrl) { diff --git a/packages/kbn-test/src/functional_test_runner/lib/index.ts b/packages/kbn-test/src/functional_test_runner/lib/index.ts index 983a185dee682..3b12849a9ec13 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/index.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/index.ts @@ -8,7 +8,7 @@ export { Lifecycle } from './lifecycle'; export { LifecyclePhase } from './lifecycle_phase'; -export { readConfigFile, Config, runCheckFtrConfigsCli } from './config'; +export * from './config'; export * from './providers'; // @internal export { runTests, setupMocha } from './mocha'; diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/load_test_files.js b/packages/kbn-test/src/functional_test_runner/lib/mocha/load_test_files.js deleted file mode 100644 index 7c4a6ddcd1430..0000000000000 --- a/packages/kbn-test/src/functional_test_runner/lib/mocha/load_test_files.js +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { isAbsolute } from 'path'; - -import { loadTracer } from '../load_tracer'; -import { decorateMochaUi } from './decorate_mocha_ui'; -import { decorateSnapshotUi } from '../snapshots/decorate_snapshot_ui'; - -/** - * Load an array of test files into a mocha instance - * - * @param {Mocha} mocha - * @param {ToolingLog} log - * @param {Config} config - * @param {ProviderCollection} providers - * @param {String} path - * @return {undefined} - mutates mocha, no return value - */ -export const loadTestFiles = ({ - mocha, - log, - config, - lifecycle, - providers, - paths, - updateBaselines, - updateSnapshots, -}) => { - const dockerServers = config.get('dockerServers'); - const isDockerGroup = dockerServers && Object.keys(dockerServers).length; - - decorateSnapshotUi({ lifecycle, updateSnapshots, isCi: !!process.env.CI }); - - const innerLoadTestFile = (path) => { - if (typeof path !== 'string' || !isAbsolute(path)) { - throw new TypeError('loadTestFile() only accepts absolute paths'); - } - - loadTracer(path, `testFile[${path}]`, () => { - log.verbose('Loading test file %s', path); - - const testModule = require(path); // eslint-disable-line import/no-dynamic-require - const testProvider = testModule.__esModule ? testModule.default : testModule; - - runTestProvider(testProvider, path); // eslint-disable-line no-use-before-define - }); - }; - - const runTestProvider = (provider, path) => { - if (typeof provider !== 'function') { - throw new Error(`Default export of test files must be a function, got ${provider}`); - } - - loadTracer(provider, `testProvider[${path}]`, () => { - // mocha.suite hocus-pocus comes from: https://git.io/vDnXO - - const context = decorateMochaUi(log, lifecycle, global, { - isDockerGroup, - rootTags: config.get('rootTags'), - }); - mocha.suite.emit('pre-require', context, path, mocha); - - const returnVal = provider({ - loadTestFile: innerLoadTestFile, - getService: providers.getService, - getPageObject: providers.getPageObject, - getPageObjects: providers.getPageObjects, - updateBaselines, - }); - - if (returnVal && typeof returnVal.then === 'function') { - throw new TypeError('Default export of test files must not be an async function'); - } - - mocha.suite.emit('require', returnVal, path, mocha); - mocha.suite.emit('post-require', global, path, mocha); - - context.revertProxiedAssignments(); - }); - }; - - paths.forEach(innerLoadTestFile); -}; diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/load_tests.ts b/packages/kbn-test/src/functional_test_runner/lib/mocha/load_tests.ts new file mode 100644 index 0000000000000..32f61caf1b3c7 --- /dev/null +++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/load_tests.ts @@ -0,0 +1,120 @@ +/* + * 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 { isAbsolute } from 'path'; + +import type { ToolingLog } from '@kbn/tooling-log'; + +import type { Config } from '../config'; +import type { GenericFtrProviderContext } from '../../public_types'; +import type { Lifecycle } from '../lifecycle'; +import type { ProviderCollection } from '../providers'; +import { loadTracer } from '../load_tracer'; +import { decorateSnapshotUi } from '../snapshots/decorate_snapshot_ui'; + +// @ts-expect-error not js yet +import { decorateMochaUi } from './decorate_mocha_ui'; + +type TestProvider = (ctx: GenericFtrProviderContext) => void; + +interface Options { + mocha: any; + log: ToolingLog; + config: Config; + lifecycle: Lifecycle; + providers: ProviderCollection; + paths: string[]; + updateBaselines: boolean; + updateSnapshots: boolean; +} + +const isObj = (v: unknown): v is Record => typeof v === 'object' && v !== null; + +/** + * Load an array of test files or a test provider into a mocha instance + */ +export const loadTests = ({ + mocha, + log, + config, + lifecycle, + providers, + paths, + updateBaselines, + updateSnapshots, +}: Options) => { + const dockerServers = config.get('dockerServers'); + const isDockerGroup = dockerServers && Object.keys(dockerServers).length; + + const ctx: GenericFtrProviderContext = { + loadTestFile, + getService: providers.getService as any, + hasService: providers.hasService as any, + getPageObject: providers.getPageObject as any, + getPageObjects: providers.getPageObjects as any, + updateBaselines, + }; + + decorateSnapshotUi({ lifecycle, updateSnapshots, isCi: !!process.env.CI }); + + function loadTestFile(path: string) { + if (typeof path !== 'string' || !isAbsolute(path)) { + throw new TypeError('loadTestFile() only accepts absolute paths'); + } + + loadTracer(path, `testFile[${path}]`, () => { + log.verbose('Loading test file %s', path); + + // eslint-disable-next-line @typescript-eslint/no-var-requires + const testModule = require(path); + const testProvider = testModule.__esModule ? testModule.default : testModule; + + runTestProvider(testProvider, path); + }); + } + + function withMocha(debugPath: string, fn: () => void) { + // mocha.suite hocus-pocus comes from: https://git.io/vDnXO + const context = decorateMochaUi(log, lifecycle, global, { + isDockerGroup, + rootTags: config.get('rootTags'), + }); + mocha.suite.emit('pre-require', context, debugPath, mocha); + + fn(); + + mocha.suite.emit('require', undefined, debugPath, mocha); + mocha.suite.emit('post-require', global, debugPath, mocha); + + context.revertProxiedAssignments(); + } + + function runTestProvider(provider: TestProvider, path: string) { + if (typeof provider !== 'function') { + throw new Error(`Default export of test files must be a function, got ${provider}`); + } + + loadTracer(provider, `testProvider[${path}]`, () => { + withMocha(path, () => { + const returnVal = provider(ctx); + if (isObj(returnVal) && typeof returnVal.then === 'function') { + throw new TypeError('Test file providers must not be async or return promises'); + } + }); + }); + } + + const cm = config.module; + if (cm.type === 'journey') { + withMocha(cm.path, () => { + cm.journey.testProvider(ctx); + }); + } else { + paths.forEach(loadTestFile); + } +}; diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js index 66a4c9ce4fd04..b2bea7b079c9b 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js +++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/reporter/reporter.js @@ -47,6 +47,7 @@ export function MochaReporterProvider({ getService }) { if (config.get('junit.enabled') && config.get('junit.reportName')) { setupJUnitReportGeneration(runner, { reportName: config.get('junit.reportName'), + metadata: config.get('junit.metadata'), }); } diff --git a/packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.js b/packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.ts similarity index 59% rename from packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.js rename to packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.ts index 9261391c5bf6a..10c51517aec94 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.js +++ b/packages/kbn-test/src/functional_test_runner/lib/mocha/setup_mocha.ts @@ -6,34 +6,50 @@ * Side Public License, v 1. */ -import Mocha from 'mocha'; import { relative } from 'path'; + import { REPO_ROOT } from '@kbn/utils'; +import { ToolingLog } from '@kbn/tooling-log'; -import { loadTestFiles } from './load_test_files'; +import { Suite } from '../../fake_mocha_types'; +import { loadTests } from './load_tests'; import { filterSuites } from './filter_suites'; +import { Lifecycle } from '../lifecycle'; +import { Config } from '../config'; +import { ProviderCollection } from '../providers'; +import { EsVersion } from '../es_version'; + +// @ts-expect-error not ts yet import { MochaReporterProvider } from './reporter'; +// @ts-expect-error not ts yet import { validateCiGroupTags } from './validate_ci_group_tags'; +interface Options { + lifecycle: Lifecycle; + log: ToolingLog; + config: Config; + providers: ProviderCollection; + esVersion: EsVersion; + reporter?: any; + reporterOptions?: any; +} + +// we use require so that @types/mocha isn't loaded +const Mocha = require('mocha'); // eslint-disable-line @typescript-eslint/no-var-requires + /** * Instantiate mocha and load testfiles into it - * - * @param {Lifecycle} lifecycle - * @param {ToolingLog} log - * @param {Config} config - * @param {ProviderCollection} providers - * @param {EsVersion} esVersion * @return {Promise} */ -export async function setupMocha( +export async function setupMocha({ lifecycle, log, config, providers, esVersion, reporter, - reporterOptions -) { + reporterOptions, +}: Options) { // configure mocha const mocha = new Mocha({ ...config.get('mochaOpts'), @@ -43,19 +59,19 @@ export async function setupMocha( }); // global beforeEach hook in root suite triggers before all others - mocha.suite.beforeEach('global before each', async function () { - await lifecycle.beforeEachTest.trigger(this.currentTest); + mocha.suite.beforeEach('global before each', async function (this: Suite) { + await lifecycle.beforeEachTest.trigger(this.currentTest!); }); - loadTestFiles({ + loadTests({ mocha, log, config, lifecycle, providers, - paths: config.get('testFiles'), updateBaselines: config.get('updateBaselines'), updateSnapshots: config.get('updateSnapshots'), + paths: config.get('testFiles'), }); // valiate that there aren't any tests in multiple ciGroups @@ -76,15 +92,15 @@ export async function setupMocha( filterSuites({ log, mocha, - include: config.get('suiteFiles.include').map((file) => relative(REPO_ROOT, file)), - exclude: config.get('suiteFiles.exclude').map((file) => relative(REPO_ROOT, file)), + include: config.get('suiteFiles.include').map((file: string) => relative(REPO_ROOT, file)), + exclude: config.get('suiteFiles.exclude').map((file: string) => relative(REPO_ROOT, file)), }); filterSuites({ log, mocha, - include: config.get('suiteTags.include').map((tag) => tag.replace(/-\d+$/, '')), - exclude: config.get('suiteTags.exclude').map((tag) => tag.replace(/-\d+$/, '')), + include: config.get('suiteTags.include').map((tag: string) => tag.replace(/-\d+$/, '')), + exclude: config.get('suiteTags.exclude').map((tag: string) => tag.replace(/-\d+$/, '')), }); return mocha; diff --git a/packages/kbn-test/src/functional_test_runner/public_types.ts b/packages/kbn-test/src/functional_test_runner/public_types.ts index 3faa19de73ce1..248b914b2ebe7 100644 --- a/packages/kbn-test/src/functional_test_runner/public_types.ts +++ b/packages/kbn-test/src/functional_test_runner/public_types.ts @@ -105,6 +105,11 @@ export interface GenericFtrProviderContext< * @param path */ loadTestFile(path: string): void; + + /** + * Did the user request that baselines get updated? + */ + updateBaselines: boolean; } export class GenericFtrService> { @@ -117,4 +122,6 @@ export interface FtrConfigProviderContext { readConfigFile(path: string): Promise; } +export type FtrConfigProvider = (ctx: FtrConfigProviderContext) => T | Promise; + export type { Test, Suite }; diff --git a/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/args.test.js.snap b/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/args.test.js.snap deleted file mode 100644 index ff8961e263f17..0000000000000 --- a/packages/kbn-test/src/functional_tests/cli/run_tests/__snapshots__/args.test.js.snap +++ /dev/null @@ -1,332 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`display help for run tests CLI displays as expected 1`] = ` -"Run Functional Tests - -Usage: - node scripts/functional_tests --help - node scripts/functional_tests [--config [--config ...]] - node scripts/functional_tests [options] [-- --] - -Options: - --help Display this menu and exit. - --config Pass in a config. Can pass in multiple configs. - --esFrom Build Elasticsearch from source or run from snapshot. Default: $TEST_ES_FROM or snapshot - --kibana-install-dir Run Kibana from existing install directory instead of from source. - --bail Stop the test run at the first failure. - --grep Pattern to select which tests to run. - --updateBaselines Replace baseline screenshots with whatever is generated from the test. - --updateSnapshots Replace inline and file snapshots with whatever is generated from the test. - --u Replace both baseline screenshots and snapshots - --include Files that must included to be run, can be included multiple times. - --exclude Files that must NOT be included to be run, can be included multiple times. - --include-tag Tags that suites must include to be run, can be included multiple times. - --exclude-tag Tags that suites must NOT include to be run, can be included multiple times. - --assert-none-excluded Exit with 1/0 based on if any test is excluded with the current set of tags. - --logToFile Write the log output from Kibana/Elasticsearch to files instead of to stdout - --verbose Log everything. - --debug Run in debug mode. - --quiet Only log errors. - --silent Log nothing. - --dry-run Report tests without executing them." -`; - -exports[`process options for run tests CLI accepts boolean value for updateBaselines 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, - "updateBaselines": true, -} -`; - -exports[`process options for run tests CLI accepts boolean value for updateSnapshots 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, - "updateSnapshots": true, -} -`; - -exports[`process options for run tests CLI accepts debug option 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "debug": true, - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; - -exports[`process options for run tests CLI accepts empty config value if default passed 1`] = ` -Object { - "assertNoneExcluded": false, - "config": "", - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; - -exports[`process options for run tests CLI accepts extra server options 1`] = ` -Object { - "_": Object { - "server.foo": "bar", - }, - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": Object { - "server.foo": "bar", - }, - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; - -exports[`process options for run tests CLI accepts quiet option 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "quiet": true, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; - -exports[`process options for run tests CLI accepts silent option 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "silent": true, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; - -exports[`process options for run tests CLI accepts source value for $TEST_ES_FROM 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "source", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; - -exports[`process options for run tests CLI accepts source value for esFrom 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "source", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; - -exports[`process options for run tests CLI accepts string value for kibana-install-dir 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "installDir": "foo", - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; - -exports[`process options for run tests CLI accepts value for grep 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "grep": "management", - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; - -exports[`process options for run tests CLI accepts verbose option 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, - "verbose": true, -} -`; - -exports[`process options for run tests CLI prioritizes source flag over $TEST_ES_FROM 1`] = ` -Object { - "assertNoneExcluded": false, - "configs": Array [ - /foo, - ], - "createLogger": [Function], - "esFrom": "snapshot", - "esVersion": "999.999.999", - "extraKbnOpts": undefined, - "logsDir": undefined, - "suiteFiles": Object { - "exclude": Array [], - "include": Array [], - }, - "suiteTags": Object { - "exclude": Array [], - "include": Array [], - }, -} -`; diff --git a/packages/kbn-test/src/functional_tests/cli/run_tests/args.js b/packages/kbn-test/src/functional_tests/cli/run_tests/args.js deleted file mode 100644 index 8b1bf471f4e98..0000000000000 --- a/packages/kbn-test/src/functional_tests/cli/run_tests/args.js +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import Path from 'path'; - -import { v4 as uuid } from 'uuid'; -import dedent from 'dedent'; -import { REPO_ROOT } from '@kbn/utils'; -import { ToolingLog, pickLevelFromFlags } from '@kbn/tooling-log'; -import { EsVersion } from '../../../functional_test_runner'; - -const options = { - help: { desc: 'Display this menu and exit.' }, - config: { - arg: '', - desc: 'Pass in a config. Can pass in multiple configs.', - }, - esFrom: { - arg: '', - choices: ['snapshot', 'source'], - desc: 'Build Elasticsearch from source or run from snapshot.', - defaultHelp: 'Default: $TEST_ES_FROM or snapshot', - }, - 'kibana-install-dir': { - arg: '', - desc: 'Run Kibana from existing install directory instead of from source.', - }, - bail: { desc: 'Stop the test run at the first failure.' }, - grep: { - arg: '', - desc: 'Pattern to select which tests to run.', - }, - updateBaselines: { - desc: 'Replace baseline screenshots with whatever is generated from the test.', - }, - updateSnapshots: { - desc: 'Replace inline and file snapshots with whatever is generated from the test.', - }, - u: { - desc: 'Replace both baseline screenshots and snapshots', - }, - include: { - arg: '', - desc: 'Files that must included to be run, can be included multiple times.', - }, - exclude: { - arg: '', - desc: 'Files that must NOT be included to be run, can be included multiple times.', - }, - 'include-tag': { - arg: '', - desc: 'Tags that suites must include to be run, can be included multiple times.', - }, - 'exclude-tag': { - arg: '', - desc: 'Tags that suites must NOT include to be run, can be included multiple times.', - }, - 'assert-none-excluded': { - desc: 'Exit with 1/0 based on if any test is excluded with the current set of tags.', - }, - logToFile: { - desc: 'Write the log output from Kibana/Elasticsearch to files instead of to stdout', - }, - verbose: { desc: 'Log everything.' }, - debug: { desc: 'Run in debug mode.' }, - quiet: { desc: 'Only log errors.' }, - silent: { desc: 'Log nothing.' }, - 'dry-run': { desc: 'Report tests without executing them.' }, -}; - -export function displayHelp() { - const helpOptions = Object.keys(options) - .filter((name) => name !== '_') - .map((name) => { - const option = options[name]; - return { - ...option, - usage: `${name} ${option.arg || ''}`, - default: option.defaultHelp || '', - }; - }) - .map((option) => { - return `--${option.usage.padEnd(28)} ${option.desc} ${option.default}`; - }) - .join(`\n `); - - return dedent(` - Run Functional Tests - - Usage: - node scripts/functional_tests --help - node scripts/functional_tests [--config [--config ...]] - node scripts/functional_tests [options] [-- --] - - Options: - ${helpOptions} - `); -} - -export function processOptions(userOptions, defaultConfigPaths) { - validateOptions(userOptions); - - let configs; - if (userOptions.config) { - configs = [].concat(userOptions.config); - } else { - if (!defaultConfigPaths || defaultConfigPaths.length === 0) { - throw new Error(`functional_tests: config is required`); - } else { - configs = defaultConfigPaths; - } - } - - if (!userOptions.esFrom) { - userOptions.esFrom = process.env.TEST_ES_FROM || 'snapshot'; - } - - if (userOptions['kibana-install-dir']) { - userOptions.installDir = userOptions['kibana-install-dir']; - delete userOptions['kibana-install-dir']; - } - - userOptions.suiteFiles = { - include: [].concat(userOptions.include || []), - exclude: [].concat(userOptions.exclude || []), - }; - delete userOptions.include; - delete userOptions.exclude; - - userOptions.suiteTags = { - include: [].concat(userOptions['include-tag'] || []), - exclude: [].concat(userOptions['exclude-tag'] || []), - }; - delete userOptions['include-tag']; - delete userOptions['exclude-tag']; - - userOptions.assertNoneExcluded = !!userOptions['assert-none-excluded']; - delete userOptions['assert-none-excluded']; - - if (userOptions['dry-run']) { - userOptions.dryRun = userOptions['dry-run']; - delete userOptions['dry-run']; - } - - const log = new ToolingLog({ - level: pickLevelFromFlags(userOptions), - writeTo: process.stdout, - }); - function createLogger() { - return log; - } - - const logToFile = !!userOptions.logToFile; - const logsDir = logToFile ? Path.resolve(REPO_ROOT, 'data/ftr_servers_logs', uuid()) : undefined; - - return { - ...userOptions, - configs: configs.map((c) => Path.resolve(c)), - createLogger, - extraKbnOpts: userOptions._, - esVersion: EsVersion.getDefault(), - logsDir, - }; -} - -function validateOptions(userOptions) { - Object.entries(userOptions).forEach(([key, val]) => { - if (key === '_' || key === 'suiteTags') { - return; - } - - // Validate flags passed - if (options[key] === undefined) { - throw new Error(`functional_tests: invalid option [${key}]`); - } - - if ( - // Validate boolean flags - (!options[key].arg && typeof val !== 'boolean') || - // Validate string/array flags - (options[key].arg && typeof val !== 'string' && !Array.isArray(val)) || - // Validate enum flags - (options[key].choices && !options[key].choices.includes(val)) - ) { - throw new Error(`functional_tests: invalid argument [${val}] to option [${key}]`); - } - }); -} diff --git a/packages/kbn-test/src/functional_tests/cli/run_tests/args.test.js b/packages/kbn-test/src/functional_tests/cli/run_tests/args.test.js deleted file mode 100644 index 888708a2b9d69..0000000000000 --- a/packages/kbn-test/src/functional_tests/cli/run_tests/args.test.js +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { createAbsolutePathSerializer } from '@kbn/jest-serializers'; - -import { displayHelp, processOptions } from './args'; - -jest.mock('../../../functional_test_runner/lib/es_version', () => { - return { - EsVersion: class { - static getDefault() { - return '999.999.999'; - } - }, - }; -}); - -expect.addSnapshotSerializer(createAbsolutePathSerializer(process.cwd())); - -const INITIAL_TEST_ES_FROM = process.env.TEST_ES_FROM; -beforeEach(() => { - process.env.TEST_ES_FROM = 'snapshot'; -}); -afterEach(() => { - process.env.TEST_ES_FROM = INITIAL_TEST_ES_FROM; -}); - -describe('display help for run tests CLI', () => { - it('displays as expected', () => { - expect(displayHelp()).toMatchSnapshot(); - }); -}); - -describe('process options for run tests CLI', () => { - it('rejects boolean config value', () => { - expect(() => { - processOptions({ config: true }); - }).toThrow('functional_tests: invalid argument [true] to option [config]'); - }); - - it('rejects empty config value if no default passed', () => { - expect(() => { - processOptions({}); - }).toThrow('functional_tests: config is required'); - }); - - it('accepts empty config value if default passed', () => { - const options = processOptions({ config: '' }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('rejects non-boolean value for bail', () => { - expect(() => { - processOptions({ bail: 'peanut' }, ['foo']); - }).toThrow('functional_tests: invalid argument [peanut] to option [bail]'); - }); - - it('accepts string value for kibana-install-dir', () => { - const options = processOptions({ 'kibana-install-dir': 'foo' }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('rejects boolean value for kibana-install-dir', () => { - expect(() => { - processOptions({ 'kibana-install-dir': true }, ['foo']); - }).toThrow('functional_tests: invalid argument [true] to option [kibana-install-dir]'); - }); - - it('accepts boolean value for updateBaselines', () => { - const options = processOptions({ updateBaselines: true }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('accepts boolean value for updateSnapshots', () => { - const options = processOptions({ updateSnapshots: true }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('accepts source value for esFrom', () => { - const options = processOptions({ esFrom: 'source' }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('accepts source value for $TEST_ES_FROM', () => { - process.env.TEST_ES_FROM = 'source'; - const options = processOptions({}, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('prioritizes source flag over $TEST_ES_FROM', () => { - process.env.TEST_ES_FROM = 'source'; - const options = processOptions({ esFrom: 'snapshot' }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('rejects non-enum value for esFrom', () => { - expect(() => { - processOptions({ esFrom: 'butter' }, ['foo']); - }).toThrow('functional_tests: invalid argument [butter] to option [esFrom]'); - }); - - it('accepts value for grep', () => { - const options = processOptions({ grep: 'management' }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('accepts debug option', () => { - const options = processOptions({ debug: true }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('accepts silent option', () => { - const options = processOptions({ silent: true }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('accepts quiet option', () => { - const options = processOptions({ quiet: true }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('accepts verbose option', () => { - const options = processOptions({ verbose: true }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('accepts extra server options', () => { - const options = processOptions({ _: { 'server.foo': 'bar' } }, ['foo']); - expect(options).toMatchSnapshot(); - }); - - it('rejects invalid options even if valid options exist', () => { - expect(() => { - processOptions({ debug: true, aintnothang: true, bail: true }, ['foo']); - }).toThrow('functional_tests: invalid option [aintnothang]'); - }); -}); diff --git a/packages/kbn-test/src/functional_tests/cli/run_tests/cli.js b/packages/kbn-test/src/functional_tests/cli/run_tests/cli.js deleted file mode 100644 index 3958c1503cd30..0000000000000 --- a/packages/kbn-test/src/functional_tests/cli/run_tests/cli.js +++ /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 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 { runTests, initLogsDir } from '../../tasks'; -import { runCli } from '../../lib'; -import { processOptions, displayHelp } from './args'; - -/** - * Run servers and tests for each config - * Only cares about --config option. Other options - * are passed directly to functional_test_runner, such as - * --bail, --verbose, etc. - * @param {string[]} defaultConfigPaths Optional paths to configs - * if no config option is passed - */ -export async function runTestsCli(defaultConfigPaths) { - await runCli(displayHelp, async (userOptions) => { - const options = processOptions(userOptions, defaultConfigPaths); - initLogsDir(options); - await runTests(options); - }); -} diff --git a/packages/kbn-test/src/functional_tests/cli/start_servers/__snapshots__/args.test.js.snap b/packages/kbn-test/src/functional_tests/cli/start_servers/__snapshots__/args.test.js.snap deleted file mode 100644 index 1f572578119f7..0000000000000 --- a/packages/kbn-test/src/functional_tests/cli/start_servers/__snapshots__/args.test.js.snap +++ /dev/null @@ -1,141 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`display help for start servers CLI displays as expected 1`] = ` -"Start Functional Test Servers - -Usage: - node scripts/functional_tests_server --help - node scripts/functional_tests_server [--config ] - node scripts/functional_tests_server [options] [-- --] - -Options: - --help Display this menu and exit. - --config Pass in a config - --esFrom Build Elasticsearch from source, snapshot or path to existing install dir. Default: $TEST_ES_FROM or snapshot - --kibana-install-dir Run Kibana from existing install directory instead of from source. - --logToFile Write the log output from Kibana/Elasticsearch to files instead of to stdout - --verbose Log everything. - --debug Run in debug mode. - --quiet Only log errors. - --silent Log nothing." -`; - -exports[`process options for start servers CLI accepts debug option 1`] = ` -Object { - "config": /foo, - "createLogger": [Function], - "debug": true, - "esFrom": "snapshot", - "extraKbnOpts": undefined, - "logsDir": undefined, - "useDefaultConfig": true, -} -`; - -exports[`process options for start servers CLI accepts empty config value if default passed 1`] = ` -Object { - "config": /foo, - "createLogger": [Function], - "esFrom": "snapshot", - "extraKbnOpts": undefined, - "logsDir": undefined, - "useDefaultConfig": true, -} -`; - -exports[`process options for start servers CLI accepts extra server options 1`] = ` -Object { - "_": Object { - "server.foo": "bar", - }, - "config": /foo, - "createLogger": [Function], - "esFrom": "snapshot", - "extraKbnOpts": Object { - "server.foo": "bar", - }, - "logsDir": undefined, - "useDefaultConfig": true, -} -`; - -exports[`process options for start servers CLI accepts quiet option 1`] = ` -Object { - "config": /foo, - "createLogger": [Function], - "esFrom": "snapshot", - "extraKbnOpts": undefined, - "logsDir": undefined, - "quiet": true, - "useDefaultConfig": true, -} -`; - -exports[`process options for start servers CLI accepts silent option 1`] = ` -Object { - "config": /foo, - "createLogger": [Function], - "esFrom": "snapshot", - "extraKbnOpts": undefined, - "logsDir": undefined, - "silent": true, - "useDefaultConfig": true, -} -`; - -exports[`process options for start servers CLI accepts source value for $TEST_ES_FROM 1`] = ` -Object { - "config": /foo, - "createLogger": [Function], - "esFrom": "source", - "extraKbnOpts": undefined, - "logsDir": undefined, - "useDefaultConfig": true, -} -`; - -exports[`process options for start servers CLI accepts source value for esFrom 1`] = ` -Object { - "config": /foo, - "createLogger": [Function], - "esFrom": "source", - "extraKbnOpts": undefined, - "logsDir": undefined, - "useDefaultConfig": true, -} -`; - -exports[`process options for start servers CLI accepts string value for kibana-install-dir 1`] = ` -Object { - "config": /foo, - "createLogger": [Function], - "esFrom": "snapshot", - "extraKbnOpts": undefined, - "installDir": "foo", - "logsDir": undefined, - "useDefaultConfig": true, -} -`; - -exports[`process options for start servers CLI accepts verbose option 1`] = ` -Object { - "config": /foo, - "createLogger": [Function], - "esFrom": "snapshot", - "extraKbnOpts": undefined, - "logsDir": undefined, - "useDefaultConfig": true, - "verbose": true, -} -`; - -exports[`process options for start servers CLI prioritizes source flag over $TEST_ES_FROM 1`] = ` -Object { - "config": /foo, - "createLogger": [Function], - "esFrom": "snapshot", - "extraKbnOpts": undefined, - "logsDir": undefined, - "useDefaultConfig": true, -} -`; diff --git a/packages/kbn-test/src/functional_tests/cli/start_servers/args.js b/packages/kbn-test/src/functional_tests/cli/start_servers/args.js deleted file mode 100644 index e025bdc339331..0000000000000 --- a/packages/kbn-test/src/functional_tests/cli/start_servers/args.js +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import Path from 'path'; - -import { v4 as uuid } from 'uuid'; -import dedent from 'dedent'; -import { REPO_ROOT } from '@kbn/utils'; -import { ToolingLog, pickLevelFromFlags } from '@kbn/tooling-log'; - -const options = { - help: { desc: 'Display this menu and exit.' }, - config: { - arg: '', - desc: 'Pass in a config', - }, - esFrom: { - arg: '', - desc: 'Build Elasticsearch from source, snapshot or path to existing install dir.', - defaultHelp: 'Default: $TEST_ES_FROM or snapshot', - }, - 'kibana-install-dir': { - arg: '', - desc: 'Run Kibana from existing install directory instead of from source.', - }, - logToFile: { - desc: 'Write the log output from Kibana/Elasticsearch to files instead of to stdout', - }, - verbose: { desc: 'Log everything.' }, - debug: { desc: 'Run in debug mode.' }, - quiet: { desc: 'Only log errors.' }, - silent: { desc: 'Log nothing.' }, -}; - -export function displayHelp() { - const helpOptions = Object.keys(options) - .filter((name) => name !== '_') - .map((name) => { - const option = options[name]; - return { - ...option, - usage: `${name} ${option.arg || ''}`, - default: option.defaultHelp || '', - }; - }) - .map((option) => { - return `--${option.usage.padEnd(30)} ${option.desc} ${option.default}`; - }) - .join(`\n `); - - return dedent(` - Start Functional Test Servers - - Usage: - node scripts/functional_tests_server --help - node scripts/functional_tests_server [--config ] - node scripts/functional_tests_server [options] [-- --] - - Options: - ${helpOptions} - `); -} - -export function processOptions(userOptions, defaultConfigPath) { - validateOptions(userOptions); - - const useDefaultConfig = !userOptions.config; - const config = useDefaultConfig ? defaultConfigPath : userOptions.config; - - if (!config) { - throw new Error(`functional_tests_server: config is required`); - } - - if (!userOptions.esFrom) { - userOptions.esFrom = process.env.TEST_ES_FROM || 'snapshot'; - } - - if (userOptions['kibana-install-dir']) { - userOptions.installDir = userOptions['kibana-install-dir']; - delete userOptions['kibana-install-dir']; - } - - const log = new ToolingLog({ - level: pickLevelFromFlags(userOptions), - writeTo: process.stdout, - }); - - function createLogger() { - return log; - } - - const logToFile = !!userOptions.logToFile; - const logsDir = logToFile ? Path.resolve(REPO_ROOT, 'data/ftr_servers_logs', uuid()) : undefined; - - return { - ...userOptions, - logsDir, - config: Path.resolve(config), - useDefaultConfig, - createLogger, - extraKbnOpts: userOptions._, - }; -} - -function validateOptions(userOptions) { - Object.entries(userOptions).forEach(([key, val]) => { - if (key === '_') return; - - // Validate flags passed - if (options[key] === undefined) { - throw new Error(`functional_tests_server: invalid option [${key}]`); - } - - if ( - // Validate boolean flags - (!options[key].arg && typeof val !== 'boolean') || - // Validate string/array flags - (options[key].arg && typeof val !== 'string' && !Array.isArray(val)) || - // Validate enum flags - (options[key].choices && !options[key].choices.includes(val)) - ) { - throw new Error(`functional_tests_server: invalid argument [${val}] to option [${key}]`); - } - }); -} diff --git a/packages/kbn-test/src/functional_tests/cli/start_servers/args.test.js b/packages/kbn-test/src/functional_tests/cli/start_servers/args.test.js deleted file mode 100644 index 7d6c77be2539e..0000000000000 --- a/packages/kbn-test/src/functional_tests/cli/start_servers/args.test.js +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { displayHelp, processOptions } from './args'; -import { createAbsolutePathSerializer } from '@kbn/jest-serializers'; - -expect.addSnapshotSerializer(createAbsolutePathSerializer(process.cwd())); - -const INITIAL_TEST_ES_FROM = process.env.TEST_ES_FROM; -beforeEach(() => { - process.env.TEST_ES_FROM = 'snapshot'; -}); -afterEach(() => { - process.env.TEST_ES_FROM = INITIAL_TEST_ES_FROM; -}); - -describe('display help for start servers CLI', () => { - it('displays as expected', () => { - expect(displayHelp()).toMatchSnapshot(); - }); -}); - -describe('process options for start servers CLI', () => { - it('rejects boolean config value', () => { - expect(() => { - processOptions({ config: true }); - }).toThrow('functional_tests_server: invalid argument [true] to option [config]'); - }); - - it('rejects empty config value if no default passed', () => { - expect(() => { - processOptions({}); - }).toThrow('functional_tests_server: config is required'); - }); - - it('accepts empty config value if default passed', () => { - const options = processOptions({ config: '' }, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('rejects invalid option', () => { - expect(() => { - processOptions({ bail: true }, 'foo'); - }).toThrow('functional_tests_server: invalid option [bail]'); - }); - - it('accepts string value for kibana-install-dir', () => { - const options = processOptions({ 'kibana-install-dir': 'foo' }, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('rejects boolean value for kibana-install-dir', () => { - expect(() => { - processOptions({ 'kibana-install-dir': true }, 'foo'); - }).toThrow('functional_tests_server: invalid argument [true] to option [kibana-install-dir]'); - }); - - it('accepts source value for esFrom', () => { - const options = processOptions({ esFrom: 'source' }, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('accepts source value for $TEST_ES_FROM', () => { - process.env.TEST_ES_FROM = 'source'; - const options = processOptions({}, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('prioritizes source flag over $TEST_ES_FROM', () => { - process.env.TEST_ES_FROM = 'source'; - const options = processOptions({ esFrom: 'snapshot' }, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('accepts debug option', () => { - const options = processOptions({ debug: true }, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('accepts silent option', () => { - const options = processOptions({ silent: true }, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('accepts quiet option', () => { - const options = processOptions({ quiet: true }, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('accepts verbose option', () => { - const options = processOptions({ verbose: true }, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('accepts extra server options', () => { - const options = processOptions({ _: { 'server.foo': 'bar' } }, 'foo'); - expect(options).toMatchSnapshot(); - }); - - it('rejects invalid options even if valid options exist', () => { - expect(() => { - processOptions({ debug: true, aintnothang: true, bail: true }, 'foo'); - }).toThrow('functional_tests_server: invalid option [aintnothang]'); - }); -}); diff --git a/packages/kbn-test/src/functional_tests/cli/start_servers/cli.js b/packages/kbn-test/src/functional_tests/cli/start_servers/cli.js deleted file mode 100644 index d57d5c4761f6e..0000000000000 --- a/packages/kbn-test/src/functional_tests/cli/start_servers/cli.js +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { startServers, initLogsDir } from '../../tasks'; -import { runCli } from '../../lib'; -import { processOptions, displayHelp } from './args'; - -/** - * Start servers - * @param {string} defaultConfigPath Optional path to config - * if no config option is passed - */ -export async function startServersCli(defaultConfigPath) { - await runCli(displayHelp, async (userOptions) => { - const options = processOptions(userOptions, defaultConfigPath); - initLogsDir(options); - await startServers({ - ...options, - }); - }); -} diff --git a/packages/kbn-test/src/functional_tests/lib/__snapshots__/run_cli.test.js.snap b/packages/kbn-test/src/functional_tests/lib/__snapshots__/run_cli.test.js.snap deleted file mode 100644 index 6506675cea9bc..0000000000000 --- a/packages/kbn-test/src/functional_tests/lib/__snapshots__/run_cli.test.js.snap +++ /dev/null @@ -1,26 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`does right thing when non-error is thrown 1`] = ` -" -'foo bar' thrown! - ...stack trace... -" -`; - -exports[`logs no stack trace then exits when stack missing 1`] = ` -" -foo error - (no stack trace) - -" -`; - -exports[`logs the stack then exits when run function throws an error 1`] = ` -" -foo error - stack 1 - stack 2 - stack 3 - -" -`; diff --git a/packages/kbn-test/src/functional_tests/lib/index.ts b/packages/kbn-test/src/functional_tests/lib/index.ts index 8844a2ee59a19..7adf9c9d6420a 100644 --- a/packages/kbn-test/src/functional_tests/lib/index.ts +++ b/packages/kbn-test/src/functional_tests/lib/index.ts @@ -8,6 +8,4 @@ export { runKibanaServer } from './run_kibana_server'; export { runElasticsearch } from './run_elasticsearch'; -export type { CreateFtrOptions, CreateFtrParams } from './run_ftr'; -export { runFtr, hasTests, assertNoneExcluded } from './run_ftr'; -export { runCli } from './run_cli'; +export * from './run_ftr'; diff --git a/packages/kbn-test/src/functional_tests/test_helpers.ts b/packages/kbn-test/src/functional_tests/lib/logs_dir.ts similarity index 52% rename from packages/kbn-test/src/functional_tests/test_helpers.ts rename to packages/kbn-test/src/functional_tests/lib/logs_dir.ts index 4131f23770a05..0671a1ffd01e3 100644 --- a/packages/kbn-test/src/functional_tests/test_helpers.ts +++ b/packages/kbn-test/src/functional_tests/lib/logs_dir.ts @@ -6,14 +6,12 @@ * Side Public License, v 1. */ -/* eslint-env jest */ +import Path from 'path'; +import Fs from 'fs'; -import { format } from 'util'; +import { ToolingLog } from '@kbn/tooling-log'; -export function checkMockConsoleLogSnapshot(logMock: jest.Mock) { - const output = logMock.mock.calls - .reduce((acc, args) => `${acc}${format(...args)}\n`, '') - .replace(/(^ at.+[>)\d]$\n?)+/m, ' ...stack trace...'); - - expect(output).toMatchSnapshot(); +export async function initLogsDir(log: ToolingLog, logsDir: string) { + log.info(`Kibana/ES logs will be written to ${Path.relative(process.cwd(), logsDir)}/`); + Fs.mkdirSync(logsDir, { recursive: true }); } diff --git a/packages/kbn-test/src/functional_tests/lib/run_cli.test.js b/packages/kbn-test/src/functional_tests/lib/run_cli.test.js deleted file mode 100644 index eccb1405d51dc..0000000000000 --- a/packages/kbn-test/src/functional_tests/lib/run_cli.test.js +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { runCli } from './run_cli'; -import { checkMockConsoleLogSnapshot } from '../test_helpers'; - -const mockProcessExit = jest.spyOn(process, 'exit').mockImplementation(() => {}); -const mockConsoleLog = jest.spyOn(console, 'log').mockImplementation(() => {}); - -const actualProcessArgv = process.argv; - -const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); - -beforeEach(() => { - process.argv = actualProcessArgv.slice(0, 2); - jest.clearAllMocks(); -}); - -afterAll(() => { - process.argv = actualProcessArgv; -}); - -it('accepts help option even if invalid options passed', async () => { - process.argv.push('--foo', '--bar', '--help'); - - const mockGetHelpText = jest.fn().mockReturnValue('mock help text'); - const mockRun = jest.fn(); - await runCli(mockGetHelpText, mockRun); - - expect(mockProcessExit).not.toHaveBeenCalled(); - expect(mockGetHelpText).toHaveBeenCalledTimes(1); - expect(mockConsoleLog).toHaveBeenCalledTimes(1); - expect(mockConsoleLog).toHaveBeenCalledWith('mock help text'); - expect(mockRun).not.toHaveBeenCalled(); -}); - -it('passes parsed argv to run function', async () => { - process.argv.push('--foo', 'bar', '--baz=box', '--', 'a', 'b', 'c'); - - const mockGetHelpText = jest.fn(); - const mockRun = jest.fn(); - await runCli(mockGetHelpText, mockRun); - - expect(mockGetHelpText).not.toHaveBeenCalled(); - expect(mockConsoleLog).not.toHaveBeenCalled(); - expect(mockProcessExit).not.toHaveBeenCalled(); - expect(mockRun).toHaveBeenCalledTimes(1); - expect(mockRun).toHaveBeenCalledWith({ - foo: 'bar', - baz: 'box', - _: ['a', 'b', 'c'], - }); -}); - -it('waits for promise returned from run function to resolve before resolving', async () => { - let resolveMockRun; - const mockRun = jest.fn().mockImplementation( - () => - new Promise((resolve) => { - resolveMockRun = resolve; - }) - ); - - const onResolved = jest.fn(); - const promise = runCli(null, mockRun).then(onResolved); - - expect(mockRun).toHaveBeenCalled(); - expect(onResolved).not.toHaveBeenCalled(); - - await sleep(500); - - expect(onResolved).not.toHaveBeenCalled(); - - resolveMockRun(); - await promise; - expect(onResolved).toHaveBeenCalled(); -}); - -it('logs the stack then exits when run function throws an error', async () => { - await runCli(null, () => { - const error = new Error('foo error'); - error.stack = 'foo error\n stack 1\n stack 2\n stack 3'; - throw error; - }); - - expect(mockProcessExit).toHaveBeenCalledTimes(1); - expect(mockProcessExit).toHaveBeenCalledWith(1); - - expect(mockConsoleLog).toHaveBeenCalled(); - checkMockConsoleLogSnapshot(mockConsoleLog); -}); - -it('logs no stack trace then exits when stack missing', async () => { - await runCli(null, () => { - const error = new Error('foo error'); - error.stack = undefined; - throw error; - }); - - expect(mockProcessExit).toHaveBeenCalledTimes(1); - expect(mockProcessExit).toHaveBeenCalledWith(1); - - expect(mockConsoleLog).toHaveBeenCalled(); - checkMockConsoleLogSnapshot(mockConsoleLog); -}); - -it('does right thing when non-error is thrown', async () => { - await runCli(null, () => { - throw 'foo bar'; - }); - - expect(mockProcessExit).toHaveBeenCalledTimes(1); - expect(mockProcessExit).toHaveBeenCalledWith(1); - - expect(mockConsoleLog).toHaveBeenCalled(); - checkMockConsoleLogSnapshot(mockConsoleLog); -}); diff --git a/packages/kbn-test/src/functional_tests/lib/run_cli.ts b/packages/kbn-test/src/functional_tests/lib/run_cli.ts deleted file mode 100644 index 3e2cb50ff2e78..0000000000000 --- a/packages/kbn-test/src/functional_tests/lib/run_cli.ts +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { inspect } from 'util'; - -import chalk from 'chalk'; -import getopts from 'getopts'; -/* eslint-disable no-console */ -export class CliError extends Error { - constructor(message: string) { - super(message); - Error.captureStackTrace(this, CliError); - } -} - -export async function runCli( - getHelpText: () => string, - run: (options: getopts.ParsedOptions) => Promise -) { - try { - const userOptions = getopts(process.argv.slice(2)) || {}; - if (userOptions.help) { - console.log(getHelpText()); - return; - } - - await run(userOptions); - } catch (error) { - if (!(error instanceof Error)) { - error = new Error(`${inspect(error)} thrown!`); - } - - console.log(); - console.log(chalk.red(error.message)); - - // CliError is a special error class that indicates that the error is produced as a part - // of using the CLI, and does not need a stack trace to make sense, so we skip the stack - // trace logging if the error thrown is an instance of this class - if (!(error instanceof CliError)) { - // first line in the stack trace is the message, skip it as we log it directly and color it red - if (error.stack) { - console.log(error.stack.split('\n').slice(1).join('\n')); - } else { - console.log(' (no stack trace)'); - } - } - - console.log(); - - process.exit(error.exitCode || 1); - } -} diff --git a/packages/kbn-test/src/functional_tests/lib/run_ftr.ts b/packages/kbn-test/src/functional_tests/lib/run_ftr.ts index b9945adbdfb56..665d27c00754e 100644 --- a/packages/kbn-test/src/functional_tests/lib/run_ftr.ts +++ b/packages/kbn-test/src/functional_tests/lib/run_ftr.ts @@ -6,127 +6,45 @@ * Side Public License, v 1. */ import type { ToolingLog } from '@kbn/tooling-log'; -import { FunctionalTestRunner, readConfigFile, EsVersion } from '../../functional_test_runner'; -import { CliError } from './run_cli'; +import { createFailError } from '@kbn/dev-cli-errors'; -export interface CreateFtrOptions { - /** installation dir from which to run Kibana */ - installDir: string; +import { EsVersion, Config, FunctionalTestRunner } from '../../functional_test_runner'; + +export async function runFtr(options: { log: ToolingLog; - /** Whether to exit test run at the first failure */ - bail?: boolean; - grep: string; - updateBaselines?: boolean; - suiteFiles?: { - include?: string[]; - exclude?: string[]; - }; - suiteTags?: { - include?: string[]; - exclude?: string[]; - }; - updateSnapshots?: boolean; + config: Config; esVersion: EsVersion; - dryRun?: boolean; -} - -export interface CreateFtrParams { - configPath: string; - options: CreateFtrOptions; -} -async function createFtr({ - configPath, - options: { - installDir, - log, - bail, - grep, - updateBaselines, - suiteFiles, - suiteTags, - updateSnapshots, - esVersion, - dryRun, - }, -}: CreateFtrParams) { - const config = await readConfigFile(log, esVersion, configPath); - - return { - config, - ftr: new FunctionalTestRunner( - log, - configPath, - { - mochaOpts: { - bail: !!bail, - grep, - dryRun: !!dryRun, - }, - kbnTestServer: { - installDir, - }, - updateBaselines, - updateSnapshots, - suiteFiles: { - include: [...(suiteFiles?.include || []), ...config.get('suiteFiles.include')], - exclude: [...(suiteFiles?.exclude || []), ...config.get('suiteFiles.exclude')], - }, - suiteTags: { - include: [...(suiteTags?.include || []), ...config.get('suiteTags.include')], - exclude: [...(suiteTags?.exclude || []), ...config.get('suiteTags.exclude')], - }, - }, - esVersion - ), - }; -} - -export async function assertNoneExcluded(params: CreateFtrParams) { - const { config, ftr } = await createFtr(params); - - if (config.get('testRunner')) { - // tests with custom test runners are not included in this check - return; - } - - const stats = await ftr.getTestStats(); - if (!stats) { - throw new Error('unable to get test stats'); - } - if (stats.testsExcludedByTag.length > 0) { - throw new CliError(` - ${stats.testsExcludedByTag.length} tests in the ${params.configPath} config - are excluded when filtering by the tags run on CI. Make sure that all suites are - tagged with one of the following tags: + signal?: AbortSignal; +}) { + const ftr = new FunctionalTestRunner(options.log, options.config, options.esVersion); - ${JSON.stringify(params.options.suiteTags)} - - - ${stats.testsExcludedByTag.join('\n - ')} - `); - } -} - -export async function runFtr(params: CreateFtrParams, signal?: AbortSignal) { - const { ftr } = await createFtr(params); - - const failureCount = await ftr.run(signal); + const failureCount = await ftr.run(options.signal); if (failureCount > 0) { - throw new CliError( + throw createFailError( `${failureCount} functional test ${failureCount === 1 ? 'failure' : 'failures'}` ); } } -export async function hasTests(params: CreateFtrParams) { - const { ftr, config } = await createFtr(params); - - if (config.get('testRunner')) { +export async function checkForEnabledTestsInFtrConfig(options: { + log: ToolingLog; + config: Config; + esVersion: EsVersion; +}) { + if (options.config.get('testRunner')) { // configs with custom test runners are assumed to always have tests return true; } + + if (options.config.module.type === 'journey') { + return !options.config.module.journey.config.isSkipped(); + } + + const ftr = new FunctionalTestRunner(options.log, options.config, options.esVersion); const stats = await ftr.getTestStats(); if (!stats) { - throw new Error('unable to get test stats'); + throw createFailError('unable to get test stats'); } + return stats.nonSkippedTestCount > 0; } diff --git a/packages/kbn-test/src/functional_tests/lib/run_kibana_server.ts b/packages/kbn-test/src/functional_tests/lib/run_kibana_server.ts index 2ae15ca5f83f8..2ab4af2df2e2d 100644 --- a/packages/kbn-test/src/functional_tests/lib/run_kibana_server.ts +++ b/packages/kbn-test/src/functional_tests/lib/run_kibana_server.ts @@ -34,25 +34,19 @@ function extendNodeOptions(installDir?: string) { }; } -export async function runKibanaServer({ - procs, - config, - options, - onEarlyExit, -}: { +export async function runKibanaServer(options: { procs: ProcRunner; config: Config; - options: { - installDir?: string; - extraKbnOpts?: string[]; - logsDir?: string; - }; + installDir?: string; + extraKbnOpts?: string[]; + logsDir?: string; onEarlyExit?: (msg: string) => void; }) { - const runOptions = config.get('kbnTestServer.runOptions'); + const { config, procs } = options; + const runOptions = options.config.get('kbnTestServer.runOptions'); const installDir = runOptions.alwaysUseSource ? undefined : options.installDir; const devMode = !installDir; - const useTaskRunner = config.get('kbnTestServer.useDedicatedTaskRunner'); + const useTaskRunner = options.config.get('kbnTestServer.useDedicatedTaskRunner'); const procRunnerOpts = { cwd: installDir || REPO_ROOT, @@ -64,11 +58,11 @@ export async function runKibanaServer({ env: { FORCE_COLOR: 1, ...process.env, - ...config.get('kbnTestServer.env'), + ...options.config.get('kbnTestServer.env'), ...extendNodeOptions(installDir), }, wait: runOptions.wait, - onEarlyExit, + onEarlyExit: options.onEarlyExit, }; const prefixArgs = devMode diff --git a/packages/kbn-test/src/functional_tests/run_tests/cli.ts b/packages/kbn-test/src/functional_tests/run_tests/cli.ts new file mode 100644 index 0000000000000..19a003dd973cf --- /dev/null +++ b/packages/kbn-test/src/functional_tests/run_tests/cli.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { run } from '@kbn/dev-cli-runner'; + +import { initLogsDir } from '../lib/logs_dir'; +import { runTests } from './run_tests'; +import { parseFlags, FLAG_OPTIONS } from './flags'; + +export function runTestsCli() { + run( + async ({ flagsReader, log }) => { + const options = parseFlags(flagsReader); + + if (options.logsDir) { + initLogsDir(log, options.logsDir); + } + + await runTests(log, options); + }, + { + description: `Run Functional Tests`, + usage: ` + node scripts/functional_tests --help + node scripts/functional_tests [--config [--config ...]] + node scripts/functional_tests [options] [-- --] + `, + flags: FLAG_OPTIONS, + } + ); +} diff --git a/packages/kbn-test/src/functional_tests/run_tests/flags.test.ts b/packages/kbn-test/src/functional_tests/run_tests/flags.test.ts new file mode 100644 index 0000000000000..dbb8b1e9762e5 --- /dev/null +++ b/packages/kbn-test/src/functional_tests/run_tests/flags.test.ts @@ -0,0 +1,151 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 { createAbsolutePathSerializer, createAnyInstanceSerializer } from '@kbn/jest-serializers'; +import { FlagsReader, getFlags } from '@kbn/dev-cli-runner'; + +import { EsVersion } from '../../functional_test_runner'; +import { parseFlags, FLAG_OPTIONS } from './flags'; + +jest.mock('uuid', () => ({ v4: () => 'some-uuid' })); + +expect.addSnapshotSerializer(createAbsolutePathSerializer()); +expect.addSnapshotSerializer( + createAnyInstanceSerializer(EsVersion, (v: EsVersion) => `EsVersion ${v.toString()}`) +); + +const INITIAL_TEST_ES_FROM = process.env.TEST_ES_FROM; +beforeEach(() => { + process.env.TEST_ES_FROM = 'snapshot'; +}); +afterEach(() => { + process.env.TEST_ES_FROM = INITIAL_TEST_ES_FROM; +}); + +const defaults = getFlags(['--config=foo'], FLAG_OPTIONS); + +const test = (opts: Record) => + parseFlags(new FlagsReader({ ...defaults, ...opts })); + +describe('parse runTest flags', () => { + it('validates defaults', () => { + expect(test({})).toMatchInlineSnapshot(` + Object { + "bail": false, + "configs": Array [ + /foo, + ], + "dryRun": false, + "esFrom": "snapshot", + "esVersion": , + "grep": undefined, + "installDir": undefined, + "logsDir": undefined, + "suiteFilters": Object { + "exclude": Array [], + "include": Array [], + }, + "suiteTags": Object { + "exclude": Array [], + "include": Array [], + }, + "updateBaselines": false, + "updateSnapshots": false, + } + `); + }); + + it('allows combinations of config and journey', () => { + expect(() => test({ config: undefined })).toThrowErrorMatchingInlineSnapshot( + `"At least one --config or --journey flag is required"` + ); + + expect(test({ config: ['configFoo'], journey: 'journeyFoo' }).configs).toMatchInlineSnapshot(` + Array [ + /configFoo, + /journeyFoo, + ] + `); + + expect(test({ config: undefined, journey: 'foo' }).configs).toMatchInlineSnapshot(` + Array [ + /foo, + ] + `); + + expect(test({ config: undefined, journey: ['foo', 'bar', 'baz'] }).configs) + .toMatchInlineSnapshot(` + Array [ + /foo, + /bar, + /baz, + ] + `); + + expect(test({ config: ['bar'], journey: ['foo', 'baz'] }).configs).toMatchInlineSnapshot(` + Array [ + /bar, + /foo, + /baz, + ] + `); + }); + + it('updates all with updateAll', () => { + const { updateBaselines, updateSnapshots } = test({ updateAll: true }); + expect({ updateBaselines, updateSnapshots }).toMatchInlineSnapshot(` + Object { + "updateBaselines": true, + "updateSnapshots": true, + } + `); + }); + + it('validates esFrom', () => { + expect(() => test({ esFrom: 'foo' })).toThrowErrorMatchingInlineSnapshot( + `"invalid --esFrom, expected one of \\"snapshot\\", \\"source\\""` + ); + }); + + it('accepts multiple tags', () => { + const { suiteFilters, suiteTags } = test({ + 'include-tag': ['foo', 'bar'], + include: 'path', + exclude: ['foo'], + 'exclude-tag': ['foo'], + }); + + expect({ suiteFilters, suiteTags }).toMatchInlineSnapshot(` + Object { + "suiteFilters": Object { + "exclude": Array [ + /foo, + ], + "include": Array [ + /path, + ], + }, + "suiteTags": Object { + "exclude": Array [ + "foo", + ], + "include": Array [ + "foo", + "bar", + ], + }, + } + `); + }); +}); + +it('supports logsDir', () => { + expect(test({ logToFile: true }).logsDir).toMatchInlineSnapshot( + `/data/ftr_servers_logs/some-uuid` + ); +}); diff --git a/packages/kbn-test/src/functional_tests/run_tests/flags.ts b/packages/kbn-test/src/functional_tests/run_tests/flags.ts new file mode 100644 index 0000000000000..7639ae341f071 --- /dev/null +++ b/packages/kbn-test/src/functional_tests/run_tests/flags.ts @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 Path from 'path'; + +import { v4 as uuidV4 } from 'uuid'; +import { REPO_ROOT } from '@kbn/utils'; +import { FlagsReader, FlagOptions } from '@kbn/dev-cli-runner'; +import { createFlagError } from '@kbn/dev-cli-errors'; + +import { EsVersion } from '../../functional_test_runner'; + +export type RunTestsOptions = ReturnType; + +export const FLAG_OPTIONS: FlagOptions = { + boolean: ['bail', 'logToFile', 'dry-run', 'updateBaselines', 'updateSnapshots', 'updateAll'], + string: [ + 'config', + 'journey', + 'esFrom', + 'kibana-install-dir', + 'grep', + 'include-tag', + 'exclude-tag', + 'include', + 'exclude', + ], + alias: { + updateAll: 'u', + }, + help: ` + --config Define a FTR config that should be executed. Can be specified multiple times + --journey Define a Journey that should be executed. Can be specified multiple times + --esFrom Build Elasticsearch from source or run from snapshot. Default: $TEST_ES_FROM or "snapshot" + --include-tag Tags that suites must include to be run, can be included multiple times + --exclude-tag Tags that suites must NOT include to be run, can be included multiple times + --include Files that must included to be run, can be included multiple times + --exclude Files that must NOT be included to be run, can be included multiple times + --grep Pattern to select which tests to run + --kibana-install-dir Run Kibana from existing install directory instead of from source + --bail Stop the test run at the first failure + --logToFile Write the log output from Kibana/ES to files instead of to stdout + --dry-run Report tests without executing them + --updateBaselines Replace baseline screenshots with whatever is generated from the test + --updateSnapshots Replace inline and file snapshots with whatever is generated from the test + --updateAll, -u Replace both baseline screenshots and snapshots + `, +}; + +export function parseFlags(flags: FlagsReader) { + const configs = [ + ...(flags.arrayOfPaths('config') ?? []), + ...(flags.arrayOfPaths('journey') ?? []), + ]; + + if (!configs.length) { + throw createFlagError('At least one --config or --journey flag is required'); + } + + const esVersionString = flags.string('es-version'); + + return { + configs, + esVersion: esVersionString ? new EsVersion(esVersionString) : EsVersion.getDefault(), + bail: flags.boolean('bail'), + dryRun: flags.boolean('dry-run'), + updateBaselines: flags.boolean('updateBaselines') || flags.boolean('updateAll'), + updateSnapshots: flags.boolean('updateSnapshots') || flags.boolean('updateAll'), + logsDir: flags.boolean('logToFile') + ? Path.resolve(REPO_ROOT, 'data/ftr_servers_logs', uuidV4()) + : undefined, + esFrom: flags.enum('esFrom', ['snapshot', 'source']) ?? 'snapshot', + installDir: flags.path('kibana-install-dir'), + grep: flags.string('grep'), + suiteTags: { + include: flags.arrayOfStrings('include-tag'), + exclude: flags.arrayOfStrings('exclude-tag'), + }, + suiteFilters: { + include: flags.arrayOfPaths('include'), + exclude: flags.arrayOfPaths('exclude'), + }, + }; +} diff --git a/packages/kbn-test/src/functional_tests/run_tests/index.ts b/packages/kbn-test/src/functional_tests/run_tests/index.ts new file mode 100644 index 0000000000000..6b0ed25db6849 --- /dev/null +++ b/packages/kbn-test/src/functional_tests/run_tests/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { runTestsCli } from './cli'; +export { runTests } from './run_tests'; diff --git a/packages/kbn-test/src/functional_tests/run_tests/run_tests.ts b/packages/kbn-test/src/functional_tests/run_tests/run_tests.ts new file mode 100644 index 0000000000000..3eb8348691a1b --- /dev/null +++ b/packages/kbn-test/src/functional_tests/run_tests/run_tests.ts @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 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 Path from 'path'; +import { setTimeout } from 'timers/promises'; + +import { REPO_ROOT } from '@kbn/utils'; +import { ToolingLog } from '@kbn/tooling-log'; +import { withProcRunner } from '@kbn/dev-proc-runner'; + +import { readConfigFile } from '../../functional_test_runner'; + +import { checkForEnabledTestsInFtrConfig, runFtr } from '../lib/run_ftr'; +import { runElasticsearch } from '../lib/run_elasticsearch'; +import { runKibanaServer } from '../lib/run_kibana_server'; +import { RunTestsOptions } from './flags'; + +/** + * Run servers and tests for each config + */ +export async function runTests(log: ToolingLog, options: RunTestsOptions) { + if (!process.env.CI) { + log.warning('❗️❗️❗️'); + log.warning('❗️❗️❗️'); + log.warning('❗️❗️❗️'); + log.warning( + " Don't forget to use `node scripts/build_kibana_platform_plugins` to build plugins you plan on testing" + ); + log.warning('❗️❗️❗️'); + log.warning('❗️❗️❗️'); + log.warning('❗️❗️❗️'); + } + + for (const [i, path] of options.configs.entries()) { + await log.indent(0, async () => { + if (options.configs.length > 1) { + const progress = `${i + 1}/${options.configs.length}`; + log.write(`--- [${progress}] Running ${Path.relative(REPO_ROOT, path)}`); + } + + const config = await readConfigFile(log, options.esVersion, path); + + const hasTests = await checkForEnabledTestsInFtrConfig({ + config, + esVersion: options.esVersion, + log, + }); + if (!hasTests) { + // just run the FTR, no Kibana or ES, which will quickly report a skipped test group to ci-stats and continue + await runFtr({ + log, + config, + esVersion: options.esVersion, + }); + return; + } + + await withProcRunner(log, async (procs) => { + const abortCtrl = new AbortController(); + + const onEarlyExit = (msg: string) => { + log.error(msg); + abortCtrl.abort(); + }; + + let shutdownEs; + try { + if (process.env.TEST_ES_DISABLE_STARTUP !== 'true') { + shutdownEs = await runElasticsearch({ ...options, log, config, onEarlyExit }); + if (abortCtrl.signal.aborted) { + return; + } + } + + await runKibanaServer({ + procs, + config, + logsDir: options.logsDir, + installDir: options.installDir, + onEarlyExit, + }); + + if (abortCtrl.signal.aborted) { + return; + } + + await runFtr({ + log, + config, + esVersion: options.esVersion, + signal: abortCtrl.signal, + }); + } finally { + try { + const delay = config.get('kbnTestServer.delayShutdown'); + if (typeof delay === 'number') { + log.info('Delaying shutdown of Kibana for', delay, 'ms'); + await setTimeout(delay); + } + + await procs.stop('kibana'); + } finally { + if (shutdownEs) { + await shutdownEs(); + } + } + } + }); + }); + } +} diff --git a/packages/kbn-test/src/functional_tests/start_servers/cli.ts b/packages/kbn-test/src/functional_tests/start_servers/cli.ts new file mode 100644 index 0000000000000..548e0310d5bcc --- /dev/null +++ b/packages/kbn-test/src/functional_tests/start_servers/cli.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { run } from '@kbn/dev-cli-runner'; + +import { initLogsDir } from '../lib/logs_dir'; + +import { parseFlags, FLAG_OPTIONS } from './flags'; +import { startServers } from './start_servers'; + +/** + * Start servers + */ +export function startServersCli() { + run( + async ({ flagsReader: flags, log }) => { + const options = parseFlags(flags); + + if (options.logsDir) { + initLogsDir(log, options.logsDir); + } + + await startServers(log, options); + }, + { + flags: FLAG_OPTIONS, + } + ); +} diff --git a/packages/kbn-test/src/functional_tests/start_servers/flags.test.ts b/packages/kbn-test/src/functional_tests/start_servers/flags.test.ts new file mode 100644 index 0000000000000..5f40b2ae66828 --- /dev/null +++ b/packages/kbn-test/src/functional_tests/start_servers/flags.test.ts @@ -0,0 +1,54 @@ +/* + * 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 { getFlags, FlagsReader } from '@kbn/dev-cli-runner'; +import { createAnyInstanceSerializer, createAbsolutePathSerializer } from '@kbn/jest-serializers'; +import { EsVersion } from '../../functional_test_runner'; +import { parseFlags, FLAG_OPTIONS } from './flags'; + +jest.mock('uuid', () => ({ v4: () => 'some-uuid' })); + +expect.addSnapshotSerializer( + createAnyInstanceSerializer(EsVersion, (v: EsVersion) => `EsVersion ${v.toString()}`) +); +expect.addSnapshotSerializer(createAbsolutePathSerializer()); + +const defaults = getFlags(['--config=foo'], FLAG_OPTIONS); + +const test = (opts: Record) => + parseFlags(new FlagsReader({ ...defaults, ...opts })); + +it('parses a subset of the flags from runTests', () => { + expect(test({ config: 'foo' })).toMatchInlineSnapshot(` + Object { + "config": "foo", + "esFrom": undefined, + "esVersion": , + "installDir": undefined, + "logsDir": undefined, + } + `); +}); + +it('rejects zero configs', () => { + expect(() => test({ config: [] })).toThrowErrorMatchingInlineSnapshot( + `"expected exactly one --config or --journey flag"` + ); +}); + +it('rejects two configs', () => { + expect(() => test({ config: ['foo'], journey: ['bar'] })).toThrowErrorMatchingInlineSnapshot( + `"expected exactly one --config or --journey flag"` + ); +}); + +it('supports logsDir', () => { + expect(test({ logToFile: true }).logsDir).toMatchInlineSnapshot( + `/data/ftr_servers_logs/some-uuid` + ); +}); diff --git a/packages/kbn-test/src/functional_tests/start_servers/flags.ts b/packages/kbn-test/src/functional_tests/start_servers/flags.ts new file mode 100644 index 0000000000000..8ce3af9f5917b --- /dev/null +++ b/packages/kbn-test/src/functional_tests/start_servers/flags.ts @@ -0,0 +1,50 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import Path from 'path'; + +import { v4 as uuidV4 } from 'uuid'; +import { FlagsReader, FlagOptions } from '@kbn/dev-cli-runner'; +import { createFlagError } from '@kbn/dev-cli-errors'; +import { REPO_ROOT } from '@kbn/utils'; + +import { EsVersion } from '../../functional_test_runner'; + +export type StartServerOptions = ReturnType; + +export const FLAG_OPTIONS: FlagOptions = { + string: ['config', 'journey', 'esFrom', 'kibana-install-dir'], + boolean: ['logToFile'], + help: ` + --config Define a FTR config that should be executed. Can be specified multiple times + --journey Define a Journey that should be executed. Can be specified multiple times + --esFrom Build Elasticsearch from source or run from snapshot. Default: $TEST_ES_FROM or "snapshot" + --kibana-install-dir Run Kibana from existing install directory instead of from source + --logToFile Write the log output from Kibana/ES to files instead of to stdout + `, +}; + +export function parseFlags(flags: FlagsReader) { + const configs = [ + ...(flags.arrayOfStrings('config') ?? []), + ...(flags.arrayOfStrings('journey') ?? []), + ]; + if (configs.length !== 1) { + throw createFlagError(`expected exactly one --config or --journey flag`); + } + + return { + config: configs[0], + esFrom: flags.enum('esFrom', ['source', 'snapshot']), + esVersion: EsVersion.getDefault(), + installDir: flags.string('kibana-install-dir'), + logsDir: flags.boolean('logToFile') + ? Path.resolve(REPO_ROOT, 'data/ftr_servers_logs', uuidV4()) + : undefined, + }; +} diff --git a/packages/kbn-test/src/functional_tests/start_servers/index.ts b/packages/kbn-test/src/functional_tests/start_servers/index.ts new file mode 100644 index 0000000000000..ff88a1f4cb476 --- /dev/null +++ b/packages/kbn-test/src/functional_tests/start_servers/index.ts @@ -0,0 +1,10 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { startServersCli } from './cli'; +export { startServers } from './start_servers'; diff --git a/packages/kbn-test/src/functional_tests/start_servers/start_servers.ts b/packages/kbn-test/src/functional_tests/start_servers/start_servers.ts new file mode 100644 index 0000000000000..3bb601fabe002 --- /dev/null +++ b/packages/kbn-test/src/functional_tests/start_servers/start_servers.ts @@ -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 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 Path from 'path'; + +import * as Rx from 'rxjs'; +import dedent from 'dedent'; +import { REPO_ROOT } from '@kbn/utils'; +import { ToolingLog } from '@kbn/tooling-log'; +import { withProcRunner } from '@kbn/dev-proc-runner'; +import { getTimeReporter } from '@kbn/ci-stats-reporter'; + +import { readConfigFile } from '../../functional_test_runner'; +import { runElasticsearch } from '../lib/run_elasticsearch'; +import { runKibanaServer } from '../lib/run_kibana_server'; +import { StartServerOptions } from './flags'; + +const FTR_SCRIPT_PATH = Path.resolve(REPO_ROOT, 'scripts/functional_test_runner'); + +export async function startServers(log: ToolingLog, options: StartServerOptions) { + const runStartTime = Date.now(); + const reportTime = getTimeReporter(log, 'scripts/functional_tests_server'); + + await withProcRunner(log, async (procs) => { + const config = await readConfigFile(log, options.esVersion, options.config); + + const shutdownEs = await runElasticsearch({ + config, + log, + esFrom: options.esFrom, + logsDir: options.logsDir, + }); + + await runKibanaServer({ + procs, + config, + installDir: options.installDir, + extraKbnOpts: options.installDir ? [] : ['--dev', '--no-dev-config', '--no-dev-credentials'], + }); + + reportTime(runStartTime, 'ready', { + success: true, + ...options, + }); + + // wait for 5 seconds of silence before logging the + // success message so that it doesn't get buried + await silence(log, 5000); + + const installDirFlag = options.installDir ? ` --kibana-install-dir=${options.installDir}` : ''; + const rel = Path.relative(process.cwd(), config.module.path); + const pathsMessage = ` --${config.module.type}=${rel}`; + + log.success( + '\n\n' + + dedent` + Elasticsearch and Kibana are ready for functional testing. Start the functional tests + in another terminal session by running this command from this directory: + + node ${Path.relative(process.cwd(), FTR_SCRIPT_PATH)}${installDirFlag}${pathsMessage} + ` + + '\n\n' + ); + + await procs.waitForAllToStop(); + await shutdownEs(); + }); +} + +async function silence(log: ToolingLog, milliseconds: number) { + await Rx.firstValueFrom( + log.getWritten$().pipe( + Rx.startWith(null), + Rx.switchMap(() => Rx.timer(milliseconds)) + ) + ); +} diff --git a/packages/kbn-test/src/functional_tests/tasks.ts b/packages/kbn-test/src/functional_tests/tasks.ts deleted file mode 100644 index 26504b07544b0..0000000000000 --- a/packages/kbn-test/src/functional_tests/tasks.ts +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import Fs from 'fs'; -import Path from 'path'; -import { setTimeout } from 'timers/promises'; - -import * as Rx from 'rxjs'; -import { startWith, switchMap, take } from 'rxjs/operators'; -import { withProcRunner } from '@kbn/dev-proc-runner'; -import { ToolingLog } from '@kbn/tooling-log'; -import { getTimeReporter } from '@kbn/ci-stats-reporter'; -import { REPO_ROOT } from '@kbn/utils'; -import dedent from 'dedent'; - -import { readConfigFile, EsVersion } from '../functional_test_runner/lib'; -import { - runElasticsearch, - runKibanaServer, - runFtr, - assertNoneExcluded, - hasTests, - CreateFtrOptions, -} from './lib'; - -const FTR_SCRIPT_PATH = Path.resolve(REPO_ROOT, 'scripts/functional_test_runner'); - -const makeSuccessMessage = (options: StartServerOptions) => { - const installDirFlag = options.installDir ? ` --kibana-install-dir=${options.installDir}` : ''; - const configPaths: string[] = Array.isArray(options.config) ? options.config : [options.config]; - const pathsMessage = options.useDefaultConfig - ? '' - : configPaths - .map((path) => Path.relative(process.cwd(), path)) - .map((path) => ` --config ${path}`) - .join(''); - - return ( - '\n\n' + - dedent` - Elasticsearch and Kibana are ready for functional testing. Start the functional tests - in another terminal session by running this command from this directory: - - node ${Path.relative(process.cwd(), FTR_SCRIPT_PATH)}${installDirFlag}${pathsMessage} - ` + - '\n\n' - ); -}; - -export async function initLogsDir(options: { logsDir?: string; createLogger(): ToolingLog }) { - if (options.logsDir) { - options - .createLogger() - .info(`Kibana/ES logs will be written to ${Path.relative(process.cwd(), options.logsDir)}/`); - - Fs.mkdirSync(options.logsDir, { recursive: true }); - } -} - -/** - * Run servers and tests for each config - */ -interface RunTestsParams extends CreateFtrOptions { - /** Array of paths to configs */ - configs: string[]; - /** run from source instead of snapshot */ - esFrom?: string; - esVersion: EsVersion; - createLogger: () => ToolingLog; - extraKbnOpts: string[]; - assertNoneExcluded: boolean; -} -export async function runTests(options: RunTestsParams) { - if (!process.env.CI && !options.assertNoneExcluded) { - const log = options.createLogger(); - log.warning('❗️❗️❗️'); - log.warning('❗️❗️❗️'); - log.warning('❗️❗️❗️'); - log.warning( - " Don't forget to use `node scripts/build_kibana_platform_plugins` to build plugins you plan on testing" - ); - log.warning('❗️❗️❗️'); - log.warning('❗️❗️❗️'); - log.warning('❗️❗️❗️'); - } - - const log = options.createLogger(); - - if (options.assertNoneExcluded) { - log.write('--- asserting that all tests belong to a ciGroup'); - for (const configPath of options.configs) { - log.info('loading', configPath); - await log.indent(4, async () => { - await assertNoneExcluded({ configPath, options: { ...options, log } }); - }); - continue; - } - - return; - } - - for (const [i, configPath] of options.configs.entries()) { - await log.indent(0, async () => { - if (options.configs.length > 1) { - const progress = `${i + 1}/${options.configs.length}`; - log.write(`--- [${progress}] Running ${Path.relative(REPO_ROOT, configPath)}`); - } - - if (!(await hasTests({ configPath, options: { ...options, log } }))) { - // just run the FTR, no Kibana or ES, which will quickly report a skipped test group to ci-stats and continue - await runFtr({ configPath, options: { ...options, log } }); - return; - } - - await withProcRunner(log, async (procs) => { - const config = await readConfigFile(log, options.esVersion, configPath); - const abortCtrl = new AbortController(); - - const onEarlyExit = (msg: string) => { - log.error(msg); - abortCtrl.abort(); - }; - - let shutdownEs; - try { - if (process.env.TEST_ES_DISABLE_STARTUP !== 'true') { - shutdownEs = await runElasticsearch({ ...options, log, config, onEarlyExit }); - if (abortCtrl.signal.aborted) { - return; - } - } - await runKibanaServer({ procs, config, options, onEarlyExit }); - if (abortCtrl.signal.aborted) { - return; - } - await runFtr({ configPath, options: { ...options, log } }, abortCtrl.signal); - } finally { - try { - const delay = config.get('kbnTestServer.delayShutdown'); - if (typeof delay === 'number') { - log.info('Delaying shutdown of Kibana for', delay, 'ms'); - await setTimeout(delay); - } - - await procs.stop('kibana'); - } finally { - if (shutdownEs) { - await shutdownEs(); - } - } - } - }); - }); - } -} - -interface StartServerOptions { - /** Path to a config file */ - config: string; - log: ToolingLog; - /** installation dir from which to run Kibana */ - installDir?: string; - /** run from source instead of snapshot */ - esFrom?: string; - createLogger: () => ToolingLog; - extraKbnOpts: string[]; - useDefaultConfig?: boolean; - esVersion: EsVersion; -} - -export async function startServers({ ...options }: StartServerOptions) { - const runStartTime = Date.now(); - const toolingLog = new ToolingLog({ - level: 'info', - writeTo: process.stdout, - }); - const reportTime = getTimeReporter(toolingLog, 'scripts/functional_tests_server'); - - const log = options.createLogger(); - const opts = { - ...options, - log, - }; - - await withProcRunner(log, async (procs) => { - const config = await readConfigFile(log, options.esVersion, options.config); - - const shutdownEs = await runElasticsearch({ ...opts, config }); - await runKibanaServer({ - procs, - config, - options: { - ...opts, - extraKbnOpts: [ - ...options.extraKbnOpts, - ...(options.installDir ? [] : ['--dev', '--no-dev-config', '--no-dev-credentials']), - ], - }, - }); - - reportTime(runStartTime, 'ready', { - success: true, - ...options, - }); - - // wait for 5 seconds of silence before logging the - // success message so that it doesn't get buried - await silence(log, 5000); - log.success(makeSuccessMessage(options)); - - await procs.waitForAllToStop(); - await shutdownEs(); - }); -} - -async function silence(log: ToolingLog, milliseconds: number) { - await log - .getWritten$() - .pipe( - startWith(null), - switchMap(() => Rx.timer(milliseconds)), - take(1) - ) - .toPromise(); -} diff --git a/packages/kbn-test/src/mocha/junit_report_generation.js b/packages/kbn-test/src/mocha/junit_report_generation.js index 98210aba770b7..599d1f366194f 100644 --- a/packages/kbn-test/src/mocha/junit_report_generation.js +++ b/packages/kbn-test/src/mocha/junit_report_generation.js @@ -24,6 +24,7 @@ export function setupJUnitReportGeneration(runner, options = {}) { reportName = 'Unnamed Mocha Tests', rootDirectory = REPO_ROOT, getTestMetadata = () => ({}), + metadata, } = options; const stats = {}; @@ -104,6 +105,7 @@ export function setupJUnitReportGeneration(runner, options = {}) { tests: allTests.length + failedHooks.length, failures: failures.length, skipped: skippedResults.length, + 'metadata-json': JSON.stringify(metadata ?? {}), }); function addTestcaseEl(node) { diff --git a/packages/kbn-test/src/mocha/junit_report_generation.test.js b/packages/kbn-test/src/mocha/junit_report_generation.test.js index c19550349fd85..ac23d91390ed9 100644 --- a/packages/kbn-test/src/mocha/junit_report_generation.test.js +++ b/packages/kbn-test/src/mocha/junit_report_generation.test.js @@ -60,6 +60,7 @@ describe('dev/mocha/junit report generation', () => { name: 'test', skipped: '1', tests: '4', + 'metadata-json': '{}', time: testsuite.$.time, timestamp: testsuite.$.timestamp, }, diff --git a/scripts/functional_tests_server.js b/scripts/functional_tests_server.js index 836a1ede126e3..1d51041dccd45 100644 --- a/scripts/functional_tests_server.js +++ b/scripts/functional_tests_server.js @@ -7,4 +7,4 @@ */ require('../src/setup_node_env'); -require('@kbn/test').startServersCli(require.resolve('../test/functional/config.base.js')); +require('@kbn/test').startServersCli(); diff --git a/scripts/report_failed_tests.js b/scripts/report_failed_tests.js index 3d69999a2bb1e..a56675523bba3 100644 --- a/scripts/report_failed_tests.js +++ b/scripts/report_failed_tests.js @@ -7,4 +7,4 @@ */ require('../src/setup_node_env'); -require('@kbn/test').runFailedTestsReporterCli(); +require('@kbn/failed-test-reporter-cli'); diff --git a/src/dev/typescript/projects.ts b/src/dev/typescript/projects.ts index d88ba3a327941..f57854b83550d 100644 --- a/src/dev/typescript/projects.ts +++ b/src/dev/typescript/projects.ts @@ -30,6 +30,7 @@ export const PROJECTS = [ createProject('tsconfig.json'), createProject('test/tsconfig.json', { name: 'kibana/test' }), createProject('x-pack/test/tsconfig.json', { name: 'x-pack/test' }), + createProject('x-pack/performance/tsconfig.json', { name: 'x-pack/performance' }), createProject('src/core/tsconfig.json'), createProject('.buildkite/tsconfig.json'), createProject('kbn_pm/tsconfig.json'), diff --git a/test/common/services/bsearch.ts b/test/common/services/bsearch.ts index 3c8a58c46867b..2a0278840a7c8 100644 --- a/test/common/services/bsearch.ts +++ b/test/common/services/bsearch.ts @@ -10,8 +10,7 @@ import expect from '@kbn/expect'; import request from 'superagent'; import type SuperTest from 'supertest'; import { IEsSearchResponse } from '@kbn/data-plugin/common'; -import { FtrProviderContext } from '../ftr_provider_context'; -import { RetryService } from './retry/retry'; +import { FtrService } from '../ftr_provider_context'; /** * Function copied from here: @@ -46,9 +45,8 @@ interface SendOptions { } /** - * Bsearch factory which will return a new bsearch capable service that can reduce flake - * on the CI systems when they are under pressure and bsearch returns an async search - * response or a sync response. + * Bsearch Service that can reduce flake on the CI systems when they are under + * pressure and bsearch returns an async search response or a sync response. * * @example * const supertest = getService('supertest'); @@ -57,21 +55,18 @@ interface SendOptions { * supertest, * options: { * defaultIndex: ['large_volume_dns_data'], - * } - * strategy: 'securitySolutionSearchStrategy', - * }); + * }, + * strategy: 'securitySolutionSearchStrategy', + * }); * expect(response).eql({ ... your value ... }); */ -export const BSearchFactory = (retry: RetryService) => ({ +export class BsearchService extends FtrService { + private readonly retry = this.ctx.getService('retry'); + /** Send method to send in your supertest, url, options, and strategy name */ - send: async ({ - supertest, - options, - strategy, - space, - }: SendOptions): Promise => { + async send({ supertest, options, strategy, space }: SendOptions) { const spaceUrl = getSpaceUrlPrefix(space); - const { body } = await retry.try(async () => { + const { body } = await this.retry.try(async () => { return supertest .post(`${spaceUrl}/internal/search/${strategy}`) .set('kbn-xsrf', 'true') @@ -79,44 +74,32 @@ export const BSearchFactory = (retry: RetryService) => ({ .expect(200); }); - if (body.isRunning) { - const result = await retry.try(async () => { - const resp = await supertest - .post(`${spaceUrl}/internal/bsearch`) - .set('kbn-xsrf', 'true') - .send({ - batch: [ - { - request: { - id: body.id, - ...options, - }, - options: { - strategy, - }, - }, - ], - }) - .expect(200); - const [parsedResponse] = parseBfetchResponse(resp); - expect(parsedResponse.result.isRunning).equal(false); - return parsedResponse.result; - }); - return result; - } else { + if (!body.isRunning) { return body; } - }, -}); -/** - * Bsearch provider which will return a new bsearch capable service that can reduce flake - * on the CI systems when they are under pressure and bsearch returns an async search response - * or a sync response. - */ -export function BSearchProvider({ - getService, -}: FtrProviderContext): ReturnType { - const retry = getService('retry'); - return BSearchFactory(retry); + const result = await this.retry.try(async () => { + const resp = await supertest + .post(`${spaceUrl}/internal/bsearch`) + .set('kbn-xsrf', 'true') + .send({ + batch: [ + { + request: { + id: body.id, + ...options, + }, + options: { + strategy, + }, + }, + ], + }) + .expect(200); + const [parsedResponse] = parseBfetchResponse(resp); + expect(parsedResponse.result.isRunning).equal(false); + return parsedResponse.result as T; + }); + return result; + } } diff --git a/test/common/services/index.ts b/test/common/services/index.ts index 91d17ce1bb3e8..25c8ea0cdd27d 100644 --- a/test/common/services/index.ts +++ b/test/common/services/index.ts @@ -6,28 +6,22 @@ * Side Public License, v 1. */ +import { commonFunctionalServices } from '@kbn/ftr-common-functional-services'; import { DeploymentService } from './deployment'; -import { ElasticsearchProvider } from './elasticsearch'; -import { EsArchiverProvider } from './es_archiver'; -import { KibanaServerProvider } from './kibana_server'; -import { RetryService } from './retry'; import { RandomnessService } from './randomness'; import { SecurityServiceProvider } from './security'; import { EsDeleteAllIndicesProvider } from './es_delete_all_indices'; import { SavedObjectInfoService } from './saved_object_info'; import { IndexPatternsService } from './index_patterns'; -import { BSearchProvider } from './bsearch'; +import { BsearchService } from './bsearch'; export const services = { + ...commonFunctionalServices, deployment: DeploymentService, - es: ElasticsearchProvider, - esArchiver: EsArchiverProvider, - kibanaServer: KibanaServerProvider, - retry: RetryService, randomness: RandomnessService, security: SecurityServiceProvider, esDeleteAllIndices: EsDeleteAllIndicesProvider, savedObjectInfo: SavedObjectInfoService, indexPatterns: IndexPatternsService, - bsearch: BSearchProvider, + bsearch: BsearchService, }; diff --git a/test/functional/services/common/failure_debugging.ts b/test/functional/services/common/failure_debugging.ts index 343036436293d..5555ae78bccf8 100644 --- a/test/functional/services/common/failure_debugging.ts +++ b/test/functional/services/common/failure_debugging.ts @@ -9,9 +9,9 @@ import { resolve } from 'path'; import { writeFile, mkdir } from 'fs'; import { promisify } from 'util'; -import { createHash } from 'crypto'; import del from 'del'; +import { FtrScreenshotFilename } from '@kbn/ftr-screenshot-filename'; import { FtrProviderContext } from '../../ftr_provider_context'; interface Test { @@ -49,15 +49,7 @@ export async function FailureDebuggingProvider({ getService }: FtrProviderContex } async function onFailure(_: any, test: Test) { - const fullName = test.fullTitle(); - - // include a hash of the full title of the test in the filename so that even with truncation filenames are - // always unique and deterministic based on the test title - const hash = createHash('sha256').update(fullName).digest('hex'); - - // Replace characters in test names which can't be used in filenames, like * - const name = `${fullName.replace(/([^ a-zA-Z0-9-]+)/g, '_').slice(0, 80)}-${hash}`; - + const name = FtrScreenshotFilename.create(test.fullTitle(), { ext: false }); await Promise.all([screenshots.takeForFailure(name), logCurrentUrl(), savePageHtml(name)]); } diff --git a/x-pack/test/performance/es_archives/ecommerce_sample_data/data.json.gz b/x-pack/performance/es_archives/ecommerce_sample_data/data.json.gz similarity index 100% rename from x-pack/test/performance/es_archives/ecommerce_sample_data/data.json.gz rename to x-pack/performance/es_archives/ecommerce_sample_data/data.json.gz diff --git a/x-pack/test/performance/es_archives/ecommerce_sample_data/mappings.json b/x-pack/performance/es_archives/ecommerce_sample_data/mappings.json similarity index 100% rename from x-pack/test/performance/es_archives/ecommerce_sample_data/mappings.json rename to x-pack/performance/es_archives/ecommerce_sample_data/mappings.json diff --git a/x-pack/test/performance/es_archives/reporting_dashboard/data.json.gz b/x-pack/performance/es_archives/reporting_dashboard/data.json.gz similarity index 100% rename from x-pack/test/performance/es_archives/reporting_dashboard/data.json.gz rename to x-pack/performance/es_archives/reporting_dashboard/data.json.gz diff --git a/x-pack/test/performance/es_archives/reporting_dashboard/mappings.json b/x-pack/performance/es_archives/reporting_dashboard/mappings.json similarity index 100% rename from x-pack/test/performance/es_archives/reporting_dashboard/mappings.json rename to x-pack/performance/es_archives/reporting_dashboard/mappings.json diff --git a/x-pack/performance/journeys/data_stress_test_lens.ts b/x-pack/performance/journeys/data_stress_test_lens.ts new file mode 100644 index 0000000000000..6d65dc5e4a0d2 --- /dev/null +++ b/x-pack/performance/journeys/data_stress_test_lens.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 { Journey } from '@kbn/journeys'; +import { waitForVisualizations } from '../utils'; + +export const journey = new Journey({ + kbnArchives: ['test/functional/fixtures/kbn_archiver/stress_test'], + esArchives: ['test/functional/fixtures/es_archiver/stress_test'], +}).step('Go to dashboard', async ({ page, kbnUrl }) => { + await page.goto(kbnUrl.get(`/app/dashboards#/view/92b143a0-2e9c-11ed-b1b6-a504560b392c`)); + + await waitForVisualizations(page, 1); +}); diff --git a/x-pack/performance/journeys/ecommerce_dashboard.ts b/x-pack/performance/journeys/ecommerce_dashboard.ts new file mode 100644 index 0000000000000..89f05902f4153 --- /dev/null +++ b/x-pack/performance/journeys/ecommerce_dashboard.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 { Journey } from '@kbn/journeys'; +import { subj } from '@kbn/test-subj-selector'; + +import { ToastsService } from '../services/toasts'; +import { waitForVisualizations } from '../utils'; + +export const journey = new Journey({ + extendContext: ({ page, log }) => ({ + toasts: new ToastsService(log, page), + }), +}) + .step('Go to Sample Data Page', async ({ page, kbnUrl }) => { + await page.goto(kbnUrl.get(`/app/home#/tutorial_directory/sampleData`)); + + await page.waitForSelector(subj('showSampleDataButton')); + }) + + .step('Open Sample Data pane', async ({ page }) => { + // open the "other sample data sets" section + await page.click(subj('showSampleDataButton')); + // wait for the logs card to be visible + await page.waitForSelector(subj('sampleDataSetCardecommerce')); + }) + + .step('Remove Ecommerce Sample Data if installed', async ({ page, log, toasts }) => { + if (!(await page.$(subj('removeSampleDataSetecommerce')))) { + log.info('Ecommerce data does not need to be removed'); + return; + } + + // click the "remove" button + await page.click(subj('removeSampleDataSetecommerce')); + // wait for the toast acknowledging uninstallation + await toasts.waitForAndClear('uninstalled'); + }) + + .step('Install Ecommerce Sample Data', async ({ page, toasts }) => { + // click the "add data" button + await page.click(subj('addSampleDataSetecommerce')); + // wait for the toast acknowledging installation + await toasts.waitForAndClear('installed'); + }) + + .step('Go to Ecommerce Dashboard', async ({ page }) => { + await page.click(subj('launchSampleDataSetecommerce')); + await page.click(subj('viewSampleDataSetecommerce-dashboard')); + + await waitForVisualizations(page, 13); + }); diff --git a/x-pack/performance/journeys/flight_dashboard.ts b/x-pack/performance/journeys/flight_dashboard.ts new file mode 100644 index 0000000000000..ac6e589d391a5 --- /dev/null +++ b/x-pack/performance/journeys/flight_dashboard.ts @@ -0,0 +1,68 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Journey } from '@kbn/journeys'; +import { subj } from '@kbn/test-subj-selector'; + +import { ToastsService } from '../services/toasts'; +import { waitForVisualizations } from '../utils'; + +export const journey = new Journey({ + extendContext: ({ page, log }) => ({ + toasts: new ToastsService(log, page), + }), +}) + .step('Go to Sample Data Page', async ({ page, kbnUrl }) => { + await page.goto(kbnUrl.get(`/app/home#/tutorial_directory/sampleData`)); + + await page.waitForSelector(subj('showSampleDataButton')); + }) + + .step('Open Sample Data pane', async ({ page }) => { + // open the "other sample data sets" section + await page.click(subj('showSampleDataButton')); + // wait for the logs card to be visible + await page.waitForSelector(subj('sampleDataSetCardflights')); + }) + + .step('Remove Flights Sample Data if installed', async ({ page, log, toasts }) => { + if (!(await page.$(subj('removeSampleDataSetflights')))) { + log.info('Flights data does not need to be removed'); + return; + } + + // click the "remove" button + await page.click(subj('removeSampleDataSetflights')); + // wait for the toast acknowledging uninstallation + await toasts.waitForAndClear('uninstalled'); + }) + + .step('Install Flights Sample Data', async ({ page, toasts }) => { + // click the "add data" button + await page.click(subj('addSampleDataSetflights')); + // wait for the toast acknowledging installation + await toasts.waitForAndClear('installed'); + }) + + .step('Go to Flights Dashboard', async ({ page }) => { + await page.click(subj('launchSampleDataSetflights')); + await page.click(subj('viewSampleDataSetflights-dashboard')); + + await waitForVisualizations(page, 15); + }) + + .step('Go to Airport Connections Visualizations Edit', async ({ page }) => { + await page.click(subj('dashboardEditMode')); + + const flightsPanelHeadingSelector = `embeddablePanelHeading-[Flights]AirportConnections(HoverOverAirport)`; + const panelToggleMenuIconSelector = `embeddablePanelToggleMenuIcon`; + await page.click(subj(`${flightsPanelHeadingSelector} > ${panelToggleMenuIconSelector}`)); + + await page.click(subj('embeddablePanelAction-editPanel')); + + await waitForVisualizations(page, 1); + }); diff --git a/x-pack/performance/journeys/login.ts b/x-pack/performance/journeys/login.ts new file mode 100644 index 0000000000000..7c5808be83607 --- /dev/null +++ b/x-pack/performance/journeys/login.ts @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Journey } from '@kbn/journeys'; +import { subj } from '@kbn/test-subj-selector'; + +export const journey = new Journey({ + skipAutoLogin: true, + scalabilitySetup: { + warmup: [ + { + action: 'constantConcurrentUsers', + userCount: 10, + duration: '30s', + }, + { + action: 'rampConcurrentUsers', + minUsersCount: 10, + maxUsersCount: 50, + duration: '2m', + }, + ], + test: [ + { + action: 'constantConcurrentUsers', + userCount: 50, + duration: '5m', + }, + ], + maxDuration: '10m', + }, +}).step('Login', async ({ page, kbnUrl, inputDelays }) => { + await page.goto(kbnUrl.get()); + + await page.type(subj('loginUsername'), 'elastic', { delay: inputDelays.TYPING }); + await page.type(subj('loginPassword'), 'changeme', { delay: inputDelays.TYPING }); + await page.click(subj('loginSubmit'), { delay: inputDelays.MOUSE_CLICK }); + + await page.waitForSelector('#headerUserMenu'); +}); diff --git a/x-pack/performance/journeys/many_fields_discover.ts b/x-pack/performance/journeys/many_fields_discover.ts new file mode 100644 index 0000000000000..41ec0373c700c --- /dev/null +++ b/x-pack/performance/journeys/many_fields_discover.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 { Journey } from '@kbn/journeys'; +import { subj } from '@kbn/test-subj-selector'; + +export const journey = new Journey({ + // FAILING: https://github.com/elastic/kibana/issues/130287 + skipped: true, + kbnArchives: ['test/functional/fixtures/kbn_archiver/many_fields_data_view'], + esArchives: ['test/functional/fixtures/es_archiver/many_fields'], +}) + .step('Go to Discover Page', async ({ page, kbnUrl }) => { + await page.goto(kbnUrl.get(`/app/discover`)); + await page.waitForSelector(subj('discoverDocTable')); + }) + .step('Expand the first document', async ({ page }) => { + const expandButtons = page.locator(subj('docTableExpandToggleColumn')); + await expandButtons.first().click(); + await page.locator('text="Expanded document"'); + }); diff --git a/x-pack/performance/journeys/promotion_tracking_dashboard.ts b/x-pack/performance/journeys/promotion_tracking_dashboard.ts new file mode 100644 index 0000000000000..e6bd67a2819c5 --- /dev/null +++ b/x-pack/performance/journeys/promotion_tracking_dashboard.ts @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Journey } from '@kbn/journeys'; +import { subj } from '@kbn/test-subj-selector'; +import { waitForVisualizations } from '../utils'; + +export const journey = new Journey({ + kbnArchives: ['x-pack/performance/kbn_archives/promotion_tracking_dashboard'], + esArchives: ['x-pack/performance/es_archives/ecommerce_sample_data'], + scalabilitySetup: { + warmup: [ + { + action: 'constantConcurrentUsers', + userCount: 10, + duration: '30s', + }, + { + action: 'rampConcurrentUsers', + minUsersCount: 10, + maxUsersCount: 50, + duration: '2m', + }, + ], + test: [ + { + action: 'constantConcurrentUsers', + userCount: 50, + duration: '5m', + }, + ], + maxDuration: '10m', + }, +}) + .step('Go to Dashboards Page', async ({ page, kbnUrl }) => { + await page.goto(kbnUrl.get(`/app/dashboards`)); + await page.waitForSelector('#dashboardListingHeading'); + }) + + .step('Go to Promotion Tracking Dashboard', async ({ page }) => { + await page.click(subj('dashboardListingTitleLink-Promotion-Dashboard')); + }) + + .step('Change time range', async ({ page }) => { + await page.click(subj('superDatePickerToggleQuickMenuButton')); + await page.click(subj('superDatePickerCommonlyUsed_Last_30 days')); + }) + + .step('Wait for visualization animations to finish', async ({ page }) => { + await waitForVisualizations(page, 1); + }); diff --git a/x-pack/performance/journeys/web_logs_dashboard.ts b/x-pack/performance/journeys/web_logs_dashboard.ts new file mode 100644 index 0000000000000..64ea47d412e0e --- /dev/null +++ b/x-pack/performance/journeys/web_logs_dashboard.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 { Journey } from '@kbn/journeys'; +import { subj } from '@kbn/test-subj-selector'; + +import { ToastsService } from '../services/toasts'; +import { waitForVisualizations } from '../utils'; + +export const journey = new Journey({ + extendContext: ({ page, log }) => ({ + toasts: new ToastsService(log, page), + }), +}) + .step('Go to Sample Data Page', async ({ page, kbnUrl }) => { + await page.goto(kbnUrl.get(`/app/home#/tutorial_directory/sampleData`)); + + await page.waitForSelector(subj('showSampleDataButton')); + }) + + .step('Open Sample Data pane', async ({ page }) => { + // open the "other sample data sets" section + await page.click(subj('showSampleDataButton')); + // wait for the logs card to be visible + await page.waitForSelector(subj('sampleDataSetCardlogs')); + }) + + .step('Remove Sample Data Logs if installed', async ({ page, log, toasts }) => { + if (!(await page.$(subj('removeSampleDataSetlogs')))) { + log.info('Logs data does not need to be removed'); + return; + } + + // click the "remove" button + await page.click(subj('removeSampleDataSetlogs')); + // wait for the toast acknowledging uninstallation + await toasts.waitForAndClear('uninstalled'); + }) + + .step('Install Logs Sample Data', async ({ page, toasts }) => { + // click the "add data" button + await page.click(subj('addSampleDataSetlogs')); + // wait for the toast acknowledging installation + await toasts.waitForAndClear('installed'); + }) + + .step('Go to Web Logs Dashboard', async ({ page }) => { + await page.click(subj('launchSampleDataSetlogs')); + await page.click(subj('viewSampleDataSetlogs-dashboard')); + + await waitForVisualizations(page, 12); + }); diff --git a/x-pack/test/performance/kbn_archives/promotion_tracking_dashboard.json b/x-pack/performance/kbn_archives/promotion_tracking_dashboard.json similarity index 100% rename from x-pack/test/performance/kbn_archives/promotion_tracking_dashboard.json rename to x-pack/performance/kbn_archives/promotion_tracking_dashboard.json diff --git a/x-pack/test/performance/kbn_archives/reporting_dashboard.json b/x-pack/performance/kbn_archives/reporting_dashboard.json similarity index 100% rename from x-pack/test/performance/kbn_archives/reporting_dashboard.json rename to x-pack/performance/kbn_archives/reporting_dashboard.json diff --git a/x-pack/performance/services/toasts.ts b/x-pack/performance/services/toasts.ts new file mode 100644 index 0000000000000..b3859ddb92ec4 --- /dev/null +++ b/x-pack/performance/services/toasts.ts @@ -0,0 +1,34 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { ToolingLog } from '@kbn/tooling-log'; +import { subj } from '@kbn/test-subj-selector'; +import { Page } from 'playwright'; + +export class ToastsService { + constructor(private readonly log: ToolingLog, private readonly page: Page) {} + + /** + * Wait for a toast with some bit of text matching the provided `textSnipped`, then clear + * it and resolve the promise. + */ + async waitForAndClear(textSnippet: string) { + const txt = JSON.stringify(textSnippet); + this.log.info(`waiting for toast that has the text ${txt}`); + const toastSel = `.euiToast:has-text(${txt})`; + + const toast = this.page.locator(toastSel); + await toast.waitFor(); + + this.log.info('toast found, closing'); + + const close = toast.locator(subj('toastCloseButton')); + await close.click(); + + await toast.waitFor({ state: 'hidden' }); + } +} diff --git a/x-pack/performance/tsconfig.json b/x-pack/performance/tsconfig.json new file mode 100644 index 0000000000000..caff6d53f4476 --- /dev/null +++ b/x-pack/performance/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "./target/types", + "emitDeclarationOnly": true, + "declaration": true, + "declarationMap": true, + "types": ["node", "mocha"] + }, + "include": ["**/*.ts"], +} diff --git a/x-pack/test/performance/utils.ts b/x-pack/performance/utils.ts similarity index 67% rename from x-pack/test/performance/utils.ts rename to x-pack/performance/utils.ts index 1e9e754088418..c0a7ba95f7ee1 100644 --- a/x-pack/test/performance/utils.ts +++ b/x-pack/performance/utils.ts @@ -7,14 +7,8 @@ import { Page } from 'playwright'; -export function serializeApmGlobalLabels(obj: any) { - return Object.entries(obj) - .filter(([, v]) => !!v) - .reduce((acc, [k, v]) => (acc ? `${acc},${k}=${v}` : `${k}=${v}`), ''); -} - -export function waitForVisualizations(page: Page, visCount: number) { - return page.waitForFunction(function renderCompleted(cnt) { +export async function waitForVisualizations(page: Page, visCount: number) { + return await page.waitForFunction(function renderCompleted(cnt) { const visualizations = Array.from(document.querySelectorAll('[data-rendering-count]')); const visualizationElementsLoaded = visualizations.length === cnt; const visualizationAnimationsFinished = visualizations.every( diff --git a/x-pack/scripts/functional_tests_server.js b/x-pack/scripts/functional_tests_server.js index 329fea019221b..938d4a465af50 100755 --- a/x-pack/scripts/functional_tests_server.js +++ b/x-pack/scripts/functional_tests_server.js @@ -8,4 +8,4 @@ process.env.ALLOW_PERFORMANCE_HOOKS_IN_TASK_MANAGER = true; require('../../src/setup_node_env'); -require('@kbn/test').startServersCli(require.resolve('../test/functional/config.base.js')); +require('@kbn/test').startServersCli(); diff --git a/x-pack/test/common/ftr_provider_context.ts b/x-pack/test/common/ftr_provider_context.ts index aa56557c09df8..e8c18508a202f 100644 --- a/x-pack/test/common/ftr_provider_context.ts +++ b/x-pack/test/common/ftr_provider_context.ts @@ -5,8 +5,9 @@ * 2.0. */ -import { GenericFtrProviderContext } from '@kbn/test'; +import { GenericFtrProviderContext, GenericFtrService } from '@kbn/test'; import { services } from './services'; export type FtrProviderContext = GenericFtrProviderContext; +export class FtrService extends GenericFtrService {} diff --git a/x-pack/test/common/services/bsearch_secure.ts b/x-pack/test/common/services/bsearch_secure.ts index f60dc6aa4c3cd..94a5abe73c901 100644 --- a/x-pack/test/common/services/bsearch_secure.ts +++ b/x-pack/test/common/services/bsearch_secure.ts @@ -12,8 +12,7 @@ import expect from '@kbn/expect'; import request from 'superagent'; import type SuperTest from 'supertest'; import { IEsSearchResponse } from '@kbn/data-plugin/common'; -import { FtrProviderContext } from '../ftr_provider_context'; -import { RetryService } from '../../../../test/common/services/retry/retry'; +import { FtrService } from '../ftr_provider_context'; const parseBfetchResponse = (resp: request.Response): Array> => { return resp.text @@ -36,8 +35,10 @@ interface SendOptions { space?: string; } -export const BSecureSearchFactory = (retry: RetryService) => ({ - send: async ({ +export class BsearchSecureService extends FtrService { + private readonly retry = this.ctx.getService('retry'); + + async send({ supertestWithoutAuth, auth, referer, @@ -45,9 +46,10 @@ export const BSecureSearchFactory = (retry: RetryService) => ({ options, strategy, space, - }: SendOptions): Promise => { + }: SendOptions) { const spaceUrl = getSpaceUrlPrefix(space); - const { body } = await retry.try(async () => { + + const { body } = await this.retry.try(async () => { let result; const url = `${spaceUrl}/internal/search/${strategy}`; if (referer && kibanaVersion) { @@ -84,40 +86,35 @@ export const BSecureSearchFactory = (retry: RetryService) => ({ } throw new Error('try again'); }); - if (body.isRunning) { - const result = await retry.try(async () => { - const resp = await supertestWithoutAuth - .post(`${spaceUrl}/internal/bsearch`) - .auth(auth.username, auth.password) - .set('kbn-xsrf', 'true') - .send({ - batch: [ - { - request: { - id: body.id, - ...options, - }, - options: { - strategy, - }, - }, - ], - }) - .expect(200); - const [parsedResponse] = parseBfetchResponse(resp); - expect(parsedResponse.result.isRunning).equal(false); - return parsedResponse.result; - }); - return result; - } else { - return body; + + if (!body.isRunning) { + return body as T; } - }, -}); -export function BSecureSearchProvider({ - getService, -}: FtrProviderContext): ReturnType { - const retry = getService('retry'); - return BSecureSearchFactory(retry); + const result = await this.retry.try(async () => { + const resp = await supertestWithoutAuth + .post(`${spaceUrl}/internal/bsearch`) + .auth(auth.username, auth.password) + .set('kbn-xsrf', 'true') + .send({ + batch: [ + { + request: { + id: body.id, + ...options, + }, + options: { + strategy, + }, + }, + ], + }) + .expect(200); + const [parsedResponse] = parseBfetchResponse(resp); + expect(parsedResponse.result.isRunning).equal(false); + return parsedResponse.result; + }); + + return result as T; + } } diff --git a/x-pack/test/common/services/index.ts b/x-pack/test/common/services/index.ts index c51fe7a06e6ac..0f247ad743edf 100644 --- a/x-pack/test/common/services/index.ts +++ b/x-pack/test/common/services/index.ts @@ -9,12 +9,12 @@ import { services as kibanaApiIntegrationServices } from '../../../../test/api_i import { services as kibanaCommonServices } from '../../../../test/common/services'; import { InfraLogViewsServiceProvider } from './infra_log_views'; import { SpacesServiceProvider } from './spaces'; -import { BSecureSearchProvider } from './bsearch_secure'; +import { BsearchSecureService } from './bsearch_secure'; export const services = { ...kibanaCommonServices, infraLogViews: InfraLogViewsServiceProvider, supertest: kibanaApiIntegrationServices.supertest, spaces: SpacesServiceProvider, - secureBsearch: BSecureSearchProvider, + secureBsearch: BsearchSecureService, }; diff --git a/x-pack/test/functional/page_objects/infra_logs_page.ts b/x-pack/test/functional/page_objects/infra_logs_page.ts index fe43dd1767d94..c1d20c2e977ad 100644 --- a/x-pack/test/functional/page_objects/infra_logs_page.ts +++ b/x-pack/test/functional/page_objects/infra_logs_page.ts @@ -5,7 +5,6 @@ * 2.0. */ -// import testSubjSelector from '@kbn/test-subj-selector'; // import moment from 'moment'; import querystring from 'querystring'; import { encode, RisonValue } from 'rison-node'; diff --git a/x-pack/test/functional_execution_context/test_utils.ts b/x-pack/test/functional_execution_context/test_utils.ts index 03299689186a2..6cf1af27b0bb2 100644 --- a/x-pack/test/functional_execution_context/test_utils.ts +++ b/x-pack/test/functional_execution_context/test_utils.ts @@ -8,7 +8,7 @@ import Fs from 'fs/promises'; import Path from 'path'; import { isEqualWith } from 'lodash'; import type { Ecs, KibanaExecutionContext } from '@kbn/core/server'; -import type { RetryService } from '../../../test/common/services/retry'; +import type { RetryService } from '@kbn/ftr-common-functional-services'; export const logFilePath = Path.resolve(__dirname, './kibana.log'); export const ANY = Symbol('any'); diff --git a/x-pack/test/performance/journeys/base.config.ts b/x-pack/test/performance/journeys/base.config.ts deleted file mode 100644 index f2924b3a8a785..0000000000000 --- a/x-pack/test/performance/journeys/base.config.ts +++ /dev/null @@ -1,95 +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 uuid from 'uuid'; -import { FtrConfigProviderContext } from '@kbn/test'; - -import { TelemetryConfigLabels } from '@kbn/telemetry-plugin/server/config'; -import { services } from '../services'; -import { pageObjects } from '../page_objects'; - -// These "secret" values are intentionally written in the source. We would make the APM server accept anonymous traffic if we could -const APM_SERVER_URL = 'https://kibana-ops-e2e-perf.apm.us-central1.gcp.cloud.es.io:443'; -const APM_PUBLIC_TOKEN = 'CTs9y3cvcfq13bQqsB'; - -export default async function ({ readConfigFile, log }: FtrConfigProviderContext) { - const functionalConfig = await readConfigFile(require.resolve('../../functional/config.base.js')); - - const testBuildId = process.env.BUILDKITE_BUILD_ID ?? `local-${uuid()}`; - const testJobId = process.env.BUILDKITE_JOB_ID ?? `local-${uuid()}`; - const executionId = uuid(); - - log.info(` 👷‍♀️ BUILD ID ${testBuildId}\n 👷 JOB ID ${testJobId}\n 👷‍♂️ EXECUTION ID:${executionId}`); - - const prId = process.env.GITHUB_PR_NUMBER - ? Number.parseInt(process.env.GITHUB_PR_NUMBER, 10) - : undefined; - - if (Number.isNaN(prId)) { - throw new Error('invalid GITHUB_PR_NUMBER environment variable'); - } - - const telemetryLabels: TelemetryConfigLabels = { - branch: process.env.BUILDKITE_BRANCH, - ciBuildId: process.env.BUILDKITE_BUILD_ID, - ciBuildJobId: process.env.BUILDKITE_JOB_ID, - ciBuildNumber: Number(process.env.BUILDKITE_BUILD_NUMBER) || 0, - gitRev: process.env.BUILDKITE_COMMIT, - isPr: prId !== undefined, - ...(prId !== undefined ? { prId } : {}), - testJobId, - testBuildId, - ciBuildName: process.env.BUILDKITE_PIPELINE_SLUG, - }; - - return { - services, - pageObjects, - servicesRequiredForTestAnalysis: ['performance'], - servers: functionalConfig.get('servers'), - esTestCluster: functionalConfig.get('esTestCluster'), - apps: functionalConfig.get('apps'), - screenshots: functionalConfig.get('screenshots'), - junit: { - reportName: 'Performance Tests', - }, - kbnTestServer: { - ...functionalConfig.get('kbnTestServer'), - serverArgs: [ - ...functionalConfig.get('kbnTestServer.serverArgs'), - `--telemetry.optIn=${process.env.TEST_PERFORMANCE_PHASE === 'TEST'}`, - `--telemetry.labels=${JSON.stringify(telemetryLabels)}`, - '--csp.strict=false', - '--csp.warnLegacyBrowsers=false', - ], - env: { - ELASTIC_APM_ACTIVE: process.env.TEST_PERFORMANCE_PHASE ? 'true' : 'false', - ELASTIC_APM_CONTEXT_PROPAGATION_ONLY: 'false', - ELASTIC_APM_ENVIRONMENT: process.env.CI ? 'ci' : 'development', - ELASTIC_APM_TRANSACTION_SAMPLE_RATE: '1.0', - ELASTIC_APM_SERVER_URL: APM_SERVER_URL, - ELASTIC_APM_SECRET_TOKEN: APM_PUBLIC_TOKEN, - // capture request body for both errors and request transactions - // https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html#capture-body - ELASTIC_APM_CAPTURE_BODY: 'all', - // capture request headers - // https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html#capture-headers - ELASTIC_APM_CAPTURE_HEADERS: true, - // request body with bigger size will be trimmed. - // 300_000 is the default of the APM server. - // for a body with larger size, we might need to reconfigure the APM server to increase the limit. - // https://www.elastic.co/guide/en/apm/agent/nodejs/current/configuration.html#long-field-max-length - ELASTIC_APM_LONG_FIELD_MAX_LENGTH: 300_000, - ELASTIC_APM_GLOBAL_LABELS: { - testJobId, - testBuildId, - }, - }, - // delay shutdown by 15 seconds to ensure that APM can report the data it collects during test execution - delayShutdown: 15_000, - }, - }; -} diff --git a/x-pack/test/performance/journeys/data_stress_test_lens/config.ts b/x-pack/test/performance/journeys/data_stress_test_lens/config.ts deleted file mode 100644 index 0eb5f841692fa..0000000000000 --- a/x-pack/test/performance/journeys/data_stress_test_lens/config.ts +++ /dev/null @@ -1,47 +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 { FtrConfigProviderContext } from '@kbn/test'; -import { serializeApmGlobalLabels } from '../../utils'; - -export const JOURNEY_DATA_STRESS_TEST_LENS = 'data_stress_test_lens'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const performanceConfig = await readConfigFile(require.resolve('../base.config')); - - const testFiles = [require.resolve(`./${JOURNEY_DATA_STRESS_TEST_LENS}`)]; - - const config = { - ...performanceConfig.getAll(), - testFiles, - testData: { - kbnArchives: ['test/functional/fixtures/kbn_archiver/stress_test'], - esArchives: ['test/functional/fixtures/es_archiver/stress_test'], - }, - }; - - const apmGlobalLabels = { - ...performanceConfig.get('kbnTestServer').env.ELASTIC_APM_GLOBAL_LABELS, - ftrConfig: `x-pack/test/performance/tests/journeys/${JOURNEY_DATA_STRESS_TEST_LENS}/config.ts`, - performancePhase: process.env.TEST_PERFORMANCE_PHASE, - journeyName: JOURNEY_DATA_STRESS_TEST_LENS, - }; - - return { - ...config, - kbnTestServer: { - ...config.kbnTestServer, - serverArgs: [ - ...performanceConfig.get('kbnTestServer.serverArgs'), - `--telemetry.labels.journeyName=${JOURNEY_DATA_STRESS_TEST_LENS}`, - ], - env: { - ...config.kbnTestServer.env, - ELASTIC_APM_GLOBAL_LABELS: serializeApmGlobalLabels(apmGlobalLabels), - }, - }, - }; -} diff --git a/x-pack/test/performance/journeys/data_stress_test_lens/data_stress_test_lens.ts b/x-pack/test/performance/journeys/data_stress_test_lens/data_stress_test_lens.ts deleted file mode 100644 index e30b6ee67d897..0000000000000 --- a/x-pack/test/performance/journeys/data_stress_test_lens/data_stress_test_lens.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { FtrProviderContext } from '../../ftr_provider_context'; -import { StepCtx } from '../../services/performance'; -import { waitForVisualizations } from '../../utils'; -import { JOURNEY_DATA_STRESS_TEST_LENS } from './config'; - -export default function ({ getService }: FtrProviderContext) { - describe(JOURNEY_DATA_STRESS_TEST_LENS, () => { - const performance = getService('performance'); - - it(JOURNEY_DATA_STRESS_TEST_LENS, async () => { - await performance.runUserJourney( - JOURNEY_DATA_STRESS_TEST_LENS, - [ - { - name: 'Go to dashboard', - handler: async ({ page, kibanaUrl }: StepCtx) => { - await page.goto( - `${kibanaUrl}/app/dashboards#/view/92b143a0-2e9c-11ed-b1b6-a504560b392c` - ); - - await waitForVisualizations(page, 1); - }, - }, - ], - { - requireAuth: false, - } - ); - }); - }); -} diff --git a/x-pack/test/performance/journeys/ecommerce_dashboard/config.ts b/x-pack/test/performance/journeys/ecommerce_dashboard/config.ts deleted file mode 100644 index 3b4d19b9a5bfc..0000000000000 --- a/x-pack/test/performance/journeys/ecommerce_dashboard/config.ts +++ /dev/null @@ -1,43 +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 { FtrConfigProviderContext } from '@kbn/test'; -import { serializeApmGlobalLabels } from '../../utils'; - -const JOURNEY_ECOMMERCE_DASHBOARD = 'ecommerce_dashboard'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const performanceConfig = await readConfigFile(require.resolve('../base.config')); - - const testFiles = [require.resolve(`./${JOURNEY_ECOMMERCE_DASHBOARD}`)]; - - const config = { - ...performanceConfig.getAll(), - testFiles, - }; - - const apmGlobalLabels = { - ...performanceConfig.get('kbnTestServer').env.ELASTIC_APM_GLOBAL_LABELS, - ftrConfig: `x-pack/test/performance/tests/journeys/${JOURNEY_ECOMMERCE_DASHBOARD}/config.ts`, - performancePhase: process.env.TEST_PERFORMANCE_PHASE, - journeyName: JOURNEY_ECOMMERCE_DASHBOARD, - }; - - return { - ...config, - kbnTestServer: { - ...config.kbnTestServer, - serverArgs: [ - ...performanceConfig.get('kbnTestServer.serverArgs'), - `--telemetry.labels.journeyName=${JOURNEY_ECOMMERCE_DASHBOARD}`, - ], - env: { - ...config.kbnTestServer.env, - ELASTIC_APM_GLOBAL_LABELS: serializeApmGlobalLabels(apmGlobalLabels), - }, - }, - }; -} diff --git a/x-pack/test/performance/journeys/ecommerce_dashboard/ecommerce_dashboard.ts b/x-pack/test/performance/journeys/ecommerce_dashboard/ecommerce_dashboard.ts deleted file mode 100644 index 5263c19902b93..0000000000000 --- a/x-pack/test/performance/journeys/ecommerce_dashboard/ecommerce_dashboard.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { Page } from 'playwright'; -import { FtrProviderContext } from '../../ftr_provider_context'; -import { StepCtx } from '../../services/performance'; -import { waitForVisualizations } from '../../utils'; - -export default function ({ getService }: FtrProviderContext) { - describe('ecommerce_dashboard', () => { - it('ecommerce_dashboard', async () => { - const performance = getService('performance'); - const logger = getService('log'); - - await performance.runUserJourney( - 'ecommerce_dashboard', - [ - { - name: 'Go to Sample Data Page', - handler: async ({ page, kibanaUrl }: StepCtx) => { - await page.goto(`${kibanaUrl}/app/home#/tutorial_directory/sampleData`); - await page.waitForSelector('text="More ways to add data"'); - }, - }, - { - name: 'Add Ecommerce Sample Data', - handler: async ({ page }: { page: Page }) => { - const showSampleDataButton = page.locator('[data-test-subj=showSampleDataButton]'); - await showSampleDataButton.click(); - const removeButton = page.locator('[data-test-subj=removeSampleDataSetecommerce]'); - try { - await removeButton.click({ timeout: 1_000 }); - } catch (e) { - logger.info('Ecommerce data does not exist'); - } - const addDataButton = page.locator('[data-test-subj=addSampleDataSetecommerce]'); - if (addDataButton) { - await addDataButton.click(); - } - }, - }, - { - name: 'Go to Ecommerce Dashboard', - handler: async ({ page }: { page: Page }) => { - await page.click('[data-test-subj=launchSampleDataSetecommerce]'); - await page.click('[data-test-subj=viewSampleDataSetecommerce-dashboard]'); - - await waitForVisualizations(page, 13); - }, - }, - ], - { - requireAuth: false, - } - ); - }); - }); -} diff --git a/x-pack/test/performance/journeys/flight_dashboard/config.ts b/x-pack/test/performance/journeys/flight_dashboard/config.ts deleted file mode 100644 index 0b060694a2881..0000000000000 --- a/x-pack/test/performance/journeys/flight_dashboard/config.ts +++ /dev/null @@ -1,43 +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 { FtrConfigProviderContext } from '@kbn/test'; -import { serializeApmGlobalLabels } from '../../utils'; - -const JOURNEY_FLIGHT_DASHBOARD = 'flight_dashboard'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const performanceConfig = await readConfigFile(require.resolve('../base.config')); - - const testFiles = [require.resolve(`./${JOURNEY_FLIGHT_DASHBOARD}`)]; - - const config = { - ...performanceConfig.getAll(), - testFiles, - }; - - const apmGlobalLabels = { - ...performanceConfig.get('kbnTestServer').env.ELASTIC_APM_GLOBAL_LABELS, - ftrConfig: `x-pack/test/performance/tests/journeys/${JOURNEY_FLIGHT_DASHBOARD}/config.ts`, - performancePhase: process.env.TEST_PERFORMANCE_PHASE, - journeyName: JOURNEY_FLIGHT_DASHBOARD, - }; - - return { - ...config, - kbnTestServer: { - ...config.kbnTestServer, - serverArgs: [ - ...performanceConfig.get('kbnTestServer.serverArgs'), - `--telemetry.labels.journeyName=${JOURNEY_FLIGHT_DASHBOARD}`, - ], - env: { - ...config.kbnTestServer.env, - ELASTIC_APM_GLOBAL_LABELS: serializeApmGlobalLabels(apmGlobalLabels), - }, - }, - }; -} diff --git a/x-pack/test/performance/journeys/flight_dashboard/flight_dashboard.ts b/x-pack/test/performance/journeys/flight_dashboard/flight_dashboard.ts deleted file mode 100644 index 5967cd6ca80f3..0000000000000 --- a/x-pack/test/performance/journeys/flight_dashboard/flight_dashboard.ts +++ /dev/null @@ -1,76 +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 { FtrProviderContext } from '../../ftr_provider_context'; -import { StepCtx } from '../../services/performance'; -import { waitForVisualizations } from '../../utils'; - -export default function ({ getService }: FtrProviderContext) { - describe('flight_dashboard', () => { - it('flight_dashboard', async () => { - const performance = getService('performance'); - const logger = getService('log'); - - await performance.runUserJourney( - 'flight_dashboard', - [ - { - name: 'Go to Sample Data Page', - handler: async ({ page, kibanaUrl }: StepCtx) => { - await page.goto(`${kibanaUrl}/app/home#/tutorial_directory/sampleData`); - await page.waitForSelector('[data-test-subj=sampleDataSetCardflights]'); - }, - }, - { - name: 'Add Flights Sample Data', - handler: async ({ page }) => { - const showSampleDataButton = page.locator('[data-test-subj=showSampleDataButton]'); - await showSampleDataButton.click(); - const removeButton = page.locator('[data-test-subj=removeSampleDataSetflights]'); - try { - await removeButton.click({ timeout: 1_000 }); - } catch (e) { - logger.info('Flights data does not exist'); - } - - const addDataButton = page.locator('[data-test-subj=addSampleDataSetflights]'); - if (addDataButton) { - await addDataButton.click(); - } - }, - }, - { - name: 'Go to Flights Dashboard', - handler: async ({ page }) => { - await page.click('[data-test-subj=launchSampleDataSetflights]'); - await page.click('[data-test-subj=viewSampleDataSetflights-dashboard]'); - - await waitForVisualizations(page, 15); - }, - }, - { - name: 'Go to Airport Connections Visualizations Edit', - handler: async ({ page }) => { - await page.click('[data-test-subj="dashboardEditMode"]'); - - const flightsPanelHeadingSelector = `[data-test-subj="embeddablePanelHeading-[Flights]AirportConnections(HoverOverAirport)"]`; - const panelToggleMenuIconSelector = `[data-test-subj="embeddablePanelToggleMenuIcon"]`; - - await page.click(`${flightsPanelHeadingSelector} ${panelToggleMenuIconSelector}`); - - await page.click('[data-test-subj="embeddablePanelAction-editPanel"]'); - - await waitForVisualizations(page, 1); - }, - }, - ], - { - requireAuth: false, - } - ); - }); - }); -} diff --git a/x-pack/test/performance/journeys/login/config.ts b/x-pack/test/performance/journeys/login/config.ts deleted file mode 100644 index adf9bc76416a4..0000000000000 --- a/x-pack/test/performance/journeys/login/config.ts +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { FtrConfigProviderContext } from '@kbn/test'; -import { serializeApmGlobalLabels } from '../../utils'; - -const JOURNEY_LOGIN = 'login'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const performanceConfig = await readConfigFile(require.resolve('../base.config')); - - const testFiles = [require.resolve(`./${JOURNEY_LOGIN}`)]; - - const config = { - ...performanceConfig.getAll(), - testFiles, - scalabilitySetup: { - warmup: [ - { - action: 'constantConcurrentUsers', - maxUsersCount: 10, - duration: '30s', - }, - { - action: 'rampConcurrentUsers', - minUsersCount: 10, - maxUsersCount: 50, - duration: '2m', - }, - ], - test: [ - { - action: 'constantConcurrentUsers', - maxUsersCount: 50, - duration: '5m', - }, - ], - maxDuration: '10m', - }, - }; - - const apmGlobalLabels = { - ...performanceConfig.get('kbnTestServer').env.ELASTIC_APM_GLOBAL_LABELS, - ftrConfig: `x-pack/test/performance/tests/journeys/${JOURNEY_LOGIN}/config.ts`, - performancePhase: process.env.TEST_PERFORMANCE_PHASE, - journeyName: JOURNEY_LOGIN, - }; - - return { - ...config, - kbnTestServer: { - ...config.kbnTestServer, - serverArgs: [ - ...performanceConfig.get('kbnTestServer.serverArgs'), - `--telemetry.labels.journeyName=${JOURNEY_LOGIN}`, - ], - env: { - ...config.kbnTestServer.env, - ELASTIC_APM_GLOBAL_LABELS: serializeApmGlobalLabels(apmGlobalLabels), - }, - }, - }; -} diff --git a/x-pack/test/performance/journeys/login/login.ts b/x-pack/test/performance/journeys/login/login.ts deleted file mode 100644 index f1fd17174322f..0000000000000 --- a/x-pack/test/performance/journeys/login/login.ts +++ /dev/null @@ -1,42 +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 { FtrProviderContext } from '../../ftr_provider_context'; -import { StepCtx } from '../../services/performance'; - -export default function ({ getService }: FtrProviderContext) { - describe('login', () => { - it('login', async () => { - const inputDelays = getService('inputDelays'); - const performance = getService('performance'); - - await performance.runUserJourney( - 'login', - [ - { - name: 'Login', - handler: async ({ page, kibanaUrl }: StepCtx) => { - await page.goto(`${kibanaUrl}`); - - const usernameLocator = page.locator('[data-test-subj=loginUsername]'); - const passwordLocator = page.locator('[data-test-subj=loginPassword]'); - const submitButtonLocator = page.locator('[data-test-subj=loginSubmit]'); - - await usernameLocator?.type('elastic', { delay: inputDelays.TYPING }); - await passwordLocator?.type('changeme', { delay: inputDelays.TYPING }); - await submitButtonLocator?.click({ delay: inputDelays.MOUSE_CLICK }); - - await page.waitForSelector('#headerUserMenu'); - }, - }, - ], - { - requireAuth: true, - } - ); - }); - }); -} diff --git a/x-pack/test/performance/journeys/many_fields_discover/config.ts b/x-pack/test/performance/journeys/many_fields_discover/config.ts deleted file mode 100644 index 11ce52089a730..0000000000000 --- a/x-pack/test/performance/journeys/many_fields_discover/config.ts +++ /dev/null @@ -1,47 +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 { FtrConfigProviderContext } from '@kbn/test'; -import { serializeApmGlobalLabels } from '../../utils'; - -const JOURNEY_MANY_FIELDS_DISCOVER = 'many_fields_discover'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const performanceConfig = await readConfigFile(require.resolve('../base.config')); - - const testFiles = [require.resolve(`./${JOURNEY_MANY_FIELDS_DISCOVER}`)]; - - const config = { - ...performanceConfig.getAll(), - testFiles, - testData: { - kbnArchives: ['test/functional/fixtures/kbn_archiver/many_fields_data_view'], - esArchives: ['test/functional/fixtures/es_archiver/many_fields'], - }, - }; - - const apmGlobalLabels = { - ...performanceConfig.get('kbnTestServer').env.ELASTIC_APM_GLOBAL_LABELS, - ftrConfig: `x-pack/test/performance/tests/journeys/${JOURNEY_MANY_FIELDS_DISCOVER}/config.ts`, - performancePhase: process.env.TEST_PERFORMANCE_PHASE, - journeyName: JOURNEY_MANY_FIELDS_DISCOVER, - }; - - return { - ...config, - kbnTestServer: { - ...config.kbnTestServer, - serverArgs: [ - ...performanceConfig.get('kbnTestServer.serverArgs'), - `--telemetry.labels.journeyName=${JOURNEY_MANY_FIELDS_DISCOVER}`, - ], - env: { - ...config.kbnTestServer.env, - ELASTIC_APM_GLOBAL_LABELS: serializeApmGlobalLabels(apmGlobalLabels), - }, - }, - }; -} diff --git a/x-pack/test/performance/journeys/many_fields_discover/many_fields_discover.ts b/x-pack/test/performance/journeys/many_fields_discover/many_fields_discover.ts deleted file mode 100644 index 648ed9fca37db..0000000000000 --- a/x-pack/test/performance/journeys/many_fields_discover/many_fields_discover.ts +++ /dev/null @@ -1,41 +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 { FtrProviderContext } from '../../ftr_provider_context'; -import { StepCtx } from '../../services/performance'; - -export default function ({ getService }: FtrProviderContext) { - // FAILING: https://github.com/elastic/kibana/issues/130287 - describe.skip('many_fields_discover', () => { - const performance = getService('performance'); - - it('many_fields_discover', async () => { - await performance.runUserJourney( - 'many_fields_discover', - [ - { - name: 'Go to Discover Page', - handler: async ({ page, kibanaUrl }: StepCtx) => { - await page.goto(`${kibanaUrl}/app/discover`); - await page.waitForSelector('[data-test-subj="discoverDocTable"]'); - }, - }, - { - name: 'Expand the first document', - handler: async ({ page }) => { - const expandButtons = page.locator('[data-test-subj="docTableExpandToggleColumn"]'); - await expandButtons.first().click(); - await page.locator('text="Expanded document"'); - }, - }, - ], - { - requireAuth: false, - } - ); - }); - }); -} diff --git a/x-pack/test/performance/journeys/promotion_tracking_dashboard/config.ts b/x-pack/test/performance/journeys/promotion_tracking_dashboard/config.ts deleted file mode 100644 index cc0074503576f..0000000000000 --- a/x-pack/test/performance/journeys/promotion_tracking_dashboard/config.ts +++ /dev/null @@ -1,70 +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 { FtrConfigProviderContext } from '@kbn/test'; -import { serializeApmGlobalLabels } from '../../utils'; - -const JOURNEY_PROMOTION_TRACKING_DASHBOARD = 'promotion_tracking_dashboard'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const performanceConfig = await readConfigFile(require.resolve('../base.config')); - - const testFiles = [require.resolve(`./${JOURNEY_PROMOTION_TRACKING_DASHBOARD}`)]; - - const config = { - ...performanceConfig.getAll(), - testFiles, - testData: { - kbnArchives: ['x-pack/test/performance/kbn_archives/promotion_tracking_dashboard'], - esArchives: ['x-pack/test/performance/es_archives/ecommerce_sample_data'], - }, - scalabilitySetup: { - warmup: [ - { - action: 'constantConcurrentUsers', - maxUsersCount: 10, - duration: '30s', - }, - { - action: 'rampConcurrentUsers', - minUsersCount: 10, - maxUsersCount: 50, - duration: '2m', - }, - ], - test: [ - { - action: 'constantConcurrentUsers', - maxUsersCount: 50, - duration: '5m', - }, - ], - maxDuration: '10m', - }, - }; - - const apmGlobalLabels = { - ...performanceConfig.get('kbnTestServer').env.ELASTIC_APM_GLOBAL_LABELS, - ftrConfig: `x-pack/test/performance/tests/journeys/${JOURNEY_PROMOTION_TRACKING_DASHBOARD}/config.ts`, - performancePhase: process.env.TEST_PERFORMANCE_PHASE, - journeyName: JOURNEY_PROMOTION_TRACKING_DASHBOARD, - }; - - return { - ...config, - kbnTestServer: { - ...config.kbnTestServer, - serverArgs: [ - ...performanceConfig.get('kbnTestServer.serverArgs'), - `--telemetry.labels.journeyName=${JOURNEY_PROMOTION_TRACKING_DASHBOARD}`, - ], - env: { - ...config.kbnTestServer.env, - ELASTIC_APM_GLOBAL_LABELS: serializeApmGlobalLabels(apmGlobalLabels), - }, - }, - }; -} diff --git a/x-pack/test/performance/journeys/promotion_tracking_dashboard/promotion_tracking_dashboard.ts b/x-pack/test/performance/journeys/promotion_tracking_dashboard/promotion_tracking_dashboard.ts deleted file mode 100644 index 590bf38b401c0..0000000000000 --- a/x-pack/test/performance/journeys/promotion_tracking_dashboard/promotion_tracking_dashboard.ts +++ /dev/null @@ -1,62 +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 { FtrProviderContext } from '../../ftr_provider_context'; -import { StepCtx } from '../../services/performance'; -import { waitForVisualizations } from '../../utils'; - -export default function ({ getService }: FtrProviderContext) { - describe('promotion_tracking_dashboard', () => { - const performance = getService('performance'); - - it('promotion_tracking_dashboard', async () => { - await performance.runUserJourney( - 'promotion_tracking_dashboard', - [ - { - name: 'Go to Dashboards Page', - handler: async ({ page, kibanaUrl }: StepCtx) => { - await page.goto(`${kibanaUrl}/app/dashboards`); - await page.waitForSelector('#dashboardListingHeading'); - }, - }, - { - name: 'Go to Promotion Tracking Dashboard', - handler: async ({ page }) => { - const promotionDashboardButton = page.locator( - '[data-test-subj="dashboardListingTitleLink-Promotion-Dashboard"]' - ); - await promotionDashboardButton.click(); - }, - }, - { - name: 'Change time range', - handler: async ({ page }) => { - const beginningTimeRangeButton = page.locator( - '[data-test-subj="superDatePickerToggleQuickMenuButton"]' - ); - await beginningTimeRangeButton.click(); - - const lastYearButton = page.locator( - '[data-test-subj="superDatePickerCommonlyUsed_Last_30 days"]' - ); - await lastYearButton.click(); - }, - }, - { - name: 'Wait for visualization animations to finish', - handler: async ({ page }) => { - await waitForVisualizations(page, 1); - }, - }, - ], - { - requireAuth: false, - } - ); - }); - }); -} diff --git a/x-pack/test/performance/journeys/web_logs_dashboard/config.ts b/x-pack/test/performance/journeys/web_logs_dashboard/config.ts deleted file mode 100644 index 0c84f7bcc2071..0000000000000 --- a/x-pack/test/performance/journeys/web_logs_dashboard/config.ts +++ /dev/null @@ -1,43 +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 { FtrConfigProviderContext } from '@kbn/test'; -import { serializeApmGlobalLabels } from '../../utils'; - -const JOURNEY_WEBLOGS_DASHBOARD = 'web_logs_dashboard'; - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const performanceConfig = await readConfigFile(require.resolve('../base.config')); - - const testFiles = [require.resolve(`./${JOURNEY_WEBLOGS_DASHBOARD}`)]; - - const config = { - ...performanceConfig.getAll(), - testFiles, - }; - - const apmGlobalLabels = { - ...performanceConfig.get('kbnTestServer').env.ELASTIC_APM_GLOBAL_LABELS, - ftrConfig: `x-pack/test/performance/tests/journeys/${JOURNEY_WEBLOGS_DASHBOARD}/config.ts`, - performancePhase: process.env.TEST_PERFORMANCE_PHASE, - journeyName: JOURNEY_WEBLOGS_DASHBOARD, - }; - - return { - ...config, - kbnTestServer: { - ...config.kbnTestServer, - serverArgs: [ - ...performanceConfig.get('kbnTestServer.serverArgs'), - `--telemetry.labels.journeyName=${JOURNEY_WEBLOGS_DASHBOARD}`, - ], - env: { - ...config.kbnTestServer.env, - ELASTIC_APM_GLOBAL_LABELS: serializeApmGlobalLabels(apmGlobalLabels), - }, - }, - }; -} diff --git a/x-pack/test/performance/journeys/web_logs_dashboard/web_logs_dashboard.ts b/x-pack/test/performance/journeys/web_logs_dashboard/web_logs_dashboard.ts deleted file mode 100644 index d7df55cac159c..0000000000000 --- a/x-pack/test/performance/journeys/web_logs_dashboard/web_logs_dashboard.ts +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ -import { FtrProviderContext } from '../../ftr_provider_context'; -import { StepCtx } from '../../services/performance'; -import { waitForVisualizations } from '../../utils'; - -export default function ({ getService }: FtrProviderContext) { - describe('weblogs_dashboard', () => { - it('weblogs_dashboard', async () => { - const performance = getService('performance'); - const logger = getService('log'); - - await performance.runUserJourney( - 'weblogs_dashboard', - [ - { - name: 'Go to Sample Data Page', - handler: async ({ page, kibanaUrl }: StepCtx) => { - await page.goto(`${kibanaUrl}/app/home#/tutorial_directory/sampleData`); - await page.waitForSelector('text="More ways to add data"'); - }, - }, - { - name: 'Add Web Logs Sample Data', - handler: async ({ page }) => { - const showSampleDataButton = page.locator('[data-test-subj=showSampleDataButton]'); - await showSampleDataButton.click(); - const removeButton = page.locator('[data-test-subj=removeSampleDataSetlogs]'); - try { - await removeButton.click({ timeout: 1_000 }); - } catch (e) { - logger.info('Weblogs data does not exist'); - } - - const addDataButton = page.locator('[data-test-subj=addSampleDataSetlogs]'); - if (addDataButton) { - await addDataButton.click(); - } - }, - }, - { - name: 'Go to Web Logs Dashboard', - handler: async ({ page }) => { - await page.click('[data-test-subj=launchSampleDataSetlogs]'); - await page.click('[data-test-subj=viewSampleDataSetlogs-dashboard]'); - - await waitForVisualizations(page, 12); - }, - }, - ], - { - requireAuth: false, - } - ); - }); - }); -} diff --git a/x-pack/test/performance/page_objects.ts b/x-pack/test/performance/page_objects.ts deleted file mode 100644 index 6c273213bf4a1..0000000000000 --- a/x-pack/test/performance/page_objects.ts +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -export const pageObjects = {}; diff --git a/x-pack/test/performance/scalability/config.ts b/x-pack/test/performance/scalability/config.ts deleted file mode 100644 index 6a8302f33fe34..0000000000000 --- a/x-pack/test/performance/scalability/config.ts +++ /dev/null @@ -1,109 +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 { FtrConfigProviderContext } from '@kbn/test'; -import fs from 'fs'; -import path from 'path'; -import { REPO_ROOT } from '@kbn/utils'; -import { createFlagError } from '@kbn/dev-cli-errors'; -import { serializeApmGlobalLabels } from '../utils'; -import { ScalabilityTestRunner } from './runner'; -import { FtrProviderContext } from '../ftr_provider_context'; - -// These "secret" values are intentionally written in the source. -const APM_SERVER_URL = 'https://142fea2d3047486e925eb8b223559cae.apm.europe-west1.gcp.cloud.es.io'; -const APM_PUBLIC_TOKEN = 'pWFFEym07AKBBhUE2i'; -const AGGS_SHARD_DELAY = process.env.LOAD_TESTING_SHARD_DELAY; -const DISABLE_PLUGINS = process.env.LOAD_TESTING_DISABLE_PLUGINS; -const scalabilityJsonPath = process.env.SCALABILITY_JOURNEY_PATH; -const gatlingProjectRootPath: string = - process.env.GATLING_PROJECT_PATH || path.resolve(REPO_ROOT, '../kibana-load-testing'); - -const readScalabilityJourney = (filePath: string): ScalabilityJourney => { - if (path.extname(filePath) !== '.json') { - throw createFlagError(`Path to scalability journey json is non-json file: '${filePath}'`); - } - try { - return JSON.parse(fs.readFileSync(filePath, 'utf-8')); - } catch (error) { - if (error.code === 'ENOENT') { - throw createFlagError(`Path to scalability journey json is invalid: ${filePath}`); - } - throw createFlagError(`Invalid JSON provided: '${filePath}', ${error}`); - } -}; - -interface ScalabilityJourney { - journeyName: string; -} - -export default async function ({ readConfigFile }: FtrConfigProviderContext) { - const performanceConfig = await readConfigFile(require.resolve('../journeys/base.config.ts')); - - if (!fs.existsSync(gatlingProjectRootPath)) { - throw createFlagError( - `Incorrect path to load testing project: '${gatlingProjectRootPath}'\n - Clone 'elastic/kibana-load-testing' and set path using 'GATLING_PROJECT_PATH' env var` - ); - } - - if (!scalabilityJsonPath) { - throw createFlagError( - `Set path to scalability journey json using 'SCALABILITY_JOURNEY_PATH' env var` - ); - } - const scalabilityJourney = readScalabilityJourney(scalabilityJsonPath); - - const apmGlobalLabels = { - ...performanceConfig.get('kbnTestServer').env.ELASTIC_APM_GLOBAL_LABELS, - journeyFilePath: path.basename(scalabilityJsonPath), - journeyName: scalabilityJourney.journeyName, - }; - - return { - ...performanceConfig.getAll(), - - testRunner: (context: FtrProviderContext) => - ScalabilityTestRunner(context, scalabilityJsonPath, gatlingProjectRootPath), - - esTestCluster: { - ...performanceConfig.get('esTestCluster'), - serverArgs: [...performanceConfig.get('esTestCluster.serverArgs')], - esJavaOpts: '-Xms8g -Xmx8g', - }, - - kbnTestServer: { - ...performanceConfig.get('kbnTestServer'), - sourceArgs: [ - ...performanceConfig.get('kbnTestServer.sourceArgs'), - '--no-base-path', - '--env.name=development', - ...(!!AGGS_SHARD_DELAY ? ['--data.search.aggs.shardDelay.enabled=true'] : []), - ...(!!DISABLE_PLUGINS ? ['--plugins.initialize=false'] : []), - ], - serverArgs: [ - ...performanceConfig.get('kbnTestServer.serverArgs'), - `--telemetry.labels.journeyName=${scalabilityJourney.journeyName}`, - ], - env: { - ELASTIC_APM_ACTIVE: process.env.ELASTIC_APM_ACTIVE, - ELASTIC_APM_CONTEXT_PROPAGATION_ONLY: 'false', - ELASTIC_APM_ENVIRONMENT: process.env.CI ? 'ci' : 'development', - ELASTIC_APM_TRANSACTION_SAMPLE_RATE: '1.0', - ELASTIC_APM_SERVER_URL: APM_SERVER_URL, - ELASTIC_APM_SECRET_TOKEN: APM_PUBLIC_TOKEN, - ELASTIC_APM_BREAKDOWN_METRICS: false, - ELASTIC_APM_CAPTURE_SPAN_STACK_TRACES: false, - ELASTIC_APM_METRICS_INTERVAL: '80s', - ELASTIC_APM_MAX_QUEUE_SIZE: 20480, - ELASTIC_APM_GLOBAL_LABELS: serializeApmGlobalLabels(apmGlobalLabels), - }, - // delay shutdown to ensure that APM can report the data it collects during test execution - delayShutdown: 90_000, - }, - }; -} diff --git a/x-pack/test/performance/services/auth.ts b/x-pack/test/performance/services/auth.ts deleted file mode 100644 index 282369751472e..0000000000000 --- a/x-pack/test/performance/services/auth.ts +++ /dev/null @@ -1,62 +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 axios, { AxiosResponse } from 'axios'; -import Url from 'url'; -import { FtrService, FtrProviderContext } from '../ftr_provider_context'; - -export interface Credentials { - username: string; - password: string; -} - -function extractCookieValue(authResponse: AxiosResponse) { - return authResponse.headers['set-cookie']?.[0].toString().split(';')[0].split('sid=')[1] ?? ''; -} -export class AuthService extends FtrService { - private readonly kibanaServer = this.ctx.getService('kibanaServer'); - private readonly config = this.ctx.getService('config'); - - constructor(ctx: FtrProviderContext) { - super(ctx); - } - - public async login({ username, password }: Credentials) { - const headers = { - 'content-type': 'application/json', - 'kbn-version': await this.kibanaServer.version.get(), - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - }; - - const baseUrl = Url.format({ - protocol: this.config.get('servers.kibana.protocol'), - hostname: this.config.get('servers.kibana.hostname'), - port: this.config.get('servers.kibana.port'), - }); - - const loginUrl = baseUrl + '/internal/security/login'; - const provider = baseUrl.includes('localhost') ? 'basic' : 'cloud-basic'; - - const authBody = { - providerType: 'basic', - providerName: provider, - currentURL: `${baseUrl}/login?next=%2F`, - params: { username, password }, - }; - - const authResponse = await axios.post(loginUrl, authBody, { headers }); - - return { - name: 'sid', - value: extractCookieValue(authResponse), - url: baseUrl, - }; - } -} - -export const AuthProvider = (ctx: FtrProviderContext) => new AuthService(ctx); diff --git a/x-pack/test/performance/services/index.ts b/x-pack/test/performance/services/index.ts deleted file mode 100644 index d8cd6075c91c2..0000000000000 --- a/x-pack/test/performance/services/index.ts +++ /dev/null @@ -1,21 +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 { services as functionalServices } from '../../functional/services'; -import { PerformanceTestingService } from './performance'; -import { InputDelaysProvider } from './input_delays'; -import { AuthProvider } from './auth'; - -export const services = { - es: functionalServices.es, - kibanaServer: functionalServices.kibanaServer, - esArchiver: functionalServices.esArchiver, - retry: functionalServices.retry, - performance: PerformanceTestingService, - inputDelays: InputDelaysProvider, - auth: AuthProvider, -}; diff --git a/x-pack/test/performance/services/performance.ts b/x-pack/test/performance/services/performance.ts deleted file mode 100644 index ffddc834dc115..0000000000000 --- a/x-pack/test/performance/services/performance.ts +++ /dev/null @@ -1,306 +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. - */ - -/* eslint-disable no-console */ - -import Url from 'url'; -import * as Rx from 'rxjs'; -import { inspect } from 'util'; -import { setTimeout } from 'timers/promises'; -import apm, { Span, Transaction } from 'elastic-apm-node'; -import playwright, { ChromiumBrowser, Page, BrowserContext, CDPSession, Request } from 'playwright'; -import { FtrService, FtrProviderContext } from '../ftr_provider_context'; - -export interface StepCtx { - page: Page; - kibanaUrl: string; -} - -type StepFn = (ctx: StepCtx) => Promise; -export type Steps = Array<{ name: string; handler: StepFn }>; - -export class PerformanceTestingService extends FtrService { - private readonly auth = this.ctx.getService('auth'); - private readonly log = this.ctx.getService('log'); - private readonly config = this.ctx.getService('config'); - - private browser: ChromiumBrowser | undefined; - private currentSpanStack: Array = []; - private currentTransaction: Transaction | undefined | null = undefined; - - private pageTeardown$ = new Rx.Subject(); - private telemetryTrackerSubs = new Map(); - - constructor(ctx: FtrProviderContext) { - super(ctx); - - ctx.getService('lifecycle').beforeTests.add(() => { - apm.start({ - serviceName: 'functional test runner', - environment: process.env.CI ? 'ci' : 'development', - active: this.config.get(`kbnTestServer.env`).ELASTIC_APM_ACTIVE !== 'false', - serverUrl: this.config.get(`kbnTestServer.env`).ELASTIC_APM_SERVER_URL, - secretToken: this.config.get(`kbnTestServer.env`).ELASTIC_APM_SECRET_TOKEN, - globalLabels: this.config.get(`kbnTestServer.env`).ELASTIC_APM_GLOBAL_LABELS, - transactionSampleRate: - this.config.get(`kbnTestServer.env`).ELASTIC_APM_TRANSACTION_SAMPLE_RATE, - logger: process.env.VERBOSE_APM_LOGGING - ? { - warn(...args: any[]) { - console.log('APM WARN', ...args); - }, - info(...args: any[]) { - console.log('APM INFO', ...args); - }, - fatal(...args: any[]) { - console.log('APM FATAL', ...args); - }, - error(...args: any[]) { - console.log('APM ERROR', ...args); - }, - debug(...args: any[]) { - console.log('APM DEBUG', ...args); - }, - trace(...args: any[]) { - console.log('APM TRACE', ...args); - }, - } - : undefined, - }); - }); - - ctx.getService('lifecycle').cleanup.add(async () => { - await this.shutdownBrowser(); - await new Promise((resolve) => apm.flush(() => resolve())); - // wait for the HTTP request that apm.flush() starts, which we - // can't track but hope is complete within 3 seconds - // https://github.com/elastic/apm-agent-nodejs/issues/2088 - await setTimeout(3000); - }); - } - - private getKibanaUrl() { - return Url.format({ - protocol: this.config.get('servers.kibana.protocol'), - hostname: this.config.get('servers.kibana.hostname'), - port: this.config.get('servers.kibana.port'), - }); - } - - private async withTransaction(name: string, block: () => Promise) { - try { - if (this.currentTransaction) { - throw new Error( - `Transaction already started, make sure you end transaction ${this.currentTransaction?.name}` - ); - } - this.currentTransaction = apm.startTransaction(name, 'performance'); - const result = await block(); - if (this.currentTransaction === undefined) { - throw new Error(`No transaction started`); - } - this.currentTransaction?.end('success'); - this.currentTransaction = undefined; - return result; - } catch (e) { - if (this.currentTransaction === undefined) { - throw new Error(`No transaction started`); - } - this.currentTransaction?.end('failure'); - this.currentTransaction = undefined; - throw e; - } - } - - private async withSpan(name: string, type: string | undefined, block: () => Promise) { - try { - this.currentSpanStack.unshift(apm.startSpan(name, type ?? null)); - const result = await block(); - if (this.currentSpanStack.length === 0) { - throw new Error(`No Span started`); - } - const span = this.currentSpanStack.shift(); - span?.setOutcome('success'); - span?.end(); - return result; - } catch (e) { - if (this.currentSpanStack.length === 0) { - throw new Error(`No Span started`); - } - const span = this.currentSpanStack.shift(); - span?.setOutcome('failure'); - span?.end(); - throw e; - } - } - - private getCurrentTraceparent() { - return (this.currentSpanStack.length ? this.currentSpanStack[0] : this.currentTransaction) - ?.traceparent; - } - - private async getBrowserInstance() { - if (this.browser) { - return this.browser; - } - return await this.withSpan('browser creation', 'setup', async () => { - const headless = !!(process.env.TEST_BROWSER_HEADLESS || process.env.CI); - this.browser = await playwright.chromium.launch({ headless, timeout: 60000 }); - return this.browser; - }); - } - - private async sendCDPCommands(context: BrowserContext, page: Page) { - const client = await context.newCDPSession(page); - - await client.send('Network.clearBrowserCache'); - await client.send('Network.setCacheDisabled', { cacheDisabled: true }); - await client.send('Network.emulateNetworkConditions', { - latency: 100, - downloadThroughput: 750_000, - uploadThroughput: 750_000, - offline: false, - }); - - return client; - } - - private telemetryTrackerCount = 0; - - private trackTelemetryRequests(page: Page) { - const id = ++this.telemetryTrackerCount; - - const requestFailure$ = Rx.fromEvent(page, 'requestfailed'); - const requestSuccess$ = Rx.fromEvent(page, 'requestfinished'); - const request$ = Rx.fromEvent(page, 'request').pipe( - Rx.takeUntil( - this.pageTeardown$.pipe( - Rx.first((p) => p === page), - Rx.delay(3000) - // If EBT client buffers: - // Rx.mergeMap(async () => { - // await page.waitForFunction(() => { - // // return window.kibana_ebt_client.buffer_size == 0 - // }); - // }) - ) - ), - Rx.mergeMap((request) => { - if (!request.url().includes('telemetry-staging.elastic.co')) { - return Rx.EMPTY; - } - - this.log.debug(`Waiting for telemetry request #${id} to complete`); - return Rx.merge(requestFailure$, requestSuccess$).pipe( - Rx.first((r) => r === request), - Rx.tap({ - complete: () => this.log.debug(`Telemetry request #${id} complete`), - }) - ); - }) - ); - - this.telemetryTrackerSubs.set(page, request$.subscribe()); - } - - private async interceptBrowserRequests(page: Page) { - await page.route('**', async (route, request) => { - const headers = await request.allHeaders(); - const traceparent = this.getCurrentTraceparent(); - if (traceparent && request.isNavigationRequest()) { - await route.continue({ headers: { traceparent, ...headers } }); - } else { - await route.continue(); - } - }); - } - - public runUserJourney( - journeyName: string, - steps: Steps, - { requireAuth }: { requireAuth: boolean } - ) { - return this.withTransaction(`Journey ${journeyName}`, async () => { - const browser = await this.getBrowserInstance(); - const context = await browser.newContext({ bypassCSP: true }); - - if (!requireAuth) { - const cookie = await this.auth.login({ username: 'elastic', password: 'changeme' }); - await context.addCookies([cookie]); - } - - const page = await context.newPage(); - if (!process.env.NO_BROWSER_LOG) { - page.on('console', this.onConsoleEvent()); - } - const client = await this.sendCDPCommands(context, page); - - this.trackTelemetryRequests(page); - await this.interceptBrowserRequests(page); - await this.handleSteps(steps, page); - await this.tearDown(page, client, context); - }); - } - - private async tearDown(page: Page, client: CDPSession, context: BrowserContext) { - if (page) { - const telemetryTracker = this.telemetryTrackerSubs.get(page); - this.telemetryTrackerSubs.delete(page); - - if (telemetryTracker && !telemetryTracker.closed) { - this.log.info( - `Waiting for telemetry requests to complete, including requests starting within next 3 secs` - ); - this.pageTeardown$.next(page); - await new Promise((resolve) => telemetryTracker.add(resolve)); - } - await client.detach(); - await page.close(); - await context.close(); - } - } - - private async shutdownBrowser() { - if (this.browser) { - await (await this.getBrowserInstance()).close(); - } - } - - private async handleSteps(steps: Array<{ name: string; handler: StepFn }>, page: Page) { - for (const step of steps) { - await this.withSpan(`step: ${step.name}`, 'step', async () => { - try { - await step.handler({ page, kibanaUrl: this.getKibanaUrl() }); - } catch (e) { - const error = new Error(`Step [${step.name}] failed: ${e.message}`); - error.stack = e.stack; - } - }); - } - } - - private onConsoleEvent() { - return async (message: playwright.ConsoleMessage) => { - try { - const args = await Promise.all(message.args().map(async (handle) => handle.jsonValue())); - - const { url, lineNumber, columnNumber } = message.location(); - - const location = `${url},${lineNumber},${columnNumber}`; - - const text = args.length - ? args.map((arg) => (typeof arg === 'string' ? arg : inspect(arg, false, null))).join(' ') - : message.text(); - - console.log(`[console.${message.type()}]`, text); - console.log(' ', location); - } catch (e) { - console.error('Failed to evaluate console.log line', e); - } - }; - } -} diff --git a/x-pack/test/scalability/config.ts b/x-pack/test/scalability/config.ts new file mode 100644 index 0000000000000..49bcfee2cf199 --- /dev/null +++ b/x-pack/test/scalability/config.ts @@ -0,0 +1,69 @@ +/* + * 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 { FtrConfigProviderContext } from '@kbn/test'; +import fs from 'fs'; +import path from 'path'; +import { REPO_ROOT } from '@kbn/utils'; +import { createFlagError } from '@kbn/dev-cli-errors'; +import { commonFunctionalServices } from '@kbn/ftr-common-functional-services'; +import { ScalabilityTestRunner } from './runner'; +import { FtrProviderContext } from './ftr_provider_context'; + +// These "secret" values are intentionally written in the source. +const AGGS_SHARD_DELAY = process.env.LOAD_TESTING_SHARD_DELAY; +const DISABLE_PLUGINS = process.env.LOAD_TESTING_DISABLE_PLUGINS; +const scalabilityJsonPath = process.env.SCALABILITY_JOURNEY_PATH; +const gatlingProjectRootPath: string = + process.env.GATLING_PROJECT_PATH || path.resolve(REPO_ROOT, '../kibana-load-testing'); + +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + if (!fs.existsSync(gatlingProjectRootPath)) { + throw createFlagError( + `Incorrect path to load testing project: '${gatlingProjectRootPath}'\n + Clone 'elastic/kibana-load-testing' and set path using 'GATLING_PROJECT_PATH' env var` + ); + } + + if (!scalabilityJsonPath) { + throw createFlagError( + `Set path to scalability journey json using 'SCALABILITY_JOURNEY_PATH' env var` + ); + } + + const baseConfig = ( + await readConfigFile(require.resolve('../../performance/journeys/login.ts')) + ).getAll(); + + return { + ...baseConfig, + + services: commonFunctionalServices, + pageObjects: {}, + + testRunner: (context: FtrProviderContext) => + ScalabilityTestRunner(context, scalabilityJsonPath, gatlingProjectRootPath), + + esTestCluster: { + ...baseConfig.esTestCluster, + esJavaOpts: '-Xms8g -Xmx8g', + }, + + kbnTestServer: { + ...baseConfig.kbnTestServer, + sourceArgs: [ + ...baseConfig.kbnTestServer.sourceArgs, + '--no-base-path', + '--env.name=development', + ...(!!AGGS_SHARD_DELAY ? ['--data.search.aggs.shardDelay.enabled=true'] : []), + ...(!!DISABLE_PLUGINS ? ['--plugins.initialize=false'] : []), + ], + // delay shutdown to ensure that APM can report the data it collects during test execution + delayShutdown: 90_000, + }, + }; +} diff --git a/x-pack/test/performance/ftr_provider_context.ts b/x-pack/test/scalability/ftr_provider_context.ts similarity index 79% rename from x-pack/test/performance/ftr_provider_context.ts rename to x-pack/test/scalability/ftr_provider_context.ts index e757164fa1de9..19c510a9ec8e7 100644 --- a/x-pack/test/performance/ftr_provider_context.ts +++ b/x-pack/test/scalability/ftr_provider_context.ts @@ -5,10 +5,8 @@ * 2.0. */ +import { commonFunctionalServices } from '@kbn/ftr-common-functional-services'; import { GenericFtrProviderContext, GenericFtrService } from '@kbn/test'; -import { pageObjects } from './page_objects'; -import { services } from './services'; - -export type FtrProviderContext = GenericFtrProviderContext; +export type FtrProviderContext = GenericFtrProviderContext; export class FtrService extends GenericFtrService {} diff --git a/x-pack/test/performance/scalability/runner.ts b/x-pack/test/scalability/runner.ts similarity index 95% rename from x-pack/test/performance/scalability/runner.ts rename to x-pack/test/scalability/runner.ts index e768339b0d498..e09a9d438b410 100644 --- a/x-pack/test/performance/scalability/runner.ts +++ b/x-pack/test/scalability/runner.ts @@ -6,7 +6,7 @@ */ import { withProcRunner } from '@kbn/dev-proc-runner'; -import { FtrProviderContext } from '../ftr_provider_context'; +import { FtrProviderContext } from './ftr_provider_context'; /** * ScalabilityTestRunner is used to run load simulation against local Kibana instance diff --git a/x-pack/test/security_api_integration/tests/audit/file_wrapper.ts b/x-pack/test/security_api_integration/tests/audit/file_wrapper.ts index bb7e707eefd8b..6f6aef69ed406 100644 --- a/x-pack/test/security_api_integration/tests/audit/file_wrapper.ts +++ b/x-pack/test/security_api_integration/tests/audit/file_wrapper.ts @@ -6,7 +6,7 @@ */ import Fs from 'fs'; -import { RetryService } from '../../../../../test/common/services/retry'; +import type { RetryService } from '@kbn/ftr-common-functional-services'; export class FileWrapper { constructor(private readonly path: string, private readonly retry: RetryService) {} diff --git a/x-pack/test/stack_functional_integration/services/es_archiver.js b/x-pack/test/stack_functional_integration/services/es_archiver.js index b34be03d896ad..821cf72e2c6bc 100644 --- a/x-pack/test/stack_functional_integration/services/es_archiver.js +++ b/x-pack/test/stack_functional_integration/services/es_archiver.js @@ -10,7 +10,7 @@ import Path from 'path'; import { EsArchiver } from '@kbn/es-archiver'; import { REPO_ROOT } from '@kbn/utils'; -import * as KibanaServer from '../../../../test/common/services/kibana_server'; +import { KibanaServer } from '@kbn/ftr-common-functional-services'; const INTEGRATION_TEST_ROOT = process.env.WORKSPACE || Path.resolve(REPO_ROOT, '../integration-test'); diff --git a/yarn.lock b/yarn.lock index 1d81724e537b8..535bf43b01e18 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3372,6 +3372,10 @@ version "0.0.0" uid "" +"@kbn/failed-test-reporter-cli@link:bazel-bin/packages/kbn-failed-test-reporter-cli": + version "0.0.0" + uid "" + "@kbn/field-types@link:bazel-bin/packages/kbn-field-types": version "0.0.0" uid "" @@ -3384,6 +3388,14 @@ version "0.0.0" uid "" +"@kbn/ftr-common-functional-services@link:bazel-bin/packages/kbn-ftr-common-functional-services": + version "0.0.0" + uid "" + +"@kbn/ftr-screenshot-filename@link:bazel-bin/packages/kbn-ftr-screenshot-filename": + version "0.0.0" + uid "" + "@kbn/generate@link:bazel-bin/packages/kbn-generate": version "0.0.0" uid "" @@ -3436,6 +3448,10 @@ version "0.0.0" uid "" +"@kbn/journeys@link:bazel-bin/packages/kbn-journeys": + version "0.0.0" + uid "" + "@kbn/kibana-manifest-schema@link:bazel-bin/packages/kbn-kibana-manifest-schema": version "0.0.0" uid "" @@ -7401,6 +7417,10 @@ version "0.0.0" uid "" +"@types/kbn__failed-test-reporter-cli@link:bazel-bin/packages/kbn-failed-test-reporter-cli/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__field-types@link:bazel-bin/packages/kbn-field-types/npm_module_types": version "0.0.0" uid "" @@ -7409,6 +7429,14 @@ version "0.0.0" uid "" +"@types/kbn__ftr-common-functional-services@link:bazel-bin/packages/kbn-ftr-common-functional-services/npm_module_types": + version "0.0.0" + uid "" + +"@types/kbn__ftr-screenshot-filename@link:bazel-bin/packages/kbn-ftr-screenshot-filename/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__generate@link:bazel-bin/packages/kbn-generate/npm_module_types": version "0.0.0" uid "" @@ -7461,6 +7489,10 @@ version "0.0.0" uid "" +"@types/kbn__journeys@link:bazel-bin/packages/kbn-journeys/npm_module_types": + version "0.0.0" + uid "" + "@types/kbn__kbn-ci-stats-performance-metrics@link:bazel-bin/packages/kbn-kbn-ci-stats-performance-metrics/npm_module_types": version "0.0.0" uid "" From 059ac9b8b66f1374396f7b36cbbf0cc029a0a597 Mon Sep 17 00:00:00 2001 From: Ido Cohen <90558359+CohenIdo@users.noreply.github.com> Date: Thu, 22 Sep 2022 11:07:56 +0300 Subject: [PATCH 28/36] [Cloud Posture] remove ILM from score index (#141254) --- .../server/create_indices/create_indices.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/cloud_security_posture/server/create_indices/create_indices.ts b/x-pack/plugins/cloud_security_posture/server/create_indices/create_indices.ts index d34678acdc845..5702cc79eba8a 100644 --- a/x-pack/plugins/cloud_security_posture/server/create_indices/create_indices.ts +++ b/x-pack/plugins/cloud_security_posture/server/create_indices/create_indices.ts @@ -48,9 +48,9 @@ const createBenchmarkScoreIndex = async (esClient: ElasticsearchClient, logger: mappings: benchmarkScoreMapping, settings: { default_pipeline: scorePipelineIngestConfig.id, + // TODO: once we will convert the score index to datastream we will no longer override the ilm to be empty lifecycle: { - // This is the default lifecycle name, it is named on the data-stream type (e.g, logs/ metrics) - name: 'logs', + name: '', }, }, }, From de74a6ba5205f9bc3617aca5e33c77ad76d35a2e Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Thu, 22 Sep 2022 11:16:55 +0300 Subject: [PATCH 29/36] Fix test (#141204) --- x-pack/test/functional/services/cases/single_case_view.ts | 8 +++++++- x-pack/test/functional_with_es_ssl/apps/cases/deletion.ts | 1 + .../test/functional_with_es_ssl/apps/cases/view_case.ts | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/services/cases/single_case_view.ts b/x-pack/test/functional/services/cases/single_case_view.ts index 6bdd35ee642e5..aead59186b46d 100644 --- a/x-pack/test/functional/services/cases/single_case_view.ts +++ b/x-pack/test/functional/services/cases/single_case_view.ts @@ -20,7 +20,13 @@ export function CasesSingleViewServiceProvider({ getService, getPageObject }: Ft return { async deleteCase() { - await common.clickAndValidate('property-actions-ellipses', 'property-actions-trash'); + const caseActions = await testSubjects.findDescendant( + 'property-actions-ellipses', + await testSubjects.find('case-view-actions') + ); + + await caseActions.click(); + await testSubjects.existOrFail('property-actions-trash'); await common.clickAndValidate('property-actions-trash', 'confirmModalConfirmButton'); await testSubjects.click('confirmModalConfirmButton'); await header.waitUntilLoadingHasFinished(); diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/deletion.ts b/x-pack/test/functional_with_es_ssl/apps/cases/deletion.ts index 8fd032a8e1b7a..b0e79c195b719 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/deletion.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/deletion.ts @@ -59,6 +59,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { it(`User ${user.username} can delete a case while on a specific case page`, async () => { await cases.singleCase.deleteCase(); + await cases.casesTable.waitForTableToFinishLoading(); await cases.casesTable.validateCasesTableHasNthRows(1); }); }); diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/view_case.ts b/x-pack/test/functional_with_es_ssl/apps/cases/view_case.ts index 52540169a4c8d..18adfa55a3d1b 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/view_case.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/view_case.ts @@ -167,6 +167,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { it('deletes the case successfully', async () => { await cases.singleCase.deleteCase(); + await cases.casesTable.waitForTableToFinishLoading(); await cases.casesTable.validateCasesTableHasNthRows(0); }); }); From 2f9015102fe051d131255f937e3055ab943718f1 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Thu, 22 Sep 2022 11:17:48 +0300 Subject: [PATCH 30/36] Fix test (#141207) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../apps/cases/attachment_framework.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts b/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts index fcab559466a74..f9bcd5946d400 100644 --- a/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts +++ b/x-pack/test/functional_with_es_ssl/apps/cases/attachment_framework.ts @@ -53,6 +53,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { const find = getService('find'); const es = getService('es'); const common = getPageObject('common'); + const retry = getService('retry'); const createAttachmentAndNavigate = async (attachment: CommentRequest) => { const caseData = await cases.api.createCase({ @@ -107,8 +108,7 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/139300 - describe.skip('Persistable state attachments', () => { + describe('Persistable state attachments', () => { const getLensState = (dataViewId: string) => ({ title: '', visualizationType: 'lnsXY', @@ -205,7 +205,10 @@ export default ({ getPageObject, getService }: FtrProviderContext) => { it('renders a persistable attachment type correctly', async () => { const attachmentId = caseWithAttachment?.comments?.[0].id; await validateAttachment(CommentType.persistableState, attachmentId); - expect(await find.existsByCssSelector('.lnsExpressionRenderer')).toBe(true); + await retry.waitFor( + 'actions accordion to exist', + async () => await find.existsByCssSelector('.lnsExpressionRenderer') + ); }); }); From d078d81eb90eb93ddc3023c912f25cf36e90de5d Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Thu, 22 Sep 2022 10:26:33 +0200 Subject: [PATCH 31/36] [ML] Transforms: Fix flaky wizard functional tests. (#141209) This replaces clickWhenNotDisabledWithoutRetry with clickWhenNotDisabled to stabilize tests. --- .../functional/apps/transform/creation_index_pattern.ts | 3 +-- .../functional/services/transform/source_selection.ts | 2 +- x-pack/test/functional/services/transform/wizard.ts | 8 ++++---- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/x-pack/test/functional/apps/transform/creation_index_pattern.ts b/x-pack/test/functional/apps/transform/creation_index_pattern.ts index f23ebdde93d9b..4dee8e3af8262 100644 --- a/x-pack/test/functional/apps/transform/creation_index_pattern.ts +++ b/x-pack/test/functional/apps/transform/creation_index_pattern.ts @@ -21,8 +21,7 @@ export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const transform = getService('transform'); - // Failing: See https://github.com/elastic/kibana/issues/139781 - describe.skip('creation_index_pattern', function () { + describe('creation_index_pattern', function () { before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce'); await transform.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date'); diff --git a/x-pack/test/functional/services/transform/source_selection.ts b/x-pack/test/functional/services/transform/source_selection.ts index 9f77dbeb7ba40..b5096a2dd2f3d 100644 --- a/x-pack/test/functional/services/transform/source_selection.ts +++ b/x-pack/test/functional/services/transform/source_selection.ts @@ -26,7 +26,7 @@ export function TransformSourceSelectionProvider({ getService }: FtrProviderCont async selectSource(sourceName: string) { await this.filterSourceSelection(sourceName); await retry.tryForTime(30 * 1000, async () => { - await testSubjects.clickWhenNotDisabledWithoutRetry(`savedObjectTitle${sourceName}`); + await testSubjects.clickWhenNotDisabled(`savedObjectTitle${sourceName}`); await testSubjects.existOrFail('transformPageCreateTransform', { timeout: 10 * 1000 }); }); }, diff --git a/x-pack/test/functional/services/transform/wizard.ts b/x-pack/test/functional/services/transform/wizard.ts index 9eff6dff611e3..df65911cb4098 100644 --- a/x-pack/test/functional/services/transform/wizard.ts +++ b/x-pack/test/functional/services/transform/wizard.ts @@ -34,7 +34,7 @@ export function TransformWizardProvider({ getService, getPageObjects }: FtrProvi return { async clickNextButton() { await testSubjects.existOrFail('transformWizardNavButtonNext'); - await testSubjects.clickWhenNotDisabledWithoutRetry('transformWizardNavButtonNext'); + await testSubjects.clickWhenNotDisabled('transformWizardNavButtonNext'); }, async assertDefineStepActive() { @@ -317,7 +317,7 @@ export function TransformWizardProvider({ getService, getPageObjects }: FtrProvi const subj = 'transformAdvancedRuntimeMappingsEditorSwitch'; if ((await this.getRuntimeMappingsEditorSwitchCheckedState()) !== toggle) { await retry.tryForTime(5 * 1000, async () => { - await testSubjects.clickWhenNotDisabledWithoutRetry(subj); + await testSubjects.clickWhenNotDisabled(subj); await this.assertRuntimeMappingsEditorSwitchCheckState(toggle); }); } @@ -355,7 +355,7 @@ export function TransformWizardProvider({ getService, getPageObjects }: FtrProvi async applyRuntimeMappings() { const subj = 'transformRuntimeMappingsApplyButton'; await testSubjects.existOrFail(subj); - await testSubjects.clickWhenNotDisabledWithoutRetry(subj); + await testSubjects.clickWhenNotDisabled(subj); const isEnabled = await testSubjects.isEnabled(subj); expect(isEnabled).to.eql( false, @@ -560,7 +560,7 @@ export function TransformWizardProvider({ getService, getPageObjects }: FtrProvi break; } } - await testSubjects.clickWhenNotDisabledWithoutRetry('transformApplyAggChanges'); + await testSubjects.clickWhenNotDisabled('transformApplyAggChanges'); await testSubjects.missingOrFail(`transformAggPopoverForm_${expectedLabel}`); }, From 8586270d1307b1185ba745c1b385f7103d2bf081 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Thu, 22 Sep 2022 02:29:24 -0700 Subject: [PATCH 32/36] Remove unused or outdated docs (#141342) --- x-pack/plugins/profiling/INTERNALS.md | 97 --------------------------- 1 file changed, 97 deletions(-) delete mode 100644 x-pack/plugins/profiling/INTERNALS.md diff --git a/x-pack/plugins/profiling/INTERNALS.md b/x-pack/plugins/profiling/INTERNALS.md deleted file mode 100644 index 9612a64380efd..0000000000000 --- a/x-pack/plugins/profiling/INTERNALS.md +++ /dev/null @@ -1,97 +0,0 @@ -This plugin is divided into two components: the UI and the server. - -The UI is responsible for rendering the charts and flamegraphs. It will make -API calls to the server component depending on the user interactions with the -UI. You will find most of the source code in the `public` directory. - -The server is responsible for retrieving data from the necessary sources and -sending it in the expected format to the UI in response to the UI's API calls. -You will find most of the source code in the `server` directory. - -## Server API - -Depending on how the plugin is configured, there are two different sets of API -calls. - -If the server uses local fixtures as a data source, then the following API is -served by the server and called by the UI: - -* /api/prodfiler/v1/topn/containers -* /api/prodfiler/v1/topn/deployments -* /api/prodfiler/v1/topn/hosts -* /api/prodfiler/v1/topn/threads -* /api/prodfiler/v1/topn/traces -* /api/prodfiler/v1/flamechart/elastic - -If the server uses an Elasticsearch cluster as a data source, then the following -API is served by the server and called by the UI: - -* /api/prodfiler/v2/topn/containers -* /api/prodfiler/v2/topn/deployments -* /api/prodfiler/v2/topn/hosts -* /api/prodfiler/v2/topn/threads -* /api/prodfiler/v2/topn/traces -* /api/prodfiler/v2/flamechart/elastic - -By default, the plugin is configured to use the second API set. See README.md to -configure the plugin to use the first API set (aka local fixtures as a data -source). - -Both API sets are expected to return the same response format. - -The design to have separate API sets for local vs Elasticsearch was partly -because the UI and server components were originally developed separately and -later merged. However, it also allows the server methods to have a single -responsibility, making it easier to test and verify that the server returns -the expected responses for the given data sources. - -## Server API Responses - -### /api/prodfiler/*/flamechart/elastic - -The response returned from this API is used by the Elastic flamegraph. - -The following example is the expected response: - -```json -{ - leaves: [ - { - id: 'pf-collection-agent: runtime.releaseSudog() in runtime2.go#282', - value: 1, - depth: 19, - pathFromRoot: { - '0': 'root', - '1': 'pf-collection-agent: runtime.goexit() in asm_amd64.s#1581', - '2': 'pf-collection-agent: github.com/optimyze/prodfiler/pf-storage-backend/storagebackend/storagebackendv1.(*ScyllaExecutor).Start.func1 in scyllaexecutor.go#102', - '3': 'pf-collection-agent: github.com/optimyze/prodfiler/pf-storage-backend/storagebackend/storagebackendv1.(*ScyllaExecutor).executeQueryAndReadResults in scyllaexecutor.go#158', - '4': 'pf-collection-agent: github.com/gocql/gocql.(*Query).Iter in session.go#1246', - '5': 'pf-collection-agent: github.com/gocql/gocql.(*Session).executeQuery in session.go#463', - '6': 'pf-collection-agent: github.com/gocql/gocql.(*queryExecutor).executeQuery in query_executor.go#66', - '7': 'pf-collection-agent: github.com/gocql/gocql.(*queryExecutor).do in query_executor.go#127', - '8': 'pf-collection-agent: github.com/gocql/gocql.(*queryExecutor).attemptQuery in query_executor.go#32', - '9': 'pf-collection-agent: github.com/gocql/gocql.(*Query).execute in session.go#1044', - '10': 'pf-collection-agent: github.com/gocql/gocql.(*Conn).executeQuery in conn.go#1129', - '11': 'pf-collection-agent: github.com/gocql/gocql.(*Conn).exec in conn.go#916', - '12': 'pf-collection-agent: github.com/gocql/gocql.(*writeExecuteFrame).writeFrame in frame.go#1618', - '13': 'pf-collection-agent: github.com/gocql/gocql.(*framer).writeExecuteFrame in frame.go#1643', - '14': 'pf-collection-agent: github.com/gocql/gocql.(*framer).finishWrite in frame.go#788', - '15': 'pf-collection-agent: github.com/gocql/gocql.(*Conn).Write in conn.go#319', - '16': 'pf-collection-agent: github.com/gocql/gocql.(*writeCoalescer).Write in conn.go#829', - '17': 'pf-collection-agent: sync.(*Cond).Wait in cond.go#83', - '18': 'pf-collection-agent: sync.runtime_notifyListWait() in sema.go#498', - '19': 'pf-collection-agent: runtime.releaseSudog() in runtime2.go#282', - }, - }, - ... - ] -} -``` - -Here is a basic description of the response format: - -* Each object in the `leaves` list represents a leaf node in the flamegraph -* `id` represents the name of the flamegraph node -* `value` represents the number of samples for that node -* `depth` represents the depth of the node in the flamegraph, starting from zero -* `pathFromRoot` represents the full path from the flamegraph root to the given node From cea17e3dbe29931da6f665aa4c5a15c360c9692b Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Thu, 22 Sep 2022 02:44:10 -0700 Subject: [PATCH 33/36] Replace log execution latency (#141341) --- .../routes/get_executables_and_stacktraces.ts | 17 +-- .../profiling/server/routes/stacktrace.ts | 137 +++++++++--------- 2 files changed, 76 insertions(+), 78 deletions(-) diff --git a/x-pack/plugins/profiling/server/routes/get_executables_and_stacktraces.ts b/x-pack/plugins/profiling/server/routes/get_executables_and_stacktraces.ts index 9e5773ad9aa91..6ef023f07a478 100644 --- a/x-pack/plugins/profiling/server/routes/get_executables_and_stacktraces.ts +++ b/x-pack/plugins/profiling/server/routes/get_executables_and_stacktraces.ts @@ -10,7 +10,6 @@ import { INDEX_EVENTS } from '../../common'; import { ProfilingESClient } from '../utils/create_profiling_es_client'; import { withProfilingSpan } from '../utils/with_profiling_span'; import { downsampleEventsRandomly, findDownsampledIndex } from './downsampling'; -import { logExecutionLatency } from './logger'; import { ProjectTimeQuery } from './query'; import { mgetExecutables, @@ -51,14 +50,14 @@ export async function getExecutablesAndStackTraces({ if (totalCount > sampleSize * 1.1) { p = sampleSize / totalCount; logger.info('downsampling events with p=' + p); - await logExecutionLatency(logger, 'downsampling events', async () => { - const downsampledTotalCount = downsampleEventsRandomly( - stackTraceEvents, - p, - filter.toString() - ); - logger.info('downsampled total count: ' + downsampledTotalCount); - }); + const t0 = new Date().getTime(); + const downsampledTotalCount = downsampleEventsRandomly( + stackTraceEvents, + p, + filter.toString() + ); + logger.info(`downsampling events took ${new Date().getTime() - t0} ms`); + logger.info('downsampled total count: ' + downsampledTotalCount); logger.info('unique downsampled stacktraces: ' + stackTraceEvents.size); } diff --git a/x-pack/plugins/profiling/server/routes/stacktrace.ts b/x-pack/plugins/profiling/server/routes/stacktrace.ts index ecf51313695fa..b98bcfc196318 100644 --- a/x-pack/plugins/profiling/server/routes/stacktrace.ts +++ b/x-pack/plugins/profiling/server/routes/stacktrace.ts @@ -28,7 +28,6 @@ import { import { ProfilingESClient } from '../utils/create_profiling_es_client'; import { withProfilingSpan } from '../utils/with_profiling_span'; import { DownsampledEventsIndex } from './downsampling'; -import { logExecutionLatency } from './logger'; import { ProjectTimeQuery } from './query'; const traceLRU = new LRUCache({ max: 20000 }); @@ -270,36 +269,36 @@ export async function mgetStackTraces({ const stackFrameDocIDs = new Set(); const executableDocIDs = new Set(); - await logExecutionLatency(logger, 'processing data', async () => { - // flatMap() is significantly slower than an explicit for loop - for (const res of stackResponses) { - for (const trace of res.docs) { - if ('error' in trace) { - continue; + const t0 = new Date().getTime(); + // flatMap() is significantly slower than an explicit for loop + for (const res of stackResponses) { + for (const trace of res.docs) { + if ('error' in trace) { + continue; + } + // Sometimes we don't find the trace. + // This is due to ES delays writing (data is not immediately seen after write). + // Also, ES doesn't know about transactions. + if (trace.found) { + const traceid = trace._id as StackTraceID; + let stackTrace = traceLRU.get(traceid) as StackTrace; + if (!stackTrace) { + stackTrace = decodeStackTrace(trace._source as EncodedStackTrace); + traceLRU.set(traceid, stackTrace); + } + + totalFrames += stackTrace.FrameIDs.length; + stackTraces.set(traceid, stackTrace); + for (const frameID of stackTrace.FrameIDs) { + stackFrameDocIDs.add(frameID); } - // Sometimes we don't find the trace. - // This is due to ES delays writing (data is not immediately seen after write). - // Also, ES doesn't know about transactions. - if (trace.found) { - const traceid = trace._id as StackTraceID; - let stackTrace = traceLRU.get(traceid) as StackTrace; - if (!stackTrace) { - stackTrace = decodeStackTrace(trace._source as EncodedStackTrace); - traceLRU.set(traceid, stackTrace); - } - - totalFrames += stackTrace.FrameIDs.length; - stackTraces.set(traceid, stackTrace); - for (const frameID of stackTrace.FrameIDs) { - stackFrameDocIDs.add(frameID); - } - for (const fileID of stackTrace.FileIDs) { - executableDocIDs.add(fileID); - } + for (const fileID of stackTrace.FileIDs) { + executableDocIDs.add(fileID); } } } - }); + } + logger.info(`processing data took ${new Date().getTime() - t0} ms`); if (stackTraces.size !== 0) { logger.info('Average size of stacktrace: ' + totalFrames / stackTraces.size); @@ -337,32 +336,32 @@ export async function mgetStackFrames({ // Create a lookup map StackFrameID -> StackFrame. let framesFound = 0; - await logExecutionLatency(logger, 'processing data', async () => { - const docs = resStackFrames.docs; - for (const frame of docs) { - if ('error' in frame) { - continue; - } - if (frame.found) { - stackFrames.set(frame._id, { - FileName: frame._source!.Stackframe.file?.name, - FunctionName: frame._source!.Stackframe.function?.name, - FunctionOffset: frame._source!.Stackframe.function?.offset, - LineNumber: frame._source!.Stackframe.line?.number, - SourceType: frame._source!.Stackframe.source?.type, - }); - framesFound++; - } else { - stackFrames.set(frame._id, { - FileName: '', - FunctionName: '', - FunctionOffset: 0, - LineNumber: 0, - SourceType: 0, - }); - } + const t0 = new Date().getTime(); + const docs = resStackFrames.docs; + for (const frame of docs) { + if ('error' in frame) { + continue; } - }); + if (frame.found) { + stackFrames.set(frame._id, { + FileName: frame._source!.Stackframe.file?.name, + FunctionName: frame._source!.Stackframe.function?.name, + FunctionOffset: frame._source!.Stackframe.function?.offset, + LineNumber: frame._source!.Stackframe.line?.number, + SourceType: frame._source!.Stackframe.source?.type, + }); + framesFound++; + } else { + stackFrames.set(frame._id, { + FileName: '', + FunctionName: '', + FunctionOffset: 0, + LineNumber: 0, + SourceType: 0, + }); + } + } + logger.info(`processing data took ${new Date().getTime() - t0} ms`); logger.info('found ' + framesFound + ' / ' + stackFrameIDs.size + ' frames'); @@ -392,24 +391,24 @@ export async function mgetExecutables({ // Create a lookup map StackFrameID -> StackFrame. let exeFound = 0; - await logExecutionLatency(logger, 'processing data', async () => { - const docs = resExecutables.docs; - for (const exe of docs) { - if ('error' in exe) { - continue; - } - if (exe.found) { - executables.set(exe._id, { - FileName: exe._source!.Executable.file.name, - }); - exeFound++; - } else { - executables.set(exe._id, { - FileName: '', - }); - } + const t0 = new Date().getTime(); + const docs = resExecutables.docs; + for (const exe of docs) { + if ('error' in exe) { + continue; } - }); + if (exe.found) { + executables.set(exe._id, { + FileName: exe._source!.Executable.file.name, + }); + exeFound++; + } else { + executables.set(exe._id, { + FileName: '', + }); + } + } + logger.info(`processing data took ${new Date().getTime() - t0} ms`); logger.info('found ' + exeFound + ' / ' + executableIDs.size + ' executables'); From 03b360a6b8db3a4129289a4249132363cd30b25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20R=C3=BChsen?= Date: Thu, 22 Sep 2022 11:45:20 +0200 Subject: [PATCH 34/36] [Profiling] Aggregate ELF frames by exeFilename, not fileID (#141139) * [Profiling] Aggregate ELF frames by exeFilename, not fileID * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/profiling/common/frame_group.test.ts | 7 ++++--- x-pack/plugins/profiling/common/frame_group.ts | 14 ++++++++++---- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/profiling/common/frame_group.test.ts b/x-pack/plugins/profiling/common/frame_group.test.ts index 57ed29001ccdf..2cdc4fd6f466e 100644 --- a/x-pack/plugins/profiling/common/frame_group.test.ts +++ b/x-pack/plugins/profiling/common/frame_group.test.ts @@ -33,18 +33,21 @@ const elfSymbolizedFrameGroups = [ createFrameGroup( createStackFrameMetadata({ FileID: '0x0123456789ABCDEF', + ExeFileName: 'libc', FunctionName: 'strlen()', }) ), createFrameGroup( createStackFrameMetadata({ FileID: '0xFEDCBA9876543210', + ExeFileName: 'libc', FunctionName: 'strtok()', }) ), createFrameGroup( createStackFrameMetadata({ FileID: '0xFEDCBA9876543210', + ExeFileName: 'myapp', FunctionName: 'main()', }) ), @@ -165,9 +168,7 @@ describe('Frame group operations', () => { }); test('non-symbolized ELF frame', () => { - expect(createFrameGroupID(elfSymbolizedFrameGroups[0])).toEqual( - 'elf;0x0123456789ABCDEF;strlen()' - ); + expect(createFrameGroupID(elfSymbolizedFrameGroups[0])).toEqual('elf;libc;strlen()'); }); test('symbolized frame', () => { diff --git a/x-pack/plugins/profiling/common/frame_group.ts b/x-pack/plugins/profiling/common/frame_group.ts index 776eccaa2e79c..985bf2c1f0cee 100644 --- a/x-pack/plugins/profiling/common/frame_group.ts +++ b/x-pack/plugins/profiling/common/frame_group.ts @@ -28,6 +28,7 @@ interface EmptyFrameGroup extends BaseFrameGroup { interface ElfFrameGroup extends BaseFrameGroup { readonly name: FrameGroupName.ELF; readonly fileID: StackFrameMetadata['FileID']; + readonly exeFilename: StackFrameMetadata['ExeFileName']; readonly functionName: StackFrameMetadata['FunctionName']; } @@ -43,7 +44,7 @@ export type FrameGroup = EmptyFrameGroup | ElfFrameGroup | FullFrameGroup; // createFrameGroup is the "standard" way of grouping frames, by commonly // shared group identifiers. // -// For ELF-symbolized frames, group by FunctionName and FileID. +// For ELF-symbolized frames, group by FunctionName, ExeFileName and FileID. // For non-symbolized frames, group by FileID and AddressOrLine. // otherwise group by ExeFileName, SourceFilename and FunctionName. export function createFrameGroup(frame: StackFrameMetadata): FrameGroup { @@ -59,6 +60,7 @@ export function createFrameGroup(frame: StackFrameMetadata): FrameGroup { return { name: FrameGroupName.ELF, fileID: frame.FileID, + exeFilename: frame.ExeFileName, functionName: frame.FunctionName, } as ElfFrameGroup; } @@ -123,12 +125,14 @@ export function compareFrameGroup(a: FrameGroup, b: FrameGroup): number { if (b.name === FrameGroupName.ELF) { if (a.functionName < b.functionName) return -1; if (a.functionName > b.functionName) return 1; - if (a.fileID < b.fileID) return -1; - if (a.fileID > b.fileID) return 1; + if (a.exeFilename < b.exeFilename) return -1; + if (a.exeFilename > b.exeFilename) return 1; return 0; } if (a.functionName < b.functionName) return -1; if (a.functionName > b.functionName) return 1; + if (a.exeFilename < b.exeFilename) return -1; + if (a.exeFilename > b.exeFilename) return 1; return -1; } @@ -144,6 +148,8 @@ export function compareFrameGroup(a: FrameGroup, b: FrameGroup): number { if (b.name === FrameGroupName.ELF) { if (a.functionName < b.functionName) return -1; if (a.functionName > b.functionName) return 1; + if (a.exeFilename < b.exeFilename) return -1; + if (a.exeFilename > b.exeFilename) return 1; } return 1; } @@ -154,7 +160,7 @@ export function createFrameGroupID(frameGroup: FrameGroup): FrameGroupID { return `${frameGroup.name};${frameGroup.fileID};${frameGroup.addressOrLine}`; break; case FrameGroupName.ELF: - return `${frameGroup.name};${frameGroup.fileID};${frameGroup.functionName}`; + return `${frameGroup.name};${frameGroup.exeFilename};${frameGroup.functionName}`; break; case FrameGroupName.FULL: return `${frameGroup.name};${frameGroup.exeFilename};${frameGroup.functionName};${frameGroup.sourceFilename}`; From ed1f06a35d1449df8e02c1832d11d2ce99400a44 Mon Sep 17 00:00:00 2001 From: Boris Kirov Date: Thu, 22 Sep 2022 12:24:16 +0200 Subject: [PATCH 35/36] [APM] Beta badge and translations (#141105) * beta/beaker badges and feedback links * translation fixes and badge update * translations and an icon for beta badge * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * translation title comments and rename the feedback link * using the BetaBadge and added a tech preview to Trace explorer * fix i18n * delete file added by mistake Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Miriam <31922082+MiriamAparicio@users.noreply.github.com> Co-authored-by: miriam.aparicio --- .../components/app/trace_overview/index.tsx | 4 +- .../templates/apm_service_template/index.tsx | 4 +- .../shared/apm_header_action_menu/index.tsx | 37 +++++++++------ .../labs/labs_flyout.tsx | 13 ++++- .../public/components/shared/beta_badge.tsx | 3 ++ .../observability/server/ui_settings.ts | 47 +++++++++++++++---- .../translations/translations/fr-FR.json | 4 -- .../translations/translations/ja-JP.json | 4 -- .../translations/translations/zh-CN.json | 4 -- 9 files changed, 81 insertions(+), 39 deletions(-) diff --git a/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx b/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx index c586b782fc6e2..1093a74f6bc2f 100644 --- a/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/trace_overview/index.tsx @@ -13,6 +13,7 @@ import { useApmRoutePath } from '../../../hooks/use_apm_route_path'; import { TraceSearchType } from '../../../../common/trace_explorer'; import { TransactionTab } from '../transaction_details/waterfall_with_summary/transaction_tabs'; import { useTraceExplorerEnabledSetting } from '../../../hooks/use_trace_explorer_enabled_setting'; +import { TechnicalPreviewBadge } from '../../shared/technical_preview_badge'; export function TraceOverview({ children }: { children: React.ReactElement }) { const isTraceExplorerEnabled = useTraceExplorerEnabledSetting(); @@ -62,7 +63,7 @@ export function TraceOverview({ children }: { children: React.ReactElement }) { return ( - + {i18n.translate('xpack.apm.traceOverview.topTracesTab', { defaultMessage: 'Top traces', @@ -70,6 +71,7 @@ export function TraceOverview({ children }: { children: React.ReactElement }) { } isSelected={routePath === '/traces/explorer'} > {i18n.translate('xpack.apm.traceOverview.traceExplorerTab', { diff --git a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx index 3f84a4bdb1347..0a0b17a4e273b 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/apm_service_template/index.tsx @@ -31,9 +31,9 @@ import { useApmParams } from '../../../../hooks/use_apm_params'; import { useApmRouter } from '../../../../hooks/use_apm_router'; import { useTimeRange } from '../../../../hooks/use_time_range'; import { getAlertingCapabilities } from '../../../alerting/get_alerting_capabilities'; -import { BetaBadge } from '../../../shared/beta_badge'; import { SearchBar } from '../../../shared/search_bar'; import { ServiceIcons } from '../../../shared/service_icons'; +import { BetaBadge } from '../../../shared/beta_badge'; import { TechnicalPreviewBadge } from '../../../shared/technical_preview_badge'; import { ApmMainTemplate } from '../apm_main_template'; import { AnalyzeDataButton } from './analyze_data_button'; @@ -293,7 +293,7 @@ function useTabs({ selectedTab }: { selectedTab: Tab['key'] }) { path: { serviceName }, query, }), - append: , + append: , label: i18n.translate('xpack.apm.home.infraTabLabel', { defaultMessage: 'Infrastructure', }), diff --git a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx index 77bdf01aea6e6..7a27a68ccd558 100644 --- a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx @@ -5,7 +5,12 @@ * 2.0. */ -import { EuiHeaderLink, EuiHeaderLinks } from '@elastic/eui'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiHeaderLink, + EuiHeaderLinks, +} from '@elastic/eui'; import { apmLabsButton } from '@kbn/observability-plugin/common'; import { i18n } from '@kbn/i18n'; import React from 'react'; @@ -53,21 +58,15 @@ export function ApmHeaderActionMenu() { - {i18n.translate('xpack.apm.storageExplorerLinkLabel', { - defaultMessage: 'Storage Explorer', - })} - - - {i18n.translate('xpack.apm.settingsLinkLabel', { - defaultMessage: 'Settings', - })} + + + {i18n.translate('xpack.apm.storageExplorerLinkLabel', { + defaultMessage: 'Storage Explorer', + })} + + {canAccessML && } {isAlertingAvailable && ( @@ -89,6 +88,16 @@ export function ApmHeaderActionMenu() { defaultMessage: 'Add data', })} + + + {i18n.translate('xpack.apm.settingsLinkLabel', { + defaultMessage: 'Settings', + })} + ); diff --git a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/labs/labs_flyout.tsx b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/labs/labs_flyout.tsx index 408070ab88900..160cf23cc7714 100644 --- a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/labs/labs_flyout.tsx +++ b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/labs/labs_flyout.tsx @@ -17,6 +17,8 @@ import { EuiHorizontalRule, EuiIcon, EuiLoadingContent, + EuiSpacer, + EuiText, EuiTitle, } from '@elastic/eui'; import { LazyField } from '@kbn/advanced-settings-plugin/public'; @@ -83,9 +85,9 @@ export function LabsFlyout({ onClose }: Props) { return ( - + - + @@ -97,6 +99,13 @@ export function LabsFlyout({ onClose }: Props) { + + + {i18n.translate('xpack.apm.labs.description', { + defaultMessage: + 'Try out the APM features that are under technical preview and in progress.', + })} + {isLoading ? ( diff --git a/x-pack/plugins/apm/public/components/shared/beta_badge.tsx b/x-pack/plugins/apm/public/components/shared/beta_badge.tsx index 0ec90f9d34467..c6b3c72575fce 100644 --- a/x-pack/plugins/apm/public/components/shared/beta_badge.tsx +++ b/x-pack/plugins/apm/public/components/shared/beta_badge.tsx @@ -19,6 +19,9 @@ export function BetaBadge({ icon }: Props) { label={i18n.translate('xpack.apm.betaBadgeLabel', { defaultMessage: 'Beta', })} + title={i18n.translate('xpack.apm.betaBadgeLabel', { + defaultMessage: 'Beta', + })} tooltipContent={i18n.translate('xpack.apm.betaBadgeDescription', { defaultMessage: 'This feature is currently in beta. If you encounter any bugs or have feedback, please open an issue or visit our discussion forum.', diff --git a/x-pack/plugins/observability/server/ui_settings.ts b/x-pack/plugins/observability/server/ui_settings.ts index 2d79e3b0e5e0a..13e47c6628399 100644 --- a/x-pack/plugins/observability/server/ui_settings.ts +++ b/x-pack/plugins/observability/server/ui_settings.ts @@ -162,8 +162,15 @@ export const uiSettings: Record = { }), value: false, description: i18n.translate('xpack.observability.enableServiceGroupsDescription', { - defaultMessage: '{technicalPreviewLabel} Enable the Service groups feature on APM UI', - values: { technicalPreviewLabel: `[${technicalPreviewLabel}]` }, + defaultMessage: 'Enable the Service groups feature on APM UI. {feedbackLink}.', + values: { + feedbackLink: + '' + + i18n.translate('xpack.observability.enableServiceGroups.feedbackLinkText', { + defaultMessage: 'Give feedback', + }) + + '', + }, }), schema: schema.boolean(), requiresPageReload: true, @@ -193,8 +200,18 @@ export const uiSettings: Record = { 'xpack.observability.apmServiceInventoryOptimizedSortingDescription', { defaultMessage: - '{technicalPreviewLabel} Default APM Service Inventory page sort (for Services without Machine Learning applied) to sort by Service Name', - values: { technicalPreviewLabel: `[${technicalPreviewLabel}]` }, + 'Default APM Service Inventory page sort (for Services without Machine Learning applied) to sort by Service Name. {feedbackLink}.', + values: { + feedbackLink: + '' + + i18n.translate( + 'xpack.observability.apmServiceInventoryOptimizedSorting.feedbackLinkText', + { + defaultMessage: 'Give feedback', + } + ) + + '', + }, } ), schema: schema.boolean(), @@ -221,8 +238,15 @@ export const uiSettings: Record = { }), description: i18n.translate('xpack.observability.apmTraceExplorerTabDescription', { defaultMessage: - '{technicalPreviewLabel} Enable the APM Trace Explorer feature, that allows you to search and inspect traces with KQL or EQL', - values: { technicalPreviewLabel: `[${technicalPreviewLabel}]` }, + 'Enable the APM Trace Explorer feature, that allows you to search and inspect traces with KQL or EQL. {feedbackLink}.', + values: { + feedbackLink: + '' + + i18n.translate('xpack.observability.apmTraceExplorerTabDescription.feedbackLinkText', { + defaultMessage: 'Give feedback', + }) + + '', + }, }), schema: schema.boolean(), value: false, @@ -237,8 +261,15 @@ export const uiSettings: Record = { }), description: i18n.translate('xpack.observability.apmOperationsBreakdownDescription', { defaultMessage: - '{technicalPreviewLabel} Enable the APM Operations Breakdown feature, that displays aggregates for backend operations', - values: { technicalPreviewLabel: `[${technicalPreviewLabel}]` }, + 'Enable the APM Operations Breakdown feature, that displays aggregates for backend operations. {feedbackLink}.', + values: { + feedbackLink: + '' + + i18n.translate('xpack.observability.apmOperationsBreakdownDescription.feedbackLinkText', { + defaultMessage: 'Give feedback', + }) + + '', + }, }), schema: schema.boolean(), value: false, diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 70333f960f0ff..19dc46cd83a85 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -23022,11 +23022,7 @@ "xpack.monitoring.updateLicenseTitle": "Mettre à jour votre licence", "xpack.monitoring.useAvailableLicenseDescription": "Si vous avez déjà une nouvelle licence, chargez-la maintenant.", "xpack.observability.alertsTable.showingAlertsTitle": "{totalAlerts, plural, =1 {alerte} other {alertes}}", - "xpack.observability.apmOperationsBreakdownDescription": "{technicalPreviewLabel} Active la fonctionnalité APM Operations Breakdown, qui affiche les agrégats pour les opérations backend", "xpack.observability.apmProgressiveLoadingDescription": "{technicalPreviewLabel} S'il faut charger les données de façon progressive pour les vues APM. Les données peuvent être demandées d'abord avec un taux d'échantillonnage inférieur, avec une précision plus faible mais des temps de réponse plus rapides, pendant que les données non échantillonnées se chargent en arrière-plan", - "xpack.observability.apmServiceInventoryOptimizedSortingDescription": "{technicalPreviewLabel} Tri par défaut de la page d'inventaire des services APM (pour les services hors Machine Learning) en fonction du nom de service", - "xpack.observability.apmTraceExplorerTabDescription": "{technicalPreviewLabel} Activer la fonctionnalité Explorateur de traces APM qui vous permet de rechercher et d'inspecter les traces avec KQL ou EQL", - "xpack.observability.enableServiceGroupsDescription": "{technicalPreviewLabel} Activer la fonctionnalité de groupes de services sur l’interface utilisateur APM", "xpack.observability.expView.columns.label": "{percentileValue} centile de {sourceField}", "xpack.observability.expView.columns.operation.label": "{operationType} de {sourceField}", "xpack.observability.expView.filterValueButton.negate": "Pas {value}", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 066d96ec83797..c82ae2e5e6bc0 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -23001,11 +23001,7 @@ "xpack.monitoring.updateLicenseTitle": "ライセンスの更新", "xpack.monitoring.useAvailableLicenseDescription": "すでに新しいライセンスがある場合は、今すぐアップロードしてください。", "xpack.observability.alertsTable.showingAlertsTitle": "{totalAlerts, plural, other {アラート}}", - "xpack.observability.apmOperationsBreakdownDescription": "{technicalPreviewLabel} バックエンド処理のアグリゲーションを表示する、APM Operations Breakdown機能を有効にします", "xpack.observability.apmProgressiveLoadingDescription": "{technicalPreviewLabel} APMビューでデータのプログレッシブ読み込みを行うかどうか。サンプリングされていないデータをバックグラウンドで読み込みながら、最初は低いサンプリングレート、低い精度、高速の応答時間でデータを要求できます", - "xpack.observability.apmServiceInventoryOptimizedSortingDescription": "{technicalPreviewLabel} サービス名によるデフォルトAPMサービスインベントリページの並べ替え(機械学習が適用されていないサービス)", - "xpack.observability.apmTraceExplorerTabDescription": "{technicalPreviewLabel} APMトレースエクスプローラー機能を有効にし、KQLまたはEQLでトレースを検索、検査できます", - "xpack.observability.enableServiceGroupsDescription": "{technicalPreviewLabel} APM UIでサービスグループ機能を有効にする", "xpack.observability.expView.columns.label": "{sourceField}の{percentileValue}パーセンタイル", "xpack.observability.expView.columns.operation.label": "{sourceField}の{operationType}", "xpack.observability.expView.filterValueButton.negate": "{value}ではない", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index d44b85a0ff1a3..a9c5f2be47229 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -23030,11 +23030,7 @@ "xpack.monitoring.updateLicenseTitle": "更新您的许可证", "xpack.monitoring.useAvailableLicenseDescription": "如果您已经持有新的许可证,请立即上传。", "xpack.observability.alertsTable.showingAlertsTitle": "{totalAlerts, plural, other {告警}}", - "xpack.observability.apmOperationsBreakdownDescription": "{technicalPreviewLabel} 启用 APM Operations Breakdown 功能,它将显示后端操作的聚合", "xpack.observability.apmProgressiveLoadingDescription": "{technicalPreviewLabel} 是否以渐进方式为 APM 视图加载数据。可以先以较低的采样速率请求数据,这样的准确性较低,但响应时间更快,同时在后台加载未采样数据", - "xpack.observability.apmServiceInventoryOptimizedSortingDescription": "{technicalPreviewLabel} 默认 APM 服务库存页面排序(对于未应用 Machine Learning 的服务)将按服务名称排序", - "xpack.observability.apmTraceExplorerTabDescription": "{technicalPreviewLabel} 启用 APM Trace Explorer 功能,它允许您通过 KQL 或 EQL 搜索和检查跟踪", - "xpack.observability.enableServiceGroupsDescription": "{technicalPreviewLabel} 在 APM UI 上启用服务组功能", "xpack.observability.expView.columns.label": "{sourceField} 的第 {percentileValue} 百分位", "xpack.observability.expView.columns.operation.label": "{sourceField} 的 {operationType}", "xpack.observability.expView.filterValueButton.negate": "不是 {value}", From aae100f7098d522a4a2f4ec869b8099012e6c24d Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Thu, 22 Sep 2022 12:31:18 +0200 Subject: [PATCH 36/36] added track adoption annotations (#140690) --- x-pack/plugins/files/public/plugin.ts | 2 ++ x-pack/plugins/files/server/types.ts | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/x-pack/plugins/files/public/plugin.ts b/x-pack/plugins/files/public/plugin.ts index 688ce0ecbb6a5..8ebbd71cdbe1f 100644 --- a/x-pack/plugins/files/public/plugin.ts +++ b/x-pack/plugins/files/public/plugin.ts @@ -22,6 +22,8 @@ export interface FilesSetup { /** * A factory for creating an {@link FilesClient} instance. This requires a * registered {@link FileKind}. + * + * @track-adoption */ filesClientFactory: FilesClientFactory; diff --git a/x-pack/plugins/files/server/types.ts b/x-pack/plugins/files/server/types.ts index 901de230bcc34..85fc6a0f60ed6 100644 --- a/x-pack/plugins/files/server/types.ts +++ b/x-pack/plugins/files/server/types.ts @@ -18,6 +18,8 @@ export interface FilesSetup { * that will be uploaded. * * @param {FileKind} fileKind - the file kind to register + * + * @track-adoption */ registerFileKind(fileKind: FileKind): void; } @@ -33,6 +35,8 @@ export interface FilesPluginSetupDependencies { export interface FilesStart { /** * Create an instance of {@link FileServiceStart}. + * + * @track-adoption */ fileServiceFactory: FileServiceFactory; }