From 4b1d833aee778e0e7278edc04260394b0c024de5 Mon Sep 17 00:00:00 2001
From: Abdon Pijpelink
Date: Tue, 22 Aug 2023 09:33:53 +0200
Subject: [PATCH 01/26] [DOCS] Change deep link to ES book for CCS privileges
(#164165)
## Summary
Relates to https://github.com/elastic/elasticsearch/pull/98330
8.10 introduces a new method to configure remote clusters (API key
based), which will live next to the existing method (certificate based).
As a result, the ES remote cluster docs will be restructured. The deep
link from "[Alerting set
up](https://www.elastic.co/guide/en/kibana/current/alerting-setup.html#alerting-ccs-setup)"
to the setting up CCS privileges section in the ES docs will break (and
would potentially bring folks to the wrong page anyway).
This PR changes the link into a link to the higher-level remote cluster
docs, from where folks can click through to the section that is relevant
to them.
---
docs/user/alerting/alerting-setup.asciidoc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/user/alerting/alerting-setup.asciidoc b/docs/user/alerting/alerting-setup.asciidoc
index 8987d2d3370a0..40ecdedad2cf4 100644
--- a/docs/user/alerting/alerting-setup.asciidoc
+++ b/docs/user/alerting/alerting-setup.asciidoc
@@ -109,5 +109,5 @@ The same behavior occurs when you change the API key in the header of your API c
[[alerting-ccs-setup]]
=== {ccs-cap}
-If you want to use alerting rules with {ccs}, you must configure
-{ref}/remote-clusters-privileges.html#clusters-privileges-ccs-kibana[privileges for {ccs-init} and {kib}].
\ No newline at end of file
+If you want to use alerting rules with {ccs}, you must configure privileges for
+{ccs-init} and {kib}. Refer to {ref}/remote-clusters.html[Remote clusters].
\ No newline at end of file
From ce93a1f8712c10b82e4e385661f34cad11c8ab4d Mon Sep 17 00:00:00 2001
From: Mark Hopkin
Date: Tue, 22 Aug 2023 09:12:20 +0100
Subject: [PATCH 02/26] [Fleet] Add ability to set a proxy for agent binary
source (#164168)
## Summary
Closes #162862
Add a proxy selector for agent download sources.
Selecting a proxy will set the agent.download.proxy_url field on the
agent policy (this can be checked in the "view full agent policy"
flyout). I have marked this functionality as beta as we currently can
only use the URL of the proxy, not the certificates or headers.
Editing a proxy should automatically update all associated policies
which use download sources with that proxy.
Deleting a proxy should remove the proxy from all associated policies.
Verifying the field is set...
### Checklist
Delete any items that are not applicable to this PR.
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
---
.../types/rest_spec/download_sources.ts | 1 +
.../download_source_flyout/index.test.tsx | 2 +-
.../download_source_flyout/index.tsx | 64 ++++++++++++++++++-
.../use_download_source_flyout_form.tsx | 5 ++
.../settings_page/fleet_proxies_section.tsx | 2 +-
.../fleet/sections/settings/index.tsx | 6 +-
6 files changed, 74 insertions(+), 6 deletions(-)
diff --git a/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts b/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts
index bb66908b3bddd..0313753ebae13 100644
--- a/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts
+++ b/x-pack/plugins/fleet/common/types/rest_spec/download_sources.ts
@@ -40,6 +40,7 @@ export interface PostDownloadSourceRequest {
name: string;
host: string;
is_default?: boolean;
+ proxy_id?: string | null;
};
}
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.test.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.test.tsx
index 1c7b1a28d560f..56a0aeb9b33f8 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.test.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.test.tsx
@@ -16,7 +16,7 @@ function renderFlyout(downloadSource?: DownloadSource) {
const renderer = createFleetTestRendererMock();
const comp = renderer.render(
- {}} />
+ {}} proxies={[]} />
);
return { comp };
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx
index 2e539494952b0..292bb63e3c54c 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/download_source_flyout/index.tsx
@@ -5,9 +5,10 @@
* 2.0.
*/
-import React from 'react';
+import React, { useMemo } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import {
+ EuiComboBox,
EuiFlyout,
EuiFlyoutBody,
EuiFlyoutHeader,
@@ -23,10 +24,11 @@ import {
EuiLink,
EuiSwitch,
EuiSpacer,
+ EuiBetaBadge,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import type { DownloadSource } from '../../../../types';
+import type { DownloadSource, FleetProxy } from '../../../../types';
import { FLYOUT_MAX_WIDTH } from '../../constants';
import { useBreadcrumbs, useStartServices } from '../../../../hooks';
@@ -35,17 +37,22 @@ import { useDowloadSourceFlyoutForm } from './use_download_source_flyout_form';
export interface EditDownloadSourceFlyoutProps {
downloadSource?: DownloadSource;
onClose: () => void;
+ proxies: FleetProxy[];
}
export const EditDownloadSourceFlyout: React.FunctionComponent = ({
onClose,
downloadSource,
+ proxies,
}) => {
useBreadcrumbs('settings');
const form = useDowloadSourceFlyoutForm(onClose, downloadSource);
const inputs = form.inputs;
const { docLinks } = useStartServices();
-
+ const proxiesOptions = useMemo(
+ () => proxies.map((proxy) => ({ value: proxy.id, label: proxy.name })),
+ [proxies]
+ );
return (
@@ -130,6 +137,57 @@ export const EditDownloadSourceFlyout: React.FunctionComponent
+
+ ),
+ }}
+ />
+ }
+ helpText={
+
+ }
+ >
+ inputs.proxyIdInput.setValue(options?.[0]?.value ?? '')}
+ selectedOptions={
+ inputs.proxyIdInput.value !== ''
+ ? proxiesOptions.filter((option) => option.value === inputs.proxyIdInput.value)
+ : []
+ }
+ options={proxiesOptions}
+ singleSelection={{ asPlainText: true }}
+ isDisabled={inputs.proxyIdInput.props.disabled}
+ isClearable={true}
+ placeholder={i18n.translate(
+ 'xpack.fleet.settings.editDownloadSourcesFlyout.proxyIdPlaceholder',
+ {
+ defaultMessage: 'Select proxy',
+ }
+ )}
+ />
+
void, downloadSource
const hostInput = useInput(downloadSource?.host ?? '', validateHost);
+ const proxyIdInput = useInput(downloadSource?.proxy_id ?? '', () => undefined);
+
const inputs = {
nameInput,
hostInput,
defaultDownloadSourceInput,
+ proxyIdInput,
};
const hasChanged = Object.values(inputs).some((input) => input.hasChanged);
@@ -61,6 +64,7 @@ export function useDowloadSourceFlyoutForm(onSuccess: () => void, downloadSource
name: nameInput.value.trim(),
host: hostInput.value.trim(),
is_default: defaultDownloadSourceInput.value,
+ proxy_id: proxyIdInput.value || null,
};
if (downloadSource) {
@@ -100,6 +104,7 @@ export function useDowloadSourceFlyoutForm(onSuccess: () => void, downloadSource
nameInput.value,
notifications.toasts,
onSuccess,
+ proxyIdInput.value,
validate,
]);
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_proxies_section.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_proxies_section.tsx
index 302736cffdaea..c4fbd758aca63 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_proxies_section.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/settings_page/fleet_proxies_section.tsx
@@ -52,7 +52,7 @@ export const FleetProxiesSection: React.FunctionComponent
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/index.tsx
index bec49a6961809..34989d2920e73 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/index.tsx
@@ -166,7 +166,10 @@ export const SettingsApp = withConfirmModalProvider(() => {
-
+
@@ -183,6 +186,7 @@ export const SettingsApp = withConfirmModalProvider(() => {
);
From 9aba253d5607c80469ad3251e375a8774c040670 Mon Sep 17 00:00:00 2001
From: Maxim Kholod
Date: Tue, 22 Aug 2023 11:23:58 +0300
Subject: [PATCH 03/26] [Cloud Security] wait for action button to be present
before clicking to fix flacky FTR tests (#164054)
## Summary
Fixing flaky FTR test where we need to navigate to the integrations page
from our onboarding views. Confirmed in the flaky test runner that with
the fix tests are not flaky anymore
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2901
fixes:
- https://github.com/elastic/kibana/issues/163950
---------
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../page_objects/findings_page.ts | 12 ++++++++++--
.../pages/findings_onboarding.ts | 5 +++--
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts
index 373ca407f7764..94b023757bf19 100644
--- a/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts
+++ b/x-pack/test/cloud_security_posture_functional/page_objects/findings_page.ts
@@ -15,7 +15,7 @@ const FINDINGS_LATEST_INDEX = 'logs-cloud_security_posture.findings_latest-defau
export function FindingsPageProvider({ getService, getPageObjects }: FtrProviderContext) {
const testSubjects = getService('testSubjects');
- const PageObjects = getPageObjects(['common']);
+ const PageObjects = getPageObjects(['common', 'header']);
const retry = getService('retry');
const es = getService('es');
const supertest = getService('supertest');
@@ -92,7 +92,15 @@ export function FindingsPageProvider({ getService, getPageObjects }: FtrProvider
},
async navigateToAction(actionTestSubject: string) {
- await testSubjects.click(actionTestSubject);
+ return await retry.try(async () => {
+ await testSubjects.click(actionTestSubject);
+ await PageObjects.header.waitUntilLoadingHasFinished();
+ const result = await testSubjects.exists('createPackagePolicy_pageTitle');
+
+ if (!result) {
+ throw new Error('Integration installation page not found');
+ }
+ });
},
});
diff --git a/x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts b/x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts
index 1df0d3ec11c21..59f2f33ba3976 100644
--- a/x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts
+++ b/x-pack/test/cloud_security_posture_functional/pages/findings_onboarding.ts
@@ -12,8 +12,7 @@ import { FtrProviderContext } from '../ftr_provider_context';
export default ({ getPageObjects }: FtrProviderContext) => {
const PageObjects = getPageObjects(['common', 'findings', 'header']);
- // Failing: See https://github.com/elastic/kibana/issues/163950
- describe.skip('Findings Page onboarding', function () {
+ describe('Findings Page onboarding', function () {
this.tags(['cloud_security_posture_findings_onboarding']);
let findings: typeof PageObjects.findings;
let notInstalledVulnerabilities: typeof findings.notInstalledVulnerabilities;
@@ -34,6 +33,7 @@ export default ({ getPageObjects }: FtrProviderContext) => {
expect(element).to.not.be(null);
await notInstalledVulnerabilities.navigateToAction('cnvm-not-installed-action');
+
await PageObjects.common.waitUntilUrlIncludes('add-integration/vuln_mgmt');
});
@@ -44,6 +44,7 @@ export default ({ getPageObjects }: FtrProviderContext) => {
expect(element).to.not.be(null);
await notInstalledCSP.navigateToAction('cspm-not-installed-action');
+
await PageObjects.common.waitUntilUrlIncludes('add-integration/cspm');
});
From 976086284ef1901017b2dc66a3f75b200e8aadf7 Mon Sep 17 00:00:00 2001
From: Pablo Machado
Date: Tue, 22 Aug 2023 11:05:13 +0200
Subject: [PATCH 04/26] [Security Solutions] Align global menu with security
solutions menu (#164268)
issue: https://github.com/elastic/kibana/issues/163458
## Summary
Update the global menu to reflect the latest changes to the security
solution menu.
## How to test it?
* start ESS kibana
* Open security solution
* Compare the global menu and the security solutions menu
* It should display the same item order
---
x-pack/plugins/security_solution/public/cases/links.ts | 2 +-
x-pack/plugins/security_solution/public/explore/links.ts | 2 +-
x-pack/plugins/security_solution/public/management/links.ts | 2 +-
x-pack/plugins/security_solution/public/rules/links.ts | 1 +
.../security_solution/public/threat_intelligence/links.ts | 2 +-
x-pack/plugins/security_solution/public/timelines/links.ts | 2 +-
6 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/x-pack/plugins/security_solution/public/cases/links.ts b/x-pack/plugins/security_solution/public/cases/links.ts
index 59916790fb9f7..54d20b42d553a 100644
--- a/x-pack/plugins/security_solution/public/cases/links.ts
+++ b/x-pack/plugins/security_solution/public/cases/links.ts
@@ -18,7 +18,7 @@ const casesLinks = getCasesDeepLinks({
basePath: CASES_PATH,
extend: {
[SecurityPageName.case]: {
- globalNavPosition: 5,
+ globalNavPosition: 4,
capabilities: [`${CASES_FEATURE_ID}.${READ_CASES_CAPABILITY}`],
},
[SecurityPageName.caseConfigure]: {
diff --git a/x-pack/plugins/security_solution/public/explore/links.ts b/x-pack/plugins/security_solution/public/explore/links.ts
index 279cbe7da6040..a1da1528845ae 100644
--- a/x-pack/plugins/security_solution/public/explore/links.ts
+++ b/x-pack/plugins/security_solution/public/explore/links.ts
@@ -180,7 +180,7 @@ export const exploreLinks: LinkItem = {
id: SecurityPageName.exploreLanding,
title: EXPLORE,
path: EXPLORE_PATH,
- globalNavPosition: 6,
+ globalNavPosition: 7,
capabilities: [`${SERVER_APP_ID}.show`],
globalSearchKeywords: [
i18n.translate('xpack.securitySolution.appLinks.explore', {
diff --git a/x-pack/plugins/security_solution/public/management/links.ts b/x-pack/plugins/security_solution/public/management/links.ts
index 72884ca71dd7a..309e9a093979b 100644
--- a/x-pack/plugins/security_solution/public/management/links.ts
+++ b/x-pack/plugins/security_solution/public/management/links.ts
@@ -86,7 +86,7 @@ export const links: LinkItem = {
path: MANAGE_PATH,
skipUrlState: true,
hideTimeline: true,
- globalNavPosition: 8,
+ globalNavPosition: 9,
capabilities: [`${SERVER_APP_ID}.show`],
globalSearchKeywords: [
i18n.translate('xpack.securitySolution.appLinks.manage', {
diff --git a/x-pack/plugins/security_solution/public/rules/links.ts b/x-pack/plugins/security_solution/public/rules/links.ts
index fd32b2804e370..4e6482ab67bbd 100644
--- a/x-pack/plugins/security_solution/public/rules/links.ts
+++ b/x-pack/plugins/security_solution/public/rules/links.ts
@@ -27,6 +27,7 @@ export const links: LinkItem = {
path: RULES_LANDING_PATH,
hideTimeline: true,
skipUrlState: true,
+ globalNavPosition: 8,
capabilities: [`${SERVER_APP_ID}.show`],
links: [
{
diff --git a/x-pack/plugins/security_solution/public/threat_intelligence/links.ts b/x-pack/plugins/security_solution/public/threat_intelligence/links.ts
index 8b2b8554e36ce..87d49e5f459a3 100644
--- a/x-pack/plugins/security_solution/public/threat_intelligence/links.ts
+++ b/x-pack/plugins/security_solution/public/threat_intelligence/links.ts
@@ -17,6 +17,6 @@ import type { LinkItem } from '../common/links';
*/
export const indicatorsLinks: LinkItem = {
...getSecuritySolutionLink('indicators'),
- globalNavPosition: 7,
+ globalNavPosition: 6,
capabilities: [`${SERVER_APP_ID}.threat-intelligence`],
};
diff --git a/x-pack/plugins/security_solution/public/timelines/links.ts b/x-pack/plugins/security_solution/public/timelines/links.ts
index e50e151e0c662..bd3b48164d097 100644
--- a/x-pack/plugins/security_solution/public/timelines/links.ts
+++ b/x-pack/plugins/security_solution/public/timelines/links.ts
@@ -14,7 +14,7 @@ export const links: LinkItem = {
id: SecurityPageName.timelines,
title: TIMELINES,
path: TIMELINES_PATH,
- globalNavPosition: 4,
+ globalNavPosition: 5,
capabilities: [`${SERVER_APP_ID}.show`],
globalSearchKeywords: [
i18n.translate('xpack.securitySolution.appLinks.timelines', {
From 90c1a4a95cdc4cbdd8b7ce7cbc30d0ed50a7192d Mon Sep 17 00:00:00 2001
From: Elastic Machine
Date: Tue, 22 Aug 2023 18:41:13 +0930
Subject: [PATCH 05/26] [main] Sync bundled packages with Package Storage
(#163852)
Automated by
https://internal-ci.elastic.co/job/package_storage/job/sync-bundled-packages-job/job/main/6309/
Co-authored-by: apmmachine
Co-authored-by: Julia Bardi <90178898+juliaElastic@users.noreply.github.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
fleet_packages.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fleet_packages.json b/fleet_packages.json
index f93c40d039e6a..0999f88041d11 100644
--- a/fleet_packages.json
+++ b/fleet_packages.json
@@ -34,7 +34,7 @@
},
{
"name": "endpoint",
- "version": "8.9.1"
+ "version": "8.10.0"
},
{
"name": "fleet_server",
From 7df1cee163e90952440752d4f038d17f9ae4ffc7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?=
Date: Tue, 22 Aug 2023 11:19:09 +0200
Subject: [PATCH 06/26] [APM] Add data access plugin (#162367)
Closes https://github.com/elastic/kibana/issues/161906
Related to:
https://github.com/elastic/observability-dev/discussions/2787
(_internal_)
This add a new plugin `apm_data_access` that contains the APM query
targets (indices to query for APM data).
This plugin can be consumed by apm and any other plugin, making it
possible for other plugins to know about the configured APM query
targets.
## Example:
APM query targets can be specified in kibana[.dev].yml using
`xpack.apm.indices.{dataset}: some-index-*` for instances:
```yml
xpack.apm.indices.transaction: apm-*
```
See all config options on:
https://www.elastic.co/guide/en/kibana/current/apm-settings-kb.html#general-apm-settings-kb
Query targets can also be specified via the UI (and persisted in a saved
object) via the settings page: `/app/apm/settings/apm-indices`
**Retrieving the query targets**
Query targets can be retrieved from other plugins via `getApmIndices`:
```ts
const apmIndices = await plugins.apmDataAccess.setup.getApmIndices(savedObjects.client);
```
TODO:
- [x] Add SO client and fetch space aware index config (see
https://github.com/sqren/kibana/blob/4d7f626da020c156500f8bf52bf8861cde54b4f1/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts#L32-L44)
- [ ] Add simple APM client for querying apm data
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
---
.github/CODEOWNERS | 1 +
docs/developer/plugin-list.asciidoc | 4 +
package.json | 1 +
tsconfig.base.json | 2 +
x-pack/.i18nrc.json | 1 +
.../apm/common/apm_saved_object_constants.ts | 7 --
x-pack/plugins/apm/kibana.jsonc | 1 +
.../diagnostics_bundle/diagnostics_bundle.ts | 4 +-
.../server/deprecations/deprecations.test.ts | 2 +-
.../plugins/apm/server/deprecations/index.ts | 2 +-
x-pack/plugins/apm/server/feature.ts | 2 +-
x-pack/plugins/apm/server/index.ts | 32 ------
.../create_anomaly_detection_jobs.ts | 4 +-
.../collect_data_telemetry/tasks.test.ts | 4 +-
.../collect_data_telemetry/tasks.ts | 8 +-
.../apm/server/lib/apm_telemetry/index.ts | 22 ++--
.../get_request_base.test.ts | 4 +-
.../get_request_base.ts | 6 +-
.../create_apm_event_client/index.ts | 6 +-
.../create_infra_metrics_client.ts | 2 +-
.../create_internal_es_client/index.ts | 22 ++--
.../lib/helpers/get_apm_alerts_client.ts | 2 +-
.../lib/helpers/get_apm_event_client.ts | 9 +-
.../lib/helpers/get_infra_metric_indices.ts | 2 +-
.../get_internal_saved_objects_client.ts | 4 -
.../apm/server/lib/helpers/get_ml_client.ts | 2 +-
.../lib/helpers/get_random_sampler/index.ts | 2 +-
x-pack/plugins/apm/server/plugin.ts | 81 +++-----------
.../routes/alerts/register_apm_rule_types.ts | 11 +-
.../get_service_group_fields_for_anomaly.ts | 19 +---
.../anomaly/register_anomaly_rule_type.ts | 6 +-
.../register_error_count_rule_type.ts | 11 +-
...register_transaction_duration_rule_type.ts | 14 +--
...gister_transaction_error_rate_rule_type.ts | 14 +--
.../server/routes/alerts/test_utils/index.ts | 17 ++-
.../apm_routes/create_apm_server_route.ts | 3 +-
.../register_apm_server_routes.test.ts | 24 +++-
.../apm_routes/register_apm_server_routes.ts | 46 +++++++-
.../data_view/create_static_data_view.test.ts | 7 +-
.../data_view/create_static_data_view.ts | 3 +-
.../data_view/get_apm_data_view_title.test.ts | 6 +-
.../data_view/get_apm_data_view_title.ts | 12 +-
.../apm/server/routes/data_view/route.ts | 12 +-
.../diagnostics/bundle/get_apm_events.ts | 4 +-
.../diagnostics/bundle/get_data_streams.ts | 4 +-
.../diagnostics/bundle/get_field_caps.ts | 4 +-
.../get_index_templates_by_index_pattern.ts | 4 +-
.../routes/diagnostics/bundle/get_indices.ts | 4 +-
.../diagnostics/bundle/get_indices_states.ts | 4 +-
.../bundle/get_non_data_stream_indices.ts | 4 +-
.../diagnostics/get_diagnostics_bundle.ts | 4 +-
.../diagnostics/get_fleet_package_info.ts | 2 +-
.../helpers/get_diagnostic_privileges.ts | 4 +-
.../apm/server/routes/diagnostics/route.ts | 55 ++++++++--
.../fleet/api_keys/create_apm_api_keys.ts | 2 +-
.../fleet/register_fleet_policy_callbacks.ts | 33 ++++--
.../plugins/apm/server/routes/fleet/route.ts | 4 +-
.../routes/fleet/run_migration_check.ts | 2 +-
.../routes/observability_overview/has_data.ts | 4 +-
.../create_agent_config_index.ts | 2 +-
.../create_or_update_configuration.ts | 2 +-
.../delete_configuration.ts | 2 +-
.../find_exact_configuration.ts | 2 +-
.../get_existing_environments_for_service.ts | 2 +-
.../list_configurations.ts | 2 +-
.../mark_applied_by_agent.ts | 2 +-
.../settings/agent_configuration/route.ts | 47 ++++----
.../search_configurations.ts | 2 +-
.../settings/anomaly_detection/route.ts | 19 +---
.../anomaly_detection/update_to_v3.ts | 4 +-
.../apm_indices/apm_system_index_constants.ts | 10 ++
.../settings/apm_indices/get_apm_indices.ts | 103 +++---------------
.../routes/settings/apm_indices/route.ts | 24 ++--
.../settings/apm_indices/save_apm_indices.ts | 14 +--
.../custom_link/create_custom_link_index.ts | 2 +-
.../create_or_update_custom_link.ts | 2 +-
.../custom_link/delete_custom_link.ts | 2 +-
.../settings/custom_link/list_custom_links.ts | 2 +-
.../routes/settings/custom_link/route.ts | 20 ++--
.../bulk_create_apm_source_maps.ts | 2 +-
.../source_maps/create_apm_source_map.ts | 2 +-
.../create_apm_source_map_index_template.ts | 2 +-
.../source_maps/delete_apm_sourcemap.ts | 2 +-
.../schedule_source_map_migration.ts | 2 +-
.../is_cross_cluster_search.test.ts | 16 +--
x-pack/plugins/apm/server/routes/typings.ts | 32 ------
.../plugins/apm/server/saved_objects/index.ts | 1 -
.../apm/server/tutorial/envs/elastic_cloud.ts | 9 +-
.../apm/server/tutorial/envs/on_prem.ts | 17 +--
.../on_prem_apm_server_instruction_set.ts | 8 +-
x-pack/plugins/apm/server/tutorial/index.ts | 8 +-
x-pack/plugins/apm/server/types.ts | 17 ++-
.../plugins/apm/server/utils/test_helpers.tsx | 9 +-
x-pack/plugins/apm/tsconfig.json | 4 +-
.../plugins/apm_data_access/common/index.ts | 9 ++
x-pack/plugins/apm_data_access/jest.config.js | 14 +++
x-pack/plugins/apm_data_access/kibana.jsonc | 14 +++
.../plugins/apm_data_access/server/index.ts | 80 ++++++++++++++
.../plugins/apm_data_access/server/plugin.ts | 59 ++++++++++
.../server/saved_objects/apm_indices.ts | 30 ++++-
..._legacy_apm_indices_to_space_aware.test.ts | 2 +-
...grate_legacy_apm_indices_to_space_aware.ts | 31 +++---
.../migrations/update_apm_oss_index_paths.ts | 4 +-
.../plugins/apm_data_access/server/types.ts | 16 +++
x-pack/plugins/apm_data_access/tsconfig.json | 14 +++
.../translations/translations/fr-FR.json | 1 -
.../translations/translations/ja-JP.json | 1 -
.../translations/translations/zh-CN.json | 1 -
.../tests/fleet/apm_package_policy.spec.ts | 4 +-
.../settings/apm_indices/apm_indices.spec.ts | 74 +++++++++++++
x-pack/test/tsconfig.json | 1 +
yarn.lock | 4 +
112 files changed, 755 insertions(+), 582 deletions(-)
create mode 100644 x-pack/plugins/apm/server/routes/settings/apm_indices/apm_system_index_constants.ts
create mode 100644 x-pack/plugins/apm_data_access/common/index.ts
create mode 100644 x-pack/plugins/apm_data_access/jest.config.js
create mode 100644 x-pack/plugins/apm_data_access/kibana.jsonc
create mode 100644 x-pack/plugins/apm_data_access/server/index.ts
create mode 100644 x-pack/plugins/apm_data_access/server/plugin.ts
rename x-pack/plugins/{apm => apm_data_access}/server/saved_objects/apm_indices.ts (66%)
rename x-pack/plugins/{apm => apm_data_access}/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts (99%)
rename x-pack/plugins/{apm => apm_data_access}/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts (78%)
rename x-pack/plugins/{apm => apm_data_access}/server/saved_objects/migrations/update_apm_oss_index_paths.ts (91%)
create mode 100644 x-pack/plugins/apm_data_access/server/types.ts
create mode 100644 x-pack/plugins/apm_data_access/tsconfig.json
create mode 100644 x-pack/test/apm_api_integration/tests/settings/apm_indices/apm_indices.spec.ts
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 2add1ca0d24c5..650c71e26c93b 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -36,6 +36,7 @@ packages/analytics/shippers/elastic_v3/server @elastic/kibana-core
packages/analytics/shippers/fullstory @elastic/kibana-core
packages/analytics/shippers/gainsight @elastic/kibana-core
packages/kbn-apm-config-loader @elastic/kibana-core @vigneshshanmugam
+x-pack/plugins/apm_data_access @elastic/apm-ui
x-pack/plugins/apm @elastic/apm-ui
packages/kbn-apm-synthtrace @elastic/apm-ui
packages/kbn-apm-synthtrace-client @elastic/apm-ui
diff --git a/docs/developer/plugin-list.asciidoc b/docs/developer/plugin-list.asciidoc
index 57e5ed40571ea..e8c008af6e0e8 100644
--- a/docs/developer/plugin-list.asciidoc
+++ b/docs/developer/plugin-list.asciidoc
@@ -434,6 +434,10 @@ The plugin exposes the static DefaultEditorController class to consume.
|This plugin provides access to App Monitoring features provided by Elastic. It allows you to monitor your software services and applications in real-time; visualize detailed performance information on your services, identify and analyze errors, and monitor host-level and APM agent-specific metrics like JVM and Go runtime metrics.
+|{kib-repo}blob/{branch}/x-pack/plugins/apm_data_access[apmDataAccess]
+|WARNING: Missing README.
+
+
|{kib-repo}blob/{branch}/x-pack/plugins/asset_manager/README.md[assetManager]
|This plugin provides access to the asset data stored in assets-* indices, primarily
for inventory and topology purposes.
diff --git a/package.json b/package.json
index ba07ef6fe5c17..e4bb9e23dbd49 100644
--- a/package.json
+++ b/package.json
@@ -152,6 +152,7 @@
"@kbn/analytics-shippers-fullstory": "link:packages/analytics/shippers/fullstory",
"@kbn/analytics-shippers-gainsight": "link:packages/analytics/shippers/gainsight",
"@kbn/apm-config-loader": "link:packages/kbn-apm-config-loader",
+ "@kbn/apm-data-access-plugin": "link:x-pack/plugins/apm_data_access",
"@kbn/apm-plugin": "link:x-pack/plugins/apm",
"@kbn/apm-utils": "link:packages/kbn-apm-utils",
"@kbn/app-link-test-plugin": "link:test/plugin_functional/plugins/app_link_test",
diff --git a/tsconfig.base.json b/tsconfig.base.json
index dd6a27a32dfa9..d13cc53e6f546 100644
--- a/tsconfig.base.json
+++ b/tsconfig.base.json
@@ -66,6 +66,8 @@
"@kbn/analytics-shippers-gainsight/*": ["packages/analytics/shippers/gainsight/*"],
"@kbn/apm-config-loader": ["packages/kbn-apm-config-loader"],
"@kbn/apm-config-loader/*": ["packages/kbn-apm-config-loader/*"],
+ "@kbn/apm-data-access-plugin": ["x-pack/plugins/apm_data_access"],
+ "@kbn/apm-data-access-plugin/*": ["x-pack/plugins/apm_data_access/*"],
"@kbn/apm-plugin": ["x-pack/plugins/apm"],
"@kbn/apm-plugin/*": ["x-pack/plugins/apm/*"],
"@kbn/apm-synthtrace": ["packages/kbn-apm-synthtrace"],
diff --git a/x-pack/.i18nrc.json b/x-pack/.i18nrc.json
index bda54b23a7f9a..3fa5a2da7c0ff 100644
--- a/x-pack/.i18nrc.json
+++ b/x-pack/.i18nrc.json
@@ -8,6 +8,7 @@
"xpack.stackAlerts": "plugins/stack_alerts",
"xpack.stackConnectors": "plugins/stack_connectors",
"xpack.apm": "plugins/apm",
+ "xpack.apmDataAccess": "plugins/apm_data_access",
"xpack.banners": "plugins/banners",
"xpack.canvas": "plugins/canvas",
"xpack.cases": "plugins/cases",
diff --git a/x-pack/plugins/apm/common/apm_saved_object_constants.ts b/x-pack/plugins/apm/common/apm_saved_object_constants.ts
index 17c5a802a440a..42ee9fb505adb 100644
--- a/x-pack/plugins/apm/common/apm_saved_object_constants.ts
+++ b/x-pack/plugins/apm/common/apm_saved_object_constants.ts
@@ -5,13 +5,6 @@
* 2.0.
*/
-// the types have to match the names of the saved object mappings
-// in /x-pack/plugins/apm/mappings.json
-
-// APM index settings
-export const APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE = 'apm-indices';
-export const APM_INDEX_SETTINGS_SAVED_OBJECT_ID = 'apm-indices';
-
// APM telemetry
export const APM_TELEMETRY_SAVED_OBJECT_TYPE = 'apm-telemetry';
export const APM_TELEMETRY_SAVED_OBJECT_ID = 'apm-telemetry';
diff --git a/x-pack/plugins/apm/kibana.jsonc b/x-pack/plugins/apm/kibana.jsonc
index 7c6b3266940a4..ed7f8fca0a241 100644
--- a/x-pack/plugins/apm/kibana.jsonc
+++ b/x-pack/plugins/apm/kibana.jsonc
@@ -9,6 +9,7 @@
"browser": true,
"configPath": ["xpack", "apm"],
"requiredPlugins": [
+ "apmDataAccess",
"data",
"dashboard",
"controls",
diff --git a/x-pack/plugins/apm/scripts/diagnostics_bundle/diagnostics_bundle.ts b/x-pack/plugins/apm/scripts/diagnostics_bundle/diagnostics_bundle.ts
index 92fe9f08e260b..a620d3e0be017 100644
--- a/x-pack/plugins/apm/scripts/diagnostics_bundle/diagnostics_bundle.ts
+++ b/x-pack/plugins/apm/scripts/diagnostics_bundle/diagnostics_bundle.ts
@@ -10,9 +10,9 @@
import { Client } from '@elastic/elasticsearch';
import fs from 'fs/promises';
import axios, { AxiosInstance } from 'axios';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { APIReturnType } from '../../public/services/rest/create_call_apm_api';
import { getDiagnosticsBundle } from '../../server/routes/diagnostics/get_diagnostics_bundle';
-import { ApmIndicesConfig } from '../../server/routes/settings/apm_indices/get_apm_indices';
type DiagnosticsBundle = APIReturnType<'GET /internal/apm/diagnostics'>;
@@ -100,7 +100,7 @@ async function getApmIndices(kibanaClient: AxiosInstance) {
savedValue ?? defaultValue,
]
)
- ) as ApmIndicesConfig;
+ ) as APMIndices;
}
async function getFleetPackageInfo(kibanaClient: AxiosInstance) {
diff --git a/x-pack/plugins/apm/server/deprecations/deprecations.test.ts b/x-pack/plugins/apm/server/deprecations/deprecations.test.ts
index 8496672e40f07..9252ed46aa6df 100644
--- a/x-pack/plugins/apm/server/deprecations/deprecations.test.ts
+++ b/x-pack/plugins/apm/server/deprecations/deprecations.test.ts
@@ -10,8 +10,8 @@ import { kibanaPackageJson } from '@kbn/repo-info';
import { GetDeprecationsContext } from '@kbn/core/server';
import { CloudSetup } from '@kbn/cloud-plugin/server';
import { getDeprecations } from '.';
-import { APMRouteHandlerResources } from '..';
import { AgentPolicy } from '@kbn/fleet-plugin/common';
+import { APMRouteHandlerResources } from '../routes/apm_routes/register_apm_server_routes';
const deprecationContext = {
esClient: {},
diff --git a/x-pack/plugins/apm/server/deprecations/index.ts b/x-pack/plugins/apm/server/deprecations/index.ts
index 6545e4bfeff09..6606a932eb96b 100644
--- a/x-pack/plugins/apm/server/deprecations/index.ts
+++ b/x-pack/plugins/apm/server/deprecations/index.ts
@@ -13,7 +13,7 @@ import {
getCloudAgentPolicy,
getApmPackagePolicy,
} from '../routes/fleet/get_cloud_apm_package_policy';
-import { APMRouteHandlerResources } from '..';
+import { APMRouteHandlerResources } from '../routes/apm_routes/register_apm_server_routes';
export function getDeprecations({
cloudSetup,
diff --git a/x-pack/plugins/apm/server/feature.ts b/x-pack/plugins/apm/server/feature.ts
index 09681f01da2d6..490c75c658ad9 100644
--- a/x-pack/plugins/apm/server/feature.ts
+++ b/x-pack/plugins/apm/server/feature.ts
@@ -12,11 +12,11 @@ import {
LicensingPluginSetup,
LicensingApiRequestHandlerContext,
} from '@kbn/licensing-plugin/server';
+import { APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE } from '@kbn/apm-data-access-plugin/server/saved_objects/apm_indices';
import {
ApmRuleType,
APM_SERVER_FEATURE_ID,
} from '../common/rules/apm_rule_types';
-import { APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE } from '../common/apm_saved_object_constants';
export const APM_FEATURE = {
id: APM_SERVER_FEATURE_ID,
diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts
index f79c83683a36b..decff8d362dfe 100644
--- a/x-pack/plugins/apm/server/index.ts
+++ b/x-pack/plugins/apm/server/index.ts
@@ -56,13 +56,6 @@ const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: false }),
}),
}),
- indices: schema.object({
- transaction: schema.string({ defaultValue: 'traces-apm*,apm-*' }),
- span: schema.string({ defaultValue: 'traces-apm*,apm-*' }),
- error: schema.string({ defaultValue: 'logs-apm*,apm-*' }),
- metric: schema.string({ defaultValue: 'metrics-apm*,apm-*' }),
- onboarding: schema.string({ defaultValue: 'apm-*' }),
- }),
forceSyntheticSource: schema.boolean({ defaultValue: false }),
latestAgentVersionsUrl: schema.string({
defaultValue: 'https://apm-agent-versions.elastic.co/versions.json',
@@ -109,35 +102,12 @@ export const config: PluginConfigDescriptor = {
deprecateFromRoot,
unusedFromRoot,
}) => [
- unused('indices.sourcemap', { level: 'warning' }),
unused('ui.transactionGroupBucketSize', {
level: 'warning',
}),
rename('autocreateApmIndexPattern', 'autoCreateApmDataView', {
level: 'warning',
}),
- renameFromRoot(
- 'apm_oss.transactionIndices',
- 'xpack.apm.indices.transaction',
- { level: 'warning' }
- ),
- renameFromRoot('apm_oss.spanIndices', 'xpack.apm.indices.span', {
- level: 'warning',
- }),
- renameFromRoot('apm_oss.errorIndices', 'xpack.apm.indices.error', {
- level: 'warning',
- }),
- renameFromRoot('apm_oss.metricsIndices', 'xpack.apm.indices.metric', {
- level: 'warning',
- }),
- renameFromRoot('apm_oss.sourcemapIndices', 'xpack.apm.indices.sourcemap', {
- level: 'warning',
- }),
- renameFromRoot(
- 'apm_oss.onboardingIndices',
- 'xpack.apm.indices.onboarding',
- { level: 'warning' }
- ),
deprecateFromRoot('apm_oss.enabled', '8.0.0', { level: 'warning' }),
unusedFromRoot('apm_oss.fleetMode', { level: 'warning' }),
unusedFromRoot('apm_oss.indexPattern', { level: 'warning' }),
@@ -165,7 +135,6 @@ export const config: PluginConfigDescriptor = {
};
export type APMConfig = TypeOf;
-export type ApmIndicesConfigName = keyof APMConfig['indices'];
export const plugin = (initContext: PluginInitializerContext) =>
new APMPlugin(initContext);
@@ -177,4 +146,3 @@ export type {
APMServerRouteRepository,
APIEndpoint,
} from './routes/apm_routes/get_global_apm_server_route_repository';
-export type { APMRouteHandlerResources } from './routes/typings';
diff --git a/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts b/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts
index 636c7b2fde323..e90776a4ee666 100644
--- a/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts
+++ b/x-pack/plugins/apm/server/lib/anomaly_detection/create_anomaly_detection_jobs.ts
@@ -12,6 +12,7 @@ import moment from 'moment';
import { v4 as uuidv4 } from 'uuid';
import { ProcessorEvent } from '@kbn/observability-plugin/common';
import { waitForIndexStatus } from '@kbn/core-saved-objects-migration-server-internal';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { ML_ERRORS } from '../../../common/anomaly_detection';
import { METRICSET_NAME, PROCESSOR_EVENT } from '../../../common/es_fields/apm';
import { Environment } from '../../../common/environment_rt';
@@ -20,7 +21,6 @@ import { withApmSpan } from '../../utils/with_apm_span';
import { MlClient } from '../helpers/get_ml_client';
import { APM_ML_JOB_GROUP, ML_MODULE_ID_APM_TRANSACTION } from './constants';
import { getAnomalyDetectionJobs } from './get_anomaly_detection_jobs';
-import { ApmIndicesConfig } from '../../routes/settings/apm_indices/get_apm_indices';
const DEFAULT_TIMEOUT = '60s';
@@ -33,7 +33,7 @@ export async function createAnomalyDetectionJobs({
}: {
mlClient?: MlClient;
esClient: ElasticsearchClient;
- indices: ApmIndicesConfig;
+ indices: APMIndices;
environments: Environment[];
logger: Logger;
}) {
diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts
index d48ab312a5674..fb061eec49baf 100644
--- a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts
+++ b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.test.ts
@@ -6,7 +6,7 @@
*/
import { savedObjectsClientMock } from '@kbn/core-saved-objects-api-server-mocks';
-import { ApmIndicesConfig } from '../../../routes/settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { tasks } from './tasks';
import {
SERVICE_NAME,
@@ -19,7 +19,7 @@ describe('data telemetry collection tasks', () => {
metric: 'apm-8.0.0-metric',
span: 'apm-8.0.0-span',
transaction: 'apm-8.0.0-transaction',
- } as ApmIndicesConfig;
+ } as APMIndices;
describe('environments', () => {
const task = tasks.find((t) => t.name === 'environments');
diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts
index a43c67eb6c66d..beb84481e84b7 100644
--- a/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts
+++ b/x-pack/plugins/apm/server/lib/apm_telemetry/collect_data_telemetry/tasks.ts
@@ -10,6 +10,7 @@ import { ProcessorEvent } from '@kbn/observability-plugin/common';
import { createHash } from 'crypto';
import { flatten, merge, pickBy, sortBy, sum, uniq } from 'lodash';
import { SavedObjectsClient } from '@kbn/core/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { AGENT_NAMES, RUM_AGENT_NAMES } from '../../../../common/agent_name';
import {
AGENT_ACTIVATION_METHOD,
@@ -56,10 +57,7 @@ import { AgentName } from '../../../../typings/es_schemas/ui/fields/agent';
import { Span } from '../../../../typings/es_schemas/ui/span';
import { Transaction } from '../../../../typings/es_schemas/ui/transaction';
import { APMTelemetry, APMPerService, APMDataTelemetry } from '../types';
-import {
- ApmIndicesConfig,
- APM_AGENT_CONFIGURATION_INDEX,
-} from '../../../routes/settings/apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../../../routes/settings/apm_indices/apm_system_index_constants';
import { TelemetryClient } from '../telemetry_client';
type ISavedObjectsClient = Pick;
@@ -76,7 +74,7 @@ interface TelemetryTask {
export interface TelemetryTaskExecutorParams {
telemetryClient: TelemetryClient;
- indices: ApmIndicesConfig;
+ indices: APMIndices;
savedObjectsClient: ISavedObjectsClient;
}
diff --git a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts
index d9b8fb3f01c83..3c990dd85e23c 100644
--- a/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts
+++ b/x-pack/plugins/apm/server/lib/apm_telemetry/index.ts
@@ -6,12 +6,17 @@
*/
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
-import { CoreSetup, Logger, SavedObjectsErrorHelpers } from '@kbn/core/server';
+import {
+ CoreSetup,
+ Logger,
+ SavedObjectsClientContract,
+ SavedObjectsErrorHelpers,
+} from '@kbn/core/server';
import {
TaskManagerSetupContract,
TaskManagerStartContract,
} from '@kbn/task-manager-plugin/server';
-import { APMConfig } from '../..';
+import { APMDataAccessConfig } from '@kbn/apm-data-access-plugin/server';
import {
APM_TELEMETRY_SAVED_OBJECT_ID,
APM_TELEMETRY_SAVED_OBJECT_TYPE,
@@ -20,14 +25,13 @@ import { getInternalSavedObjectsClient } from '../helpers/get_internal_saved_obj
import { collectDataTelemetry } from './collect_data_telemetry';
import { APMUsage } from './types';
import { apmSchema } from './schema';
-import { getApmIndices } from '../../routes/settings/apm_indices/get_apm_indices';
import { getTelemetryClient } from './telemetry_client';
export const APM_TELEMETRY_TASK_NAME = 'apm-telemetry-task';
export async function createApmTelemetry({
core,
- config,
+ getApmIndices,
usageCollector,
taskManager,
logger,
@@ -35,7 +39,9 @@ export async function createApmTelemetry({
isProd,
}: {
core: CoreSetup;
- config: APMConfig;
+ getApmIndices: (
+ soClient: SavedObjectsClientContract
+ ) => Promise;
usageCollector: UsageCollectionSetup;
taskManager: TaskManagerSetupContract;
logger: Logger;
@@ -56,14 +62,14 @@ export async function createApmTelemetry({
},
});
+ const telemetryClient = await getTelemetryClient({ core });
const [coreStart] = await core.getStartServices();
const savedObjectsClient = await getInternalSavedObjectsClient(coreStart);
- const indices = await getApmIndices({ config, savedObjectsClient });
- const telemetryClient = await getTelemetryClient({ core });
+ const apmIndices = await getApmIndices(savedObjectsClient);
const collectAndStore = async () => {
const dataTelemetry = await collectDataTelemetry({
- indices,
+ indices: apmIndices,
telemetryClient,
logger,
savedObjectsClient,
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.test.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.test.ts
index 58be670cbb30c..253a0993d1a8c 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.test.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.test.ts
@@ -6,7 +6,7 @@
*/
import { APMEventESSearchRequest } from '.';
-import { ApmIndicesConfig } from '../../../../routes/settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { getRequestBase } from './get_request_base';
describe('getRequestBase', () => {
@@ -26,7 +26,7 @@ describe('getRequestBase', () => {
error: 'my-apm-*-error-*',
span: 'my-apm-*-span-*',
onboarding: 'my-apm-*-onboarding-*',
- } as ApmIndicesConfig;
+ } as APMIndices;
res = getRequestBase({ ...request, indices });
});
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts
index 16e8b0edba21a..1c2c3ad296101 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/get_request_base.ts
@@ -6,12 +6,12 @@
*/
import type { ESFilter } from '@kbn/es-types';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { ProcessorEvent } from '@kbn/observability-plugin/common';
import { uniq } from 'lodash';
import { ApmDataSource } from '../../../../../common/data_source';
import {} from '../../../../../common/document_type';
import { PROCESSOR_EVENT } from '../../../../../common/es_fields/apm';
-import { ApmIndicesConfig } from '../../../../routes/settings/apm_indices/get_apm_indices';
import {
getConfigForDocumentType,
getProcessorEventForDocumentType,
@@ -26,7 +26,7 @@ const processorEventIndexMap = {
export function processorEventsToIndex(
events: ProcessorEvent[],
- indices: ApmIndicesConfig
+ indices: APMIndices
) {
return uniq(
events.flatMap((event) =>
@@ -37,7 +37,7 @@ export function processorEventsToIndex(
export function getRequestBase(options: {
apm: { events: ProcessorEvent[] } | { sources: ApmDataSource[] };
- indices: ApmIndicesConfig;
+ indices: APMIndices;
}) {
const events =
'events' in options.apm
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts
index b40918cbf750e..a9a5e02b9eae1 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_apm_event_client/index.ts
@@ -20,12 +20,12 @@ import { ProcessorEvent } from '@kbn/observability-plugin/common';
import { unwrapEsResponse } from '@kbn/observability-plugin/server';
import { compact, omit } from 'lodash';
import { ValuesType } from 'utility-types';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { ApmDataSource } from '../../../../../common/data_source';
import { APMError } from '../../../../../typings/es_schemas/ui/apm_error';
import { Metric } from '../../../../../typings/es_schemas/ui/metric';
import { Span } from '../../../../../typings/es_schemas/ui/span';
import { Transaction } from '../../../../../typings/es_schemas/ui/transaction';
-import { ApmIndicesConfig } from '../../../../routes/settings/apm_indices/get_apm_indices';
import { withApmSpan } from '../../../../utils/with_apm_span';
import {
callAsyncWithDebug,
@@ -87,7 +87,7 @@ export interface APMEventClientConfig {
esClient: ElasticsearchClient;
debug: boolean;
request: KibanaRequest;
- indices: ApmIndicesConfig;
+ indices: APMIndices;
options: {
includeFrozen: boolean;
forceSyntheticSource: boolean;
@@ -98,7 +98,7 @@ export class APMEventClient {
private readonly esClient: ElasticsearchClient;
private readonly debug: boolean;
private readonly request: KibanaRequest;
- public readonly indices: ApmIndicesConfig;
+ public readonly indices: APMIndices;
private readonly includeFrozen: boolean;
private readonly forceSyntheticSource: boolean;
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts
index 5cc9f8bb427cf..0128d6aa92d21 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_infra_metrics_client/create_infra_metrics_client.ts
@@ -6,7 +6,7 @@
*/
import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types';
-import { APMRouteHandlerResources } from '../../../../routes/typings';
+import { APMRouteHandlerResources } from '../../../../routes/apm_routes/register_apm_server_routes';
import { getInfraMetricIndices } from '../../get_infra_metric_indices';
type InfraMetricsSearchParams = Omit & {
diff --git a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts
index d1cd9054fbac1..e205a07129d3d 100644
--- a/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/create_es_client/create_internal_es_client/index.ts
@@ -8,17 +8,15 @@
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { unwrapEsResponse } from '@kbn/observability-plugin/server';
import type { ESSearchResponse, ESSearchRequest } from '@kbn/es-types';
-import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { APMConfig } from '../../../..';
-import { APMRouteHandlerResources } from '../../../../routes/typings';
+import { APMRouteHandlerResources } from '../../../../routes/apm_routes/register_apm_server_routes';
import {
callAsyncWithDebug,
getDebugBody,
getDebugTitle,
} from '../call_async_with_debug';
import { cancelEsRequestOnAbort } from '../cancel_es_request_on_abort';
-import { getApmIndices } from '../../../../routes/settings/apm_indices/get_apm_indices';
export type APMIndexDocumentParams = estypes.IndexRequest;
@@ -28,39 +26,35 @@ export type APMInternalESClient = Awaited<
export async function createInternalESClientWithContext({
debug,
- config,
+ apmIndices,
request,
context,
}: {
debug: boolean;
- config: APMConfig;
+ apmIndices: APMIndices;
request: APMRouteHandlerResources['request'];
context: APMRouteHandlerResources['context'];
}) {
const coreContext = await context.core;
const { asInternalUser } = coreContext.elasticsearch.client;
- const savedObjectsClient = coreContext.savedObjects.client;
return createInternalESClient({
debug,
- config,
+ apmIndices,
request,
- savedObjectsClient,
elasticsearchClient: asInternalUser,
});
}
export async function createInternalESClient({
debug,
- config,
+ apmIndices,
request,
- savedObjectsClient,
elasticsearchClient,
}: {
debug: boolean;
- config: APMConfig;
+ apmIndices: APMIndices;
request?: APMRouteHandlerResources['request'];
- savedObjectsClient: SavedObjectsClientContract;
elasticsearchClient: ElasticsearchClient;
}) {
function callEs(
@@ -98,7 +92,7 @@ export async function createInternalESClient({
}
return {
- apmIndices: await getApmIndices({ savedObjectsClient, config }),
+ apmIndices,
search: async <
TDocument = unknown,
TSearchRequest extends ESSearchRequest = ESSearchRequest
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_apm_alerts_client.ts b/x-pack/plugins/apm/server/lib/helpers/get_apm_alerts_client.ts
index 5be010b613383..1a63067aa7ea2 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_apm_alerts_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_apm_alerts_client.ts
@@ -8,7 +8,7 @@
import { isEmpty } from 'lodash';
import { ESSearchRequest, InferSearchResponseOf } from '@kbn/es-types';
import { ParsedTechnicalFields } from '@kbn/rule-registry-plugin/common';
-import { APMRouteHandlerResources } from '../../routes/typings';
+import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes';
export type ApmAlertsClient = Awaited>;
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts b/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts
index 7ed4902fa0615..e7425a01c4bd1 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_apm_event_client.ts
@@ -6,24 +6,21 @@
*/
import { UI_SETTINGS } from '@kbn/data-plugin/common';
-import { APMRouteHandlerResources } from '../../routes/typings';
-import { getApmIndices } from '../../routes/settings/apm_indices/get_apm_indices';
import { APMEventClient } from './create_es_client/create_apm_event_client';
import { withApmSpan } from '../../utils/with_apm_span';
+import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes';
export async function getApmEventClient({
context,
params,
config,
+ getApmIndices,
request,
}: APMRouteHandlerResources): Promise {
return withApmSpan('get_apm_event_client', async () => {
const coreContext = await context.core;
const [indices, includeFrozen] = await Promise.all([
- getApmIndices({
- savedObjectsClient: coreContext.savedObjects.client,
- config,
- }),
+ getApmIndices(),
withApmSpan('get_ui_settings', () =>
coreContext.uiSettings.client.get(
UI_SETTINGS.SEARCH_INCLUDE_FROZEN
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts b/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts
index aa978b1643a86..aec76a75fb944 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_infra_metric_indices.ts
@@ -6,7 +6,7 @@
*/
import { SavedObjectsClientContract } from '@kbn/core/server';
-import { APMRouteHandlerResources } from '../../routes/typings';
+import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes';
export async function getInfraMetricIndices({
infraPlugin,
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_internal_saved_objects_client.ts b/x-pack/plugins/apm/server/lib/helpers/get_internal_saved_objects_client.ts
index 8d2609867d8f2..a69a705b2f374 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_internal_saved_objects_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_internal_saved_objects_client.ts
@@ -7,10 +7,6 @@
import { CoreStart } from '@kbn/core/server';
-export type InternalSavedObjectsClient = Awaited<
- ReturnType
->;
-
export async function getInternalSavedObjectsClient(coreStart: CoreStart) {
return coreStart.savedObjects.createInternalRepository();
}
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_ml_client.ts b/x-pack/plugins/apm/server/lib/helpers/get_ml_client.ts
index 37f17833ed9da..32ebc4f11f90d 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_ml_client.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_ml_client.ts
@@ -11,7 +11,7 @@ import {
MlModules,
} from '@kbn/ml-plugin/server';
import { isActivePlatinumLicense } from '../../../common/license_check';
-import { APMRouteHandlerResources } from '../../routes/typings';
+import { APMRouteHandlerResources } from '../../routes/apm_routes/register_apm_server_routes';
export interface MlClient {
mlSystem: MlMlSystem;
diff --git a/x-pack/plugins/apm/server/lib/helpers/get_random_sampler/index.ts b/x-pack/plugins/apm/server/lib/helpers/get_random_sampler/index.ts
index 5c822ca762dc9..071969cae7251 100644
--- a/x-pack/plugins/apm/server/lib/helpers/get_random_sampler/index.ts
+++ b/x-pack/plugins/apm/server/lib/helpers/get_random_sampler/index.ts
@@ -7,7 +7,7 @@
import { KibanaRequest } from '@kbn/core/server';
import seedrandom from 'seedrandom';
-import { APMRouteHandlerResources } from '../../..';
+import { APMRouteHandlerResources } from '../../../routes/apm_routes/register_apm_server_routes';
export async function getRandomSampler({
security,
diff --git a/x-pack/plugins/apm/server/plugin.ts b/x-pack/plugins/apm/server/plugin.ts
index 618c1b388bfab..79e5f353f3ce3 100644
--- a/x-pack/plugins/apm/server/plugin.ts
+++ b/x-pack/plugins/apm/server/plugin.ts
@@ -5,18 +5,15 @@
* 2.0.
*/
-import { firstValueFrom } from 'rxjs';
import {
CoreSetup,
CoreStart,
- KibanaRequest,
Logger,
Plugin,
PluginInitializerContext,
} from '@kbn/core/server';
import { isEmpty, mapValues } from 'lodash';
import { Dataset } from '@kbn/rule-registry-plugin/server';
-import { UI_SETTINGS } from '@kbn/data-plugin/common';
import { mappingFromFieldMap } from '@kbn/alerting-plugin/common';
import { alertsLocatorID } from '@kbn/observability-plugin/common';
import { APMConfig, APM_SERVER_FEATURE_ID } from '.';
@@ -28,30 +25,25 @@ import {
} from './routes/alerts/register_apm_rule_types';
import { registerFleetPolicyCallbacks } from './routes/fleet/register_fleet_policy_callbacks';
import { createApmTelemetry } from './lib/apm_telemetry';
-import { APMEventClient } from './lib/helpers/create_es_client/create_apm_event_client';
import { getInternalSavedObjectsClient } from './lib/helpers/get_internal_saved_objects_client';
import { createApmAgentConfigurationIndex } from './routes/settings/agent_configuration/create_agent_config_index';
-import { getApmIndices } from './routes/settings/apm_indices/get_apm_indices';
import { createApmCustomLinkIndex } from './routes/settings/custom_link/create_custom_link_index';
import {
- apmIndices,
apmTelemetry,
apmServerSettings,
apmServiceGroups,
} from './saved_objects';
-import type {
- ApmPluginRequestHandlerContext,
- APMRouteHandlerResources,
-} from './routes/typings';
import {
APMPluginSetup,
APMPluginSetupDependencies,
APMPluginStartDependencies,
} from './types';
-import { registerRoutes } from './routes/apm_routes/register_apm_server_routes';
+import {
+ APMRouteHandlerResources,
+ registerRoutes,
+} from './routes/apm_routes/register_apm_server_routes';
import { getGlobalApmServerRouteRepository } from './routes/apm_routes/get_global_apm_server_route_repository';
import { tutorialProvider } from './tutorial';
-import { migrateLegacyAPMIndicesToSpaceAware } from './saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware';
import { scheduleSourceMapMigration } from './routes/source_maps/schedule_source_map_migration';
import { createApmSourceMapIndexTemplate } from './routes/source_maps/create_apm_source_map_index_template';
import { addApiKeysToEveryPackagePolicyIfMissing } from './routes/fleet/api_keys/add_api_keys_to_policies_if_missing';
@@ -80,7 +72,6 @@ export class APMPlugin
this.logger = this.initContext.logger.get();
const config$ = this.initContext.config.create();
- core.savedObjects.registerType(apmIndices);
core.savedObjects.registerType(apmTelemetry);
core.savedObjects.registerType(apmServerSettings);
core.savedObjects.registerType(apmServiceGroups);
@@ -95,7 +86,7 @@ export class APMPlugin
) {
createApmTelemetry({
core,
- config: currentConfig,
+ getApmIndices: plugins.apmDataAccess.getApmIndices,
usageCollector: plugins.usageCollection,
taskManager: plugins.taskManager,
logger: this.logger,
@@ -141,13 +132,12 @@ export class APMPlugin
};
}) as APMRouteHandlerResources['plugins'];
- const boundGetApmIndices = async () => {
+ const apmIndicesPromise = (async () => {
const coreStart = await getCoreStart();
- return getApmIndices({
- savedObjectsClient: await getInternalSavedObjectsClient(coreStart),
- config: await firstValueFrom(config$),
- });
- };
+ const soClient = await getInternalSavedObjectsClient(coreStart);
+ const { getApmIndices } = plugins.apmDataAccess;
+ return getApmIndices(soClient);
+ })();
// This if else block will go away in favour of removing Home Tutorial Integration
// Ideally we will directly register a custom integration and pass the configs
@@ -158,11 +148,11 @@ export class APMPlugin
apmTutorialCustomIntegration
);
} else {
- boundGetApmIndices().then((indices) => {
+ apmIndicesPromise.then((apmIndices) => {
plugins.home?.tutorials.registerTutorial(
tutorialProvider({
apmConfig: currentConfig,
- apmIndices: indices,
+ apmIndices,
cloud: plugins.cloud,
isFleetPluginEnabled: !isEmpty(resourcePlugins.fleet),
})
@@ -190,11 +180,14 @@ export class APMPlugin
kibanaVersion: this.initContext.env.packageInfo.version,
});
+ const { getApmIndices } = plugins.apmDataAccess;
+
if (plugins.alerting) {
registerApmRuleTypes({
+ getApmIndices,
alerting: plugins.alerting,
basePath: core.http.basePath,
- config$,
+ apmConfig: currentConfig,
logger: this.logger!.get('rule'),
ml: plugins.ml,
observability: plugins.observability,
@@ -207,7 +200,6 @@ export class APMPlugin
logger: this.logger,
coreStartPromise: getCoreStart(),
plugins: resourcePlugins,
- config: currentConfig,
}).catch((e) => {
this.logger?.error('Failed to register APM Fleet policy callbacks');
this.logger?.error(e);
@@ -236,38 +228,7 @@ export class APMPlugin
this.logger?.error(e);
});
- return {
- config$,
- getApmIndices: boundGetApmIndices,
- createApmEventClient: async ({
- request,
- context,
- debug,
- }: {
- debug?: boolean;
- request: KibanaRequest;
- context: ApmPluginRequestHandlerContext;
- }) => {
- const coreContext = await context.core;
- const [indices, includeFrozen] = await Promise.all([
- boundGetApmIndices(),
- coreContext.uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN),
- ]);
-
- const esClient = coreContext.elasticsearch.client.asCurrentUser;
-
- return new APMEventClient({
- debug: debug ?? false,
- esClient,
- request,
- indices,
- options: {
- includeFrozen,
- forceSyntheticSource: currentConfig.forceSyntheticSource,
- },
- });
- },
- };
+ return { config$ };
}
public start(core: CoreStart, plugins: APMPluginStartDependencies) {
@@ -295,14 +256,6 @@ export class APMPlugin
logger.error('Failed to create apm-source-map index template');
logger.error(e);
});
-
- // TODO: remove in 9.0
- migrateLegacyAPMIndicesToSpaceAware({ coreStart: core, logger }).catch(
- (e) => {
- logger.error('Failed to run migration making APM indices space aware');
- logger.error(e);
- }
- );
}
public stop() {}
diff --git a/x-pack/plugins/apm/server/routes/alerts/register_apm_rule_types.ts b/x-pack/plugins/apm/server/routes/alerts/register_apm_rule_types.ts
index 2245ddf574885..54f4a824ee687 100644
--- a/x-pack/plugins/apm/server/routes/alerts/register_apm_rule_types.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/register_apm_rule_types.ts
@@ -7,8 +7,11 @@
import type { AlertsLocatorParams } from '@kbn/observability-plugin/common';
import { LocatorPublic } from '@kbn/share-plugin/common';
-import { Observable } from 'rxjs';
-import { IBasePath, Logger } from '@kbn/core/server';
+import {
+ IBasePath,
+ Logger,
+ SavedObjectsClientContract,
+} from '@kbn/core/server';
import {
PluginSetupContract as AlertingPluginSetupContract,
type IRuleTypeAlerts,
@@ -17,6 +20,7 @@ import { ObservabilityPluginSetup } from '@kbn/observability-plugin/server';
import { IRuleDataClient } from '@kbn/rule-registry-plugin/server';
import { MlPluginSetup } from '@kbn/ml-plugin/server';
import { legacyExperimentalFieldMap } from '@kbn/alerts-as-data-utils';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import {
AGENT_NAME,
ERROR_GROUP_ID,
@@ -91,7 +95,8 @@ export const ApmRuleTypeAlertDefinition: IRuleTypeAlerts = {
export interface RegisterRuleDependencies {
alerting: AlertingPluginSetupContract;
basePath: IBasePath;
- config$: Observable;
+ getApmIndices: (soClient: SavedObjectsClientContract) => Promise;
+ apmConfig: APMConfig;
logger: Logger;
ml?: MlPluginSetup;
observability: ObservabilityPluginSetup;
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/get_service_group_fields_for_anomaly.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/get_service_group_fields_for_anomaly.ts
index a5c4205298438..168d4456d3f2c 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/get_service_group_fields_for_anomaly.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/get_service_group_fields_for_anomaly.ts
@@ -4,11 +4,12 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-import { firstValueFrom } from 'rxjs';
+
import {
IScopedClusterClient,
SavedObjectsClientContract,
} from '@kbn/core/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import {
SERVICE_ENVIRONMENT,
SERVICE_NAME,
@@ -20,20 +21,17 @@ import {
getServiceGroupFields,
getServiceGroupFieldsAgg,
} from '../get_service_group_fields';
-import { getApmIndices } from '../../../settings/apm_indices/get_apm_indices';
-import { RegisterRuleDependencies } from '../../register_apm_rule_types';
export async function getServiceGroupFieldsForAnomaly({
- config$,
+ apmIndices,
scopedClusterClient,
- savedObjectsClient,
serviceName,
environment,
transactionType,
timestamp,
bucketSpan,
}: {
- config$: RegisterRuleDependencies['config$'];
+ apmIndices: APMIndices;
scopedClusterClient: IScopedClusterClient;
savedObjectsClient: SavedObjectsClientContract;
serviceName: string;
@@ -42,15 +40,8 @@ export async function getServiceGroupFieldsForAnomaly({
timestamp: number;
bucketSpan: number;
}) {
- const config = await firstValueFrom(config$);
- const indices = await getApmIndices({
- config,
- savedObjectsClient,
- });
- const { transaction: index } = indices;
-
const params = {
- index,
+ index: apmIndices.transaction,
body: {
size: 0,
track_total_hits: false,
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts
index 81da325350dbd..ed313b6f95dab 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/anomaly/register_anomaly_rule_type.ts
@@ -63,8 +63,8 @@ const ruleTypeConfig = RULE_TYPES_CONFIG[ApmRuleType.Anomaly];
export function registerAnomalyRuleType({
alerting,
alertsLocator,
+ getApmIndices,
basePath,
- config$,
logger,
ml,
ruleDataClient,
@@ -108,6 +108,8 @@ export function registerAnomalyRuleType({
scopedClusterClient,
} = services;
+ const apmIndices = await getApmIndices(savedObjectsClient);
+
const ruleParams = params;
const request = {} as KibanaRequest;
const { mlAnomalySearch } = ml.mlSystemProvider(
@@ -256,7 +258,7 @@ export function registerAnomalyRuleType({
} = anomaly;
const eventSourceFields = await getServiceGroupFieldsForAnomaly({
- config$,
+ apmIndices,
scopedClusterClient,
savedObjectsClient,
serviceName,
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts
index 6f736fb3e5d82..dde54fa604fc7 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/error_count/register_error_count_rule_type.ts
@@ -25,7 +25,6 @@ import {
} from '@kbn/observability-plugin/server';
import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
import { asyncForEach } from '@kbn/std';
-import { firstValueFrom } from 'rxjs';
import { getEnvironmentEsField } from '../../../../../common/environment_filter_values';
import {
ERROR_GROUP_ID,
@@ -42,7 +41,6 @@ import {
import { errorCountParamsSchema } from '../../../../../common/rules/schema';
import { environmentQuery } from '../../../../../common/utils/environment_query';
import { getAlertUrlErrorCount } from '../../../../../common/utils/formatters';
-import { getApmIndices } from '../../../settings/apm_indices/get_apm_indices';
import { apmActionVariables } from '../../action_variables';
import { alertingEsClient } from '../../alerting_es_client';
import {
@@ -63,7 +61,7 @@ export function registerErrorCountRuleType({
alerting,
alertsLocator,
basePath,
- config$,
+ getApmIndices,
logger,
ruleDataClient,
}: RegisterRuleDependencies) {
@@ -108,8 +106,6 @@ export function registerErrorCountRuleType({
ruleParams.groupBy
);
- const config = await firstValueFrom(config$);
-
const {
getAlertUuid,
getAlertStartedDate,
@@ -117,10 +113,7 @@ export function registerErrorCountRuleType({
scopedClusterClient,
} = services;
- const indices = await getApmIndices({
- config,
- savedObjectsClient,
- });
+ const indices = await getApmIndices(savedObjectsClient);
const termFilterQuery = !ruleParams.kqlFilter
? [
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts
index c64eb650d8d84..05f1d6adf6e5b 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_duration/register_transaction_duration_rule_type.ts
@@ -26,7 +26,6 @@ import {
} from '@kbn/rule-data-utils';
import { createLifecycleRuleTypeFactory } from '@kbn/rule-registry-plugin/server';
import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
-import { firstValueFrom } from 'rxjs';
import { getGroupByTerms } from '../utils/get_groupby_terms';
import { SearchAggregatedTransactionSetting } from '../../../../../common/aggregated_transactions';
import { getEnvironmentEsField } from '../../../../../common/environment_filter_values';
@@ -53,7 +52,6 @@ import {
getDocumentTypeFilterForTransactions,
getDurationFieldForTransactions,
} from '../../../../lib/helpers/transactions';
-import { getApmIndices } from '../../../settings/apm_indices/get_apm_indices';
import { apmActionVariables } from '../../action_variables';
import { alertingEsClient } from '../../alerting_es_client';
import {
@@ -76,7 +74,8 @@ const ruleTypeConfig = RULE_TYPES_CONFIG[ApmRuleType.TransactionDuration];
export function registerTransactionDurationRuleType({
alerting,
ruleDataClient,
- config$,
+ getApmIndices,
+ apmConfig,
logger,
basePath,
}: RegisterRuleDependencies) {
@@ -114,21 +113,16 @@ export function registerTransactionDurationRuleType({
ruleParams.groupBy
);
- const config = await firstValueFrom(config$);
-
const { getAlertUuid, savedObjectsClient, scopedClusterClient } =
services;
- const indices = await getApmIndices({
- config,
- savedObjectsClient,
- });
+ const indices = await getApmIndices(savedObjectsClient);
// only query transaction events when set to 'never',
// to prevent (likely) unnecessary blocking request
// in rule execution
const searchAggregatedTransactions =
- config.searchAggregatedTransactions !==
+ apmConfig.searchAggregatedTransactions !==
SearchAggregatedTransactionSetting.never;
const index = searchAggregatedTransactions
diff --git a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts
index 7b39de2a1b3af..6761ca14abf86 100644
--- a/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/rule_types/transaction_error_rate/register_transaction_error_rate_rule_type.ts
@@ -26,7 +26,6 @@ import {
import { createLifecycleRuleTypeFactory } from '@kbn/rule-registry-plugin/server';
import { addSpaceIdToPath } from '@kbn/spaces-plugin/common';
import { asyncForEach } from '@kbn/std';
-import { firstValueFrom } from 'rxjs';
import { SearchAggregatedTransactionSetting } from '../../../../../common/aggregated_transactions';
import { getEnvironmentEsField } from '../../../../../common/environment_filter_values';
import {
@@ -51,7 +50,6 @@ import {
getAlertUrlTransaction,
} from '../../../../../common/utils/formatters';
import { getDocumentTypeFilterForTransactions } from '../../../../lib/helpers/transactions';
-import { getApmIndices } from '../../../settings/apm_indices/get_apm_indices';
import { apmActionVariables } from '../../action_variables';
import { alertingEsClient } from '../../alerting_es_client';
import {
@@ -72,7 +70,8 @@ export function registerTransactionErrorRateRuleType({
alerting,
alertsLocator,
basePath,
- config$,
+ getApmIndices,
+ apmConfig,
logger,
ruleDataClient,
}: RegisterRuleDependencies) {
@@ -117,8 +116,6 @@ export function registerTransactionErrorRateRuleType({
ruleParams.groupBy
);
- const config = await firstValueFrom(config$);
-
const {
getAlertUuid,
getAlertStartedDate,
@@ -126,16 +123,13 @@ export function registerTransactionErrorRateRuleType({
scopedClusterClient,
} = services;
- const indices = await getApmIndices({
- config,
- savedObjectsClient,
- });
+ const indices = await getApmIndices(savedObjectsClient);
// only query transaction events when set to 'never',
// to prevent (likely) unnecessary blocking request
// in rule execution
const searchAggregatedTransactions =
- config.searchAggregatedTransactions !==
+ apmConfig.searchAggregatedTransactions !==
SearchAggregatedTransactionSetting.never;
const index = searchAggregatedTransactions
diff --git a/x-pack/plugins/apm/server/routes/alerts/test_utils/index.ts b/x-pack/plugins/apm/server/routes/alerts/test_utils/index.ts
index fecb5c8fba19d..7071d43eec989 100644
--- a/x-pack/plugins/apm/server/routes/alerts/test_utils/index.ts
+++ b/x-pack/plugins/apm/server/routes/alerts/test_utils/index.ts
@@ -5,7 +5,6 @@
* 2.0.
*/
-import { of } from 'rxjs';
import { IBasePath, Logger } from '@kbn/core/server';
import { elasticsearchServiceMock } from '@kbn/core/server/mocks';
import type { AlertsLocatorParams } from '@kbn/observability-plugin/common';
@@ -20,13 +19,6 @@ import { APMConfig, APM_SERVER_FEATURE_ID } from '../../..';
export const createRuleTypeMocks = () => {
let alertExecutor: (...args: any[]) => Promise;
- const mockedConfig$ = of({
- indices: {
- error: 'apm-*',
- transaction: 'apm-*',
- },
- } as APMConfig);
-
const loggerMock = {
debug: jest.fn(),
warn: jest.fn(),
@@ -64,7 +56,14 @@ export const createRuleTypeMocks = () => {
publicBaseUrl: 'http://localhost:5601/eyr',
serverBasePath: '/eyr',
} as IBasePath,
- config$: mockedConfig$,
+ apmConfig: { searchAggregatedTransactions: true } as any as APMConfig,
+ getApmIndices: async () => ({
+ error: 'apm-*',
+ transaction: 'apm-*',
+ span: 'apm-*',
+ metric: 'apm-*',
+ onboarding: 'apm-*',
+ }),
observability: {
getAlertDetailsConfig: jest.fn().mockReturnValue({ apm: true }),
} as unknown as ObservabilityPluginSetup,
diff --git a/x-pack/plugins/apm/server/routes/apm_routes/create_apm_server_route.ts b/x-pack/plugins/apm/server/routes/apm_routes/create_apm_server_route.ts
index b00b1ad6a1fa5..e2f0251a6343c 100644
--- a/x-pack/plugins/apm/server/routes/apm_routes/create_apm_server_route.ts
+++ b/x-pack/plugins/apm/server/routes/apm_routes/create_apm_server_route.ts
@@ -5,7 +5,8 @@
* 2.0.
*/
import { createServerRouteFactory } from '@kbn/server-route-repository';
-import { APMRouteCreateOptions, APMRouteHandlerResources } from '../typings';
+import { APMRouteCreateOptions } from '../typings';
+import { APMRouteHandlerResources } from './register_apm_server_routes';
export const createApmServerRoute = createServerRouteFactory<
APMRouteHandlerResources,
diff --git a/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.test.ts b/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.test.ts
index ed879d2017e7b..339f7044583b4 100644
--- a/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.test.ts
+++ b/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.test.ts
@@ -13,8 +13,11 @@ import {
import * as t from 'io-ts';
import { CoreSetup, Logger } from '@kbn/core/server';
import { APMConfig } from '../..';
-import { APMRouteCreateOptions, APMRouteHandlerResources } from '../typings';
-import { registerRoutes } from './register_apm_server_routes';
+import { APMRouteCreateOptions } from '../typings';
+import {
+ APMRouteHandlerResources,
+ registerRoutes,
+} from './register_apm_server_routes';
import { NEVER } from 'rxjs';
type RegisterRouteDependencies = Parameters[0];
@@ -54,7 +57,18 @@ const getRegisterRouteDependencies = () => {
},
logger,
config: {} as APMConfig,
- plugins: {},
+ plugins: {
+ apmDataAccess: {
+ setup: {
+ indices: {
+ errorIndices: 'apm-*',
+ metricsIndices: 'apm-*',
+ spanIndices: 'apm-*',
+ transactionIndices: 'apm-*',
+ },
+ },
+ },
+ },
} as unknown as RegisterRouteDependencies,
};
};
@@ -208,9 +222,7 @@ describe('createApi', () => {
} = initApi([
{
endpoint: 'GET /foo',
- options: {
- tags: [],
- },
+ options: { tags: [] },
handler: handlerMock,
},
]);
diff --git a/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.ts b/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.ts
index 014c5139971eb..f4e6c1aaa98df 100644
--- a/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.ts
+++ b/x-pack/plugins/apm/server/routes/apm_routes/register_apm_server_routes.ts
@@ -8,6 +8,7 @@
import Boom from '@hapi/boom';
import * as t from 'io-ts';
import {
+ Logger,
KibanaRequest,
KibanaResponseFactory,
RouteRegistrar,
@@ -25,9 +26,17 @@ import { jsonRt, mergeRt } from '@kbn/io-ts-utils';
import { InspectResponse } from '@kbn/observability-plugin/typings/common';
import apm from 'elastic-apm-node';
import { VersionedRouteRegistrar } from '@kbn/core-http-server';
+import { IRuleDataClient } from '@kbn/rule-registry-plugin/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
+import { ApmFeatureFlags } from '../../../common/apm_feature_flags';
import { pickKeys } from '../../../common/utils/pick_keys';
-import { APMRouteHandlerResources, TelemetryUsageCounter } from '../typings';
+import { APMCore, TelemetryUsageCounter } from '../typings';
import type { ApmPluginRequestHandlerContext } from '../typings';
+import { APMConfig } from '../..';
+import {
+ APMPluginSetupDependencies,
+ APMPluginStartDependencies,
+} from '../../types';
const inspectRt = t.exact(
t.partial({
@@ -99,6 +108,14 @@ export function registerRoutes({
runtimeType
);
+ const getApmIndices = async () => {
+ const coreContext = await context.core;
+ const apmIndices = await plugins.apmDataAccess.setup.getApmIndices(
+ coreContext.savedObjects.client
+ );
+ return apmIndices;
+ };
+
const { aborted, data } = await Promise.race([
handler({
request,
@@ -109,6 +126,7 @@ export function registerRoutes({
core,
plugins,
telemetryUsageCounter,
+ getApmIndices,
params: merge(
{
query: {
@@ -231,3 +249,29 @@ export function registerRoutes({
}
});
}
+
+type Plugins = {
+ [key in keyof APMPluginSetupDependencies]: {
+ setup: Required[key];
+ start: () => Promise[key]>;
+ };
+};
+
+export interface APMRouteHandlerResources {
+ request: KibanaRequest;
+ context: ApmPluginRequestHandlerContext;
+ params: {
+ query: {
+ _inspect: boolean;
+ };
+ };
+ config: APMConfig;
+ featureFlags: ApmFeatureFlags;
+ logger: Logger;
+ core: APMCore;
+ plugins: Plugins;
+ ruleDataClient: IRuleDataClient;
+ telemetryUsageCounter?: TelemetryUsageCounter;
+ kibanaVersion: string;
+ getApmIndices: () => Promise;
+}
diff --git a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts
index 512a1f78a62b7..714f97b1a4801 100644
--- a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.test.ts
@@ -8,9 +8,10 @@
import { createStaticDataView } from './create_static_data_view';
import * as HistoricalAgentData from '../historical_data/has_historical_agent_data';
import { DataViewsService } from '@kbn/data-views-plugin/common';
-import { APMRouteHandlerResources, APMCore } from '../typings';
+import { APMCore } from '../typings';
import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
-import { APMConfig } from '../..';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
+import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
function getMockedDataViewService(existingDataViewTitle: string) {
return {
@@ -42,7 +43,7 @@ const apmEventClientMock = {
span: 'apm-*-span-*',
error: 'apm-*-error-*',
metric: 'apm-*-metrics-*',
- } as APMConfig['indices'],
+ } as APMIndices,
} as unknown as APMEventClient;
describe('createStaticDataView', () => {
diff --git a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts
index 7422c878163b7..715a568eaf6bd 100644
--- a/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/create_static_data_view.ts
@@ -17,9 +17,8 @@ import { APM_STATIC_DATA_VIEW_ID } from '../../../common/data_view_constants';
import { hasHistoricalAgentData } from '../historical_data/has_historical_agent_data';
import { withApmSpan } from '../../utils/with_apm_span';
import { getApmDataViewTitle } from './get_apm_data_view_title';
-
-import { APMRouteHandlerResources } from '../typings';
import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
+import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
export type CreateDataViewResponse = Promise<
| { created: boolean; dataView: DataView }
diff --git a/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.test.ts b/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.test.ts
index 718316f4f241f..a8dc25e493006 100644
--- a/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.test.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.test.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { getApmDataViewTitle } from './get_apm_data_view_title';
describe('getApmDataViewTitle', () => {
@@ -15,7 +15,7 @@ describe('getApmDataViewTitle', () => {
span: 'apm-*-span-*',
error: 'apm-*-error-*',
metric: 'apm-*-metrics-*',
- } as ApmIndicesConfig);
+ } as APMIndices);
expect(title).toBe(
'apm-*-transaction-*,apm-*-span-*,apm-*-error-*,apm-*-metrics-*'
);
@@ -27,7 +27,7 @@ describe('getApmDataViewTitle', () => {
span: 'apm-*',
error: 'apm-*',
metric: 'apm-*',
- } as ApmIndicesConfig);
+ } as APMIndices);
expect(title).toBe('apm-*');
});
});
diff --git a/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.ts b/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.ts
index a70987fd2622c..3061a1ac15714 100644
--- a/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/get_apm_data_view_title.ts
@@ -6,13 +6,13 @@
*/
import { uniq } from 'lodash';
-import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
-export function getApmDataViewTitle(apmIndicesConfig: ApmIndicesConfig) {
+export function getApmDataViewTitle(apmIndices: APMIndices) {
return uniq([
- apmIndicesConfig.transaction,
- apmIndicesConfig.span,
- apmIndicesConfig.error,
- apmIndicesConfig.metric,
+ apmIndices.transaction,
+ apmIndices.span,
+ apmIndices.error,
+ apmIndices.metric,
]).join(',');
}
diff --git a/x-pack/plugins/apm/server/routes/data_view/route.ts b/x-pack/plugins/apm/server/routes/data_view/route.ts
index 53f4b3d68566f..388884c4f5761 100644
--- a/x-pack/plugins/apm/server/routes/data_view/route.ts
+++ b/x-pack/plugins/apm/server/routes/data_view/route.ts
@@ -11,7 +11,6 @@ import {
} from './create_static_data_view';
import { createApmServerRoute } from '../apm_routes/create_apm_server_route';
import { getApmDataViewTitle } from './get_apm_data_view_title';
-import { getApmIndices } from '../settings/apm_indices/get_apm_indices';
import { getApmEventClient } from '../../lib/helpers/get_apm_event_client';
const staticDataViewRoute = createApmServerRoute({
@@ -43,15 +42,8 @@ const staticDataViewRoute = createApmServerRoute({
const dataViewTitleRoute = createApmServerRoute({
endpoint: 'GET /internal/apm/data_view/title',
options: { tags: ['access:apm'] },
- handler: async ({
- context,
- config,
- }): Promise<{ apmDataViewTitle: string }> => {
- const coreContext = await context.core;
- const apmIndicies = await getApmIndices({
- savedObjectsClient: coreContext.savedObjects.client,
- config,
- });
+ handler: async ({ getApmIndices }): Promise<{ apmDataViewTitle: string }> => {
+ const apmIndicies = await getApmIndices();
const apmDataViewTitle = getApmDataViewTitle(apmIndicies);
return { apmDataViewTitle };
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts
index b1dd52e630783..cefe5768f6542 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_apm_events.ts
@@ -8,6 +8,7 @@
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import { kqlQuery, rangeQuery } from '@kbn/observability-plugin/server';
import { merge } from 'lodash';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import {
PROCESSOR_EVENT,
METRICSET_NAME,
@@ -15,7 +16,6 @@ import {
TRANSACTION_DURATION_SUMMARY,
INDEX,
} from '../../../../common/es_fields/apm';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
import { getTypedSearch, TypedSearch } from '../create_typed_es_client';
import { getApmIndexPatterns } from './get_indices';
@@ -36,7 +36,7 @@ export async function getApmEvents({
kuery,
}: {
esClient: ElasticsearchClient;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
start: number;
end: number;
kuery?: string;
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_data_streams.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_data_streams.ts
index 44136bd1dd19f..6444739e6c4b5 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_data_streams.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_data_streams.ts
@@ -6,7 +6,7 @@
*/
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { getApmIndexPatterns } from './get_indices';
export async function getDataStreams({
@@ -14,7 +14,7 @@ export async function getDataStreams({
apmIndices,
}: {
esClient: ElasticsearchClient;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
}) {
const apmIndexPatterns = getApmIndexPatterns([
apmIndices.error,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_field_caps.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_field_caps.ts
index de24c10945708..c734207fa7ece 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_field_caps.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_field_caps.ts
@@ -6,8 +6,8 @@
*/
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { SERVICE_NAME } from '../../../../common/es_fields/apm';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
import { getApmIndexPatterns } from './get_indices';
export function getFieldCaps({
@@ -15,7 +15,7 @@ export function getFieldCaps({
apmIndices,
}: {
esClient: ElasticsearchClient;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
}) {
return esClient.fieldCaps({
index: getApmIndexPatterns([apmIndices.metric, apmIndices.transaction]),
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_index_templates_by_index_pattern.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_index_templates_by_index_pattern.ts
index 58e6d7293737e..fc9d18c255ab1 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_index_templates_by_index_pattern.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_index_templates_by_index_pattern.ts
@@ -9,7 +9,7 @@ import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import { IndicesSimulateTemplateResponse } from '@elastic/elasticsearch/lib/api/types';
import { orderBy } from 'lodash';
import { errors } from '@elastic/elasticsearch';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { getApmIndexPatterns } from './get_indices';
import { getIndexTemplate } from './get_index_template';
import { getApmIndexTemplateNames } from '../helpers/get_apm_index_template_names';
@@ -19,7 +19,7 @@ export async function getIndexTemplatesByIndexPattern({
apmIndices,
}: {
esClient: ElasticsearchClient;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
}) {
const indexPatterns = getApmIndexPatterns([
apmIndices.error,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices.ts
index 686fc7cde3170..e597495e171b4 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices.ts
@@ -7,7 +7,7 @@
import { compact, uniq } from 'lodash';
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
export function getApmIndexPatterns(indices: string[]) {
return uniq(indices.flatMap((index): string[] => index.split(',')));
@@ -18,7 +18,7 @@ export async function getIndicesAndIngestPipelines({
apmIndices,
}: {
esClient: ElasticsearchClient;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
}) {
const indices = await esClient.indices.get({
index: getApmIndexPatterns([
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices_states.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices_states.ts
index 4aeaee5db5349..5a95cec4f2e6b 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices_states.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_indices_states.ts
@@ -6,7 +6,7 @@
*/
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '@kbn/observability-plugin/common/typings';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { SERVICE_NAME } from '../../../../common/es_fields/apm';
import { getApmIndexTemplateNames } from '../helpers/get_apm_index_template_names';
import { getFieldCaps } from './get_field_caps';
@@ -17,7 +17,7 @@ export async function getIndicesStates({
apmIndices,
}: {
esClient: ElasticsearchClient;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
}) {
const { indices, ingestPipelines } = await getIndicesAndIngestPipelines({
esClient,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_non_data_stream_indices.ts b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_non_data_stream_indices.ts
index 31629d5644eda..f2507657229a1 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_non_data_stream_indices.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/bundle/get_non_data_stream_indices.ts
@@ -6,7 +6,7 @@
*/
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '@kbn/observability-plugin/common/typings';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { getApmIndexPatterns } from './get_indices';
export async function getNonDataStreamIndices({
@@ -14,7 +14,7 @@ export async function getNonDataStreamIndices({
apmIndices,
}: {
esClient: ElasticsearchClient;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
}) {
const apmIndexPatterns = getApmIndexPatterns([
apmIndices.error,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/get_diagnostics_bundle.ts b/x-pack/plugins/apm/server/routes/diagnostics/get_diagnostics_bundle.ts
index f00af8454fbe8..1fa6ae4fdba11 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/get_diagnostics_bundle.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/get_diagnostics_bundle.ts
@@ -6,8 +6,8 @@
*/
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { NOT_AVAILABLE_LABEL } from '../../../common/i18n';
-import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices';
import { getDataStreams } from './bundle/get_data_streams';
import { getNonDataStreamIndices } from './bundle/get_non_data_stream_indices';
import { getElasticsearchVersion } from './get_elasticsearch_version';
@@ -30,7 +30,7 @@ export async function getDiagnosticsBundle({
kuery,
}: {
esClient: ElasticsearchClient;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
start: number | undefined;
end: number | undefined;
kuery: string | undefined;
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/get_fleet_package_info.ts b/x-pack/plugins/apm/server/routes/diagnostics/get_fleet_package_info.ts
index 15d0dcb76a101..bbfc30c76ad7a 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/get_fleet_package_info.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/get_fleet_package_info.ts
@@ -6,7 +6,7 @@
*/
import { FleetUnauthorizedError } from '@kbn/fleet-plugin/server/errors';
-import { APMRouteHandlerResources } from '../typings';
+import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
export async function getFleetPackageInfo(resources: APMRouteHandlerResources) {
const fleetPluginStart = await resources.plugins.fleet?.start();
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/helpers/get_diagnostic_privileges.ts b/x-pack/plugins/apm/server/routes/diagnostics/helpers/get_diagnostic_privileges.ts
index 9531d3dfde3a6..6d42658d3ac24 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/helpers/get_diagnostic_privileges.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/helpers/get_diagnostic_privileges.ts
@@ -6,7 +6,7 @@
*/
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { ApmIndicesConfig } from '../../settings/apm_indices/get_apm_indices';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { getApmIndexPatterns } from '../bundle/get_indices';
export async function getDiagnosticsPrivileges({
@@ -14,7 +14,7 @@ export async function getDiagnosticsPrivileges({
apmIndices,
}: {
esClient: ElasticsearchClient;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
}) {
const indexPatterns = getApmIndexPatterns([
apmIndices.error,
diff --git a/x-pack/plugins/apm/server/routes/diagnostics/route.ts b/x-pack/plugins/apm/server/routes/diagnostics/route.ts
index 390e7bfa51f36..fcd41df55afc7 100644
--- a/x-pack/plugins/apm/server/routes/diagnostics/route.ts
+++ b/x-pack/plugins/apm/server/routes/diagnostics/route.ts
@@ -13,13 +13,10 @@ import {
IngestGetPipelineResponse,
SecurityHasPrivilegesPrivileges,
} from '@elastic/elasticsearch/lib/api/types';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import * as t from 'io-ts';
import { isoToEpochRt } from '@kbn/io-ts-utils';
import { createApmServerRoute } from '../apm_routes/create_apm_server_route';
-import {
- ApmIndicesConfig,
- getApmIndices,
-} from '../settings/apm_indices/get_apm_indices';
import { ApmEvent } from './bundle/get_apm_events';
import { getDiagnosticsBundle } from './get_diagnostics_bundle';
import { getFleetPackageInfo } from './get_fleet_package_info';
@@ -38,6 +35,49 @@ export interface IndiciesItem {
isValid: boolean;
}
+export type DiagnosticsBundle = Promise<{
+ esResponses: {
+ existingIndexTemplates: IndicesGetIndexTemplateIndexTemplateItem[];
+ fieldCaps: FieldCapsResponse;
+ indices: IndicesGetResponse;
+ ingestPipelines: IngestGetPipelineResponse;
+ };
+ diagnosticsPrivileges: {
+ index: Record;
+ cluster: Record;
+ hasAllClusterPrivileges: boolean;
+ hasAllIndexPrivileges: boolean;
+ hasAllPrivileges: boolean;
+ };
+ apmIndices: APMIndices;
+ apmIndexTemplates: Array<{
+ name: string;
+ isNonStandard: boolean;
+ exists: boolean;
+ }>;
+ fleetPackageInfo: {
+ isInstalled: boolean;
+ version?: string;
+ };
+ kibanaVersion: string;
+ elasticsearchVersion: string;
+ apmEvents: ApmEvent[];
+ invalidIndices: IndiciesItem[];
+ validIndices: IndiciesItem[];
+ dataStreams: IndicesDataStream[];
+ nonDataStreamIndices: string[];
+ indexTemplatesByIndexPattern: Array<{
+ indexPattern: string;
+ indexTemplates: Array<{
+ priority: number | undefined;
+ isNonStandard: boolean;
+ templateIndexPatterns: string[];
+ templateName: string;
+ }>;
+ }>;
+ params: { start: number; end: number; kuery?: string };
+}>;
+
const getDiagnosticsRoute = createApmServerRoute({
endpoint: 'GET /internal/apm/diagnostics',
options: { tags: ['access:apm'] },
@@ -64,7 +104,7 @@ const getDiagnosticsRoute = createApmServerRoute({
hasAllIndexPrivileges: boolean;
hasAllPrivileges: boolean;
};
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
apmIndexTemplates: Array<{
name: string;
isNonStandard: boolean;
@@ -94,11 +134,8 @@ const getDiagnosticsRoute = createApmServerRoute({
}> => {
const { start, end, kuery } = resources.params.query;
const coreContext = await resources.context.core;
+ const apmIndices = await resources.getApmIndices();
const { asCurrentUser: esClient } = coreContext.elasticsearch.client;
- const apmIndices = await getApmIndices({
- savedObjectsClient: coreContext.savedObjects.client,
- config: resources.config,
- });
const bundle = await getDiagnosticsBundle({
esClient,
diff --git a/x-pack/plugins/apm/server/routes/fleet/api_keys/create_apm_api_keys.ts b/x-pack/plugins/apm/server/routes/fleet/api_keys/create_apm_api_keys.ts
index 7f69b7525e214..fbc365f775ddd 100644
--- a/x-pack/plugins/apm/server/routes/fleet/api_keys/create_apm_api_keys.ts
+++ b/x-pack/plugins/apm/server/routes/fleet/api_keys/create_apm_api_keys.ts
@@ -9,7 +9,7 @@ import { CoreStart, Logger } from '@kbn/core/server';
import {
APM_AGENT_CONFIGURATION_INDEX,
APM_SOURCE_MAP_INDEX,
-} from '../../settings/apm_indices/get_apm_indices';
+} from '../../settings/apm_indices/apm_system_index_constants';
const apiKeyMetadata = {
application: 'apm',
diff --git a/x-pack/plugins/apm/server/routes/fleet/register_fleet_policy_callbacks.ts b/x-pack/plugins/apm/server/routes/fleet/register_fleet_policy_callbacks.ts
index 13815779c6013..9008fabdd3e3b 100644
--- a/x-pack/plugins/apm/server/routes/fleet/register_fleet_policy_callbacks.ts
+++ b/x-pack/plugins/apm/server/routes/fleet/register_fleet_policy_callbacks.ts
@@ -5,7 +5,11 @@
* 2.0.
*/
-import { Logger, CoreStart } from '@kbn/core/server';
+import {
+ Logger,
+ CoreStart,
+ SavedObjectsClientContract,
+} from '@kbn/core/server';
import {
FleetStartContract,
PostPackagePolicyCreateCallback,
@@ -14,7 +18,7 @@ import {
PutPackagePolicyUpdateCallback,
} from '@kbn/fleet-plugin/server';
import { get } from 'lodash';
-import { APMConfig, APMPlugin, APMRouteHandlerResources } from '../..';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { decoratePackagePolicyWithAgentConfigAndSourceMap } from './merge_package_policy_with_apm';
import { addApiKeysToPackagePolicyIfMissing } from './api_keys/add_api_keys_to_policies_if_missing';
import {
@@ -23,33 +27,41 @@ import {
} from './get_package_policy_decorators';
import { createInternalESClient } from '../../lib/helpers/create_es_client/create_internal_es_client';
import { getInternalSavedObjectsClient } from '../../lib/helpers/get_internal_saved_objects_client';
+import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
export async function registerFleetPolicyCallbacks({
logger,
coreStartPromise,
plugins,
- config,
}: {
logger: Logger;
coreStartPromise: Promise;
plugins: APMRouteHandlerResources['plugins'];
- config: NonNullable;
}) {
if (!plugins.fleet) {
return;
}
const fleetPluginStart = await plugins.fleet.start();
+ const { getApmIndices } = plugins.apmDataAccess.setup;
const coreStart = await coreStartPromise;
fleetPluginStart.registerExternalCallback(
'packagePolicyUpdate',
- onPackagePolicyCreateOrUpdate({ fleetPluginStart, config, coreStart })
+ onPackagePolicyCreateOrUpdate({
+ fleetPluginStart,
+ getApmIndices,
+ coreStart,
+ })
);
fleetPluginStart.registerExternalCallback(
'packagePolicyCreate',
- onPackagePolicyCreateOrUpdate({ fleetPluginStart, config, coreStart })
+ onPackagePolicyCreateOrUpdate({
+ fleetPluginStart,
+ getApmIndices,
+ coreStart,
+ })
);
fleetPluginStart.registerExternalCallback(
@@ -143,11 +155,11 @@ function onPackagePolicyPostCreate({
*/
function onPackagePolicyCreateOrUpdate({
fleetPluginStart,
- config,
+ getApmIndices,
coreStart,
}: {
fleetPluginStart: FleetStartContract;
- config: APMConfig;
+ getApmIndices: (soClient: SavedObjectsClientContract) => Promise;
coreStart: CoreStart;
}): PutPackagePolicyUpdateCallback & PostPackagePolicyCreateCallback {
return async (packagePolicy) => {
@@ -157,10 +169,11 @@ function onPackagePolicyCreateOrUpdate({
const { asInternalUser } = coreStart.elasticsearch.client;
const savedObjectsClient = await getInternalSavedObjectsClient(coreStart);
+ const apmIndices = await getApmIndices(savedObjectsClient);
+
const internalESClient = await createInternalESClient({
debug: false,
- config,
- savedObjectsClient,
+ apmIndices,
elasticsearchClient: asInternalUser,
});
diff --git a/x-pack/plugins/apm/server/routes/fleet/route.ts b/x-pack/plugins/apm/server/routes/fleet/route.ts
index 592042b30c56e..3223d71a77b49 100644
--- a/x-pack/plugins/apm/server/routes/fleet/route.ts
+++ b/x-pack/plugins/apm/server/routes/fleet/route.ts
@@ -153,11 +153,13 @@ const createCloudApmPackagePolicyRoute = createApmServerRoute({
coreStart,
fleetPluginStart,
securityPluginStart,
+ apmIndices,
] = await Promise.all([
(await context.core).savedObjects.client,
resources.core.start(),
plugins.fleet.start(),
plugins.security.start(),
+ resources.getApmIndices(),
]);
const esClient = coreStart.elasticsearch.client.asScoped(
@@ -174,7 +176,7 @@ const createCloudApmPackagePolicyRoute = createApmServerRoute({
context,
request,
debug: resources.params.query._inspect,
- config: resources.config,
+ apmIndices,
});
const cloudApmPackagePolicy = await createCloudApmPackgePolicy({
diff --git a/x-pack/plugins/apm/server/routes/fleet/run_migration_check.ts b/x-pack/plugins/apm/server/routes/fleet/run_migration_check.ts
index 072d280200850..124350a70c093 100644
--- a/x-pack/plugins/apm/server/routes/fleet/run_migration_check.ts
+++ b/x-pack/plugins/apm/server/routes/fleet/run_migration_check.ts
@@ -6,7 +6,7 @@
*/
import { PackagePolicy } from '@kbn/fleet-plugin/common';
-import { APMRouteHandlerResources } from '../typings';
+import { APMRouteHandlerResources } from '../apm_routes/register_apm_server_routes';
import { getApmPackagePolicies } from './get_apm_package_policies';
import {
getApmPackagePolicy,
diff --git a/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts b/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts
index 01cb73ebeedf9..8d503628d6c1a 100644
--- a/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts
+++ b/x-pack/plugins/apm/server/routes/observability_overview/has_data.ts
@@ -6,8 +6,8 @@
*/
import { ProcessorEvent } from '@kbn/observability-plugin/common';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
-import { ApmIndicesConfig } from '../settings/apm_indices/get_apm_indices';
export interface HasDataResponse {
hasData: boolean;
@@ -24,7 +24,7 @@ export async function getHasData({
indices,
apmEventClient,
}: {
- indices: ApmIndicesConfig;
+ indices: APMIndices;
apmEventClient: APMEventClient;
}): Promise {
try {
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_agent_config_index.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_agent_config_index.ts
index 4aebdfaf03e6a..b6d1e153c5e73 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_agent_config_index.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_agent_config_index.ts
@@ -10,7 +10,7 @@ import {
createOrUpdateIndex,
Mappings,
} from '@kbn/observability-plugin/server';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
export async function createApmAgentConfigurationIndex({
client,
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_or_update_configuration.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_or_update_configuration.ts
index 5520b51137235..3839949df6cc4 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_or_update_configuration.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/create_or_update_configuration.ts
@@ -14,7 +14,7 @@ import {
APMIndexDocumentParams,
APMInternalESClient,
} from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
export function createOrUpdateConfiguration({
configurationId,
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/delete_configuration.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/delete_configuration.ts
index d0897fb48941b..fc49660cd53e1 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/delete_configuration.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/delete_configuration.ts
@@ -6,7 +6,7 @@
*/
import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
export async function deleteConfiguration({
configurationId,
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/find_exact_configuration.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/find_exact_configuration.ts
index 3d65d534e9545..3cd71c1d29027 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/find_exact_configuration.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/find_exact_configuration.ts
@@ -12,7 +12,7 @@ import {
SERVICE_NAME,
} from '../../../../common/es_fields/apm';
import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
import { convertConfigSettingsToString } from './convert_settings_to_string';
import { getConfigsAppliedToAgentsThroughFleet } from './get_config_applied_to_agent_through_fleet';
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts
index 3e588a5c8d9e5..67286f3413e36 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/get_environments/get_existing_environments_for_service.ts
@@ -11,7 +11,7 @@ import {
} from '../../../../../common/es_fields/apm';
import { ALL_OPTION_VALUE } from '../../../../../common/agent_configuration/all_option';
import { APMInternalESClient } from '../../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../../apm_indices/apm_system_index_constants';
export async function getExistingEnvironmentsForService({
serviceName,
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/list_configurations.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/list_configurations.ts
index 6a7e53097945e..1cca702dfb45f 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/list_configurations.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/list_configurations.ts
@@ -9,7 +9,7 @@ import { AgentConfiguration } from '../../../../common/agent_configuration/confi
import { convertConfigSettingsToString } from './convert_settings_to_string';
import { getConfigsAppliedToAgentsThroughFleet } from './get_config_applied_to_agent_through_fleet';
import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
export async function listConfigurations(
internalESClient: APMInternalESClient
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/mark_applied_by_agent.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/mark_applied_by_agent.ts
index 6b32bbacd3b2a..33a97a3a85ed4 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/mark_applied_by_agent.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/mark_applied_by_agent.ts
@@ -7,7 +7,7 @@
import { AgentConfiguration } from '../../../../common/agent_configuration/configuration_types';
import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
// We're not wrapping this function with a span as it is not blocking the request
export async function markAppliedByAgent({
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts
index ffadf970dc414..c11eba5ac7740 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/route.ts
@@ -49,13 +49,14 @@ const agentConfigurationRoute = createApmServerRoute({
}> => {
throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
- const { context, request, params, config } = resources;
+ const { context, request, params } = resources;
+ const apmIndices = await resources.getApmIndices();
const internalESClient = await createInternalESClientWithContext({
context,
request,
debug: params.query._inspect,
- config,
+ apmIndices,
});
const configurations = await listConfigurations(internalESClient);
@@ -74,15 +75,16 @@ const getSingleAgentConfigurationRoute = createApmServerRoute({
handler: async (resources): Promise => {
throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
- const { params, logger, context, request, config } = resources;
+ const { params, logger, context, request } = resources;
const { name, environment, _inspect } = params.query;
const service = { name, environment };
+ const apmIndices = await resources.getApmIndices();
const internalESClient = await createInternalESClientWithContext({
context,
request,
debug: _inspect,
- config,
+ apmIndices,
});
const exactConfig = await findExactConfiguration({
service,
@@ -115,22 +117,16 @@ const deleteAgentConfigurationRoute = createApmServerRoute({
handler: async (resources): Promise<{ result: string }> => {
throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
- const {
- params,
- logger,
- core,
- telemetryUsageCounter,
- context,
- request,
- config,
- } = resources;
+ const { params, logger, core, telemetryUsageCounter, context, request } =
+ resources;
const { service } = params.body;
+ const apmIndices = await resources.getApmIndices();
const internalESClient = await createInternalESClientWithContext({
context,
request,
debug: params.query._inspect,
- config,
+ apmIndices,
});
const exactConfig = await findExactConfiguration({
service,
@@ -181,22 +177,16 @@ const createOrUpdateAgentConfigurationRoute = createApmServerRoute({
]),
handler: async (resources): Promise => {
throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
- const {
- params,
- logger,
- core,
- telemetryUsageCounter,
- context,
- request,
- config,
- } = resources;
+ const { params, logger, core, telemetryUsageCounter, context, request } =
+ resources;
const { body, query } = params;
+ const apmIndices = await resources.getApmIndices();
const internalESClient = await createInternalESClientWithContext({
context,
request,
debug: params.query._inspect,
- config,
+ apmIndices,
});
// if the config already exists, it is fetched and updated
@@ -258,19 +248,20 @@ const agentConfigurationSearchRoute = createApmServerRoute({
): Promise | null> => {
throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
- const { params, logger, context, config, request } = resources;
+ const { params, logger, context, request } = resources;
const {
service,
etag,
mark_as_applied_by_agent: markAsAppliedByAgent,
} = params.body;
+ const apmIndices = await resources.getApmIndices();
const internalESClient = await createInternalESClientWithContext({
context,
request,
debug: params.query._inspect,
- config,
+ apmIndices,
});
const configuration = await searchConfigurations({
service,
@@ -332,12 +323,14 @@ const listAgentConfigurationEnvironmentsRoute = createApmServerRoute({
throwNotFoundIfAgentConfigNotAvailable(resources.featureFlags);
const { context, request, params, config } = resources;
+ const apmIndices = await resources.getApmIndices();
+
const [internalESClient, apmEventClient] = await Promise.all([
createInternalESClientWithContext({
context,
request,
debug: params.query._inspect,
- config,
+ apmIndices,
}),
getApmEventClient(resources),
]);
diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration/search_configurations.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration/search_configurations.ts
index 77da47b62c1c8..f2673433791e3 100644
--- a/x-pack/plugins/apm/server/routes/settings/agent_configuration/search_configurations.ts
+++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration/search_configurations.ts
@@ -13,7 +13,7 @@ import {
import { AgentConfiguration } from '../../../../common/agent_configuration/configuration_types';
import { convertConfigSettingsToString } from './convert_settings_to_string';
import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_AGENT_CONFIGURATION_INDEX } from '../apm_indices/apm_system_index_constants';
export async function searchConfigurations({
service,
diff --git a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts
index 451ec87bc3670..8ad3d6bb92b6c 100644
--- a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts
+++ b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/route.ts
@@ -21,7 +21,6 @@ import { updateToV3 } from './update_to_v3';
import { environmentStringRt } from '../../../../common/environment_rt';
import { getMlJobsWithAPMGroup } from '../../../lib/anomaly_detection/get_ml_jobs_with_apm_group';
import { getApmEventClient } from '../../../lib/helpers/get_apm_event_client';
-import { getApmIndices } from '../apm_indices/get_apm_indices';
import { ApmMlJob } from '../../../../common/anomaly_detection/apm_ml_job';
// get ML anomaly detection jobs for each environment
const anomalyDetectionJobsRoute = createApmServerRoute({
@@ -68,18 +67,14 @@ const createAnomalyDetectionJobsRoute = createApmServerRoute({
}),
}),
handler: async (resources): Promise<{ jobCreated: true }> => {
- const { params, context, logger, config } = resources;
+ const { params, context, logger, getApmIndices } = resources;
const { environments } = params.body;
const licensingContext = await context.licensing;
- const coreContext = await context.core;
const esClient = (await context.core).elasticsearch.client;
const [mlClient, indices] = await Promise.all([
getMlClient(resources),
- getApmIndices({
- savedObjectsClient: coreContext.savedObjects.client,
- config,
- }),
+ getApmIndices(),
]);
if (!isActivePlatinumLicense(licensingContext.license)) {
@@ -142,9 +137,9 @@ const anomalyDetectionUpdateToV3Route = createApmServerRoute({
],
},
handler: async (resources): Promise<{ update: boolean }> => {
- const { config, context } = resources;
- const coreContext = await context.core;
- const [mlClient, esClient, indices] = await Promise.all([
+ const { getApmIndices } = resources;
+ const [indices, mlClient, esClient] = await Promise.all([
+ getApmIndices(),
getMlClient(resources),
resources.core
.start()
@@ -152,10 +147,6 @@ const anomalyDetectionUpdateToV3Route = createApmServerRoute({
(start): ElasticsearchClient =>
start.elasticsearch.client.asInternalUser
),
- getApmIndices({
- config,
- savedObjectsClient: coreContext.savedObjects.client,
- }),
]);
const { logger } = resources;
diff --git a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/update_to_v3.ts b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/update_to_v3.ts
index 32ab3815dd307..577273cbfb03c 100644
--- a/x-pack/plugins/apm/server/routes/settings/anomaly_detection/update_to_v3.ts
+++ b/x-pack/plugins/apm/server/routes/settings/anomaly_detection/update_to_v3.ts
@@ -9,11 +9,11 @@ import { uniq } from 'lodash';
import pLimit from 'p-limit';
import { ElasticsearchClient } from '@kbn/core/server';
import { JOB_STATE } from '@kbn/ml-plugin/common';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { createAnomalyDetectionJobs } from '../../../lib/anomaly_detection/create_anomaly_detection_jobs';
import { getAnomalyDetectionJobs } from '../../../lib/anomaly_detection/get_anomaly_detection_jobs';
import { MlClient } from '../../../lib/helpers/get_ml_client';
import { withApmSpan } from '../../../utils/with_apm_span';
-import { ApmIndicesConfig } from '../apm_indices/get_apm_indices';
export async function updateToV3({
logger,
@@ -23,7 +23,7 @@ export async function updateToV3({
}: {
logger: Logger;
mlClient?: MlClient;
- indices: ApmIndicesConfig;
+ indices: APMIndices;
esClient: ElasticsearchClient;
}) {
const allJobs = await getAnomalyDetectionJobs(mlClient);
diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/apm_system_index_constants.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/apm_system_index_constants.ts
new file mode 100644
index 0000000000000..bd74af0536ba7
--- /dev/null
+++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/apm_system_index_constants.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; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export const APM_AGENT_CONFIGURATION_INDEX = '.apm-agent-configuration';
+export const APM_CUSTOM_LINK_INDEX = '.apm-custom-link';
+export const APM_SOURCE_MAP_INDEX = '.apm-source-map';
diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts
index b652fcde39d13..b6a1cd750f102 100644
--- a/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts
+++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/get_apm_indices.ts
@@ -5,71 +5,8 @@
* 2.0.
*/
-import { SavedObjectsClient } from '@kbn/core/server';
-import {
- APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
- APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
-} from '../../../../common/apm_saved_object_constants';
-import { APMConfig } from '../../..';
-import { APMRouteHandlerResources } from '../../typings';
-import { withApmSpan } from '../../../utils/with_apm_span';
-import { APMIndices } from '../../../saved_objects/apm_indices';
-
-export type ApmIndicesConfig = Readonly<{
- error: string;
- onboarding: string;
- span: string;
- transaction: string;
- metric: string;
-}>;
-
-export const APM_AGENT_CONFIGURATION_INDEX = '.apm-agent-configuration';
-export const APM_CUSTOM_LINK_INDEX = '.apm-custom-link';
-export const APM_SOURCE_MAP_INDEX = '.apm-source-map';
-
-type ISavedObjectsClient = Pick;
-
-async function getApmIndicesSavedObject(
- savedObjectsClient: ISavedObjectsClient
-) {
- const apmIndicesSavedObject = await withApmSpan(
- 'get_apm_indices_saved_object',
- () =>
- savedObjectsClient.get>(
- APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
- APM_INDEX_SETTINGS_SAVED_OBJECT_ID
- )
- );
- return apmIndicesSavedObject.attributes.apmIndices;
-}
-
-export function getApmIndicesConfig(config: APMConfig): ApmIndicesConfig {
- return {
- error: config.indices.error,
- onboarding: config.indices.onboarding,
- span: config.indices.span,
- transaction: config.indices.transaction,
- metric: config.indices.metric,
- };
-}
-
-export async function getApmIndices({
- config,
- savedObjectsClient,
-}: {
- config: APMConfig;
- savedObjectsClient: ISavedObjectsClient;
-}): Promise {
- try {
- const apmIndicesSavedObject = await getApmIndicesSavedObject(
- savedObjectsClient
- );
- const apmIndicesConfig = getApmIndicesConfig(config);
- return { ...apmIndicesConfig, ...apmIndicesSavedObject };
- } catch (error) {
- return getApmIndicesConfig(config);
- }
-}
+import { getApmIndicesSavedObject } from '@kbn/apm-data-access-plugin/server/saved_objects/apm_indices';
+import { APMRouteHandlerResources } from '../../apm_routes/register_apm_server_routes';
export type ApmIndexSettingsResponse = Array<{
configurationName: 'transaction' | 'span' | 'error' | 'metric' | 'onboarding';
@@ -77,35 +14,21 @@ export type ApmIndexSettingsResponse = Array<{
savedValue: string | undefined;
}>;
-export async function getApmIndexSettings({
- context,
- config,
-}: Pick<
- APMRouteHandlerResources,
- 'context' | 'config'
->): Promise {
- let apmIndicesSavedObject: Awaited<
- ReturnType
- >;
- try {
- const soClient = (await context.core).savedObjects.client;
- apmIndicesSavedObject = await getApmIndicesSavedObject(soClient);
- } catch (error: any) {
- if (error.output && error.output.statusCode === 404) {
- apmIndicesSavedObject = {};
- } else {
- throw error;
- }
- }
- const apmIndicesConfig = getApmIndicesConfig(config);
+export async function getApmIndexSettings(
+ resources: APMRouteHandlerResources
+): Promise {
+ const { apmIndicesFromConfigFile } = resources.plugins.apmDataAccess.setup;
+
+ const soClient = (await resources.context.core).savedObjects.client;
+ const apmIndicesSavedObject = await getApmIndicesSavedObject(soClient);
- const apmIndices = Object.keys(config.indices) as Array<
- keyof typeof config.indices
+ const apmIndicesKeys = Object.keys(apmIndicesFromConfigFile) as Array<
+ keyof typeof apmIndicesFromConfigFile
>;
- return apmIndices.map((configurationName) => ({
+ return apmIndicesKeys.map((configurationName) => ({
configurationName,
- defaultValue: apmIndicesConfig[configurationName], // value defined in kibana[.dev].yml
+ defaultValue: apmIndicesFromConfigFile[configurationName], // value defined in kibana[.dev].yml
savedValue: apmIndicesSavedObject?.[configurationName], // value saved via Saved Objects service
}));
}
diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts
index 24b6d48e92314..434ae4785ce5a 100644
--- a/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts
+++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/route.ts
@@ -7,27 +7,24 @@
import * as t from 'io-ts';
import { SavedObject } from '@kbn/core/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { createApmServerRoute } from '../../apm_routes/create_apm_server_route';
import {
- getApmIndices,
getApmIndexSettings,
ApmIndexSettingsResponse,
- ApmIndicesConfig,
} from './get_apm_indices';
import { saveApmIndices } from './save_apm_indices';
-import { APMConfig } from '../../..';
// get list of apm indices and values
const apmIndexSettingsRoute = createApmServerRoute({
endpoint: 'GET /internal/apm/settings/apm-index-settings',
options: { tags: ['access:apm'] },
- handler: async ({
- config,
- context,
- }): Promise<{
+ handler: async (
+ resources
+ ): Promise<{
apmIndexSettings: ApmIndexSettingsResponse;
}> => {
- const apmIndexSettings = await getApmIndexSettings({ config, context });
+ const apmIndexSettings = await getApmIndexSettings(resources);
return { apmIndexSettings };
},
});
@@ -36,18 +33,13 @@ const apmIndexSettingsRoute = createApmServerRoute({
const apmIndicesRoute = createApmServerRoute({
endpoint: 'GET /internal/apm/settings/apm-indices',
options: { tags: ['access:apm'] },
- handler: async (resources): Promise => {
- const { context, config } = resources;
- const savedObjectsClient = (await context.core).savedObjects.client;
- return await getApmIndices({
- savedObjectsClient,
- config,
- });
+ handler: async (resources): Promise => {
+ return await resources.getApmIndices();
},
});
type SaveApmIndicesBodySchema = {
- [Property in keyof APMConfig['indices']]: t.StringC;
+ [Property in keyof APMIndices]: t.StringC;
};
// save ui indices
diff --git a/x-pack/plugins/apm/server/routes/settings/apm_indices/save_apm_indices.ts b/x-pack/plugins/apm/server/routes/settings/apm_indices/save_apm_indices.ts
index a5926c6dfc0cb..e9d2bd5fbea92 100644
--- a/x-pack/plugins/apm/server/routes/settings/apm_indices/save_apm_indices.ts
+++ b/x-pack/plugins/apm/server/routes/settings/apm_indices/save_apm_indices.ts
@@ -6,20 +6,20 @@
*/
import { SavedObjectsClientContract } from '@kbn/core/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import {
- APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+ APMIndicesSavedObjectBody,
APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
-} from '../../../../common/apm_saved_object_constants';
-import { APMIndices } from '../../../saved_objects/apm_indices';
+ APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+} from '@kbn/apm-data-access-plugin/server/saved_objects/apm_indices';
import { withApmSpan } from '../../../utils/with_apm_span';
-import { ApmIndicesConfig } from './get_apm_indices';
export function saveApmIndices(
savedObjectsClient: SavedObjectsClientContract,
- apmIndices: Partial
+ apmIndices: Partial
) {
return withApmSpan('save_apm_indices', () =>
- savedObjectsClient.create(
+ savedObjectsClient.create(
APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
{ apmIndices: removeEmpty(apmIndices), isSpaceAware: true },
{ id: APM_INDEX_SETTINGS_SAVED_OBJECT_ID, overwrite: true }
@@ -28,7 +28,7 @@ export function saveApmIndices(
}
// remove empty/undefined values
-function removeEmpty(apmIndices: Partial) {
+function removeEmpty(apmIndices: Partial) {
return Object.entries(apmIndices)
.map(([key, value]) => [key, value?.trim()])
.filter(([_, value]) => !!value)
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts
index b8bfc3b3f2f72..ba3b06f6dbbc9 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/create_custom_link_index.ts
@@ -11,7 +11,7 @@ import {
createOrUpdateIndex,
Mappings,
} from '@kbn/observability-plugin/server';
-import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/apm_system_index_constants';
export const createApmCustomLinkIndex = async ({
client,
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/create_or_update_custom_link.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/create_or_update_custom_link.ts
index 979c16ad53473..e70b5257a7680 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/create_or_update_custom_link.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/create_or_update_custom_link.ts
@@ -14,7 +14,7 @@ import {
APMIndexDocumentParams,
APMInternalESClient,
} from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/apm_system_index_constants';
export function createOrUpdateCustomLink({
customLinkId,
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/delete_custom_link.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/delete_custom_link.ts
index 16318fe696712..cc000ceda963f 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/delete_custom_link.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/delete_custom_link.ts
@@ -6,7 +6,7 @@
*/
import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/apm_system_index_constants';
export function deleteCustomLink({
customLinkId,
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/list_custom_links.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/list_custom_links.ts
index 27b7c08ca9a4b..38d371e0a5b6d 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/list_custom_links.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/list_custom_links.ts
@@ -14,7 +14,7 @@ import {
import { fromESFormat } from './helper';
import { filterOptionsRt } from './custom_link_types';
import { APMInternalESClient } from '../../../lib/helpers/create_es_client/create_internal_es_client';
-import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/get_apm_indices';
+import { APM_CUSTOM_LINK_INDEX } from '../apm_indices/apm_system_index_constants';
export async function listCustomLinks({
internalESClient,
diff --git a/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts b/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts
index 7e79a2d241224..1db1d74fb7134 100644
--- a/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts
+++ b/x-pack/plugins/apm/server/routes/settings/custom_link/route.ts
@@ -50,8 +50,9 @@ const listCustomLinksRoute = createApmServerRoute({
): Promise<{
customLinks: CustomLink[];
}> => {
- const { context, params, request, config } = resources;
+ const { context, params, request } = resources;
const licensingContext = await context.licensing;
+ const apmIndices = await resources.getApmIndices();
if (!isActiveGoldLicense(licensingContext.license)) {
throw Boom.forbidden(INVALID_LICENSE);
@@ -63,7 +64,7 @@ const listCustomLinksRoute = createApmServerRoute({
context,
request,
debug: resources.params.query._inspect,
- config,
+ apmIndices,
});
// picks only the items listed in FILTER_OPTIONS
@@ -83,8 +84,9 @@ const createCustomLinkRoute = createApmServerRoute({
}),
options: { tags: ['access:apm', 'access:apm_write'] },
handler: async (resources): Promise => {
- const { context, params, request, config } = resources;
+ const { context, params, request } = resources;
const licensingContext = await context.licensing;
+ const apmIndices = await resources.getApmIndices();
if (!isActiveGoldLicense(licensingContext.license)) {
throw Boom.forbidden(INVALID_LICENSE);
@@ -94,7 +96,7 @@ const createCustomLinkRoute = createApmServerRoute({
context,
request,
debug: resources.params.query._inspect,
- config,
+ apmIndices,
});
const customLink = params.body;
@@ -119,8 +121,9 @@ const updateCustomLinkRoute = createApmServerRoute({
tags: ['access:apm', 'access:apm_write'],
},
handler: async (resources): Promise => {
- const { params, context, request, config } = resources;
+ const { params, context, request } = resources;
const licensingContext = await context.licensing;
+ const apmIndices = await resources.getApmIndices();
if (!isActiveGoldLicense(licensingContext.license)) {
throw Boom.forbidden(INVALID_LICENSE);
@@ -130,7 +133,7 @@ const updateCustomLinkRoute = createApmServerRoute({
context,
request,
debug: resources.params.query._inspect,
- config,
+ apmIndices,
});
const { id } = params.path;
@@ -155,8 +158,9 @@ const deleteCustomLinkRoute = createApmServerRoute({
tags: ['access:apm', 'access:apm_write'],
},
handler: async (resources): Promise<{ result: string }> => {
- const { context, params, request, config } = resources;
+ const { context, params, request } = resources;
const licensingContext = await context.licensing;
+ const apmIndices = await resources.getApmIndices();
if (!isActiveGoldLicense(licensingContext.license)) {
throw Boom.forbidden(INVALID_LICENSE);
@@ -166,7 +170,7 @@ const deleteCustomLinkRoute = createApmServerRoute({
context,
request,
debug: resources.params.query._inspect,
- config,
+ apmIndices,
});
const { id } = params.path;
const res = await deleteCustomLink({
diff --git a/x-pack/plugins/apm/server/routes/source_maps/bulk_create_apm_source_maps.ts b/x-pack/plugins/apm/server/routes/source_maps/bulk_create_apm_source_maps.ts
index 5cc9f93e49b7b..3aa5c9a780aa3 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/bulk_create_apm_source_maps.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/bulk_create_apm_source_maps.ts
@@ -8,7 +8,7 @@
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import { Artifact } from '@kbn/fleet-plugin/server';
import { getUnzippedArtifactBody } from '../fleet/source_maps';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
import { ApmSourceMap } from './create_apm_source_map_index_template';
import { getEncodedSourceMapContent, getSourceMapId } from './sourcemap_utils';
diff --git a/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map.ts b/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map.ts
index 132a92a225187..bda2601080434 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map.ts
@@ -7,7 +7,7 @@
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import { Logger } from '@kbn/core/server';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
import { ApmSourceMap } from './create_apm_source_map_index_template';
import { SourceMap } from './route';
import {
diff --git a/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map_index_template.ts b/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map_index_template.ts
index 4fa24358e7b07..c99e834b65483 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map_index_template.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/create_apm_source_map_index_template.ts
@@ -8,7 +8,7 @@
import { IndicesPutIndexTemplateRequest } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { ElasticsearchClient, Logger } from '@kbn/core/server';
import { createOrUpdateIndexTemplate } from '@kbn/observability-plugin/server';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
const indexTemplate: IndicesPutIndexTemplateRequest = {
name: 'apm-source-map',
diff --git a/x-pack/plugins/apm/server/routes/source_maps/delete_apm_sourcemap.ts b/x-pack/plugins/apm/server/routes/source_maps/delete_apm_sourcemap.ts
index ffdaf02c165d8..2f4723f9e470f 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/delete_apm_sourcemap.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/delete_apm_sourcemap.ts
@@ -6,7 +6,7 @@
*/
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
export async function deleteApmSourceMap({
internalESClient,
diff --git a/x-pack/plugins/apm/server/routes/source_maps/schedule_source_map_migration.ts b/x-pack/plugins/apm/server/routes/source_maps/schedule_source_map_migration.ts
index 3ab48db456845..71f1e3af0b5c2 100644
--- a/x-pack/plugins/apm/server/routes/source_maps/schedule_source_map_migration.ts
+++ b/x-pack/plugins/apm/server/routes/source_maps/schedule_source_map_migration.ts
@@ -12,7 +12,7 @@ import { TaskManagerSetupContract } from '@kbn/task-manager-plugin/server';
import { CoreStart, Logger } from '@kbn/core/server';
import { getApmArtifactClient } from '../fleet/source_maps';
import { bulkCreateApmSourceMaps } from './bulk_create_apm_source_maps';
-import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/get_apm_indices';
+import { APM_SOURCE_MAP_INDEX } from '../settings/apm_indices/apm_system_index_constants';
import { ApmSourceMap } from './create_apm_source_map_index_template';
import { APMPluginStartDependencies } from '../../types';
import { createApmSourceMapIndexTemplate } from './create_apm_source_map_index_template';
diff --git a/x-pack/plugins/apm/server/routes/storage_explorer/is_cross_cluster_search.test.ts b/x-pack/plugins/apm/server/routes/storage_explorer/is_cross_cluster_search.test.ts
index edb28d9bfa490..21b5b163e7663 100644
--- a/x-pack/plugins/apm/server/routes/storage_explorer/is_cross_cluster_search.test.ts
+++ b/x-pack/plugins/apm/server/routes/storage_explorer/is_cross_cluster_search.test.ts
@@ -6,7 +6,7 @@
*/
import { isCrossClusterSearch } from './is_cross_cluster_search';
-import { ApmIndicesConfig } from '@kbn/observability-plugin/common/typings';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { APMEventClient } from '../../lib/helpers/create_es_client/create_apm_event_client';
describe('isCrossClusterSearch', () => {
@@ -17,7 +17,7 @@ describe('isCrossClusterSearch', () => {
span: 'traces-apm*',
metric: 'metrics-apm*',
error: 'logs-apm*',
- } as ApmIndicesConfig,
+ } as APMIndices,
} as unknown as APMEventClient;
expect(isCrossClusterSearch(mockApmEventClient)).toBe(false);
@@ -30,7 +30,7 @@ describe('isCrossClusterSearch', () => {
span: 'traces-apm*,test-apm*',
metric: 'metrics-apm*,test-apm*',
error: 'logs-apm*,test-apm*',
- } as ApmIndicesConfig,
+ } as APMIndices,
} as unknown as APMEventClient;
expect(isCrossClusterSearch(mockApmEventClient)).toBe(false);
@@ -44,7 +44,7 @@ describe('isCrossClusterSearch', () => {
metric: '',
error: '',
onboarding: 'apm-*,remote_cluster:apm-*',
- } as ApmIndicesConfig,
+ } as APMIndices,
} as unknown as APMEventClient;
expect(isCrossClusterSearch(mockApmEventClient)).toBe(false);
@@ -57,7 +57,7 @@ describe('isCrossClusterSearch', () => {
span: '',
metric: '',
error: '',
- } as ApmIndicesConfig,
+ } as APMIndices,
} as unknown as APMEventClient;
expect(isCrossClusterSearch(mockApmEventClient)).toBe(true);
@@ -70,7 +70,7 @@ describe('isCrossClusterSearch', () => {
span: 'traces-apm*,remote_cluster:traces-apm*',
metric: '',
error: '',
- } as ApmIndicesConfig,
+ } as APMIndices,
} as unknown as APMEventClient;
expect(isCrossClusterSearch(mockApmEventClient)).toBe(true);
@@ -83,7 +83,7 @@ describe('isCrossClusterSearch', () => {
span: '',
metric: 'metrics-apm*,remote_cluster:metrics-apm*',
error: '',
- } as ApmIndicesConfig,
+ } as APMIndices,
} as unknown as APMEventClient;
expect(isCrossClusterSearch(mockApmEventClient)).toBe(true);
@@ -96,7 +96,7 @@ describe('isCrossClusterSearch', () => {
span: '',
metric: '',
error: 'logs-apm*,remote_cluster:logs-apm*',
- } as ApmIndicesConfig,
+ } as APMIndices,
} as unknown as APMEventClient;
expect(isCrossClusterSearch(mockApmEventClient)).toBe(true);
diff --git a/x-pack/plugins/apm/server/routes/typings.ts b/x-pack/plugins/apm/server/routes/typings.ts
index 6e83404b2c905..c25d30cdb77e4 100644
--- a/x-pack/plugins/apm/server/routes/typings.ts
+++ b/x-pack/plugins/apm/server/routes/typings.ts
@@ -8,22 +8,13 @@
import {
CoreSetup,
CustomRequestHandlerContext,
- Logger,
- KibanaRequest,
CoreStart,
RouteConfigOptions,
} from '@kbn/core/server';
-import { IRuleDataClient } from '@kbn/rule-registry-plugin/server';
import { AlertingApiRequestHandlerContext } from '@kbn/alerting-plugin/server';
import type { RacApiRequestHandlerContext } from '@kbn/rule-registry-plugin/server';
import { LicensingApiRequestHandlerContext } from '@kbn/licensing-plugin/server';
import { UsageCollectionSetup } from '@kbn/usage-collection-plugin/server';
-import { APMConfig } from '..';
-import {
- APMPluginSetupDependencies,
- APMPluginStartDependencies,
-} from '../types';
-import { ApmFeatureFlags } from '../../common/apm_feature_flags';
export type ApmPluginRequestHandlerContext = CustomRequestHandlerContext<{
licensing: LicensingApiRequestHandlerContext;
@@ -54,26 +45,3 @@ export interface APMCore {
setup: CoreSetup;
start: () => Promise;
}
-
-export interface APMRouteHandlerResources {
- request: KibanaRequest;
- context: ApmPluginRequestHandlerContext;
- params: {
- query: {
- _inspect: boolean;
- };
- };
- config: APMConfig;
- featureFlags: ApmFeatureFlags;
- logger: Logger;
- core: APMCore;
- plugins: {
- [key in keyof APMPluginSetupDependencies]: {
- setup: Required[key];
- start: () => Promise[key]>;
- };
- };
- ruleDataClient: IRuleDataClient;
- telemetryUsageCounter?: TelemetryUsageCounter;
- kibanaVersion: string;
-}
diff --git a/x-pack/plugins/apm/server/saved_objects/index.ts b/x-pack/plugins/apm/server/saved_objects/index.ts
index 048db493cb2fa..b39e032ad14bd 100644
--- a/x-pack/plugins/apm/server/saved_objects/index.ts
+++ b/x-pack/plugins/apm/server/saved_objects/index.ts
@@ -5,7 +5,6 @@
* 2.0.
*/
-export { apmIndices } from './apm_indices';
export { apmTelemetry } from './apm_telemetry';
export { apmServerSettings } from './apm_server_settings';
export { apmServiceGroups } from './apm_service_groups';
diff --git a/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts b/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts
index f2804ce645a7f..358f69020598d 100644
--- a/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts
+++ b/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts
@@ -11,8 +11,8 @@ import {
TutorialSchema,
InstructionSetSchema,
} from '@kbn/home-plugin/server';
-
import { CloudSetup } from '@kbn/cloud-plugin/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import {
createNodeAgentInstructions,
createDjangoAgentInstructions,
@@ -26,16 +26,15 @@ import {
createPhpAgentInstructions,
createOpenTelemetryAgentInstructions,
} from '../../../common/tutorial/instructions/apm_agent_instructions';
-import { APMConfig } from '../..';
import { getOnPremApmServerInstructionSet } from './on_prem_apm_server_instruction_set';
export function createElasticCloudInstructions({
cloudSetup,
- apmConfig,
+ apmIndices,
isFleetPluginEnabled,
}: {
cloudSetup?: CloudSetup;
- apmConfig: APMConfig;
+ apmIndices: APMIndices;
isFleetPluginEnabled: boolean;
}): TutorialSchema['elasticCloud'] {
const apmServerUrl = cloudSetup?.apm.url;
@@ -46,7 +45,7 @@ export function createElasticCloudInstructions({
}
instructionSets.push(
- getOnPremApmServerInstructionSet({ apmConfig, isFleetPluginEnabled })
+ getOnPremApmServerInstructionSet({ apmIndices, isFleetPluginEnabled })
);
instructionSets.push(getApmAgentInstructionSet(cloudSetup));
diff --git a/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts b/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts
index 1780c5bd87bcd..b7a4f4568928d 100644
--- a/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts
+++ b/x-pack/plugins/apm/server/tutorial/envs/on_prem.ts
@@ -10,7 +10,7 @@ import {
INSTRUCTION_VARIANT,
InstructionsSchema,
} from '@kbn/home-plugin/server';
-import { APMConfig } from '../..';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import {
createDjangoAgentInstructions,
createDotNetAgentInstructions,
@@ -27,15 +27,18 @@ import {
import { getOnPremApmServerInstructionSet } from './on_prem_apm_server_instruction_set';
export function onPremInstructions({
- apmConfig,
+ apmIndices,
isFleetPluginEnabled,
}: {
- apmConfig: APMConfig;
+ apmIndices: APMIndices;
isFleetPluginEnabled: boolean;
}): InstructionsSchema {
return {
instructionSets: [
- getOnPremApmServerInstructionSet({ apmConfig, isFleetPluginEnabled }),
+ getOnPremApmServerInstructionSet({
+ apmIndices,
+ isFleetPluginEnabled,
+ }),
{
title: i18n.translate('xpack.apm.tutorial.apmAgents.title', {
defaultMessage: 'APM Agents',
@@ -121,9 +124,9 @@ export function onPremInstructions({
),
esHitsCheck: {
index: [
- apmConfig.indices.error,
- apmConfig.indices.transaction,
- apmConfig.indices.metric,
+ apmIndices.error,
+ apmIndices.transaction,
+ apmIndices.metric,
],
query: {
bool: {
diff --git a/x-pack/plugins/apm/server/tutorial/envs/on_prem_apm_server_instruction_set.ts b/x-pack/plugins/apm/server/tutorial/envs/on_prem_apm_server_instruction_set.ts
index 2409c78cf1f37..ce4b1f49a0091 100644
--- a/x-pack/plugins/apm/server/tutorial/envs/on_prem_apm_server_instruction_set.ts
+++ b/x-pack/plugins/apm/server/tutorial/envs/on_prem_apm_server_instruction_set.ts
@@ -10,7 +10,7 @@ import {
InstructionsSchema,
INSTRUCTION_VARIANT,
} from '@kbn/home-plugin/server';
-import { APMConfig } from '../..';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import {
createDownloadServerDeb,
createDownloadServerOsx,
@@ -29,10 +29,10 @@ const START_SERVER_UNIX_SYSV = createStartServerUnixSysv();
const START_SERVER_UNIX_BINARI = createStartServerUnixBinari();
export function getOnPremApmServerInstructionSet({
- apmConfig,
+ apmIndices,
isFleetPluginEnabled,
}: {
- apmConfig: APMConfig;
+ apmIndices: APMIndices;
isFleetPluginEnabled: boolean;
}): InstructionsSchema['instructionSets'][0] {
return {
@@ -132,7 +132,7 @@ export function getOnPremApmServerInstructionSet({
}
),
esHitsCheck: {
- index: apmConfig.indices.onboarding,
+ index: apmIndices.onboarding,
query: {
bool: {
filter: [{ term: { 'processor.event': 'onboarding' } }],
diff --git a/x-pack/plugins/apm/server/tutorial/index.ts b/x-pack/plugins/apm/server/tutorial/index.ts
index a22919b2f9f39..b8201564f4154 100644
--- a/x-pack/plugins/apm/server/tutorial/index.ts
+++ b/x-pack/plugins/apm/server/tutorial/index.ts
@@ -12,8 +12,8 @@ import {
TutorialSchema,
} from '@kbn/home-plugin/server';
import { CloudSetup } from '@kbn/cloud-plugin/server';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { APMConfig } from '..';
-import { ApmIndicesConfig } from '../routes/settings/apm_indices/get_apm_indices';
import { createElasticCloudInstructions } from './envs/elastic_cloud';
import { onPremInstructions } from './envs/on_prem';
@@ -31,7 +31,7 @@ export const tutorialProvider =
isFleetPluginEnabled,
}: {
apmConfig: APMConfig;
- apmIndices: ApmIndicesConfig;
+ apmIndices: APMIndices;
cloud?: CloudSetup;
isFleetPluginEnabled: boolean;
}) =>
@@ -90,9 +90,9 @@ It allows you to monitor the performance of thousands of applications in real ti
integrationBrowserCategories: ['observability', 'apm'],
artifacts,
customStatusCheckName: 'apm_fleet_server_status_check',
- onPrem: onPremInstructions({ apmConfig, isFleetPluginEnabled }),
+ onPrem: onPremInstructions({ apmIndices, isFleetPluginEnabled }),
elasticCloud: createElasticCloudInstructions({
- apmConfig,
+ apmIndices,
isFleetPluginEnabled,
cloudSetup: cloud,
}),
diff --git a/x-pack/plugins/apm/server/types.ts b/x-pack/plugins/apm/server/types.ts
index 51ed7a3a7c0a6..054861a082b44 100644
--- a/x-pack/plugins/apm/server/types.ts
+++ b/x-pack/plugins/apm/server/types.ts
@@ -7,7 +7,6 @@
import { SharePluginSetup } from '@kbn/share-plugin/server';
import { Observable } from 'rxjs';
-import { KibanaRequest } from '@kbn/core/server';
import {
RuleRegistryPluginSetupContract,
RuleRegistryPluginStartContract,
@@ -16,6 +15,11 @@ import {
PluginSetup as DataPluginSetup,
PluginStart as DataPluginStart,
} from '@kbn/data-plugin/server';
+import {
+ ApmDataAccessPluginSetup,
+ ApmDataAccessPluginStart,
+} from '@kbn/apm-data-access-plugin/server';
+
import {
SpacesPluginSetup,
SpacesPluginStart,
@@ -58,22 +62,14 @@ import {
CustomIntegrationsPluginStart,
} from '@kbn/custom-integrations-plugin/server';
import { APMConfig } from '.';
-import { ApmIndicesConfig } from './routes/settings/apm_indices/get_apm_indices';
-import { APMEventClient } from './lib/helpers/create_es_client/create_apm_event_client';
-import { ApmPluginRequestHandlerContext } from './routes/typings';
export interface APMPluginSetup {
config$: Observable;
- getApmIndices: () => Promise;
- createApmEventClient: (params: {
- debug?: boolean;
- request: KibanaRequest;
- context: ApmPluginRequestHandlerContext;
- }) => Promise;
}
export interface APMPluginSetupDependencies {
// required dependencies
+ apmDataAccess: ApmDataAccessPluginSetup;
data: DataPluginSetup;
features: FeaturesPluginSetup;
licensing: LicensingPluginSetup;
@@ -98,6 +94,7 @@ export interface APMPluginSetupDependencies {
}
export interface APMPluginStartDependencies {
// required dependencies
+ apmDataAccess: ApmDataAccessPluginStart;
data: DataPluginStart;
features: FeaturesPluginStart;
licensing: LicensingPluginStart;
diff --git a/x-pack/plugins/apm/server/utils/test_helpers.tsx b/x-pack/plugins/apm/server/utils/test_helpers.tsx
index c4349ce920e30..807d47fa5a2b9 100644
--- a/x-pack/plugins/apm/server/utils/test_helpers.tsx
+++ b/x-pack/plugins/apm/server/utils/test_helpers.tsx
@@ -6,11 +6,11 @@
*/
import type { ESSearchRequest, ESSearchResponse } from '@kbn/es-types';
+import type { APMIndices } from '@kbn/apm-data-access-plugin/server';
import { APMConfig } from '..';
import { APMEventClient } from '../lib/helpers/create_es_client/create_apm_event_client';
import { APMInternalESClient } from '../lib/helpers/create_es_client/create_internal_es_client';
import { ApmAlertsClient } from '../lib/helpers/get_apm_alerts_client';
-import { ApmIndicesConfig } from '../routes/settings/apm_indices/get_apm_indices';
interface Options {
mockResponse?: (
@@ -30,7 +30,7 @@ export async function inspectSearchParams(
mockApmEventClient: APMEventClient;
mockConfig: APMConfig;
mockInternalESClient: APMInternalESClient;
- mockIndices: ApmIndicesConfig;
+ mockIndices: APMIndices;
mockApmAlertsClient: ApmAlertsClient;
}) => Promise,
options: Options = {}
@@ -53,7 +53,7 @@ export async function inspectSearchParams(
let error;
const mockApmEventClient = { search: spy } as any;
const indices: {
- [Property in keyof APMConfig['indices']]: string;
+ [Property in keyof APMIndices]: string;
} = {
error: 'myIndex',
onboarding: 'myIndex',
@@ -61,6 +61,7 @@ export async function inspectSearchParams(
transaction: 'myIndex',
metric: 'myIndex',
};
+
const mockConfig = new Proxy(
{},
{
@@ -73,8 +74,6 @@ export async function inspectSearchParams(
switch (key) {
default:
return 'myIndex';
- case 'indices':
- return indices;
case 'ui':
return {
enabled: true,
diff --git a/x-pack/plugins/apm/tsconfig.json b/x-pack/plugins/apm/tsconfig.json
index a81771fbd1f6b..1b06fa44a8dd5 100644
--- a/x-pack/plugins/apm/tsconfig.json
+++ b/x-pack/plugins/apm/tsconfig.json
@@ -76,7 +76,6 @@
"@kbn/babel-register",
"@kbn/core-saved-objects-migration-server-internal",
"@kbn/core-elasticsearch-server",
- "@kbn/core-saved-objects-api-server",
"@kbn/safer-lodash-set",
"@kbn/shared-ux-router",
"@kbn/alerts-as-data-utils",
@@ -96,7 +95,8 @@
"@kbn/logs-shared-plugin",
"@kbn/unified-field-list",
"@kbn/discover-plugin",
- "@kbn/observability-ai-assistant-plugin"
+ "@kbn/observability-ai-assistant-plugin",
+ "@kbn/apm-data-access-plugin"
],
"exclude": ["target/**/*"]
}
diff --git a/x-pack/plugins/apm_data_access/common/index.ts b/x-pack/plugins/apm_data_access/common/index.ts
new file mode 100644
index 0000000000000..19d4963c3cec5
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/common/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export const PLUGIN_ID = 'apmDataAccess';
+export const PLUGIN_NAME = 'apmDataAccess';
diff --git a/x-pack/plugins/apm_data_access/jest.config.js b/x-pack/plugins/apm_data_access/jest.config.js
new file mode 100644
index 0000000000000..8fb297afcc48e
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/jest.config.js
@@ -0,0 +1,14 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+const path = require('path');
+
+module.exports = {
+ preset: '@kbn/test',
+ rootDir: path.resolve(__dirname, '../../..'),
+ roots: ['/x-pack/plugins/apm_data_access'],
+};
diff --git a/x-pack/plugins/apm_data_access/kibana.jsonc b/x-pack/plugins/apm_data_access/kibana.jsonc
new file mode 100644
index 0000000000000..d0ee0befda101
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/kibana.jsonc
@@ -0,0 +1,14 @@
+{
+ "type": "plugin",
+ "id": "@kbn/apm-data-access-plugin",
+ "owner": "@elastic/apm-ui",
+ "plugin": {
+ "id": "apmDataAccess",
+ "server": true,
+ "browser": false,
+ "configPath": ["xpack", "apm_data_access"],
+ "requiredPlugins": ["data"],
+ "optionalPlugins": [],
+ "requiredBundles": []
+ }
+}
diff --git a/x-pack/plugins/apm_data_access/server/index.ts b/x-pack/plugins/apm_data_access/server/index.ts
new file mode 100644
index 0000000000000..4d7ae2b1eb6c3
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/server/index.ts
@@ -0,0 +1,80 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { schema, TypeOf } from '@kbn/config-schema';
+import { PluginConfigDescriptor, PluginInitializerContext } from '@kbn/core/server';
+import { ApmDataAccessPlugin } from './plugin';
+
+const configSchema = schema.object({
+ indices: schema.object({
+ transaction: schema.string({ defaultValue: 'traces-apm*,apm-*' }), // TODO: remove apm-* pattern in 9.0
+ span: schema.string({ defaultValue: 'traces-apm*,apm-*' }),
+ error: schema.string({ defaultValue: 'logs-apm*,apm-*' }),
+ metric: schema.string({ defaultValue: 'metrics-apm*,apm-*' }),
+ onboarding: schema.string({ defaultValue: 'apm-*' }), // Unused: to be deleted
+ }),
+});
+
+// plugin config
+export const config: PluginConfigDescriptor = {
+ deprecations: ({ renameFromRoot, unused, deprecate }) => [
+ // deprecations
+ unused('indices.sourcemap', { level: 'warning' }),
+ deprecate('indices.onboarding', 'a future version', {
+ level: 'warning',
+ message: `Configuring "xpack.apm.indices.onboarding" is deprecated and will be removed in a future version. Please remove this setting.`,
+ }),
+
+ // deprecations due to removal of apm_oss plugin
+ renameFromRoot('apm_oss.transactionIndices', 'xpack.apm.indices.transaction', {
+ level: 'warning',
+ }),
+ renameFromRoot('apm_oss.spanIndices', 'xpack.apm.indices.span', {
+ level: 'warning',
+ }),
+ renameFromRoot('apm_oss.errorIndices', 'xpack.apm.indices.error', {
+ level: 'warning',
+ }),
+ renameFromRoot('apm_oss.metricsIndices', 'xpack.apm.indices.metric', {
+ level: 'warning',
+ }),
+ renameFromRoot('apm_oss.onboardingIndices', 'xpack.apm.indices.onboarding', {
+ level: 'warning',
+ }),
+
+ // rename from apm to apm_data_access plugin
+ renameFromRoot('xpack.apm.indices.transaction', 'xpack.apm_data_access.indices.transaction', {
+ level: 'warning',
+ silent: true,
+ }),
+ renameFromRoot('xpack.apm.indices.span', 'xpack.apm_data_access.indices.span', {
+ level: 'warning',
+ }),
+ renameFromRoot('xpack.apm.indices.error', 'xpack.apm_data_access.indices.error', {
+ level: 'warning',
+ }),
+ renameFromRoot('xpack.apm.indices.metric', 'xpack.apm_data_access.indices.metric', {
+ level: 'warning',
+ }),
+ renameFromRoot('xpack.apm.indices.sourcemap', 'xpack.apm_data_access.indices.sourcemap', {
+ level: 'warning',
+ }),
+ renameFromRoot('xpack.apm.indices.onboarding', 'xpack.apm_data_access.indices.onboarding', {
+ level: 'warning',
+ }),
+ ],
+
+ schema: configSchema,
+};
+export type APMDataAccessConfig = TypeOf;
+export type APMIndices = APMDataAccessConfig['indices'];
+
+export function plugin(initializerContext: PluginInitializerContext) {
+ return new ApmDataAccessPlugin(initializerContext);
+}
+
+export type { ApmDataAccessPluginSetup, ApmDataAccessPluginStart } from './types';
diff --git a/x-pack/plugins/apm_data_access/server/plugin.ts b/x-pack/plugins/apm_data_access/server/plugin.ts
new file mode 100644
index 0000000000000..bba13bc6fea36
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/server/plugin.ts
@@ -0,0 +1,59 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import {
+ PluginInitializerContext,
+ CoreSetup,
+ CoreStart,
+ Plugin,
+ SavedObjectsClientContract,
+} from '@kbn/core/server';
+import { APMDataAccessConfig } from '.';
+import { ApmDataAccessPluginSetup, ApmDataAccessPluginStart } from './types';
+import { migrateLegacyAPMIndicesToSpaceAware } from './saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware';
+import {
+ apmIndicesSavedObjectDefinition,
+ getApmIndicesSavedObject,
+} from './saved_objects/apm_indices';
+
+export class ApmDataAccessPlugin
+ implements Plugin
+{
+ constructor(private readonly initContext: PluginInitializerContext) {
+ this.initContext = initContext;
+ }
+
+ public setup(core: CoreSetup): ApmDataAccessPluginSetup {
+ // retrieve APM indices from config
+ const apmDataAccessConfig = this.initContext.config.get();
+ const apmIndicesFromConfigFile = apmDataAccessConfig.indices;
+
+ // register saved object
+ core.savedObjects.registerType(apmIndicesSavedObjectDefinition);
+
+ // expose
+ return {
+ apmIndicesFromConfigFile,
+ getApmIndices: async (savedObjectsClient: SavedObjectsClientContract) => {
+ const apmIndicesFromSavedObject = await getApmIndicesSavedObject(savedObjectsClient);
+ return { ...apmIndicesFromConfigFile, ...apmIndicesFromSavedObject };
+ },
+ };
+ }
+
+ public start(core: CoreStart) {
+ const logger = this.initContext.logger.get();
+ // TODO: remove in 9.0
+ migrateLegacyAPMIndicesToSpaceAware({ coreStart: core, logger }).catch((e) => {
+ logger.error('Failed to run migration making APM indices space aware');
+ logger.error(e);
+ });
+ return {};
+ }
+
+ public stop() {}
+}
diff --git a/x-pack/plugins/apm/server/saved_objects/apm_indices.ts b/x-pack/plugins/apm_data_access/server/saved_objects/apm_indices.ts
similarity index 66%
rename from x-pack/plugins/apm/server/saved_objects/apm_indices.ts
rename to x-pack/plugins/apm_data_access/server/saved_objects/apm_indices.ts
index 9a7ab40dfee1a..7ab90ef0a605c 100644
--- a/x-pack/plugins/apm/server/saved_objects/apm_indices.ts
+++ b/x-pack/plugins/apm_data_access/server/saved_objects/apm_indices.ts
@@ -8,9 +8,14 @@
import { SavedObjectsType } from '@kbn/core/server';
import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
+import { SavedObjectsErrorHelpers } from '@kbn/core/server';
+import { SavedObjectsClientContract } from '@kbn/core/server';
import { updateApmOssIndexPaths } from './migrations/update_apm_oss_index_paths';
-export interface APMIndices {
+export const APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE = 'apm-indices';
+export const APM_INDEX_SETTINGS_SAVED_OBJECT_ID = 'apm-indices';
+
+export interface APMIndicesSavedObjectBody {
apmIndices?: {
error?: string;
onboarding?: string;
@@ -21,8 +26,8 @@ export interface APMIndices {
isSpaceAware?: boolean;
}
-export const apmIndices: SavedObjectsType = {
- name: 'apm-indices',
+export const apmIndicesSavedObjectDefinition: SavedObjectsType = {
+ name: APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
hidden: false,
namespaceType: 'single',
mappings: {
@@ -33,7 +38,7 @@ export const apmIndices: SavedObjectsType = {
importableAndExportable: true,
icon: 'apmApp',
getTitle: () =>
- i18n.translate('xpack.apm.apmSettings.index', {
+ i18n.translate('xpack.apmDataAccess.apmSettings.index', {
defaultMessage: 'APM Settings - Index',
}),
},
@@ -67,3 +72,20 @@ export const apmIndices: SavedObjectsType = {
},
},
};
+
+export async function getApmIndicesSavedObject(savedObjectsClient: SavedObjectsClientContract) {
+ try {
+ const apmIndicesSavedObject = await savedObjectsClient.get>(
+ APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+ APM_INDEX_SETTINGS_SAVED_OBJECT_ID
+ );
+ return apmIndicesSavedObject.attributes.apmIndices;
+ } catch (error) {
+ // swallow error if saved object does not exist
+ if (SavedObjectsErrorHelpers.isNotFoundError(error)) {
+ return {};
+ }
+
+ throw error;
+ }
+}
diff --git a/x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
similarity index 99%
rename from x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
rename to x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
index 4f794d48c3056..8b87b52dee166 100644
--- a/x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
+++ b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.test.ts
@@ -8,7 +8,7 @@ import type { CoreStart, Logger } from '@kbn/core/server';
import {
APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
-} from '../../../common/apm_saved_object_constants';
+} from '../apm_indices';
import { migrateLegacyAPMIndicesToSpaceAware } from './migrate_legacy_apm_indices_to_space_aware';
const loggerMock = {
diff --git a/x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
similarity index 78%
rename from x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
rename to x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
index 8098318ce61e6..6e1b989146e04 100644
--- a/x-pack/plugins/apm/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
+++ b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/migrate_legacy_apm_indices_to_space_aware.ts
@@ -4,22 +4,19 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-import type {
- CoreStart,
- Logger,
- ISavedObjectsRepository,
-} from '@kbn/core/server';
+import type { CoreStart, Logger, ISavedObjectsRepository } from '@kbn/core/server';
import { SavedObjectsErrorHelpers } from '@kbn/core/server';
+import type { APMIndices } from '../..';
+
import {
+ APMIndicesSavedObjectBody,
APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
-} from '../../../common/apm_saved_object_constants';
-import { ApmIndicesConfig } from '../../routes/settings/apm_indices/get_apm_indices';
-import { APMIndices } from '../apm_indices';
+} from '../apm_indices';
async function fetchLegacyAPMIndices(repository: ISavedObjectsRepository) {
try {
- const apmIndices = await repository.get>(
+ const apmIndices = await repository.get>(
APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
APM_INDEX_SETTINGS_SAVED_OBJECT_ID
);
@@ -66,15 +63,17 @@ export async function migrateLegacyAPMIndicesToSpaceAware({
};
// Calls create first to update the default space setting isSpaceAware to true
- await repository.create<
- Partial
- >(APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE, savedObjectAttributes, {
- id: APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
- overwrite: true,
- });
+ await repository.create>(
+ APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+ savedObjectAttributes,
+ {
+ id: APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
+ overwrite: true,
+ }
+ );
// Create new APM indices space aware for all spaces available
- await repository.bulkCreate>(
+ await repository.bulkCreate>(
spaces.saved_objects
// Skip default space since it was already updated
.filter(({ id: spaceId }) => spaceId !== 'default')
diff --git a/x-pack/plugins/apm/server/saved_objects/migrations/update_apm_oss_index_paths.ts b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/update_apm_oss_index_paths.ts
similarity index 91%
rename from x-pack/plugins/apm/server/saved_objects/migrations/update_apm_oss_index_paths.ts
rename to x-pack/plugins/apm_data_access/server/saved_objects/migrations/update_apm_oss_index_paths.ts
index 1d129eda16e6d..da0f7904a487a 100644
--- a/x-pack/plugins/apm/server/saved_objects/migrations/update_apm_oss_index_paths.ts
+++ b/x-pack/plugins/apm_data_access/server/saved_objects/migrations/update_apm_oss_index_paths.ts
@@ -22,9 +22,7 @@ type DeprecatedApmIndicesSavedObjectAttributes = Partial<{
[Property in DeprecatedApmIndexConfigPaths]: string;
}>;
-export function updateApmOssIndexPaths(
- attributes: DeprecatedApmIndicesSavedObjectAttributes
-) {
+export function updateApmOssIndexPaths(attributes: DeprecatedApmIndicesSavedObjectAttributes) {
return apmIndexConfigs.reduce((attrs, [configPath, deprecatedConfigPath]) => {
const indexConfig: string | undefined = attributes[deprecatedConfigPath];
if (indexConfig) {
diff --git a/x-pack/plugins/apm_data_access/server/types.ts b/x-pack/plugins/apm_data_access/server/types.ts
new file mode 100644
index 0000000000000..39c21c8aa0016
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/server/types.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
+import { APMIndices } from '.';
+
+export interface ApmDataAccessPluginSetup {
+ apmIndicesFromConfigFile: APMIndices;
+ getApmIndices: (soClient: SavedObjectsClientContract) => Promise;
+}
+// eslint-disable-next-line @typescript-eslint/no-empty-interface
+export interface ApmDataAccessPluginStart {}
diff --git a/x-pack/plugins/apm_data_access/tsconfig.json b/x-pack/plugins/apm_data_access/tsconfig.json
new file mode 100644
index 0000000000000..3a40428cab960
--- /dev/null
+++ b/x-pack/plugins/apm_data_access/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "extends": "../../../tsconfig.base.json",
+ "compilerOptions": {
+ "outDir": "target/types"
+ },
+ "include": ["../../../typings/**/*", "common/**/*", "server/**/*", "jest.config.js"],
+ "exclude": ["target/**/*"],
+ "kbn_references": [
+ "@kbn/config-schema",
+ "@kbn/core",
+ "@kbn/i18n",
+ "@kbn/core-saved-objects-api-server",
+ ]
+}
diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json
index 22ee2086a1a33..536325568ccd2 100644
--- a/x-pack/plugins/translations/translations/fr-FR.json
+++ b/x-pack/plugins/translations/translations/fr-FR.json
@@ -7889,7 +7889,6 @@
"xpack.apm.apmDescription": "Collecte automatiquement les indicateurs et les erreurs de performances détaillés depuis vos applications.",
"xpack.apm.apmSchema.index": "Schéma du serveur APM - Index",
"xpack.apm.apmServiceGroups.title": "Groupes de services APM",
- "xpack.apm.apmSettings.index": "Paramètres APM - Index",
"xpack.apm.apmSettings.save.error": "Une erreur s'est produite lors de l'enregistrement des paramètres",
"xpack.apm.apmSettings.saveButton": "Enregistrer les modifications",
"xpack.apm.appName": "APM",
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index 84c71c20e176d..0b839aaea88f6 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -7905,7 +7905,6 @@
"xpack.apm.apmDescription": "アプリケーション内から自動的に詳細なパフォーマンスメトリックやエラーを集めます。",
"xpack.apm.apmSchema.index": "APMサーバースキーマ - インデックス",
"xpack.apm.apmServiceGroups.title": "APMサービスグループ",
- "xpack.apm.apmSettings.index": "APM 設定 - インデックス",
"xpack.apm.apmSettings.save.error": "設定の保存中にエラーが発生しました",
"xpack.apm.apmSettings.saveButton": "変更を保存",
"xpack.apm.appName": "APM",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index c15e2f639c597..3ac0d9aa42fbf 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -7904,7 +7904,6 @@
"xpack.apm.apmDescription": "自动从您的应用程序内收集深层的性能指标和错误。",
"xpack.apm.apmSchema.index": "APM Server 架构 - 索引",
"xpack.apm.apmServiceGroups.title": "APM 服务组",
- "xpack.apm.apmSettings.index": "APM 设置 - 索引",
"xpack.apm.apmSettings.save.error": "保存设置时出错",
"xpack.apm.apmSettings.saveButton": "保存更改",
"xpack.apm.appName": "APM",
diff --git a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts b/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts
index 4d4488b674a05..0ba4336b36e0c 100644
--- a/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts
+++ b/x-pack/test/apm_api_integration/tests/fleet/apm_package_policy.spec.ts
@@ -17,11 +17,11 @@ import expect from '@kbn/expect';
import { get } from 'lodash';
import type { SourceMap } from '@kbn/apm-plugin/server/routes/source_maps/route';
import { APIReturnType } from '@kbn/apm-plugin/public/services/rest/create_call_apm_api';
+import { createEsClientForTesting } from '@kbn/test';
import {
APM_AGENT_CONFIGURATION_INDEX,
APM_SOURCE_MAP_INDEX,
-} from '@kbn/apm-plugin/server/routes/settings/apm_indices/get_apm_indices';
-import { createEsClientForTesting } from '@kbn/test';
+} from '@kbn/apm-plugin/server/routes/settings/apm_indices/apm_system_index_constants';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import {
createAgentPolicy,
diff --git a/x-pack/test/apm_api_integration/tests/settings/apm_indices/apm_indices.spec.ts b/x-pack/test/apm_api_integration/tests/settings/apm_indices/apm_indices.spec.ts
new file mode 100644
index 0000000000000..5aef295ddb324
--- /dev/null
+++ b/x-pack/test/apm_api_integration/tests/settings/apm_indices/apm_indices.spec.ts
@@ -0,0 +1,74 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import {
+ APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
+ APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+} from '@kbn/apm-data-access-plugin/server/saved_objects/apm_indices';
+import expect from '@kbn/expect';
+import { FtrProviderContext } from '../../../common/ftr_provider_context';
+
+export default function apmIndicesTests({ getService }: FtrProviderContext) {
+ const registry = getService('registry');
+ const kibanaServer = getService('kibanaServer');
+ const apmApiClient = getService('apmApiClient');
+
+ async function deleteSavedObject() {
+ try {
+ return await kibanaServer.savedObjects.delete({
+ type: APM_INDEX_SETTINGS_SAVED_OBJECT_TYPE,
+ id: APM_INDEX_SETTINGS_SAVED_OBJECT_ID,
+ });
+ } catch (e) {
+ if (e.response.status !== 404) {
+ throw e;
+ }
+ }
+ }
+
+ registry.when('APM Indices', { config: 'basic', archives: [] }, () => {
+ beforeEach(async () => {
+ await deleteSavedObject();
+ });
+ afterEach(async () => {
+ await deleteSavedObject();
+ });
+
+ it('returns APM Indices', async () => {
+ const response = await apmApiClient.readUser({
+ endpoint: 'GET /internal/apm/settings/apm-indices',
+ });
+ expect(response.status).to.be(200);
+ expect(response.body).to.eql({
+ transaction: 'traces-apm*,apm-*',
+ span: 'traces-apm*,apm-*',
+ error: 'logs-apm*,apm-*',
+ metric: 'metrics-apm*,apm-*',
+ onboarding: 'apm-*',
+ });
+ });
+
+ it('updates apm indices', async () => {
+ const INDEX_VALUE = 'foo-*';
+
+ const writeResponse = await apmApiClient.writeUser({
+ endpoint: 'POST /internal/apm/settings/apm-indices/save',
+ params: {
+ body: { transaction: INDEX_VALUE },
+ },
+ });
+ expect(writeResponse.status).to.be(200);
+
+ const readResponse = await apmApiClient.readUser({
+ endpoint: 'GET /internal/apm/settings/apm-indices',
+ });
+
+ expect(readResponse.status).to.be(200);
+ expect(readResponse.body.transaction).to.eql(INDEX_VALUE);
+ });
+ });
+}
diff --git a/x-pack/test/tsconfig.json b/x-pack/test/tsconfig.json
index efe7ea1f5e8f8..558660c435b8a 100644
--- a/x-pack/test/tsconfig.json
+++ b/x-pack/test/tsconfig.json
@@ -140,5 +140,6 @@
"@kbn/stack-connectors-plugin",
"@kbn/aiops-utils",
"@kbn/stack-alerts-plugin",
+ "@kbn/apm-data-access-plugin",
]
}
diff --git a/yarn.lock b/yarn.lock
index b4e6feab73a58..a97726e56888d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3038,6 +3038,10 @@
version "0.0.0"
uid ""
+"@kbn/apm-data-access-plugin@link:x-pack/plugins/apm_data_access":
+ version "0.0.0"
+ uid ""
+
"@kbn/apm-plugin@link:x-pack/plugins/apm":
version "0.0.0"
uid ""
From 9d2696b5c5159870cecf02c9f23090b26c924c87 Mon Sep 17 00:00:00 2001
From: Alex Szabo
Date: Tue, 22 Aug 2023 11:47:48 +0200
Subject: [PATCH 07/26] [Ops] Upgrade to axios 1.4 (#163732)
## Summary
upgrade `axios` to 1.4
- adjust to header usage, and config optionality
- Axios' adapters are now resolved from a string key by axios, no need
to import/instantiate adapters
- most of the changed code stems from changes in Axios' types
- `response.config` is now optional
- there was a change in the type of AxiosHeaders <->
InternalAxiosHeaders
Closes: #162661
Closes: #162414
---------
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
package.json | 2 +-
.../src/ci_stats_reporter.ts | 5 +----
.../failed_tests_reporter/github_api.ts | 8 ++++----
packages/kbn-test/src/jest/resolver.js | 7 +++++++
.../src/kbn_client/kbn_client_requester.ts | 2 +-
src/dev/build/lib/download.ts | 8 ++------
.../axios_utils_connection.test.ts | 5 +----
.../axios_utils_proxy.test.ts | 5 +----
.../plugins/actions/server/lib/axios_utils.ts | 20 ++++++++++++++-----
.../sub_action_connector.test.ts | 4 ++--
.../sub_action_connector.ts | 15 ++++++++++----
.../create_apm_users/create_apm_users_cli.ts | 2 +-
.../create_apm_users/helpers/get_version.ts | 6 +++---
.../integration_tests/downloads.test.ts | 2 +-
.../endpoint/common/format_axios_error.ts | 6 +++---
.../server/lib/telemetry/preview_sender.ts | 6 ++++--
.../cases_webhook/utils.test.ts | 2 ++
.../email/send_email_graph_api.test.ts | 1 +
.../connector_types/gen_ai/lib/utils.ts | 4 ++--
.../lib/http_response_retry_header.ts | 4 ++--
.../lib/servicenow/utils.test.ts | 3 ++-
.../connector_types/lib/servicenow/utils.ts | 9 ++++++---
.../connector_types/slack_api/service.ts | 6 ++++--
.../server/connector_types/torq/index.ts | 1 -
.../common/services/ui_capabilities.ts | 4 ++--
yarn.lock | 10 +---------
26 files changed, 80 insertions(+), 67 deletions(-)
diff --git a/package.json b/package.json
index e4bb9e23dbd49..19247a3a1a2fc 100644
--- a/package.json
+++ b/package.json
@@ -808,7 +808,7 @@
"antlr4ts": "^0.5.0-alpha.3",
"archiver": "^5.3.1",
"async": "^3.2.3",
- "axios": "^0.27.2",
+ "axios": "^1.4.0",
"base64-js": "^1.3.1",
"bitmap-sdf": "^1.0.3",
"blurhash": "^2.0.1",
diff --git a/packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts b/packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts
index 0f469de2a4ebe..62da562ad1476 100644
--- a/packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts
+++ b/packages/kbn-ci-stats-reporter/src/ci_stats_reporter.ts
@@ -18,9 +18,6 @@ import { REPO_ROOT, kibanaPackageJson } from '@kbn/repo-info';
import { parseConfig, Config, CiStatsMetadata } from '@kbn/ci-stats-core';
import type { SomeDevLog } from '@kbn/some-dev-log';
-// @ts-expect-error not "public", but necessary to prevent Jest shimming from breaking things
-import httpAdapter from 'axios/lib/adapters/http';
-
import type { CiStatsTestGroupInfo, CiStatsTestRun } from './ci_stats_test_group_types';
const BASE_URL = 'https://ci-stats.kibana.dev';
@@ -375,7 +372,7 @@ export class CiStatsReporter {
headers,
data: body,
params: query,
- adapter: httpAdapter,
+ adapter: 'http',
// if it can be serialized into a string, send it
maxBodyLength: Infinity,
diff --git a/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/github_api.ts b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/github_api.ts
index 5ad0f8417d651..5475dfb9f2da8 100644
--- a/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/github_api.ts
+++ b/packages/kbn-failed-test-reporter-cli/failed_tests_reporter/github_api.ts
@@ -8,7 +8,7 @@
import Url from 'url';
-import Axios, { AxiosRequestConfig, AxiosInstance } from 'axios';
+import Axios, { AxiosRequestConfig, AxiosInstance, AxiosHeaders, AxiosHeaderValue } from 'axios';
import { isAxiosResponseError, isAxiosRequestError } from '@kbn/dev-utils';
import { ToolingLog } from '@kbn/tooling-log';
@@ -130,7 +130,7 @@ export class GithubApi {
): Promise<{
status: number;
statusText: string;
- headers: Record;
+ headers: Record;
data: T;
}> {
const executeRequest = !this.dryRun || options.safeForDryRun;
@@ -145,7 +145,7 @@ export class GithubApi {
return {
status: 200,
statusText: 'OK',
- headers: {},
+ headers: new AxiosHeaders(),
data: dryRunResponse,
};
}
@@ -158,7 +158,7 @@ export class GithubApi {
const githubApiFailed = isAxiosResponseError(error) && error.response.status >= 500;
const errorResponseLog =
isAxiosResponseError(error) &&
- `[${error.config.method} ${error.config.url}] ${error.response.status} ${error.response.statusText} Error`;
+ `[${error.config?.method} ${error.config?.url}] ${error.response.status} ${error.response.statusText} Error`;
if ((unableToReachGithub || githubApiFailed) && attempt < maxAttempts) {
const waitMs = 1000 * attempt;
diff --git a/packages/kbn-test/src/jest/resolver.js b/packages/kbn-test/src/jest/resolver.js
index 6f964b1478fb7..2723851340ae4 100644
--- a/packages/kbn-test/src/jest/resolver.js
+++ b/packages/kbn-test/src/jest/resolver.js
@@ -43,6 +43,13 @@ module.exports = (request, options) => {
return module.exports(request.replace('@elastic/eui/lib/', '@elastic/eui/test-env/'), options);
}
+ if (request === 'axios') {
+ return resolve.sync('axios/dist/node/axios.cjs', {
+ basedir: options.basedir,
+ extensions: options.extensions,
+ });
+ }
+
if (request === `elastic-apm-node`) {
return APM_AGENT_MOCK;
}
diff --git a/packages/kbn-test/src/kbn_client/kbn_client_requester.ts b/packages/kbn-test/src/kbn_client/kbn_client_requester.ts
index be9ea42d94d66..9481e6481b936 100644
--- a/packages/kbn-test/src/kbn_client/kbn_client_requester.ts
+++ b/packages/kbn-test/src/kbn_client/kbn_client_requester.ts
@@ -17,7 +17,7 @@ import { KbnClientRequesterError } from './kbn_client_requester_error';
const isConcliftOnGetError = (error: any) => {
return (
- isAxiosResponseError(error) && error.config.method === 'GET' && error.response.status === 409
+ isAxiosResponseError(error) && error.config?.method === 'GET' && error.response.status === 409
);
};
diff --git a/src/dev/build/lib/download.ts b/src/dev/build/lib/download.ts
index ea9f56cb4fe35..e7ee49e72f79f 100644
--- a/src/dev/build/lib/download.ts
+++ b/src/dev/build/lib/download.ts
@@ -16,10 +16,6 @@ import Axios from 'axios';
import { isAxiosResponseError } from '@kbn/dev-utils';
import { ToolingLog } from '@kbn/tooling-log';
-// https://github.com/axios/axios/tree/ffea03453f77a8176c51554d5f6c3c6829294649/lib/adapters
-// @ts-expect-error untyped internal module used to prevent axios from using xhr adapter in tests
-import AxiosHttpAdapter from 'axios/lib/adapters/http';
-
import { mkdirp } from './fs';
function tryUnlink(path: string) {
@@ -78,7 +74,7 @@ export async function downloadToDisk({
const response = await Axios.request({
url,
responseType: 'stream',
- adapter: AxiosHttpAdapter,
+ adapter: 'http',
});
if (response.status !== 200) {
@@ -171,7 +167,7 @@ export async function downloadToString({
const resp = await Axios.request({
url,
method: 'GET',
- adapter: AxiosHttpAdapter,
+ adapter: 'http',
responseType: 'text',
validateStatus: !expectStatus ? undefined : (status) => status === expectStatus,
});
diff --git a/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts b/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts
index 7a5ed95170cc6..21d2f09537727 100644
--- a/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts
+++ b/x-pack/plugins/actions/server/integration_tests/axios_utils_connection.test.ts
@@ -53,9 +53,6 @@ const UNAUTHORIZED_CA = fsReadFileSync(UNAUTHORIZED_CA_FILE);
const Auth = 'elastic:changeme';
const AuthB64 = Buffer.from(Auth).toString('base64');
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const AxiosDefaultsAadapter = require('axios/lib/adapters/http');
-
describe('axios connections', () => {
let testServer: http.Server | https.Server | null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -65,7 +62,7 @@ describe('axios connections', () => {
// needed to prevent the dreaded Error: Cross origin http://localhost forbidden
// see: https://github.com/axios/axios/issues/1754#issuecomment-572778305
savedAxiosDefaultsAdapter = axios.defaults.adapter;
- axios.defaults.adapter = AxiosDefaultsAadapter;
+ axios.defaults.adapter = 'http';
});
afterEach(() => {
diff --git a/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts b/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts
index fb979968a4636..d5dd8ae91632e 100644
--- a/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts
+++ b/x-pack/plugins/actions/server/integration_tests/axios_utils_proxy.test.ts
@@ -39,9 +39,6 @@ const CA = fsReadFileSync(CA_FILE, 'utf8');
const Auth = 'elastic:changeme';
const AuthB64 = Buffer.from(Auth).toString('base64');
-// eslint-disable-next-line @typescript-eslint/no-var-requires
-const AxiosDefaultsAadapter = require('axios/lib/adapters/http');
-
const ServerResponse = 'A unique response returned by the server!';
describe('axios connections', () => {
@@ -53,7 +50,7 @@ describe('axios connections', () => {
// needed to prevent the dreaded Error: Cross origin http://localhost forbidden
// see: https://github.com/axios/axios/issues/1754#issuecomment-572778305
savedAxiosDefaultsAdapter = axios.defaults.adapter;
- axios.defaults.adapter = AxiosDefaultsAadapter;
+ axios.defaults.adapter = 'http';
});
afterEach(() => {
diff --git a/x-pack/plugins/actions/server/lib/axios_utils.ts b/x-pack/plugins/actions/server/lib/axios_utils.ts
index 30232991f3964..181893db15f0c 100644
--- a/x-pack/plugins/actions/server/lib/axios_utils.ts
+++ b/x-pack/plugins/actions/server/lib/axios_utils.ts
@@ -6,7 +6,14 @@
*/
import { isObjectLike, isEmpty } from 'lodash';
-import { AxiosInstance, Method, AxiosResponse, AxiosRequestConfig } from 'axios';
+import {
+ AxiosInstance,
+ Method,
+ AxiosResponse,
+ AxiosRequestConfig,
+ AxiosHeaders,
+ AxiosHeaderValue,
+} from 'axios';
import { Logger } from '@kbn/core/server';
import { getCustomAgents } from './get_custom_agents';
import { ActionsConfigurationUtilities } from '../actions_config';
@@ -29,7 +36,7 @@ export const request = async ({
method?: Method;
data?: T;
configurationUtilities: ActionsConfigurationUtilities;
- headers?: Record | null;
+ headers?: Record;
sslOverrides?: SSLSettings;
} & AxiosRequestConfig): Promise => {
const { httpAgent, httpsAgent } = getCustomAgents(
@@ -43,8 +50,7 @@ export const request = async ({
return await axios(url, {
...config,
method,
- // Axios doesn't support `null` value for `headers` property.
- headers: headers ?? undefined,
+ headers,
data: data ?? {},
// use httpAgent and httpsAgent and set axios proxy: false, to be able to handle fail on invalid certs
httpAgent,
@@ -149,6 +155,10 @@ export const createAxiosResponse = (res: Partial): AxiosResponse
status: 200,
statusText: 'OK',
headers: { ['content-type']: 'application/json' },
- config: { method: 'GET', url: 'https://example.com' },
+ config: {
+ method: 'GET',
+ url: 'https://example.com',
+ headers: new AxiosHeaders(),
+ },
...res,
});
diff --git a/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.test.ts b/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.test.ts
index 006286cc99a35..5980072217dd5 100644
--- a/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.test.ts
+++ b/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.test.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import axios, { AxiosError, AxiosInstance, AxiosResponse } from 'axios';
+import axios, { AxiosError, AxiosHeaders, AxiosInstance, AxiosResponse } from 'axios';
import { loggingSystemMock } from '@kbn/core/server/mocks';
import { MockedLogger } from '@kbn/logging-mocks';
import { actionsConfigMock } from '../actions_config.mock';
@@ -29,7 +29,7 @@ const requestMock = utils.request as jest.Mock;
const createAxiosError = (): AxiosError => {
const error = new Error() as AxiosError;
error.isAxiosError = true;
- error.config = { method: 'get', url: 'https://example.com' };
+ error.config = { method: 'get', url: 'https://example.com', headers: new AxiosHeaders() };
error.response = {
data: { errorMessage: 'An error occurred', errorCode: 500 },
} as AxiosResponse;
diff --git a/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.ts b/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.ts
index 66f29afcd5ef1..f8b395d31ce4a 100644
--- a/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.ts
+++ b/x-pack/plugins/actions/server/sub_action_framework/sub_action_connector.ts
@@ -8,7 +8,14 @@
import { isPlainObject, isEmpty } from 'lodash';
import { Type } from '@kbn/config-schema';
import { Logger } from '@kbn/logging';
-import axios, { AxiosInstance, AxiosResponse, AxiosError, AxiosRequestHeaders } from 'axios';
+import axios, {
+ AxiosInstance,
+ AxiosResponse,
+ AxiosError,
+ AxiosRequestHeaders,
+ AxiosHeaders,
+ AxiosHeaderValue,
+} from 'axios';
import { SavedObjectsClientContract } from '@kbn/core-saved-objects-api-server';
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import { finished } from 'stream/promises';
@@ -75,7 +82,7 @@ export abstract class SubActionConnector {
}
}
- private getHeaders(headers?: AxiosRequestHeaders) {
+ private getHeaders(headers?: AxiosRequestHeaders): Record {
return { ...headers, 'Content-Type': 'application/json' };
}
@@ -130,7 +137,7 @@ export abstract class SubActionConnector {
method,
data: this.normalizeData(data),
configurationUtilities: this.configurationUtilities,
- headers: this.getHeaders(headers),
+ headers: this.getHeaders(headers as AxiosHeaders),
});
this.validateResponse(responseSchema, res.data);
@@ -139,7 +146,7 @@ export abstract class SubActionConnector {
} catch (error) {
if (isAxiosError(error)) {
this.logger.debug(
- `Request to external service failed. Connector Id: ${this.connector.id}. Connector type: ${this.connector.type}. Method: ${error.config.method}. URL: ${error.config.url}`
+ `Request to external service failed. Connector Id: ${this.connector.id}. Connector type: ${this.connector.type}. Method: ${error.config?.method}. URL: ${error.config?.url}`
);
let responseBody = '';
diff --git a/x-pack/plugins/apm/scripts/create_apm_users/create_apm_users_cli.ts b/x-pack/plugins/apm/scripts/create_apm_users/create_apm_users_cli.ts
index 24cda99fd669b..752c1dba04e93 100644
--- a/x-pack/plugins/apm/scripts/create_apm_users/create_apm_users_cli.ts
+++ b/x-pack/plugins/apm/scripts/create_apm_users/create_apm_users_cli.ts
@@ -84,7 +84,7 @@ init().catch((e) => {
console.error(e.message);
} else if (isAxiosError(e)) {
console.error(
- `${e.config.method?.toUpperCase() || 'GET'} ${e.config.url} (Code: ${
+ `${e.config?.method?.toUpperCase() || 'GET'} ${e.config?.url} (Code: ${
e.response?.status
})`
);
diff --git a/x-pack/plugins/apm/server/test_helpers/create_apm_users/helpers/get_version.ts b/x-pack/plugins/apm/server/test_helpers/create_apm_users/helpers/get_version.ts
index a00747ae78582..070c86dd0be9f 100644
--- a/x-pack/plugins/apm/server/test_helpers/create_apm_users/helpers/get_version.ts
+++ b/x-pack/plugins/apm/server/test_helpers/create_apm_users/helpers/get_version.ts
@@ -31,17 +31,17 @@ export async function getKibanaVersion({
switch (e.response?.status) {
case 401:
throw new AbortError(
- `Could not access Kibana with the provided credentials. Username: "${e.config.auth?.username}". Password: "${e.config.auth?.password}"`
+ `Could not access Kibana with the provided credentials. Username: "${e.config?.auth?.username}". Password: "${e.config?.auth?.password}"`
);
case 404:
throw new AbortError(
- `Could not get version on ${e.config.url} (Code: 404)`
+ `Could not get version on ${e.config?.url} (Code: 404)`
);
default:
throw new AbortError(
- `Cannot access Kibana on ${e.config.baseURL}. Please specify Kibana with: "--kibana-url "`
+ `Cannot access Kibana on ${e.config?.baseURL}. Please specify Kibana with: "--kibana-url "`
);
}
}
diff --git a/x-pack/plugins/screenshotting/server/browsers/chromium/integration_tests/downloads.test.ts b/x-pack/plugins/screenshotting/server/browsers/chromium/integration_tests/downloads.test.ts
index 17031c9dc8c70..a2c331e039389 100644
--- a/x-pack/plugins/screenshotting/server/browsers/chromium/integration_tests/downloads.test.ts
+++ b/x-pack/plugins/screenshotting/server/browsers/chromium/integration_tests/downloads.test.ts
@@ -44,7 +44,7 @@ describe.each(packageInfos)('Chromium archive: %s/%s', (architecture, platform)
const originalAxios = axios.defaults.adapter;
beforeAll(async () => {
- axios.defaults.adapter = require('axios/lib/adapters/http'); // allow Axios to send actual requests
+ axios.defaults.adapter = 'http';
});
afterAll(() => {
diff --git a/x-pack/plugins/security_solution/scripts/endpoint/common/format_axios_error.ts b/x-pack/plugins/security_solution/scripts/endpoint/common/format_axios_error.ts
index ccb3dc125f561..f1b69c8665fc6 100644
--- a/x-pack/plugins/security_solution/scripts/endpoint/common/format_axios_error.ts
+++ b/x-pack/plugins/security_solution/scripts/endpoint/common/format_axios_error.ts
@@ -25,9 +25,9 @@ export class FormattedAxiosError extends Error {
super(axiosError.message);
this.request = {
- method: axiosError.config.method ?? '?',
- url: axiosError.config.url ?? '?',
- data: axiosError.config.data ?? '',
+ method: axiosError.config?.method ?? '?',
+ url: axiosError.config?.url ?? '?',
+ data: axiosError.config?.data ?? '',
};
this.response = {
diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/preview_sender.ts b/x-pack/plugins/security_solution/server/lib/telemetry/preview_sender.ts
index 2c6a55900a14d..a26bbef5ee9d7 100644
--- a/x-pack/plugins/security_solution/server/lib/telemetry/preview_sender.ts
+++ b/x-pack/plugins/security_solution/server/lib/telemetry/preview_sender.ts
@@ -6,7 +6,7 @@
*/
import type { AxiosInstance, AxiosResponse } from 'axios';
-import axios from 'axios';
+import axios, { AxiosHeaders } from 'axios';
import type { Logger } from '@kbn/core/server';
import type { TelemetryPluginStart, TelemetryPluginSetup } from '@kbn/telemetry-plugin/server';
import type { UsageCounter } from '@kbn/usage-collection-plugin/server';
@@ -71,7 +71,9 @@ export class PreviewTelemetryEventsSender implements ITelemetryEventsSender {
status: 200,
statusText: 'ok',
headers: {},
- config: {},
+ config: {
+ headers: new AxiosHeaders(),
+ },
};
return Promise.resolve(okResponse);
}
diff --git a/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/utils.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/utils.test.ts
index 29c732c1b7d40..8e73e1d6682fd 100644
--- a/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/utils.test.ts
+++ b/x-pack/plugins/stack_connectors/server/connector_types/cases_webhook/utils.test.ts
@@ -5,6 +5,7 @@
* 2.0.
*/
+import { AxiosHeaders } from 'axios';
import {
getObjectValueByKeyAsString,
stringifyObjValues,
@@ -60,6 +61,7 @@ describe('cases_webhook/utils', () => {
config: {
method: 'post',
url: 'https://poster.com',
+ headers: new AxiosHeaders({}),
},
};
it('Throws error when missing content-type', () => {
diff --git a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts
index 199681a13e968..bbb5fa2ae5f4e 100644
--- a/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts
+++ b/x-pack/plugins/stack_connectors/server/connector_types/email/send_email_graph_api.test.ts
@@ -6,6 +6,7 @@
*/
jest.mock('axios', () => ({
create: jest.fn(),
+ AxiosHeaders: jest.requireActual('axios').AxiosHeaders,
}));
import axios from 'axios';
diff --git a/x-pack/plugins/stack_connectors/server/connector_types/gen_ai/lib/utils.ts b/x-pack/plugins/stack_connectors/server/connector_types/gen_ai/lib/utils.ts
index b0c953eaa3ae1..d51f85c7aa514 100644
--- a/x-pack/plugins/stack_connectors/server/connector_types/gen_ai/lib/utils.ts
+++ b/x-pack/plugins/stack_connectors/server/connector_types/gen_ai/lib/utils.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { AxiosRequestHeaders, AxiosResponse, ResponseType } from 'axios';
+import { AxiosResponse, ResponseType } from 'axios';
import { IncomingMessage } from 'http';
import { OpenAiProviderType } from '../../../../common/gen_ai/constants';
import {
@@ -77,7 +77,7 @@ export const getAxiosOptions = (
provider: string,
apiKey: string,
stream: boolean
-): { headers: AxiosRequestHeaders; responseType?: ResponseType } => {
+): { headers: Record; responseType?: ResponseType } => {
const responseType = stream ? { responseType: 'stream' as ResponseType } : {};
switch (provider) {
case OpenAiProviderType.OpenAi:
diff --git a/x-pack/plugins/stack_connectors/server/connector_types/lib/http_response_retry_header.ts b/x-pack/plugins/stack_connectors/server/connector_types/lib/http_response_retry_header.ts
index 7f13c3bcf022c..d3c36219da641 100644
--- a/x-pack/plugins/stack_connectors/server/connector_types/lib/http_response_retry_header.ts
+++ b/x-pack/plugins/stack_connectors/server/connector_types/lib/http_response_retry_header.ts
@@ -8,10 +8,10 @@
import { fromNullable, Option, map, filter } from 'fp-ts/lib/Option';
import { pipe } from 'fp-ts/lib/pipeable';
-export function getRetryAfterIntervalFromHeaders(headers: Record): Option {
+export function getRetryAfterIntervalFromHeaders(headers: Record): Option {
return pipe(
fromNullable(headers['retry-after']),
- map((retryAfter) => parseInt(retryAfter, 10)),
+ map((retryAfter) => parseInt(retryAfter as string, 10)),
filter((retryAfter) => !isNaN(retryAfter))
);
}
diff --git a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/utils.test.ts b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/utils.test.ts
index d31dbca880f36..79ca4a662608c 100644
--- a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/utils.test.ts
+++ b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/utils.test.ts
@@ -27,6 +27,7 @@ jest.mock('@kbn/actions-plugin/server/lib/get_oauth_jwt_access_token', () => ({
jest.mock('axios', () => ({
create: jest.fn(),
+ AxiosHeaders: jest.requireActual('axios').AxiosHeaders,
}));
const createAxiosInstanceMock = axios.create as jest.Mock;
const axiosInstanceMock = {
@@ -226,7 +227,7 @@ describe('utils', () => {
const mockRequestCallback = (axiosInstanceMock.interceptors.request.use as jest.Mock).mock
.calls[0][0];
expect(await mockRequestCallback({ headers: {} })).toEqual({
- headers: { Authorization: 'Bearer tokentokentoken' },
+ headers: new axios.AxiosHeaders({ Authorization: 'Bearer tokentokentoken' }),
});
expect(getOAuthJwtAccessToken as jest.Mock).toHaveBeenCalledWith({
diff --git a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/utils.ts b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/utils.ts
index f5ae7baa3e256..2e6ba5327ed2b 100644
--- a/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/utils.ts
+++ b/x-pack/plugins/stack_connectors/server/connector_types/lib/servicenow/utils.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
+import axios, { AxiosHeaders, AxiosInstance, AxiosResponse } from 'axios';
import { Logger } from '@kbn/core/server';
import { addTimeZoneToDate, getErrorMessage } from '@kbn/actions-plugin/server/lib/axios_utils';
import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config';
@@ -112,7 +112,7 @@ export const getAxiosInstance = ({
} else {
axiosInstance = axios.create();
axiosInstance.interceptors.request.use(
- async (axiosConfig: AxiosRequestConfig) => {
+ async (axiosConfig) => {
const accessToken = await getOAuthJwtAccessToken({
connectorId,
logger,
@@ -137,7 +137,10 @@ export const getAxiosInstance = ({
if (!accessToken) {
throw new Error(`Unable to retrieve access token for connectorId: ${connectorId}`);
}
- axiosConfig.headers = { ...axiosConfig.headers, Authorization: accessToken };
+ axiosConfig.headers = new AxiosHeaders({
+ ...axiosConfig.headers,
+ Authorization: accessToken,
+ });
return axiosConfig;
},
(error) => {
diff --git a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts
index 2db25dc52f223..ae85127eb457a 100644
--- a/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts
+++ b/x-pack/plugins/stack_connectors/server/connector_types/slack_api/service.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import axios, { AxiosResponse } from 'axios';
+import axios, { AxiosHeaders, AxiosResponse } from 'axios';
import { Logger } from '@kbn/core/server';
import { i18n } from '@kbn/i18n';
import { ActionsConfigurationUtilities } from '@kbn/actions-plugin/server/actions_config';
@@ -147,7 +147,9 @@ export const createExternalService = (
status: 0,
statusText: '',
headers: {},
- config: {},
+ config: {
+ headers: new AxiosHeaders({}),
+ },
};
while (numberOfFetch < RE_TRY) {
diff --git a/x-pack/plugins/stack_connectors/server/connector_types/torq/index.ts b/x-pack/plugins/stack_connectors/server/connector_types/torq/index.ts
index 860e87397eb44..9d805291cf92c 100644
--- a/x-pack/plugins/stack_connectors/server/connector_types/torq/index.ts
+++ b/x-pack/plugins/stack_connectors/server/connector_types/torq/index.ts
@@ -366,7 +366,6 @@ function retryResult(actionId: string, serviceMessage: string): ActionTypeExecut
function retryResultSeconds(
actionId: string,
serviceMessage: string,
-
retryAfter: number
): ActionTypeExecutorResult {
const retryEpoch = Date.now() + retryAfter * 1000;
diff --git a/x-pack/test/ui_capabilities/common/services/ui_capabilities.ts b/x-pack/test/ui_capabilities/common/services/ui_capabilities.ts
index 9cb3da7e8fd5c..4367b53d1f0f2 100644
--- a/x-pack/test/ui_capabilities/common/services/ui_capabilities.ts
+++ b/x-pack/test/ui_capabilities/common/services/ui_capabilities.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import axios, { AxiosInstance, AxiosRequestHeaders } from 'axios';
+import axios, { AxiosInstance } from 'axios';
import type { Capabilities as UICapabilities } from '@kbn/core/types';
import { format as formatUrl } from 'url';
import util from 'util';
@@ -61,7 +61,7 @@ export class UICapabilitiesService {
this.log.debug(
`requesting ${spaceUrlPrefix}/api/core/capabilities to parse the uiCapabilities`
);
- const requestHeaders: AxiosRequestHeaders = credentials
+ const requestHeaders: Record = credentials
? {
Authorization: `Basic ${Buffer.from(
`${credentials.username}:${credentials.password}`
diff --git a/yarn.lock b/yarn.lock
index a97726e56888d..61fe8a795521c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -11291,14 +11291,6 @@ axios@^0.26.0:
dependencies:
follow-redirects "^1.14.8"
-axios@^0.27.2:
- version "0.27.2"
- resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
- integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
- dependencies:
- follow-redirects "^1.14.9"
- form-data "^4.0.0"
-
axios@^1.3.4, axios@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f"
@@ -16705,7 +16697,7 @@ folktale@2.3.2:
resolved "https://registry.yarnpkg.com/folktale/-/folktale-2.3.2.tgz#38231b039e5ef36989920cbf805bf6b227bf4fd4"
integrity sha512-+8GbtQBwEqutP0v3uajDDoN64K2ehmHd0cjlghhxh0WpcfPzAIjPA03e1VvHlxL02FVGR0A6lwXsNQKn3H1RNQ==
-follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.14.8, follow-redirects@^1.14.9, follow-redirects@^1.15.0:
+follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.14.8, follow-redirects@^1.15.0:
version "1.15.2"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
From 826633cffa677302154ea82ff8288a86a80d6d5a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tim=20R=C3=BChsen?=
Date: Tue, 22 Aug 2023 12:02:17 +0200
Subject: [PATCH 08/26] [Profiling] More realistic CO2 and $ calculations
(#164282)
This PR amends two constants for the CO2 emission and dollar cost
calculations to get more realistic results for the year 2023.
---
.../calculate_impact_estimates.test.ts | 49 ++++++++++---------
.../calculate_impact_estimates/index.ts | 19 ++++---
2 files changed, 38 insertions(+), 30 deletions(-)
diff --git a/x-pack/plugins/profiling/common/calculate_impact_estimates/calculate_impact_estimates.test.ts b/x-pack/plugins/profiling/common/calculate_impact_estimates/calculate_impact_estimates.test.ts
index 626ec8a26dfc2..a1abe24a79faf 100644
--- a/x-pack/plugins/profiling/common/calculate_impact_estimates/calculate_impact_estimates.test.ts
+++ b/x-pack/plugins/profiling/common/calculate_impact_estimates/calculate_impact_estimates.test.ts
@@ -16,35 +16,36 @@ describe('calculateImpactEstimates', () => {
});
expect(totalCPU).toEqual({
- annualizedCo2: 17.909333333333336,
- annualizedCoreSeconds: 1752000,
- annualizedDollarCost: 20.683333333333334,
- co2: 0.0005111111111111112,
+ percentage: 0.1,
coreSeconds: 50,
+ annualizedCoreSeconds: 1752000,
+ co2: 0.00006265168194444443,
+ annualizedCo2: 2.1953149353333328,
dollarCost: 0.0005902777777777778,
- percentage: 0.1,
+ annualizedDollarCost: 20.683333333333334,
});
expect(selfCPU).toEqual({
- annualizedCo2: 8.954666666666668,
- annualizedCoreSeconds: 876000,
- annualizedDollarCost: 10.341666666666667,
- co2: 0.0002555555555555556,
+ percentage: 0.05,
coreSeconds: 25,
+ annualizedCoreSeconds: 876000,
+ co2: 0.000031325840972222215,
+ annualizedCo2: 1.0976574676666664,
dollarCost: 0.0002951388888888889,
- percentage: 0.05,
+ annualizedDollarCost: 10.341666666666667,
});
expect(totalSamples).toEqual({
percentage: 1,
coreSeconds: 500,
annualizedCoreSeconds: 17520000,
- co2: 0.005111111111111111,
- annualizedCo2: 179.09333333333333,
+ co2: 0.0006265168194444444,
+ annualizedCo2: 21.95314935333333,
dollarCost: 0.0059027777777777785,
annualizedDollarCost: 206.83333333333337,
});
});
+
it('calculates impact', () => {
const { selfCPU, totalCPU, totalSamples } = calculateImpactEstimates({
countExclusive: 1000,
@@ -54,31 +55,31 @@ describe('calculateImpactEstimates', () => {
});
expect(totalCPU).toEqual({
- annualizedCo2: 17.909333333333336,
- annualizedCoreSeconds: 1752000,
- annualizedDollarCost: 20.683333333333334,
- co2: 0.0005111111111111112,
+ percentage: 0.1,
coreSeconds: 50,
+ annualizedCoreSeconds: 1752000,
+ co2: 0.00006265168194444443,
+ annualizedCo2: 2.1953149353333328,
dollarCost: 0.0005902777777777778,
- percentage: 0.1,
+ annualizedDollarCost: 20.683333333333334,
});
expect(selfCPU).toEqual({
- annualizedCo2: 17.909333333333336,
- annualizedCoreSeconds: 1752000,
- annualizedDollarCost: 20.683333333333334,
- co2: 0.0005111111111111112,
+ percentage: 0.1,
coreSeconds: 50,
+ annualizedCoreSeconds: 1752000,
+ co2: 0.00006265168194444443,
+ annualizedCo2: 2.1953149353333328,
dollarCost: 0.0005902777777777778,
- percentage: 0.1,
+ annualizedDollarCost: 20.683333333333334,
});
expect(totalSamples).toEqual({
percentage: 1,
coreSeconds: 500,
annualizedCoreSeconds: 17520000,
- co2: 0.005111111111111111,
- annualizedCo2: 179.09333333333333,
+ co2: 0.0006265168194444444,
+ annualizedCo2: 21.95314935333333,
dollarCost: 0.0059027777777777785,
annualizedDollarCost: 206.83333333333337,
});
diff --git a/x-pack/plugins/profiling/common/calculate_impact_estimates/index.ts b/x-pack/plugins/profiling/common/calculate_impact_estimates/index.ts
index 70cfdc109a107..6ebbe26a9fb43 100644
--- a/x-pack/plugins/profiling/common/calculate_impact_estimates/index.ts
+++ b/x-pack/plugins/profiling/common/calculate_impact_estimates/index.ts
@@ -7,13 +7,20 @@
const ANNUAL_SECONDS = 60 * 60 * 24 * 365;
-// The assumed amortized per-core average power consumption.
-const PER_CORE_WATT = 40;
+// The assumed amortized per-core average power consumption (based on 100% CPU Utilization).
+// Reference: https://www.cloudcarbonfootprint.org/docs/methodology/#appendix-i-energy-coefficients
+const PER_CORE_WATT = 7;
-// The assumed CO2 emissions per KWH (sourced from www.eia.gov)
-const CO2_PER_KWH = 0.92;
+// The assumed CO2 emissions in kg per kWh (the reference uses metric tons/kWh).
+// This value represents "regional carbon intensity" and it defaults to AWS us-east-1.
+// Reference: https://www.cloudcarbonfootprint.org/docs/methodology/#appendix-v-grid-emissions-factors
+const CO2_PER_KWH = 0.379069;
-// The cost of a CPU core per hour, in dollars
+// The assumed PUE of the datacenter (1.7 is likely to be an on-prem value).
+const DATACENTER_PUE = 1.7;
+
+// The cost of an x86 CPU core per hour, in US$.
+// (ARM is 60% less based graviton 3 data, see https://aws.amazon.com/ec2/graviton/)
const CORE_COST_PER_HOUR = 0.0425;
export function calculateImpactEstimates({
@@ -61,7 +68,7 @@ function calculateImpact({
const coreSeconds = totalCoreSeconds * percentage;
const annualizedCoreSeconds = coreSeconds * annualizedScaleUp;
const coreHours = coreSeconds / (60 * 60);
- const co2 = ((PER_CORE_WATT * coreHours) / 1000.0) * CO2_PER_KWH;
+ const co2 = ((PER_CORE_WATT * coreHours) / 1000.0) * CO2_PER_KWH * DATACENTER_PUE;
const annualizedCo2 = co2 * annualizedScaleUp;
const dollarCost = coreHours * CORE_COST_PER_HOUR;
const annualizedDollarCost = dollarCost * annualizedScaleUp;
From 2e854d65ce0bc7bbe579d90582151f2ebe50d004 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cau=C3=AA=20Marcondes?=
<55978943+cauemarcondes@users.noreply.github.com>
Date: Tue, 22 Aug 2023 11:14:18 +0100
Subject: [PATCH 09/26] [Profiling] checking viewer resources in the admin
check (#164086)
We identified a bug in the set up check where for admin users we should
also include the checks that were made in the step above.
We also decided to revert the changes in the package names.
---------
Co-authored-by: Francesco Gualazzi
---
x-pack/plugins/profiling/common/setup.test.ts | 54 +++++++++++++++++++
x-pack/plugins/profiling/common/setup.ts | 1 +
.../server/lib/setup/fleet_policies.ts | 8 +--
.../plugins/profiling/server/routes/setup.ts | 5 +-
4 files changed, 60 insertions(+), 8 deletions(-)
diff --git a/x-pack/plugins/profiling/common/setup.test.ts b/x-pack/plugins/profiling/common/setup.test.ts
index 8ffd43c2857e4..100c0efa5cace 100644
--- a/x-pack/plugins/profiling/common/setup.test.ts
+++ b/x-pack/plugins/profiling/common/setup.test.ts
@@ -82,6 +82,9 @@ describe('Merging partial state operations', () => {
const defaultSetupState = createDefaultSetupState();
it('returns false when permission is not configured', () => {
const mergedState = mergePartialSetupStates(defaultSetupState, [
+ createCollectorPolicyState(true),
+ createSymbolizerPolicyState(true),
+ createProfilingInApmPolicyState(true),
createResourceState({ enabled: true, created: true }),
createSettingsState(true),
createPermissionState(false),
@@ -92,6 +95,9 @@ describe('Merging partial state operations', () => {
it('returns false when resource management is not enabled', () => {
const mergedState = mergePartialSetupStates(defaultSetupState, [
+ createCollectorPolicyState(true),
+ createSymbolizerPolicyState(true),
+ createProfilingInApmPolicyState(true),
createResourceState({ enabled: false, created: true }),
createSettingsState(true),
createPermissionState(true),
@@ -102,6 +108,9 @@ describe('Merging partial state operations', () => {
it('returns false when resources are not created', () => {
const mergedState = mergePartialSetupStates(defaultSetupState, [
+ createCollectorPolicyState(true),
+ createSymbolizerPolicyState(true),
+ createProfilingInApmPolicyState(true),
createResourceState({ enabled: true, created: false }),
createSettingsState(true),
createPermissionState(true),
@@ -112,6 +121,9 @@ describe('Merging partial state operations', () => {
it('returns false when settings are not configured', () => {
const mergedState = mergePartialSetupStates(defaultSetupState, [
+ createCollectorPolicyState(true),
+ createSymbolizerPolicyState(true),
+ createProfilingInApmPolicyState(true),
createResourceState({ enabled: true, created: true }),
createSettingsState(false),
createPermissionState(true),
@@ -122,6 +134,9 @@ describe('Merging partial state operations', () => {
it('returns true when all checks are valid', () => {
const mergedState = mergePartialSetupStates(defaultSetupState, [
+ createCollectorPolicyState(true),
+ createSymbolizerPolicyState(true),
+ createProfilingInApmPolicyState(false),
createResourceState({ enabled: true, created: true }),
createSettingsState(true),
createPermissionState(true),
@@ -129,6 +144,45 @@ describe('Merging partial state operations', () => {
expect(areResourcesSetupForAdmin(mergedState)).toBeTruthy();
});
+
+ it('returns false when collector is not found', () => {
+ const mergedState = mergePartialSetupStates(defaultSetupState, [
+ createCollectorPolicyState(false),
+ createSymbolizerPolicyState(true),
+ createProfilingInApmPolicyState(false),
+ createResourceState({ enabled: true, created: true }),
+ createSettingsState(true),
+ createPermissionState(true),
+ ]);
+
+ expect(areResourcesSetupForAdmin(mergedState)).toBeFalsy();
+ });
+
+ it('returns false when symbolizer is not found', () => {
+ const mergedState = mergePartialSetupStates(defaultSetupState, [
+ createCollectorPolicyState(true),
+ createSymbolizerPolicyState(false),
+ createProfilingInApmPolicyState(false),
+ createResourceState({ enabled: true, created: true }),
+ createSettingsState(true),
+ createPermissionState(true),
+ ]);
+
+ expect(areResourcesSetupForAdmin(mergedState)).toBeFalsy();
+ });
+
+ it('returns false when profiling is in APM server', () => {
+ const mergedState = mergePartialSetupStates(defaultSetupState, [
+ createCollectorPolicyState(true),
+ createSymbolizerPolicyState(true),
+ createProfilingInApmPolicyState(true),
+ createResourceState({ enabled: true, created: true }),
+ createSettingsState(true),
+ createPermissionState(true),
+ ]);
+
+ expect(areResourcesSetupForAdmin(mergedState)).toBeFalsy();
+ });
});
describe('For viewer users', () => {
diff --git a/x-pack/plugins/profiling/common/setup.ts b/x-pack/plugins/profiling/common/setup.ts
index b8b998417cc94..e1ee768d9d3d0 100644
--- a/x-pack/plugins/profiling/common/setup.ts
+++ b/x-pack/plugins/profiling/common/setup.ts
@@ -88,6 +88,7 @@ export function areResourcesSetupForViewer(state: SetupState): boolean {
export function areResourcesSetupForAdmin(state: SetupState): boolean {
return (
+ areResourcesSetupForViewer(state) &&
state.resource_management.enabled &&
state.resources.created &&
state.permissions.configured &&
diff --git a/x-pack/plugins/profiling/server/lib/setup/fleet_policies.ts b/x-pack/plugins/profiling/server/lib/setup/fleet_policies.ts
index c6ac504042da5..8ffe13695cddb 100644
--- a/x-pack/plugins/profiling/server/lib/setup/fleet_policies.ts
+++ b/x-pack/plugins/profiling/server/lib/setup/fleet_policies.ts
@@ -15,8 +15,8 @@ import { ELASTIC_CLOUD_APM_POLICY, getApmPolicy } from './get_apm_policy';
import { ProfilingSetupOptions } from './types';
const CLOUD_AGENT_POLICY_ID = 'policy-elastic-agent-on-cloud';
-const COLLECTOR_PACKAGE_POLICY_NAME = 'Universal Profiling Collector';
-const SYMBOLIZER_PACKAGE_POLICY_NAME = 'Universal Profiling Symbolizer';
+const COLLECTOR_PACKAGE_POLICY_NAME = 'elastic-universal-profiling-collector';
+const SYMBOLIZER_PACKAGE_POLICY_NAME = 'elastic-universal-profiling-symbolizer';
async function getPackagePolicy({
soClient,
@@ -103,7 +103,7 @@ export async function createCollectorPackagePolicy({
enabled: true,
package: {
name: packageName,
- title: COLLECTOR_PACKAGE_POLICY_NAME,
+ title: 'Universal Profiling Collector',
version,
},
name: COLLECTOR_PACKAGE_POLICY_NAME,
@@ -161,7 +161,7 @@ export async function createSymbolizerPackagePolicy({
enabled: true,
package: {
name: packageName,
- title: SYMBOLIZER_PACKAGE_POLICY_NAME,
+ title: 'Universal Profiling Symbolizer',
version,
},
name: SYMBOLIZER_PACKAGE_POLICY_NAME,
diff --git a/x-pack/plugins/profiling/server/routes/setup.ts b/x-pack/plugins/profiling/server/routes/setup.ts
index 289a360038fad..4e4e2c15b9f66 100644
--- a/x-pack/plugins/profiling/server/routes/setup.ts
+++ b/x-pack/plugins/profiling/server/routes/setup.ts
@@ -110,10 +110,7 @@ export function registerSetupRoute({
* because of users with viewer privileges
* cannot get the cluster settings
*/
- if (
- areResourcesSetupForViewer(mergedStateForViewer) &&
- mergedStateForViewer.data.available
- ) {
+ if (areResourcesSetupForViewer(mergedStateForViewer)) {
return response.ok({
body: {
has_setup: true,
From 2ca108135a1c6747f4c22bf7a44b45702d01fb5a Mon Sep 17 00:00:00 2001
From: Carlos Crespo
Date: Tue, 22 Aug 2023 12:34:10 +0200
Subject: [PATCH 10/26] [Infra UI] Node Details using Asset Details component
(#164077)
part of [#162898](https://github.com/elastic/kibana/issues/162898)
## Summary
This PR implements the new node details page for hosts. It uses the
Asset Details component, which is the same used in the Hosts View
flyout.
https://github.com/elastic/kibana/assets/2767137/0d3d2b2d-ed82-4275-b424-ddae82cdbddc
It **does not** change the behaviour of other asset types (kubernetes,
container, aws...). The main change this PR introduces is internalizing
the Data Views logic so that clients don't have to worry about passing
it to the Asset Details.
The fundamental change between flyout and page is the template.
Everything else is shared.
Functional tests will be added in a separate PR.
### How to test this PR
- Setup a local Kibana instance
- Navigate to `Infrastructure` > `Hosts`
- Click on a host name and check if the new Node Details page opened
- Return to the hosts page and open a flyout
- Click on `Open as page` and check if the new Node Details page opened
- Navigate to `Infrastructure` > `Inventory`
- With `Show: Host` selected, click on a waffle item to open the flyout,
click on `Open as page` and check if the new Node Details page opened
- Select another asset type in `Show` , open the flyout and check if the
old version of the Node Details Page will show
#### Storybook
`yarn storybook infra`
### For reviewers
Errors in the new page will be handled differently from what the current
Node Details page. i.e: accessing the page with invalid asset id, won't
show this page
---------
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../context/fixtures/asset_details_props.ts | 72 ++++++++
.../context/fixtures/asset_details_state.ts | 37 ----
.../__stories__/context/fixtures/index.ts | 2 +-
.../asset_details/__stories__/decorator.tsx | 45 ++++-
.../asset_details/asset_details.stories.tsx | 57 +-----
.../asset_details/asset_details.tsx | 94 +++-------
.../asset_details_embeddable.tsx | 1 +
.../components/asset_details/constants.ts | 1 +
.../asset_details/context_providers.tsx | 38 ++++
.../asset_details/header/flyout_header.tsx | 87 +++++++++
.../asset_details/header/header.tsx | 148 ---------------
.../hooks/use_asset_details_state.ts | 56 ++----
.../asset_details/hooks/use_data_views.ts | 39 ++++
.../asset_details/hooks/use_date_range.ts | 38 ++++
.../asset_details/hooks/use_metadata_state.ts | 38 ++++
.../asset_details/hooks/use_page_header.tsx | 169 ++++++++++++++++++
.../components/asset_details/links/index.ts | 3 +-
.../links/link_to_apm_services.tsx | 2 +-
.../links/link_to_node_details.tsx | 8 +-
.../asset_details/links/link_to_uptime.tsx | 39 ++++
.../asset_details/links/tab_to_apm_traces.tsx | 44 -----
.../asset_details/links/tab_to_uptime.tsx | 51 ------
.../asset_details/tabs/logs/logs.tsx | 6 +-
.../tabs/metadata/metadata.test.tsx | 19 +-
.../asset_details/tabs/metadata/metadata.tsx | 20 +--
.../asset_details/tabs/osquery/osquery.tsx | 5 +-
.../asset_details/tabs/overview/alerts.tsx | 4 +-
.../tabs/overview/metrics/metrics_grid.tsx | 4 +-
.../asset_details/tabs/overview/overview.tsx | 20 ++-
.../asset_details/template/flyout.tsx | 68 +++++++
.../asset_details/template/page.tsx | 59 ++++++
.../public/components/asset_details/types.ts | 30 ++--
.../public/components/lens/lens_chart.tsx | 4 +-
.../hooks/use_log_view_reference.ts | 4 +-
.../hooks/use_metrics_adhoc_data_view.ts | 42 +++++
.../public/pages/link_to/query_params.ts | 5 +
.../pages/link_to/redirect_to_node_detail.tsx | 23 ++-
.../host_details_flyout/flyout_wrapper.tsx | 33 +---
.../hosts/components/table/entry_title.tsx | 1 +
.../components/tabs/logs/logs_tab_content.tsx | 2 +-
.../public/pages/metrics/hosts/constants.ts | 3 -
.../metrics/hosts/hooks/use_data_view.ts | 27 +--
.../components/node_details/overlay.tsx | 1 +
.../metric_detail/asset_detail_page.tsx | 124 +++++++++++++
.../pages/metrics/metric_detail/index.tsx | 142 +++------------
.../metric_detail/metric_detail_page.tsx | 114 ++++++++++++
.../test/functional/apps/infra/home_page.ts | 3 +-
47 files changed, 1141 insertions(+), 691 deletions(-)
create mode 100644 x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/asset_details_props.ts
delete mode 100644 x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/asset_details_state.ts
create mode 100644 x-pack/plugins/infra/public/components/asset_details/context_providers.tsx
create mode 100644 x-pack/plugins/infra/public/components/asset_details/header/flyout_header.tsx
delete mode 100644 x-pack/plugins/infra/public/components/asset_details/header/header.tsx
create mode 100644 x-pack/plugins/infra/public/components/asset_details/hooks/use_data_views.ts
create mode 100644 x-pack/plugins/infra/public/components/asset_details/hooks/use_date_range.ts
create mode 100644 x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata_state.ts
create mode 100644 x-pack/plugins/infra/public/components/asset_details/hooks/use_page_header.tsx
create mode 100644 x-pack/plugins/infra/public/components/asset_details/links/link_to_uptime.tsx
delete mode 100644 x-pack/plugins/infra/public/components/asset_details/links/tab_to_apm_traces.tsx
delete mode 100644 x-pack/plugins/infra/public/components/asset_details/links/tab_to_uptime.tsx
create mode 100644 x-pack/plugins/infra/public/components/asset_details/template/flyout.tsx
create mode 100644 x-pack/plugins/infra/public/components/asset_details/template/page.tsx
rename x-pack/plugins/infra/public/{pages/metrics/hosts => }/hooks/use_log_view_reference.ts (94%)
create mode 100644 x-pack/plugins/infra/public/hooks/use_metrics_adhoc_data_view.ts
create mode 100644 x-pack/plugins/infra/public/pages/metrics/metric_detail/asset_detail_page.tsx
create mode 100644 x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx
diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/asset_details_props.ts b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/asset_details_props.ts
new file mode 100644
index 0000000000000..05e17c16eb929
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/asset_details_props.ts
@@ -0,0 +1,72 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { i18n } from '@kbn/i18n';
+import { type AssetDetailsProps, FlyoutTabIds, type Tab } from '../../../types';
+
+const links: AssetDetailsProps['links'] = ['alertRule', 'nodeDetails', 'apmServices'];
+const tabs: Tab[] = [
+ {
+ id: FlyoutTabIds.OVERVIEW,
+ name: i18n.translate('xpack.infra.nodeDetails.tabs.overview.title', {
+ defaultMessage: 'Overview',
+ }),
+ },
+ {
+ id: FlyoutTabIds.LOGS,
+ name: i18n.translate('xpack.infra.nodeDetails.tabs.logs', {
+ defaultMessage: 'Logs',
+ }),
+ },
+ {
+ id: FlyoutTabIds.METADATA,
+ name: i18n.translate('xpack.infra.metrics.nodeDetails.tabs.metadata', {
+ defaultMessage: 'Metadata',
+ }),
+ },
+ {
+ id: FlyoutTabIds.PROCESSES,
+ name: i18n.translate('xpack.infra.metrics.nodeDetails.tabs.processes', {
+ defaultMessage: 'Processes',
+ }),
+ },
+ {
+ id: FlyoutTabIds.ANOMALIES,
+ name: i18n.translate('xpack.infra.nodeDetails.tabs.anomalies', {
+ defaultMessage: 'Anomalies',
+ }),
+ },
+ {
+ id: FlyoutTabIds.LINK_TO_APM,
+ name: i18n.translate('xpack.infra.infra.nodeDetails.apmTabLabel', {
+ defaultMessage: 'APM',
+ }),
+ },
+];
+
+export const assetDetailsProps: AssetDetailsProps = {
+ asset: {
+ name: 'host1',
+ id: 'host1',
+ },
+ overrides: {
+ metadata: {
+ showActionsColumn: true,
+ },
+ },
+ assetType: 'host',
+ renderMode: {
+ mode: 'page',
+ },
+ dateRange: {
+ from: '2023-04-09T11:07:49Z',
+ to: '2023-04-09T11:23:49Z',
+ },
+ tabs,
+ links,
+ metricAlias: 'metrics-*',
+};
diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/asset_details_state.ts b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/asset_details_state.ts
deleted file mode 100644
index 4e88dc368ca0a..0000000000000
--- a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/asset_details_state.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 type { DataViewField, DataView } from '@kbn/data-views-plugin/common';
-import { UseAssetDetailsStateProps } from '../../../hooks/use_asset_details_state';
-
-export const assetDetailsState: UseAssetDetailsStateProps['state'] = {
- asset: {
- name: 'host1',
- id: 'host1-macOS',
- ip: '192.168.0.1',
- },
- overrides: {
- overview: {
- metricsDataView: {
- id: 'default',
- getFieldByName: () => 'hostname' as unknown as DataViewField,
- } as unknown as DataView,
- logsDataView: {
- id: 'default',
- getFieldByName: () => 'hostname' as unknown as DataViewField,
- } as unknown as DataView,
- },
- metadata: {
- showActionsColumn: true,
- },
- },
- assetType: 'host',
- dateRange: {
- from: '2023-04-09T11:07:49Z',
- to: '2023-04-09T11:23:49Z',
- },
-};
diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/index.ts b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/index.ts
index 00467475b80b4..74ddade7c54ef 100644
--- a/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/index.ts
+++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/context/fixtures/index.ts
@@ -15,4 +15,4 @@ export { alertsSummaryHttpResponse, type AlertsSummaryHttpMocks } from './alerts
export { anomaliesHttpResponse, type AnomaliesHttpMocks } from './anomalies';
export { snapshotAPItHttpResponse, type SnapshotAPIHttpMocks } from './snapshot_api';
export { getLogEntries } from './log_entries';
-export { assetDetailsState } from './asset_details_state';
+export { assetDetailsProps } from './asset_details_props';
diff --git a/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx b/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx
index e0a9ca3ec8679..340d314be6ce4 100644
--- a/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/__stories__/decorator.tsx
@@ -21,17 +21,25 @@ import type { IKibanaSearchRequest, ISearchOptions } from '@kbn/data-plugin/publ
import { AlertSummaryWidget } from '@kbn/triggers-actions-ui-plugin/public/application/sections/alert_summary_widget/alert_summary_widget';
import type { Theme } from '@elastic/charts/dist/utils/themes/theme';
import type { AlertSummaryWidgetProps } from '@kbn/triggers-actions-ui-plugin/public/application/sections/alert_summary_widget';
+import { defaultLogViewAttributes } from '@kbn/logs-shared-plugin/common';
+import { DataView, DataViewField } from '@kbn/data-views-plugin/common';
import type { PluginKibanaContextValue } from '../../../hooks/use_kibana';
import { SourceProvider } from '../../../containers/metrics_source';
import { getHttp } from './context/http';
-import { assetDetailsState, getLogEntries } from './context/fixtures';
-import { AssetDetailsStateProvider } from '../hooks/use_asset_details_state';
+import { assetDetailsProps, getLogEntries } from './context/fixtures';
+import { ContextProviders } from '../context_providers';
+import { DataViewsProvider } from '../hooks/use_data_views';
const settings: Record = {
'dateFormat:scaled': [['', 'HH:mm:ss.SSS']],
};
const getSettings = (key: string): any => settings[key];
+const mockDataView = {
+ id: 'default',
+ getFieldByName: () => 'hostname' as unknown as DataViewField,
+} as unknown as DataView;
+
export const DecorateWithKibanaContext: DecoratorFn = (story) => {
const initialProcesses = useParameter<{ mock: string }>('apiResponse', {
mock: 'default',
@@ -58,6 +66,9 @@ export const DecorateWithKibanaContext: DecoratorFn = (story) => {
},
},
},
+ dataViews: {
+ create: () => Promise.resolve(mockDataView),
+ },
locators: {
nodeLogsLocator: {
getRedirectUrl: () => {
@@ -111,6 +122,22 @@ export const DecorateWithKibanaContext: DecoratorFn = (story) => {
},
},
},
+ logsShared: {
+ logViews: {
+ client: {
+ getLogView: () =>
+ Promise.resolve({
+ id: 'log',
+ attributes: defaultLogViewAttributes,
+ origin: 'internal',
+ }),
+ getResolvedLogView: () =>
+ Promise.resolve({
+ dataViewReference: mockDataView,
+ } as any),
+ },
+ },
+ },
lens: {
navigateToPrefilledEditor: () => {},
stateHelperApi: () => new Promise(() => {}),
@@ -130,5 +157,17 @@ export const DecorateWithKibanaContext: DecoratorFn = (story) => {
};
export const DecorateWithAssetDetailsStateContext: DecoratorFn = (story) => {
- return {story()} ;
+ return (
+
+ {story()}
+
+ );
};
diff --git a/x-pack/plugins/infra/public/components/asset_details/asset_details.stories.tsx b/x-pack/plugins/infra/public/components/asset_details/asset_details.stories.tsx
index 824a4e5f65ef0..0816e25dc800b 100644
--- a/x-pack/plugins/infra/public/components/asset_details/asset_details.stories.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/asset_details.stories.tsx
@@ -8,52 +8,11 @@
import React, { useState } from 'react';
import { EuiButton } from '@elastic/eui';
import type { Meta, Story } from '@storybook/react/types-6-0';
-import { i18n } from '@kbn/i18n';
import { AssetDetails } from './asset_details';
import { decorateWithGlobalStorybookThemeProviders } from '../../test_utils/use_global_storybook_theme';
-import { FlyoutTabIds, Tab, type AssetDetailsProps } from './types';
+import { type AssetDetailsProps } from './types';
import { DecorateWithKibanaContext } from './__stories__/decorator';
-import { assetDetailsState } from './__stories__/context/fixtures';
-
-const links: AssetDetailsProps['links'] = ['alertRule', 'nodeDetails', 'apmServices'];
-const tabs: Tab[] = [
- {
- id: FlyoutTabIds.OVERVIEW,
- name: i18n.translate('xpack.infra.nodeDetails.tabs.overview.title', {
- defaultMessage: 'Overview',
- }),
- },
- {
- id: FlyoutTabIds.LOGS,
- name: i18n.translate('xpack.infra.nodeDetails.tabs.logs', {
- defaultMessage: 'Logs',
- }),
- },
- {
- id: FlyoutTabIds.METADATA,
- name: i18n.translate('xpack.infra.metrics.nodeDetails.tabs.metadata', {
- defaultMessage: 'Metadata',
- }),
- },
- {
- id: FlyoutTabIds.PROCESSES,
- name: i18n.translate('xpack.infra.metrics.nodeDetails.tabs.processes', {
- defaultMessage: 'Processes',
- }),
- },
- {
- id: FlyoutTabIds.ANOMALIES,
- name: i18n.translate('xpack.infra.nodeDetails.tabs.anomalies', {
- defaultMessage: 'Anomalies',
- }),
- },
- {
- id: FlyoutTabIds.LINK_TO_APM,
- name: i18n.translate('xpack.infra.infra.nodeDetails.apmTabLabel', {
- defaultMessage: 'APM',
- }),
- },
-];
+import { assetDetailsProps } from './__stories__/context/fixtures';
const stories: Meta = {
title: 'infra/Asset Details View',
@@ -61,16 +20,14 @@ const stories: Meta = {
component: AssetDetails,
argTypes: {
links: {
- options: links,
+ options: assetDetailsProps.links,
control: {
type: 'inline-check',
},
},
},
args: {
- ...assetDetailsState,
- tabs,
- links,
+ ...assetDetailsProps,
},
};
@@ -99,11 +56,5 @@ const FlyoutTemplate: Story = (args) => {
export const Page = PageTemplate.bind({});
export const Flyout = FlyoutTemplate.bind({});
-Flyout.args = {
- renderMode: {
- mode: 'flyout',
- closeFlyout: () => {},
- },
-};
export default stories;
diff --git a/x-pack/plugins/infra/public/components/asset_details/asset_details.tsx b/x-pack/plugins/infra/public/components/asset_details/asset_details.tsx
index e55a222b54719..95c5b4836a196 100644
--- a/x-pack/plugins/infra/public/components/asset_details/asset_details.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/asset_details.tsx
@@ -6,92 +6,42 @@
*/
import React from 'react';
-import { EuiFlyout, EuiFlyoutHeader, EuiFlyoutBody } from '@elastic/eui';
-import useEffectOnce from 'react-use/lib/useEffectOnce';
-import type { AssetDetailsProps, RenderMode } from './types';
-import { Content } from './content/content';
-import { Header } from './header/header';
-import { TabSwitcherProvider, useTabSwitcherContext } from './hooks/use_tab_switcher';
-import {
- AssetDetailsStateProvider,
- useAssetDetailsStateContext,
-} from './hooks/use_asset_details_state';
-import { useKibanaContextForPlugin } from '../../hooks/use_kibana';
-import { ASSET_DETAILS_FLYOUT_COMPONENT_NAME } from './constants';
-
-interface ContentTemplateProps {
- header: React.ReactElement;
- body: React.ReactElement;
- renderMode: RenderMode;
-}
-
-const ContentTemplate = ({ header, body, renderMode }: ContentTemplateProps) => {
- const { assetType } = useAssetDetailsStateContext();
- const { initialActiveTabId } = useTabSwitcherContext();
- const {
- services: { telemetry },
- } = useKibanaContextForPlugin();
-
- useEffectOnce(() => {
- telemetry.reportAssetDetailsFlyoutViewed({
- componentName: ASSET_DETAILS_FLYOUT_COMPONENT_NAME,
- assetType,
- tabId: initialActiveTabId,
- });
- });
+import type { AssetDetailsProps, ContentTemplateProps, RenderMode } from './types';
+import { Flyout } from './template/flyout';
+import { Page } from './template/page';
+import { ContextProviders } from './context_providers';
+import { TabSwitcherProvider } from './hooks/use_tab_switcher';
+import { DataViewsProvider } from './hooks/use_data_views';
+const ContentTemplate = ({
+ header,
+ renderMode,
+}: ContentTemplateProps & { renderMode: RenderMode }) => {
return renderMode.mode === 'flyout' ? (
-
- {header}
- {body}
-
+
) : (
- <>
- {header}
- {body}
- >
+
);
};
export const AssetDetails = ({
- asset,
- dateRange,
+ tabs,
+ links,
+ renderMode,
activeTabId,
- overrides,
- onTabsStateChange,
- tabs = [],
- links = [],
- assetType = 'host',
- renderMode = {
- mode: 'page',
- },
+ metricAlias,
+ ...props
}: AssetDetailsProps) => {
return (
-
+
0 ? activeTabId ?? tabs[0].id : undefined}
>
- }
- body={ }
- renderMode={renderMode}
- />
+
+
+
-
+
);
};
diff --git a/x-pack/plugins/infra/public/components/asset_details/asset_details_embeddable.tsx b/x-pack/plugins/infra/public/components/asset_details/asset_details_embeddable.tsx
index 534ba4c2e4265..3aff0ea4b2548 100644
--- a/x-pack/plugins/infra/public/components/asset_details/asset_details_embeddable.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/asset_details_embeddable.tsx
@@ -80,6 +80,7 @@ export class AssetDetailsEmbeddable extends Embeddable
diff --git a/x-pack/plugins/infra/public/components/asset_details/constants.ts b/x-pack/plugins/infra/public/components/asset_details/constants.ts
index e45a842951a4c..726f47450d0cc 100644
--- a/x-pack/plugins/infra/public/components/asset_details/constants.ts
+++ b/x-pack/plugins/infra/public/components/asset_details/constants.ts
@@ -7,3 +7,4 @@
export const ASSET_DETAILS_FLYOUT_COMPONENT_NAME = 'infraAssetDetailsFlyout';
export const METRIC_CHART_HEIGHT = 300;
+export const APM_HOST_FILTER_FIELD = 'host.hostname';
diff --git a/x-pack/plugins/infra/public/components/asset_details/context_providers.tsx b/x-pack/plugins/infra/public/components/asset_details/context_providers.tsx
new file mode 100644
index 0000000000000..179a1bfaf80b3
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/context_providers.tsx
@@ -0,0 +1,38 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import { AssetDetailsStateProvider } from './hooks/use_asset_details_state';
+import { DateRangeProvider } from './hooks/use_date_range';
+import { MetadataStateProvider } from './hooks/use_metadata_state';
+import { AssetDetailsProps } from './types';
+
+export const ContextProviders = ({
+ props,
+ children,
+}: { props: Omit } & {
+ children: React.ReactNode;
+}) => {
+ const { asset, dateRange, overrides, onTabsStateChange, assetType = 'host', renderMode } = props;
+ return (
+
+
+
+ {children}
+
+
+
+ );
+};
diff --git a/x-pack/plugins/infra/public/components/asset_details/header/flyout_header.tsx b/x-pack/plugins/infra/public/components/asset_details/header/flyout_header.tsx
new file mode 100644
index 0000000000000..05f96a331a07c
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/header/flyout_header.tsx
@@ -0,0 +1,87 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import {
+ EuiTitle,
+ EuiSpacer,
+ EuiFlexItem,
+ EuiFlexGroup,
+ EuiTabs,
+ EuiTab,
+ useEuiTheme,
+ useEuiMinBreakpoint,
+ type EuiPageHeaderProps,
+} from '@elastic/eui';
+import { css } from '@emotion/react';
+type Props = Pick;
+
+export const FlyoutHeader = ({ title, tabs = [], rightSideItems = [] }: Props) => {
+ const { euiTheme } = useEuiTheme();
+
+ return (
+ <>
+
+
+
+ {title}
+
+
+
+
+ {rightSideItems?.map((item, index) => (
+
+ {item}
+
+ ))}
+
+
+
+
+
+ {tabs.map(({ label, ...tab }, index) => (
+
+ {label}
+
+ ))}
+
+ >
+ );
+};
diff --git a/x-pack/plugins/infra/public/components/asset_details/header/header.tsx b/x-pack/plugins/infra/public/components/asset_details/header/header.tsx
deleted file mode 100644
index 2d9993f0f16d0..0000000000000
--- a/x-pack/plugins/infra/public/components/asset_details/header/header.tsx
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import React from 'react';
-import {
- EuiTitle,
- EuiSpacer,
- EuiFlexItem,
- EuiFlexGroup,
- EuiTabs,
- EuiTab,
- useEuiTheme,
- useEuiMinBreakpoint,
-} from '@elastic/eui';
-import { css } from '@emotion/react';
-import { capitalize } from 'lodash';
-import { AssetDetailsProps, FlyoutTabIds, LinkOptions, Tab, TabIds } from '../types';
-import {
- LinkToApmServices,
- LinkToAlertsRule,
- LinkToNodeDetails,
- TabToApmTraces,
- TabToUptime,
-} from '../links';
-import { useTabSwitcherContext } from '../hooks/use_tab_switcher';
-import { useAssetDetailsStateContext } from '../hooks/use_asset_details_state';
-import { toTimestampRange } from '../utils';
-
-type Props = Pick & {
- compact: boolean;
-};
-
-const APM_FIELD = 'host.hostname';
-
-export const Header = ({ tabs = [], links = [], compact }: Props) => {
- const { asset, assetType, overrides, dateRange: timeRange } = useAssetDetailsStateContext();
- const { euiTheme } = useEuiTheme();
- const { showTab, activeTabId } = useTabSwitcherContext();
-
- const onTabClick = (tabId: TabIds) => {
- showTab(tabId);
- };
-
- const tabLinkComponents = {
- [FlyoutTabIds.LINK_TO_APM]: (tab: Tab) => (
-
- ),
- [FlyoutTabIds.LINK_TO_UPTIME]: (tab: Tab) => (
-
- ),
- };
-
- const topCornerLinkComponents: Record = {
- nodeDetails: (
-
- ),
- alertRule: ,
- apmServices: ,
- };
-
- const tabEntries = tabs.map(({ name, ...tab }) => {
- if (Object.keys(tabLinkComponents).includes(tab.id)) {
- return (
-
- {tabLinkComponents[tab.id as keyof typeof tabLinkComponents]({ name, ...tab })}
-
- );
- }
-
- return (
- onTabClick(tab.id)}
- isSelected={tab.id === activeTabId}
- >
- {name}
-
- );
- });
-
- return (
- <>
-
-
-
- {compact ? {asset.name} : {asset.name} }
-
-
-
-
- {links?.map((link, index) => (
-
- {topCornerLinkComponents[link]}
-
- ))}
-
-
-
-
-
- {tabEntries}
-
- >
- );
-};
diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_asset_details_state.ts b/x-pack/plugins/infra/public/components/asset_details/hooks/use_asset_details_state.ts
index 3ef55cc755b03..c8bd88f126859 100644
--- a/x-pack/plugins/infra/public/components/asset_details/hooks/use_asset_details_state.ts
+++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_asset_details_state.ts
@@ -6,66 +6,38 @@
*/
import createContainer from 'constate';
-import { useMemo } from 'react';
-import { findInventoryModel } from '../../../../common/inventory_models';
-import { useSourceContext } from '../../../containers/metrics_source';
-import { useMetadata } from './use_metadata';
-import { parseDateRange } from '../../../utils/datemath';
import type { AssetDetailsProps } from '../types';
-import { toTimestampRange } from '../utils';
-
-const DEFAULT_DATE_RANGE = {
- from: 'now-15m',
- to: 'now',
-};
+import { useDateRangeProviderContext } from './use_date_range';
+import { useMetadataStateProviderContext } from './use_metadata_state';
export interface UseAssetDetailsStateProps {
state: Pick<
AssetDetailsProps,
- 'asset' | 'assetType' | 'overrides' | 'dateRange' | 'onTabsStateChange' | 'renderMode'
+ 'asset' | 'assetType' | 'overrides' | 'onTabsStateChange' | 'renderMode'
>;
}
export function useAssetDetailsState({ state }: UseAssetDetailsStateProps) {
- const {
- asset,
- assetType,
- dateRange: rawDateRange,
- onTabsStateChange,
- overrides,
- renderMode,
- } = state;
+ const { metadata } = useMetadataStateProviderContext();
+ const { dateRange, dateRangeTs } = useDateRangeProviderContext();
+ const { asset, assetType, onTabsStateChange, overrides, renderMode } = state;
- const dateRange = useMemo(() => {
- const { from = DEFAULT_DATE_RANGE.from, to = DEFAULT_DATE_RANGE.to } =
- parseDateRange(rawDateRange);
-
- return { from, to };
- }, [rawDateRange]);
-
- const dateRangeTs = toTimestampRange(dateRange);
-
- const inventoryModel = findInventoryModel(assetType);
- const { sourceId } = useSourceContext();
- const {
- loading: metadataLoading,
- error: fetchMetadataError,
- metadata,
- } = useMetadata(asset.name, assetType, inventoryModel.requiredMetrics, sourceId, dateRangeTs);
+ // When the asset asset.name is known we can load the page faster
+ // Otherwise we need to use metadata response.
+ const loading = !asset.name && !metadata?.name;
return {
- asset,
+ asset: {
+ ...asset,
+ name: asset.name || metadata?.name || 'asset-name',
+ },
assetType,
dateRange,
dateRangeTs,
onTabsStateChange,
overrides,
renderMode,
- metadataResponse: {
- metadataLoading,
- fetchMetadataError,
- metadata,
- },
+ loading,
};
}
diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_data_views.ts b/x-pack/plugins/infra/public/components/asset_details/hooks/use_data_views.ts
new file mode 100644
index 0000000000000..ec299be484f2d
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_data_views.ts
@@ -0,0 +1,39 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import useAsync from 'react-use/lib/useAsync';
+import createContainer from 'constate';
+import { useLogViewReference } from '../../../hooks/use_log_view_reference';
+import { useDataMetricsAdHocDataView } from '../../../hooks/use_metrics_adhoc_data_view';
+
+const useDataViews = ({ metricAlias }: { metricAlias: string }) => {
+ const { dataView: metricsDataView, loading: metricsDataViewLoading } =
+ useDataMetricsAdHocDataView({ metricAlias });
+ const {
+ logViewReference,
+ getLogsDataView,
+ loading: logsReferenceLoading,
+ } = useLogViewReference({
+ id: 'asset-details-logs-view',
+ });
+
+ const { value: logsDataView, loading: logsDataViewLoading } = useAsync(
+ () => getLogsDataView(logViewReference),
+ [logViewReference]
+ );
+
+ return {
+ metrics: { dataView: metricsDataView, loading: metricsDataViewLoading },
+ logs: {
+ dataView: logsDataView,
+ reference: logViewReference,
+ loading: logsReferenceLoading || logsDataViewLoading,
+ },
+ };
+};
+
+export const [DataViewsProvider, useDataViewsProviderContext] = createContainer(useDataViews);
diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_date_range.ts b/x-pack/plugins/infra/public/components/asset_details/hooks/use_date_range.ts
new file mode 100644
index 0000000000000..bb20ddab56957
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_date_range.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import createContainer from 'constate';
+import { useMemo } from 'react';
+import { parseDateRange } from '../../../utils/datemath';
+import type { AssetDetailsProps } from '../types';
+import { toTimestampRange } from '../utils';
+
+const DEFAULT_DATE_RANGE = {
+ from: 'now-15m',
+ to: 'now',
+};
+
+export type UseAssetDetailsStateProps = Pick;
+
+export function useDateRangeProvider({ dateRange: rawDateRange }: UseAssetDetailsStateProps) {
+ const dateRange = useMemo(() => {
+ const { from = DEFAULT_DATE_RANGE.from, to = DEFAULT_DATE_RANGE.to } =
+ parseDateRange(rawDateRange);
+
+ return { from, to };
+ }, [rawDateRange]);
+
+ const dateRangeTs = toTimestampRange(dateRange);
+
+ return {
+ dateRange,
+ dateRangeTs,
+ };
+}
+
+export const [DateRangeProvider, useDateRangeProviderContext] =
+ createContainer(useDateRangeProvider);
diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata_state.ts b/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata_state.ts
new file mode 100644
index 0000000000000..e9a162b2a4c7e
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_metadata_state.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import createContainer from 'constate';
+import { findInventoryModel } from '../../../../common/inventory_models';
+import { useSourceContext } from '../../../containers/metrics_source';
+import { useMetadata } from './use_metadata';
+import { AssetDetailsProps } from '../types';
+import { useDateRangeProviderContext } from './use_date_range';
+
+export type UseMetadataProviderProps = Pick;
+
+export function useMetadataProvider({ asset, assetType }: UseMetadataProviderProps) {
+ const { dateRangeTs } = useDateRangeProviderContext();
+ const inventoryModel = findInventoryModel(assetType);
+ const { sourceId } = useSourceContext();
+
+ const { loading, error, metadata } = useMetadata(
+ asset.id,
+ assetType,
+ inventoryModel.requiredMetrics,
+ sourceId,
+ dateRangeTs
+ );
+
+ return {
+ loading,
+ error,
+ metadata,
+ };
+}
+
+export const [MetadataStateProvider, useMetadataStateProviderContext] =
+ createContainer(useMetadataProvider);
diff --git a/x-pack/plugins/infra/public/components/asset_details/hooks/use_page_header.tsx b/x-pack/plugins/infra/public/components/asset_details/hooks/use_page_header.tsx
new file mode 100644
index 0000000000000..c7db9b6c4893c
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/hooks/use_page_header.tsx
@@ -0,0 +1,169 @@
+/*
+ * Copyright 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 { useEuiTheme, EuiIcon, type EuiPageHeaderProps } from '@elastic/eui';
+import { css } from '@emotion/react';
+import { useLinkProps } from '@kbn/observability-shared-plugin/public';
+import React, { useCallback, useMemo } from 'react';
+import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/public';
+import { capitalize } from 'lodash';
+import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';
+import { APM_HOST_FILTER_FIELD } from '../constants';
+import { LinkToAlertsRule, LinkToApmServices, LinkToNodeDetails, LinkToUptime } from '../links';
+import { FlyoutTabIds, type LinkOptions, type Tab, type TabIds } from '../types';
+import { toTimestampRange } from '../utils';
+import { useAssetDetailsStateContext } from './use_asset_details_state';
+import { useDateRangeProviderContext } from './use_date_range';
+import { useTabSwitcherContext } from './use_tab_switcher';
+import { useMetadataStateProviderContext } from './use_metadata_state';
+
+type TabItem = NonNullable['tabs']>[number];
+
+export const usePageHeader = (tabs: Tab[], links?: LinkOptions[]) => {
+ const { rightSideItems } = useRightSideItems(links);
+ const { tabEntries } = useTabs(tabs);
+
+ return { rightSideItems, tabEntries };
+};
+
+const useRightSideItems = (links?: LinkOptions[]) => {
+ const { dateRange } = useDateRangeProviderContext();
+ const { asset, assetType, overrides } = useAssetDetailsStateContext();
+ const { metadata } = useMetadataStateProviderContext();
+
+ const topCornerLinkComponents: Record = useMemo(
+ () => ({
+ nodeDetails: (
+
+ ),
+ alertRule: ,
+ apmServices: ,
+ uptime: (
+
+ ),
+ }),
+ [asset, assetType, dateRange, metadata?.info?.host?.ip, overrides?.alertRule?.onCreateRuleClick]
+ );
+
+ const rightSideItems = useMemo(
+ () => links?.map((link) => topCornerLinkComponents[link]),
+ [links, topCornerLinkComponents]
+ );
+
+ return { rightSideItems };
+};
+
+const useTabs = (tabs: Tab[]) => {
+ const { showTab, activeTabId } = useTabSwitcherContext();
+ const { asset, assetType } = useAssetDetailsStateContext();
+ const { metadata } = useMetadataStateProviderContext();
+ const { share } = useKibanaContextForPlugin().services;
+ const { euiTheme } = useEuiTheme();
+
+ const onTabClick = useCallback(
+ (tabId: TabIds) => {
+ showTab(tabId);
+ },
+ [showTab]
+ );
+
+ const apmTracesMenuItemLinkProps = useLinkProps({
+ app: 'apm',
+ hash: 'traces',
+ search: {
+ kuery: `${APM_HOST_FILTER_FIELD}:"${asset.name}"`,
+ },
+ });
+
+ const getTabToApmTraces = useCallback(
+ (name: string) => ({
+ ...apmTracesMenuItemLinkProps,
+ 'data-test-subj': 'infraAssetDetailsApmServicesLinkTab',
+ label: (
+ <>
+
+ {name}
+ >
+ ),
+ }),
+ [apmTracesMenuItemLinkProps, euiTheme.size.xs]
+ );
+
+ const getTabToUptime = useCallback(
+ (name: string) => ({
+ 'data-test-subj': 'infraAssetDetailsUptimeLinkTab',
+ onClick: () =>
+ share.url.locators.get(uptimeOverviewLocatorID)!.navigate({
+ [assetType]: asset.id,
+ ip: (Array.isArray(metadata?.info?.host?.ip)
+ ? metadata?.info?.host?.ip ?? []
+ : [metadata?.info?.host?.ip])[0],
+ }),
+ label: (
+ <>
+
+ {name}
+ >
+ ),
+ }),
+ [asset.id, assetType, euiTheme.size.xs, metadata?.info?.host?.ip, share.url.locators]
+ );
+
+ const tabbedLinks = useMemo(
+ () => ({
+ [FlyoutTabIds.LINK_TO_APM]: getTabToApmTraces,
+ [FlyoutTabIds.LINK_TO_UPTIME]: getTabToUptime,
+ }),
+ [getTabToApmTraces, getTabToUptime]
+ );
+
+ const tabEntries: TabItem[] = useMemo(
+ () =>
+ tabs.map(({ name, ...tab }) => {
+ if (Object.keys(tabbedLinks).includes(tab.id)) {
+ return tabbedLinks[tab.id as keyof typeof tabbedLinks](name);
+ }
+
+ if (tab.id === FlyoutTabIds.LINK_TO_APM) {
+ return getTabToUptime(name);
+ }
+
+ return {
+ ...tab,
+ 'data-test-subj': `infraAssetDetails${capitalize(tab.id)}Tab`,
+ onClick: () => onTabClick(tab.id),
+ isSelected: tab.id === activeTabId,
+ label: name,
+ };
+ }),
+ [activeTabId, getTabToUptime, onTabClick, tabbedLinks, tabs]
+ );
+
+ return { tabEntries };
+};
diff --git a/x-pack/plugins/infra/public/components/asset_details/links/index.ts b/x-pack/plugins/infra/public/components/asset_details/links/index.ts
index 074879f4ffd54..fa46176e44e50 100644
--- a/x-pack/plugins/infra/public/components/asset_details/links/index.ts
+++ b/x-pack/plugins/infra/public/components/asset_details/links/index.ts
@@ -6,7 +6,6 @@
*/
export { LinkToApmServices } from './link_to_apm_services';
+export { LinkToUptime } from './link_to_uptime';
export { LinkToAlertsRule } from './link_to_alerts';
export { LinkToNodeDetails } from './link_to_node_details';
-export { TabToApmTraces } from './tab_to_apm_traces';
-export { TabToUptime } from './tab_to_uptime';
diff --git a/x-pack/plugins/infra/public/components/asset_details/links/link_to_apm_services.tsx b/x-pack/plugins/infra/public/components/asset_details/links/link_to_apm_services.tsx
index b83f76deea829..59cd4ca72ef1e 100644
--- a/x-pack/plugins/infra/public/components/asset_details/links/link_to_apm_services.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/links/link_to_apm_services.tsx
@@ -41,7 +41,7 @@ export const LinkToApmServices = ({ assetName, apmField }: LinkToApmServicesProp
>
diff --git a/x-pack/plugins/infra/public/components/asset_details/links/link_to_node_details.tsx b/x-pack/plugins/infra/public/components/asset_details/links/link_to_node_details.tsx
index 66f212582722c..f53ece1159e45 100644
--- a/x-pack/plugins/infra/public/components/asset_details/links/link_to_node_details.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/links/link_to_node_details.tsx
@@ -11,15 +11,16 @@ import { useLinkProps } from '@kbn/observability-shared-plugin/public';
import { getNodeDetailUrl } from '../../../pages/link_to';
import { findInventoryModel } from '../../../../common/inventory_models';
import type { InventoryItemType } from '../../../../common/inventory_models/types';
+import type { Asset } from '../types';
export interface LinkToNodeDetailsProps {
currentTimestamp: number;
- assetName: string;
+ asset: Asset;
assetType: InventoryItemType;
}
export const LinkToNodeDetails = ({
- assetName,
+ asset,
assetType,
currentTimestamp,
}: LinkToNodeDetailsProps) => {
@@ -29,9 +30,10 @@ export const LinkToNodeDetails = ({
const nodeDetailMenuItemLinkProps = useLinkProps({
...getNodeDetailUrl({
nodeType: assetType,
- nodeId: assetName,
+ nodeId: asset.id,
from: nodeDetailFrom,
to: currentTimestamp,
+ assetName: asset.name,
}),
});
diff --git a/x-pack/plugins/infra/public/components/asset_details/links/link_to_uptime.tsx b/x-pack/plugins/infra/public/components/asset_details/links/link_to_uptime.tsx
new file mode 100644
index 0000000000000..1800741aaf810
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/links/link_to_uptime.tsx
@@ -0,0 +1,39 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import React from 'react';
+import { EuiButtonEmpty } from '@elastic/eui';
+import { FormattedMessage } from '@kbn/i18n-react';
+import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/public';
+import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';
+import type { InventoryItemType } from '../../../../common/inventory_models/types';
+
+export interface LinkToUptimeProps {
+ assetType: InventoryItemType;
+ assetName: string;
+ ip?: string | null;
+}
+
+export const LinkToUptime = ({ assetType, assetName, ip }: LinkToUptimeProps) => {
+ const { share } = useKibanaContextForPlugin().services;
+
+ return (
+
+ share.url.locators.get(uptimeOverviewLocatorID)!.navigate({ [assetType]: assetName, ip })
+ }
+ >
+
+
+ );
+};
diff --git a/x-pack/plugins/infra/public/components/asset_details/links/tab_to_apm_traces.tsx b/x-pack/plugins/infra/public/components/asset_details/links/tab_to_apm_traces.tsx
deleted file mode 100644
index 538009844cdce..0000000000000
--- a/x-pack/plugins/infra/public/components/asset_details/links/tab_to_apm_traces.tsx
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-import React from 'react';
-import { css } from '@emotion/react';
-import { EuiIcon, useEuiTheme, EuiTab } from '@elastic/eui';
-import { useLinkProps } from '@kbn/observability-shared-plugin/public';
-import type { Tab } from '../types';
-
-export interface LinkToApmServicesProps extends Tab {
- assetName: string;
- apmField: string;
-}
-
-export const TabToApmTraces = ({ assetName, apmField, name, ...props }: LinkToApmServicesProps) => {
- const { euiTheme } = useEuiTheme();
-
- const apmTracesMenuItemLinkProps = useLinkProps({
- app: 'apm',
- hash: 'traces',
- search: {
- kuery: `${apmField}:"${assetName}"`,
- },
- });
-
- return (
-
-
- {name}
-
- );
-};
diff --git a/x-pack/plugins/infra/public/components/asset_details/links/tab_to_uptime.tsx b/x-pack/plugins/infra/public/components/asset_details/links/tab_to_uptime.tsx
deleted file mode 100644
index af830d499901a..0000000000000
--- a/x-pack/plugins/infra/public/components/asset_details/links/tab_to_uptime.tsx
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-import React from 'react';
-import { EuiTab, EuiIcon, useEuiTheme } from '@elastic/eui';
-import { css } from '@emotion/react';
-import { uptimeOverviewLocatorID } from '@kbn/observability-plugin/public';
-import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';
-import type { InventoryItemType } from '../../../../common/inventory_models/types';
-import type { Tab } from '../types';
-
-export interface LinkToUptimeProps extends Tab {
- assetType: InventoryItemType;
- assetName: string;
- nodeIp?: string | null;
-}
-
-export const TabToUptime = ({
- assetType,
- assetName,
- nodeIp,
- name,
- ...props
-}: LinkToUptimeProps) => {
- const { share } = useKibanaContextForPlugin().services;
- const { euiTheme } = useEuiTheme();
-
- return (
-
- share.url.locators
- .get(uptimeOverviewLocatorID)!
- .navigate({ [assetType]: assetName, ip: nodeIp })
- }
- >
-
- {name}
-
- );
-};
diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx
index 35337032805c1..10478af29d86e 100644
--- a/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/tabs/logs/logs.tsx
@@ -18,15 +18,17 @@ import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
import { findInventoryFields } from '../../../../../common/inventory_models';
import { InfraLoadingPanel } from '../../../loading';
import { useAssetDetailsStateContext } from '../../hooks/use_asset_details_state';
+import { useDataViewsProviderContext } from '../../hooks/use_data_views';
const TEXT_QUERY_THROTTLE_INTERVAL_MS = 500;
export const Logs = () => {
const { asset, assetType, overrides, onTabsStateChange, dateRangeTs } =
useAssetDetailsStateContext();
+ const { logs } = useDataViewsProviderContext();
- const { logView: overrideLogView, query: overrideQuery } = overrides?.logs ?? {};
- const { loading: logViewLoading, reference: logViewReference } = overrideLogView ?? {};
+ const { query: overrideQuery } = overrides?.logs ?? {};
+ const { loading: logViewLoading, reference: logViewReference } = logs ?? {};
const { services } = useKibanaContextForPlugin();
const { locators } = services;
diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.test.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.test.tsx
index 9f8a04ef64e6c..291f9911a3f85 100644
--- a/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.test.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.test.tsx
@@ -12,7 +12,7 @@ import { useSourceContext } from '../../../../containers/metrics_source';
import { render } from '@testing-library/react';
import { I18nProvider } from '@kbn/i18n-react';
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
-import { AssetDetailsStateProvider } from '../../hooks/use_asset_details_state';
+import { ContextProviders } from '../../context_providers';
jest.mock('../../../../containers/metrics_source');
jest.mock('../../hooks/use_metadata');
@@ -20,12 +20,8 @@ jest.mock('../../hooks/use_metadata');
const renderHostMetadata = () =>
render(
-
showActionsColumn: true,
},
},
+ dateRange: {
+ from: '2023-04-09T11:07:49Z',
+ to: '2023-04-09T11:23:49Z',
+ },
+ renderMode: {
+ mode: 'page',
+ },
}}
>
-
+
,
{ wrapper: EuiThemeProvider }
);
diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.tsx
index 70f1bda8c0c68..f3b27b9a8caca 100644
--- a/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/tabs/metadata/metadata.tsx
@@ -9,10 +9,9 @@ import React, { useCallback, useMemo } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiCallOut, EuiLink } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
-import { TimeRange } from '@kbn/es-query';
-import type { InventoryItemType } from '../../../../../common/inventory_models/types';
import { Table } from './table';
import { getAllFields } from './utils';
+import { useMetadataStateProviderContext } from '../../hooks/use_metadata_state';
import { useAssetDetailsStateContext } from '../../hooks/use_asset_details_state';
export interface MetadataSearchUrlState {
@@ -20,19 +19,14 @@ export interface MetadataSearchUrlState {
setMetadataSearchUrlState: (metadataSearch: { metadataSearch?: string }) => void;
}
-export interface MetadataProps {
- assetName: string;
- assetType: InventoryItemType;
- dateRange: TimeRange;
- showActionsColumn?: boolean;
- search?: string;
- onSearchChange?: (query: string) => void;
-}
-
export const Metadata = () => {
- const { overrides, onTabsStateChange, metadataResponse } = useAssetDetailsStateContext();
+ const { overrides, onTabsStateChange } = useAssetDetailsStateContext();
+ const {
+ metadata,
+ loading: metadataLoading,
+ error: fetchMetadataError,
+ } = useMetadataStateProviderContext();
const { query, showActionsColumn = false } = overrides?.metadata ?? {};
- const { metadataLoading, fetchMetadataError, metadata } = metadataResponse;
const fields = useMemo(() => getAllFields(metadata), [metadata]);
diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/osquery/osquery.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/osquery/osquery.tsx
index f2809c86ae5b9..a71778cb98d19 100644
--- a/x-pack/plugins/infra/public/components/asset_details/tabs/osquery/osquery.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/tabs/osquery/osquery.tsx
@@ -8,12 +8,11 @@
import { EuiSkeletonText } from '@elastic/eui';
import React, { useMemo } from 'react';
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
-import { useAssetDetailsStateContext } from '../../hooks/use_asset_details_state';
+import { useMetadataStateProviderContext } from '../../hooks/use_metadata_state';
export const Osquery = () => {
- const { metadataResponse } = useAssetDetailsStateContext();
+ const { metadata, loading: metadataLoading } = useMetadataStateProviderContext();
- const { metadataLoading, metadata } = metadataResponse;
const {
services: { osquery },
} = useKibanaContextForPlugin();
diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts.tsx
index 88c62cfa027c0..cb622fe054009 100644
--- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/alerts.tsx
@@ -111,12 +111,12 @@ const AlertsSectionTitle = () => {
-
+
-
+
diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metrics_grid.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metrics_grid.tsx
index f41ec41e51868..609feca5222e2 100644
--- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metrics_grid.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/metrics/metrics_grid.tsx
@@ -94,12 +94,12 @@ const MetricsSectionTitle = () => {
-
+
-
+
diff --git a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/overview.tsx b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/overview.tsx
index 9036f09ad4257..c8e0e08bba85f 100644
--- a/x-pack/plugins/infra/public/components/asset_details/tabs/overview/overview.tsx
+++ b/x-pack/plugins/infra/public/components/asset_details/tabs/overview/overview.tsx
@@ -15,18 +15,22 @@ import { AlertsSummaryContent } from './alerts';
import { KPIGrid } from './kpis/kpi_grid';
import { MetricsGrid } from './metrics/metrics_grid';
import { useAssetDetailsStateContext } from '../../hooks/use_asset_details_state';
+import { useMetadataStateProviderContext } from '../../hooks/use_metadata_state';
+import { useDataViewsProviderContext } from '../../hooks/use_data_views';
export const Overview = () => {
- const { asset, assetType, overrides, dateRange, renderMode, metadataResponse } =
- useAssetDetailsStateContext();
- const { logsDataView, metricsDataView } = overrides?.overview ?? {};
-
- const { metadataLoading, fetchMetadataError, metadata } = metadataResponse;
+ const { asset, assetType, dateRange, renderMode } = useAssetDetailsStateContext();
+ const {
+ metadata,
+ loading: metadataLoading,
+ error: fetchMetadataError,
+ } = useMetadataStateProviderContext();
+ const { logs, metrics } = useDataViewsProviderContext();
return (
-
+
{fetchMetadataError ? (
@@ -71,8 +75,8 @@ export const Overview = () => {
diff --git a/x-pack/plugins/infra/public/components/asset_details/template/flyout.tsx b/x-pack/plugins/infra/public/components/asset_details/template/flyout.tsx
new file mode 100644
index 0000000000000..9bc9a60777fad
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/template/flyout.tsx
@@ -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 { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import React from 'react';
+import useEffectOnce from 'react-use/lib/useEffectOnce';
+import { useKibanaContextForPlugin } from '../../../hooks/use_kibana';
+import { InfraLoadingPanel } from '../../loading';
+import { ASSET_DETAILS_FLYOUT_COMPONENT_NAME } from '../constants';
+import { Content } from '../content/content';
+import { FlyoutHeader } from '../header/flyout_header';
+import { useAssetDetailsStateContext } from '../hooks/use_asset_details_state';
+import { usePageHeader } from '../hooks/use_page_header';
+import { useTabSwitcherContext } from '../hooks/use_tab_switcher';
+import type { ContentTemplateProps } from '../types';
+
+export const Flyout = ({
+ header: { tabs = [], links = [] },
+ closeFlyout,
+}: ContentTemplateProps & { closeFlyout: () => void }) => {
+ const { asset, assetType, loading } = useAssetDetailsStateContext();
+ const { rightSideItems, tabEntries } = usePageHeader(tabs, links);
+ const { initialActiveTabId } = useTabSwitcherContext();
+ const {
+ services: { telemetry },
+ } = useKibanaContextForPlugin();
+
+ useEffectOnce(() => {
+ telemetry.reportAssetDetailsFlyoutViewed({
+ componentName: ASSET_DETAILS_FLYOUT_COMPONENT_NAME,
+ assetType,
+ tabId: initialActiveTabId,
+ });
+ });
+
+ return (
+
+ {loading ? (
+
+ ) : (
+ <>
+
+
+
+
+
+
+ >
+ )}
+
+ );
+};
diff --git a/x-pack/plugins/infra/public/components/asset_details/template/page.tsx b/x-pack/plugins/infra/public/components/asset_details/template/page.tsx
new file mode 100644
index 0000000000000..a95638bfca55a
--- /dev/null
+++ b/x-pack/plugins/infra/public/components/asset_details/template/page.tsx
@@ -0,0 +1,59 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { EuiFlexGroup, EuiPageTemplate } from '@elastic/eui';
+import { css } from '@emotion/react';
+import { i18n } from '@kbn/i18n';
+import React from 'react';
+import { useKibanaHeader } from '../../../hooks/use_kibana_header';
+import { InfraLoadingPanel } from '../../loading';
+import { Content } from '../content/content';
+import { useAssetDetailsStateContext } from '../hooks/use_asset_details_state';
+import { usePageHeader } from '../hooks/use_page_header';
+import type { ContentTemplateProps } from '../types';
+
+export const Page = ({ header: { tabs = [], links = [] } }: ContentTemplateProps) => {
+ const { asset, loading } = useAssetDetailsStateContext();
+ const { rightSideItems, tabEntries } = usePageHeader(tabs, links);
+ const { headerHeight } = useKibanaHeader();
+
+ return loading ? (
+
+
+
+ ) : (
+
+
+
+
+
+
+
+
+ );
+};
diff --git a/x-pack/plugins/infra/public/components/asset_details/types.ts b/x-pack/plugins/infra/public/components/asset_details/types.ts
index cbf66d66f0a27..44cc7fbb4faf9 100644
--- a/x-pack/plugins/infra/public/components/asset_details/types.ts
+++ b/x-pack/plugins/infra/public/components/asset_details/types.ts
@@ -5,18 +5,13 @@
* 2.0.
*/
-import type { DataView } from '@kbn/data-views-plugin/public';
-import type { LogViewReference } from '@kbn/logs-shared-plugin/common';
import { TimeRange } from '@kbn/es-query';
import type { InventoryItemType } from '../../../common/inventory_models/types';
-interface Metadata {
- ip?: string | null;
-}
-export type Asset = Metadata & {
+export interface Asset {
id: string;
- name: string;
-};
+ name?: string;
+}
export enum FlyoutTabIds {
OVERVIEW = 'overview',
@@ -32,10 +27,6 @@ export enum FlyoutTabIds {
export type TabIds = `${FlyoutTabIds}`;
export interface TabState {
- overview?: {
- metricsDataView?: DataView;
- logsDataView?: DataView;
- };
metadata?: {
query?: string;
showActionsColumn?: boolean;
@@ -51,10 +42,6 @@ export interface TabState {
};
logs?: {
query?: string;
- logView?: {
- reference?: LogViewReference | null;
- loading?: boolean;
- };
};
}
@@ -74,7 +61,7 @@ export interface Tab {
name: string;
}
-export type LinkOptions = 'alertRule' | 'nodeDetails' | 'apmServices';
+export type LinkOptions = 'alertRule' | 'nodeDetails' | 'apmServices' | 'uptime';
export interface AssetDetailsProps {
asset: Asset;
@@ -83,9 +70,16 @@ export interface AssetDetailsProps {
tabs: Tab[];
activeTabId?: TabIds;
overrides?: TabState;
- renderMode?: RenderMode;
+ renderMode: RenderMode;
onTabsStateChange?: TabsStateChangeFn;
links?: LinkOptions[];
+ // This is temporary. Once we start using the asset details in other plugins,
+ // It will have to retrieve the metricAlias internally rather than receive it via props
+ metricAlias: string;
}
export type TabsStateChangeFn = (state: TabState & { activeTabId?: TabIds }) => void;
+
+export interface ContentTemplateProps {
+ header: Pick;
+}
diff --git a/x-pack/plugins/infra/public/components/lens/lens_chart.tsx b/x-pack/plugins/infra/public/components/lens/lens_chart.tsx
index 2d4b599d56de2..abcbe555a5d6a 100644
--- a/x-pack/plugins/infra/public/components/lens/lens_chart.tsx
+++ b/x-pack/plugins/infra/public/components/lens/lens_chart.tsx
@@ -87,7 +87,9 @@ export const LensChart = ({
})}
anchorClassName="eui-fullWidth"
>
- {Lens}
+ {/* EuiToolTip forwards some event handlers to the child component.
+ Wrapping Lens inside a div prevents that from causing unnecessary re-renders */}
+ {Lens}
);
};
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts b/x-pack/plugins/infra/public/hooks/use_log_view_reference.ts
similarity index 94%
rename from x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts
rename to x-pack/plugins/infra/public/hooks/use_log_view_reference.ts
index 5d10bc48dce5d..d8c063767a8d1 100644
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_log_view_reference.ts
+++ b/x-pack/plugins/infra/public/hooks/use_log_view_reference.ts
@@ -9,8 +9,8 @@ import useAsync from 'react-use/lib/useAsync';
import { v4 as uuidv4 } from 'uuid';
import { DEFAULT_LOG_VIEW, LogViewReference } from '@kbn/logs-shared-plugin/common';
import { useCallback } from 'react';
-import { useLazyRef } from '../../../../hooks/use_lazy_ref';
-import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
+import { useLazyRef } from './use_lazy_ref';
+import { useKibanaContextForPlugin } from './use_kibana';
interface Props {
id: string;
diff --git a/x-pack/plugins/infra/public/hooks/use_metrics_adhoc_data_view.ts b/x-pack/plugins/infra/public/hooks/use_metrics_adhoc_data_view.ts
new file mode 100644
index 0000000000000..1761297e9dcff
--- /dev/null
+++ b/x-pack/plugins/infra/public/hooks/use_metrics_adhoc_data_view.ts
@@ -0,0 +1,42 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { v5 as uuidv5 } from 'uuid';
+import useAsyncRetry from 'react-use/lib/useAsyncRetry';
+import { useKibanaContextForPlugin } from './use_kibana';
+
+export const TIMESTAMP_FIELD = '@timestamp';
+export const DATA_VIEW_PREFIX = 'infra_metrics';
+
+export const generateDataViewId = (indexPattern: string) => {
+ // generates a unique but the same uuid as long as the index pattern doesn't change
+ return `${DATA_VIEW_PREFIX}_${uuidv5(indexPattern, uuidv5.DNS)}`;
+};
+
+export const useDataMetricsAdHocDataView = ({ metricAlias }: { metricAlias: string }) => {
+ const {
+ services: { dataViews },
+ } = useKibanaContextForPlugin();
+
+ const state = useAsyncRetry(() => {
+ return dataViews.create({
+ id: generateDataViewId(metricAlias),
+ title: metricAlias,
+ timeFieldName: TIMESTAMP_FIELD,
+ });
+ }, [metricAlias]);
+
+ const { value: dataView, loading, error, retry } = state;
+
+ return {
+ metricAlias,
+ dataView,
+ loading,
+ loadDataView: retry,
+ error,
+ };
+};
diff --git a/x-pack/plugins/infra/public/pages/link_to/query_params.ts b/x-pack/plugins/infra/public/pages/link_to/query_params.ts
index 45e1bc9a7991d..e071ec0a82e34 100644
--- a/x-pack/plugins/infra/public/pages/link_to/query_params.ts
+++ b/x-pack/plugins/infra/public/pages/link_to/query_params.ts
@@ -28,3 +28,8 @@ export const getFromFromLocation = (location: Location) => {
const timeParam = getParamFromQueryString(getQueryStringFromLocation(location), 'from');
return timeParam ? parseFloat(timeParam) : NaN;
};
+
+export const getNodeNameFromLocation = (location: Location) => {
+ const nameParam = getParamFromQueryString(getQueryStringFromLocation(location), 'assetName');
+ return nameParam;
+};
diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx
index 412585fec9cc7..8045c95fe78d6 100644
--- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx
+++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_detail.tsx
@@ -10,7 +10,7 @@ import { Redirect, RouteComponentProps } from 'react-router-dom';
import { LinkDescriptor } from '@kbn/observability-shared-plugin/public';
import { replaceMetricTimeInQueryString } from '../metrics/metric_detail/hooks/use_metrics_time';
-import { getFromFromLocation, getToFromLocation } from './query_params';
+import { getFromFromLocation, getToFromLocation, getNodeNameFromLocation } from './query_params';
import { InventoryItemType } from '../../../common/inventory_models/types';
type RedirectToNodeDetailProps = RouteComponentProps<{
@@ -29,7 +29,16 @@ export const RedirectToNodeDetail = ({
getToFromLocation(location)
)('');
- return ;
+ const queryParams = new URLSearchParams(searchString);
+
+ if (nodeType === 'host') {
+ const assetName = getNodeNameFromLocation(location);
+ if (assetName) {
+ queryParams.set('assetName', assetName);
+ }
+ }
+
+ return ;
};
export const getNodeDetailUrl = ({
@@ -37,21 +46,25 @@ export const getNodeDetailUrl = ({
nodeId,
to,
from,
+ assetName,
}: {
nodeType: InventoryItemType;
nodeId: string;
to?: number;
from?: number;
+ assetName?: string;
}): LinkDescriptor => {
return {
app: 'metrics',
pathname: `link-to/${nodeType}-detail/${nodeId}`,
- search:
- to && from
+ search: {
+ ...(assetName ? { assetName } : undefined),
+ ...(to && from
? {
to: `${to}`,
from: `${from}`,
}
- : undefined,
+ : undefined),
+ },
};
};
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/host_details_flyout/flyout_wrapper.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/host_details_flyout/flyout_wrapper.tsx
index 884e0dd389cd3..6daf6b36e5609 100644
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/host_details_flyout/flyout_wrapper.tsx
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/host_details_flyout/flyout_wrapper.tsx
@@ -6,45 +6,31 @@
*/
import React from 'react';
-import useAsync from 'react-use/lib/useAsync';
+
+import { useSourceContext } from '../../../../../containers/metrics_source';
import { useUnifiedSearchContext } from '../../hooks/use_unified_search';
import type { HostNodeRow } from '../../hooks/use_hosts_table';
import { HostFlyout, useHostFlyoutUrlState } from '../../hooks/use_host_flyout_url_state';
import { AssetDetails } from '../../../../../components/asset_details/asset_details';
import { orderedFlyoutTabs } from './tabs';
-import { useLogViewReference } from '../../hooks/use_log_view_reference';
-import { useMetricsDataViewContext } from '../../hooks/use_data_view';
export interface Props {
node: HostNodeRow;
closeFlyout: () => void;
}
-export const FlyoutWrapper = ({ node, closeFlyout }: Props) => {
+export const FlyoutWrapper = ({ node: { name }, closeFlyout }: Props) => {
+ const { source } = useSourceContext();
const { searchCriteria } = useUnifiedSearchContext();
- const { dataView } = useMetricsDataViewContext();
- const { logViewReference, loading, getLogsDataView } = useLogViewReference({
- id: 'hosts-flyout-logs-view',
- });
-
- const { value: logsDataView } = useAsync(
- () => getLogsDataView(logViewReference),
- [logViewReference]
- );
-
const [hostFlyoutState, setHostFlyoutState] = useHostFlyoutUrlState();
- return (
+ return source ? (
{
},
logs: {
query: hostFlyoutState?.logsSearch,
- logView: {
- reference: logViewReference,
- loading,
- },
},
}}
onTabsStateChange={(state) =>
@@ -74,6 +56,7 @@ export const FlyoutWrapper = ({ node, closeFlyout }: Props) => {
mode: 'flyout',
closeFlyout,
}}
+ metricAlias={source.configuration.metricAlias}
/>
- );
+ ) : null;
};
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/table/entry_title.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/table/entry_title.tsx
index 27739b3ed4a49..b853ca3c8f9b1 100644
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/table/entry_title.tsx
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/table/entry_title.tsx
@@ -32,6 +32,7 @@ export const EntryTitle = ({ onClick, time, title }: EntryTitleProps) => {
pathname: `/detail/host/${name}`,
search: {
_a: encode({ time: { ...time, interval: '>=1m' } }),
+ assetName: name,
},
});
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx
index 15ab7b9f0eca6..331cc35722998 100644
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/tabs/logs/logs_tab_content.tsx
@@ -16,7 +16,7 @@ import { useLogsSearchUrlState } from '../../../hooks/use_logs_search_url_state'
import { LogsLinkToStream } from './logs_link_to_stream';
import { LogsSearchBar } from './logs_search_bar';
import { buildCombinedHostsFilter } from '../../../../../../utils/filters/build';
-import { useLogViewReference } from '../../../hooks/use_log_view_reference';
+import { useLogViewReference } from '../../../../../../hooks/use_log_view_reference';
export const LogsTabContent = () => {
const [filterQuery] = useLogsSearchUrlState();
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/constants.ts b/x-pack/plugins/infra/public/pages/metrics/hosts/constants.ts
index aace07448692e..997ae6fd5ed66 100644
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/constants.ts
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/constants.ts
@@ -7,9 +7,6 @@
import { HostLimitOptions } from './types';
-export const TIMESTAMP_FIELD = '@timestamp';
-export const DATA_VIEW_PREFIX = 'infra_metrics';
-
export const DEFAULT_HOST_LIMIT: HostLimitOptions = 100;
export const DEFAULT_PAGE_SIZE = 10;
export const LOCAL_STORAGE_HOST_LIMIT_KEY = 'hostsView:hostLimitSelection';
diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.ts b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.ts
index 66bbe02c9932a..b7b3103dacfc4 100644
--- a/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.ts
+++ b/x-pack/plugins/infra/public/pages/metrics/hosts/hooks/use_data_view.ts
@@ -5,31 +5,16 @@
* 2.0.
*/
-import { v5 as uuidv5 } from 'uuid';
import createContainer from 'constate';
-import useAsyncRetry from 'react-use/lib/useAsyncRetry';
-import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
-import { DATA_VIEW_PREFIX, TIMESTAMP_FIELD } from '../constants';
-
-export const generateDataViewId = (indexPattern: string) => {
- // generates a unique but the same uuid as long as the index pattern doesn't change
- return `${DATA_VIEW_PREFIX}_${uuidv5(indexPattern, uuidv5.DNS)}`;
-};
+import { useDataMetricsAdHocDataView } from '../../../../hooks/use_metrics_adhoc_data_view';
export const useDataView = ({ metricAlias }: { metricAlias: string }) => {
const {
- services: { dataViews },
- } = useKibanaContextForPlugin();
-
- const state = useAsyncRetry(() => {
- return dataViews.create({
- id: generateDataViewId(metricAlias),
- title: metricAlias,
- timeFieldName: TIMESTAMP_FIELD,
- });
- }, [metricAlias]);
-
- const { value: dataView, loading, error, retry } = state;
+ dataView,
+ loading,
+ loadDataView: retry,
+ error,
+ } = useDataMetricsAdHocDataView({ metricAlias });
return {
metricAlias,
diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx
index 3314d06fc4693..74fd472629198 100644
--- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx
+++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/node_details/overlay.tsx
@@ -83,6 +83,7 @@ export const NodeContextPopover = ({
nodeId: node.id,
from: nodeDetailFrom,
to: currentTime,
+ assetName: node.name,
}),
});
const apmField = nodeType === 'host' ? 'host.hostname' : inventoryModel.fields.id;
diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/asset_detail_page.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/asset_detail_page.tsx
new file mode 100644
index 0000000000000..e28650aaf5cde
--- /dev/null
+++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/asset_detail_page.tsx
@@ -0,0 +1,124 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import type { TimeRange } from '@kbn/es-query';
+import React, { useMemo } from 'react';
+import { useLocation, useRouteMatch } from 'react-router-dom';
+import { i18n } from '@kbn/i18n';
+import { NoRemoteCluster } from '../../../components/empty_states';
+import { SourceErrorPage } from '../../../components/source_error_page';
+import { SourceLoadingPage } from '../../../components/source_loading_page';
+import { useSourceContext } from '../../../containers/metrics_source';
+import { FlyoutTabIds, type Tab } from '../../../components/asset_details/types';
+import type { InventoryItemType } from '../../../../common/inventory_models/types';
+import { AssetDetails } from '../../../components/asset_details/asset_details';
+import { useMetricsTimeContext } from './hooks/use_metrics_time';
+import { MetricsPageTemplate } from '../page_template';
+
+const orderedFlyoutTabs: Tab[] = [
+ {
+ id: FlyoutTabIds.OVERVIEW,
+ name: i18n.translate('xpack.infra.nodeDetails.tabs.overview.title', {
+ defaultMessage: 'Overview',
+ }),
+ },
+ {
+ id: FlyoutTabIds.METADATA,
+ name: i18n.translate('xpack.infra.nodeDetails.tabs.metadata.title', {
+ defaultMessage: 'Metadata',
+ }),
+ },
+ {
+ id: FlyoutTabIds.PROCESSES,
+ name: i18n.translate('xpack.infra.metrics.nodeDetails.tabs.processes', {
+ defaultMessage: 'Processes',
+ }),
+ },
+ {
+ id: FlyoutTabIds.LOGS,
+ name: i18n.translate('xpack.infra.nodeDetails.tabs.logs.title', {
+ defaultMessage: 'Logs',
+ }),
+ },
+ {
+ id: FlyoutTabIds.ANOMALIES,
+ name: i18n.translate('xpack.infra.nodeDetails.tabs.anomalies', {
+ defaultMessage: 'Anomalies',
+ }),
+ },
+ {
+ id: FlyoutTabIds.OSQUERY,
+ name: i18n.translate('xpack.infra.nodeDetails.tabs.osquery', {
+ defaultMessage: 'Osquery',
+ }),
+ },
+];
+
+export const AssetDetailPage = () => {
+ const { isLoading, loadSourceFailureMessage, loadSource, source } = useSourceContext();
+ const {
+ params: { type: nodeType, node: nodeId },
+ } = useRouteMatch<{ type: InventoryItemType; node: string }>();
+ const { search } = useLocation();
+
+ const assetName = useMemo(() => {
+ const queryParams = new URLSearchParams(search);
+ return queryParams.get('assetName') ?? undefined;
+ }, [search]);
+
+ const { parsedTimeRange } = useMetricsTimeContext();
+
+ const dateRange: TimeRange = useMemo(
+ () => ({
+ from: new Date(parsedTimeRange.from).toISOString(),
+ to: new Date(parsedTimeRange.to).toISOString(),
+ }),
+ [parsedTimeRange.from, parsedTimeRange.to]
+ );
+
+ const { metricIndicesExist, remoteClustersExist } = source?.status ?? {};
+
+ if (isLoading || !source) return ;
+
+ if (!remoteClustersExist) {
+ return ;
+ }
+
+ if (!metricIndicesExist) {
+ return (
+
+ );
+ }
+
+ if (loadSourceFailureMessage)
+ return ;
+
+ return (
+
+
+
+ );
+};
diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx
index e4819242c011d..36a7d3d853eb7 100644
--- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx
+++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/index.tsx
@@ -5,122 +5,26 @@
* 2.0.
*/
-import { i18n } from '@kbn/i18n';
-import React, { useState } from 'react';
-import { EuiTheme, withTheme } from '@kbn/kibana-react-plugin/common';
-import { useLinkProps } from '@kbn/observability-shared-plugin/public';
-import { withMetricPageProviders } from './page_providers';
-import { useMetadata } from '../../../components/asset_details/hooks/use_metadata';
-import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs';
-import { useSourceContext } from '../../../containers/metrics_source';
-import { InfraLoadingPanel } from '../../../components/loading';
-import { findInventoryModel } from '../../../../common/inventory_models';
-import { NavItem } from './lib/side_nav_context';
-import { NodeDetailsPage } from './components/node_details_page';
-import { InventoryItemType } from '../../../../common/inventory_models/types';
-import { useMetricsTimeContext } from './hooks/use_metrics_time';
-import { MetricsPageTemplate } from '../page_template';
-import { inventoryTitle } from '../../../translations';
-
-interface Props {
- theme: EuiTheme | undefined;
- match: {
- params: {
- type: string;
- node: string;
- };
- };
-}
-
-export const MetricDetail = withMetricPageProviders(
- withTheme(({ match }: Props) => {
- const nodeId = match.params.node;
- const nodeType = match.params.type as InventoryItemType;
- const inventoryModel = findInventoryModel(nodeType);
- const { sourceId, metricIndicesExist } = useSourceContext();
-
- const {
- timeRange,
- parsedTimeRange,
- setTimeRange,
- refreshInterval,
- setRefreshInterval,
- isAutoReloading,
- setAutoReload,
- triggerRefresh,
- } = useMetricsTimeContext();
- const {
- name,
- filteredRequiredMetrics,
- loading: metadataLoading,
- cloudId,
- metadata,
- } = useMetadata(nodeId, nodeType, inventoryModel.requiredMetrics, sourceId, parsedTimeRange);
-
- const [sideNav, setSideNav] = useState([]);
-
- const addNavItem = React.useCallback(
- (item: NavItem) => {
- if (!sideNav.some((n) => n.id === item.id)) {
- setSideNav([item, ...sideNav]);
- }
- },
- [sideNav]
- );
-
- const inventoryLinkProps = useLinkProps({
- app: 'metrics',
- pathname: '/inventory',
- });
-
- useMetricsBreadcrumbs([
- {
- ...inventoryLinkProps,
- text: inventoryTitle,
- },
- {
- text: name,
- },
- ]);
-
- if (metadataLoading && !filteredRequiredMetrics.length) {
- return (
-
-
-
- );
- }
-
- return (
- <>
- {metadata ? (
-
- ) : null}
- >
- );
- })
-);
+import { EuiErrorBoundary } from '@elastic/eui';
+import React from 'react';
+import { useRouteMatch } from 'react-router-dom';
+import type { InventoryItemType } from '../../../../common/inventory_models/types';
+import { AssetDetailPage } from './asset_detail_page';
+import { MetricsTimeProvider } from './hooks/use_metrics_time';
+import { MetricDetailPage } from './metric_detail_page';
+
+export const MetricDetail = () => {
+ const {
+ params: { type: nodeType },
+ } = useRouteMatch<{ type: InventoryItemType; node: string }>();
+
+ const PageContent = () => (nodeType === 'host' ? : );
+
+ return (
+
+
+
+
+
+ );
+};
diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx b/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx
new file mode 100644
index 0000000000000..6823147c8b6b0
--- /dev/null
+++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/metric_detail_page.tsx
@@ -0,0 +1,114 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { i18n } from '@kbn/i18n';
+import React, { useState } from 'react';
+import { useLinkProps } from '@kbn/observability-shared-plugin/public';
+import { useRouteMatch } from 'react-router-dom';
+import { useMetadata } from '../../../components/asset_details/hooks/use_metadata';
+import { useMetricsBreadcrumbs } from '../../../hooks/use_metrics_breadcrumbs';
+import { useSourceContext } from '../../../containers/metrics_source';
+import { InfraLoadingPanel } from '../../../components/loading';
+import { findInventoryModel } from '../../../../common/inventory_models';
+import type { NavItem } from './lib/side_nav_context';
+import { NodeDetailsPage } from './components/node_details_page';
+import type { InventoryItemType } from '../../../../common/inventory_models/types';
+import { useMetricsTimeContext } from './hooks/use_metrics_time';
+import { MetricsPageTemplate } from '../page_template';
+import { inventoryTitle } from '../../../translations';
+
+export const MetricDetailPage = () => {
+ const {
+ params: { type: nodeType, node: nodeId },
+ } = useRouteMatch<{ type: InventoryItemType; node: string }>();
+ const inventoryModel = findInventoryModel(nodeType);
+ const { sourceId, metricIndicesExist } = useSourceContext();
+
+ const {
+ timeRange,
+ parsedTimeRange,
+ setTimeRange,
+ refreshInterval,
+ setRefreshInterval,
+ isAutoReloading,
+ setAutoReload,
+ triggerRefresh,
+ } = useMetricsTimeContext();
+ const {
+ name,
+ filteredRequiredMetrics,
+ loading: metadataLoading,
+ cloudId,
+ metadata,
+ } = useMetadata(nodeId, nodeType, inventoryModel.requiredMetrics, sourceId, parsedTimeRange);
+
+ const [sideNav, setSideNav] = useState([]);
+
+ const addNavItem = React.useCallback(
+ (item: NavItem) => {
+ if (!sideNav.some((n) => n.id === item.id)) {
+ setSideNav([item, ...sideNav]);
+ }
+ },
+ [sideNav]
+ );
+
+ const inventoryLinkProps = useLinkProps({
+ app: 'metrics',
+ pathname: '/inventory',
+ });
+
+ useMetricsBreadcrumbs([
+ {
+ ...inventoryLinkProps,
+ text: inventoryTitle,
+ },
+ {
+ text: name,
+ },
+ ]);
+
+ if (metadataLoading && !filteredRequiredMetrics.length) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+ <>
+ {metadata ? (
+
+ ) : null}
+ >
+ );
+};
diff --git a/x-pack/test/functional/apps/infra/home_page.ts b/x-pack/test/functional/apps/infra/home_page.ts
index 1e187587ce901..8ea0ad09a50f0 100644
--- a/x-pack/test/functional/apps/infra/home_page.ts
+++ b/x-pack/test/functional/apps/infra/home_page.ts
@@ -38,7 +38,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
await pageObjects.infraHome.getNoMetricsIndicesPrompt();
});
- it('renders the correct error page title', async () => {
+ // Unskip once asset details error handling has been implemented
+ it.skip('renders the correct error page title', async () => {
await pageObjects.common.navigateToUrlWithBrowserHistory(
'infraOps',
'/detail/host/test',
From a8c28d9951dbd9c23c0a4107e983c199fb02ffb9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?=
Date: Tue, 22 Aug 2023 12:35:22 +0200
Subject: [PATCH 11/26] [Flaky test #116048] Unskip tests (#163681)
---
.../feature_controls/saved_objects_management_security.ts | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/x-pack/test/functional/apps/saved_objects_management/feature_controls/saved_objects_management_security.ts b/x-pack/test/functional/apps/saved_objects_management/feature_controls/saved_objects_management_security.ts
index a626c613fd50d..8e1dae82ab2aa 100644
--- a/x-pack/test/functional/apps/saved_objects_management/feature_controls/saved_objects_management_security.ts
+++ b/x-pack/test/functional/apps/saved_objects_management/feature_controls/saved_objects_management_security.ts
@@ -245,9 +245,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
// From https://github.com/elastic/kibana/issues/59588 edit view became read-only json view
// test description changed from "edit" to "inspect"
// Skipping the test to allow code owners to delete or modify the test.
- //
- // FLAKY: https://github.com/elastic/kibana/issues/116048
- describe.skip('inspect visualization', () => {
+ describe('inspect visualization', () => {
before(async () => {
await PageObjects.settings.navigateTo();
await PageObjects.settings.clickKibanaSavedObjects();
From 95912641f284595b1d4a1c62dd505f8daa356d0d Mon Sep 17 00:00:00 2001
From: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Date: Tue, 22 Aug 2023 06:36:40 -0400
Subject: [PATCH 12/26] skip failing test suite (#158851)
---
x-pack/test/functional/apps/aiops/change_point_detection.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/x-pack/test/functional/apps/aiops/change_point_detection.ts b/x-pack/test/functional/apps/aiops/change_point_detection.ts
index 9b11431b2e700..0c55e081afc92 100644
--- a/x-pack/test/functional/apps/aiops/change_point_detection.ts
+++ b/x-pack/test/functional/apps/aiops/change_point_detection.ts
@@ -16,7 +16,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
// aiops lives in the ML UI so we need some related services.
const ml = getService('ml');
- describe('change point detection', async function () {
+ // Failing: See https://github.com/elastic/kibana/issues/158851
+ describe.skip('change point detection', async function () {
before(async () => {
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce');
await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date');
From be32a39555b8cc57cd82671b762d6f9c253fc949 Mon Sep 17 00:00:00 2001
From: Elastic Machine
Date: Tue, 22 Aug 2023 20:26:46 +0930
Subject: [PATCH 13/26] [main] Sync bundled packages with Package Storage
(#164407)
Automated by
https://internal-ci.elastic.co/job/package_storage/job/sync-bundled-packages-job/job/main/6457/
Co-authored-by: apmmachine
---
fleet_packages.json | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fleet_packages.json b/fleet_packages.json
index 0999f88041d11..e902be45dda44 100644
--- a/fleet_packages.json
+++ b/fleet_packages.json
@@ -24,17 +24,17 @@
[
{
"name": "apm",
- "version": "8.10.0-preview-1689351101",
+ "version": "8.11.0-preview-1692605695",
"forceAlignStackVersion": true,
"allowSyncToPrerelease": true
},
{
"name": "elastic_agent",
- "version": "1.11.0"
+ "version": "1.11.2"
},
{
"name": "endpoint",
- "version": "8.10.0"
+ "version": "8.10.2"
},
{
"name": "fleet_server",
@@ -58,6 +58,6 @@
},
{
"name": "security_detection_engine",
- "version": "8.9.3"
+ "version": "8.10.1"
}
]
\ No newline at end of file
From e98b4b3e88a1a5774a3c96429adbccc109eb4e34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?=
Date: Tue, 22 Aug 2023 12:59:15 +0200
Subject: [PATCH 14/26] [config-schema] `offeringBasedSchema` helper (#163786)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
.../core/configuration-service.asciidoc | 19 ++
.../src/http_config.ts | 11 +-
.../src/ui_settings_config.ts | 9 +-
packages/kbn-config-schema/index.ts | 1 +
.../kbn-config-schema/src/helpers/index.ts | 9 +
.../src/helpers/offering_based_schema.test.ts | 216 ++++++++++++++++++
.../src/helpers/offering_based_schema.ts | 59 +++++
src/plugins/input_control_vis/config.ts | 11 +-
src/plugins/telemetry/server/config/config.ts | 14 +-
.../server/config/telemetry_labels.ts | 6 +-
src/plugins/vis_types/gauge/config.ts | 11 +-
src/plugins/vis_types/heatmap/config.ts | 11 +-
src/plugins/vis_types/metric/config.ts | 11 +-
src/plugins/vis_types/pie/config.ts | 11 +-
src/plugins/vis_types/table/config.ts | 11 +-
src/plugins/vis_types/tagcloud/config.ts | 11 +-
src/plugins/vis_types/timelion/config.ts | 11 +-
src/plugins/vis_types/timeseries/config.ts | 11 +-
src/plugins/vis_types/vislib/config.ts | 11 +-
src/plugins/vis_types/xy/config.ts | 11 +-
x-pack/plugins/apm/server/index.ts | 41 ++--
x-pack/plugins/cloud/server/config.ts | 9 +-
.../cloud_data_migration/server/config.ts | 11 +-
.../server/config.ts | 11 +-
.../discover_log_explorer/server/config.ts | 15 +-
x-pack/plugins/graph/config.ts | 9 +-
.../server/config.ts | 11 +-
.../plugins/index_management/server/config.ts | 20 +-
x-pack/plugins/infra/server/plugin.ts | 17 +-
.../license_management/server/config.ts | 11 +-
.../observability_onboarding/server/index.ts | 13 +-
.../plugins/remote_clusters/server/config.ts | 11 +-
.../plugins/reporting/server/config/schema.ts | 42 ++--
x-pack/plugins/rollup/server/config.ts | 11 +-
x-pack/plugins/security/server/config.ts | 11 +-
.../plugins/snapshot_restore/server/config.ts | 11 +-
x-pack/plugins/spaces/server/config.ts | 14 +-
.../upgrade_assistant/server/config.ts | 11 +-
x-pack/plugins/watcher/server/index.ts | 11 +-
39 files changed, 469 insertions(+), 286 deletions(-)
create mode 100644 packages/kbn-config-schema/src/helpers/index.ts
create mode 100644 packages/kbn-config-schema/src/helpers/offering_based_schema.test.ts
create mode 100644 packages/kbn-config-schema/src/helpers/offering_based_schema.ts
diff --git a/docs/developer/architecture/core/configuration-service.asciidoc b/docs/developer/architecture/core/configuration-service.asciidoc
index 570bea37ddf09..ed03be73296cb 100644
--- a/docs/developer/architecture/core/configuration-service.asciidoc
+++ b/docs/developer/architecture/core/configuration-service.asciidoc
@@ -212,3 +212,22 @@ export const config = {
}),
};
----
+
+For Serverless vs. Traditional configuration, you are encouraged to use the `offeringBasedSchema` helper:
+
+[source,js]
+----
+import { schema, offeringBasedSchema } from '@kbn/config-schema'
+
+export const config = {
+ schema: schema.object({
+ // Enabled by default in Dev mode
+ enabled: schema.boolean({ defaultValue: schema.contextRef('dev') }),
+
+ // Setting only allowed in the Serverless offering
+ plansForWorldPeace: offeringBasedSchema({
+ serverless: schema.string({ defaultValue: 'Free hugs' }),
+ }),
+ }),
+};
+----
\ No newline at end of file
diff --git a/packages/core/http/core-http-server-internal/src/http_config.ts b/packages/core/http/core-http-server-internal/src/http_config.ts
index 4cb3d5df0ef01..9e8984783a106 100644
--- a/packages/core/http/core-http-server-internal/src/http_config.ts
+++ b/packages/core/http/core-http-server-internal/src/http_config.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { ByteSizeValue, schema, TypeOf } from '@kbn/config-schema';
+import { ByteSizeValue, offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { IHttpConfig, SslConfig, sslSchema } from '@kbn/server-http-tools';
import type { ServiceConfigDescriptor } from '@kbn/core-base-server-internal';
import { uuidRegexp } from '@kbn/core-base-server-internal';
@@ -168,12 +168,9 @@ const configSchema = schema.object(
}
),
// allow access to internal routes by default to prevent breaking changes in current offerings
- restrictInternalApis: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.boolean({ defaultValue: false }),
- schema.never()
- ),
+ restrictInternalApis: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
versioned: schema.object({
/**
diff --git a/packages/core/ui-settings/core-ui-settings-server-internal/src/ui_settings_config.ts b/packages/core/ui-settings/core-ui-settings-server-internal/src/ui_settings_config.ts
index bfcc5316a78a0..dc3b2b080340e 100644
--- a/packages/core/ui-settings/core-ui-settings-server-internal/src/ui_settings_config.ts
+++ b/packages/core/ui-settings/core-ui-settings-server-internal/src/ui_settings_config.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { schema, TypeOf, offeringBasedSchema } from '@kbn/config-schema';
import type { ServiceConfigDescriptor } from '@kbn/core-base-server-internal';
import { ConfigDeprecationProvider } from '@kbn/config';
@@ -17,12 +17,7 @@ const deprecations: ConfigDeprecationProvider = ({ unused, renameFromRoot }) =>
const configSchema = schema.object({
overrides: schema.object({}, { unknowns: 'allow' }),
- publicApiEnabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.boolean({ defaultValue: false }),
- schema.never()
- ),
+ publicApiEnabled: offeringBasedSchema({ serverless: schema.boolean({ defaultValue: false }) }),
});
export type UiSettingsConfigType = TypeOf;
diff --git a/packages/kbn-config-schema/index.ts b/packages/kbn-config-schema/index.ts
index 2d5e240a7041f..88666aac94c7e 100644
--- a/packages/kbn-config-schema/index.ts
+++ b/packages/kbn-config-schema/index.ts
@@ -55,6 +55,7 @@ export { ObjectType, Type };
export { ByteSizeValue } from './src/byte_size_value';
export { SchemaTypeError, ValidationError } from './src/errors';
export { isConfigSchema } from './src/typeguards';
+export { offeringBasedSchema } from './src/helpers';
function any(options?: TypeOptions) {
return new AnyType(options);
diff --git a/packages/kbn-config-schema/src/helpers/index.ts b/packages/kbn-config-schema/src/helpers/index.ts
new file mode 100644
index 0000000000000..ee27d5bed22a2
--- /dev/null
+++ b/packages/kbn-config-schema/src/helpers/index.ts
@@ -0,0 +1,9 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+export { offeringBasedSchema } from './offering_based_schema';
diff --git a/packages/kbn-config-schema/src/helpers/offering_based_schema.test.ts b/packages/kbn-config-schema/src/helpers/offering_based_schema.test.ts
new file mode 100644
index 0000000000000..02876a78a36b2
--- /dev/null
+++ b/packages/kbn-config-schema/src/helpers/offering_based_schema.test.ts
@@ -0,0 +1,216 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { schema } from '../..';
+import { offeringBasedSchema } from './offering_based_schema';
+
+describe('Helper: offeringBasedSchema()', () => {
+ describe('Example: Only allow the setting on Serverless', () => {
+ const validation = schema.object({
+ myProp: offeringBasedSchema({ serverless: schema.boolean({ defaultValue: true }) }),
+ });
+
+ test('it uses the non-serverless validation when the context is not present', () => {
+ expect(validation.validate({})).toEqual({});
+ });
+
+ test('it uses the non-serverless validation when context claims "not in serverless"', () => {
+ expect(validation.validate({}, { serverless: false })).toEqual({});
+ });
+
+ test('it uses serverless validation when context claims "in serverless"', () => {
+ expect(validation.validate({}, { serverless: true })).toEqual({ myProp: true });
+ });
+
+ test('it does not allow changing the flag when context claims "not in serverless"', () => {
+ expect(() =>
+ validation.validate({ myProp: true }, { serverless: false })
+ ).toThrowErrorMatchingInlineSnapshot(`"[myProp]: a value wasn't expected to be present"`);
+ });
+
+ test('it allows changing the flag when context claims "in serverless"', () => {
+ expect(validation.validate({ myProp: false }, { serverless: true })).toEqual({
+ myProp: false,
+ });
+ });
+ });
+
+ describe('Example: Only allow the setting on Traditional', () => {
+ const validation = schema.object({
+ myProp: offeringBasedSchema({ traditional: schema.boolean({ defaultValue: true }) }),
+ });
+
+ test('it uses the non-serverless validation when the context is not present', () => {
+ expect(validation.validate({})).toEqual({ myProp: true });
+ });
+
+ test('it uses the non-serverless validation when context claims "not in serverless"', () => {
+ expect(validation.validate({}, { serverless: false })).toEqual({ myProp: true });
+ });
+
+ test('it uses serverless validation when context claims "in serverless"', () => {
+ expect(validation.validate({}, { serverless: true })).toEqual({});
+ });
+
+ test('it allows changing the flag when context claims "not in serverless"', () => {
+ expect(validation.validate({ myProp: false }, { serverless: false })).toEqual({
+ myProp: false,
+ });
+ });
+
+ test('it does not allow changing the flag when context claims "in serverless"', () => {
+ expect(() =>
+ validation.validate({ myProp: true }, { serverless: true })
+ ).toThrowErrorMatchingInlineSnapshot(`"[myProp]: a value wasn't expected to be present"`);
+ });
+ });
+
+ describe('Example: Fixed setting on Traditional, configurable on Serverless', () => {
+ const validation = schema.object({
+ myProp: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: true }),
+ options: { defaultValue: false },
+ }),
+ });
+
+ test('it uses the non-serverless validation when the context is not present', () => {
+ expect(validation.validate({})).toEqual({ myProp: false });
+ });
+
+ test('it uses the non-serverless validation when context claims "not in serverless"', () => {
+ expect(validation.validate({}, { serverless: false })).toEqual({ myProp: false });
+ });
+
+ test('it uses serverless validation when context claims "in serverless"', () => {
+ expect(validation.validate({}, { serverless: true })).toEqual({ myProp: true });
+ });
+
+ test('it does not allow changing the flag when context claims "not in serverless"', () => {
+ expect(() =>
+ validation.validate({ myProp: true }, { serverless: false })
+ ).toThrowErrorMatchingInlineSnapshot(`"[myProp]: a value wasn't expected to be present"`);
+ });
+
+ test('it allows changing the flag when context claims "in serverless"', () => {
+ expect(validation.validate({ myProp: false }, { serverless: true })).toEqual({
+ myProp: false,
+ });
+ });
+ });
+
+ describe('Example: Fixed setting on Traditional (though settable), configurable on Serverless', () => {
+ const validation = schema.object({
+ myProp: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: true }),
+ traditional: schema.literal(false),
+ options: { defaultValue: false },
+ }),
+ });
+
+ test('it uses the non-serverless validation when the context is not present', () => {
+ expect(validation.validate({})).toEqual({ myProp: false });
+ });
+
+ test('it uses the non-serverless validation when context claims "not in serverless"', () => {
+ expect(validation.validate({}, { serverless: false })).toEqual({ myProp: false });
+ });
+
+ test('it uses serverless validation when context claims "in serverless"', () => {
+ expect(validation.validate({}, { serverless: true })).toEqual({ myProp: true });
+ });
+
+ test('it does not allow changing the flag when context claims "not in serverless"', () => {
+ expect(() =>
+ validation.validate({ myProp: true }, { serverless: false })
+ ).toThrowErrorMatchingInlineSnapshot(`"[myProp]: expected value to equal [false]"`);
+ });
+
+ test('it allows changing the flag when context claims "in serverless"', () => {
+ expect(validation.validate({ myProp: false }, { serverless: true })).toEqual({
+ myProp: false,
+ });
+ });
+ });
+
+ describe('Example: Fixed setting on Serverless (though settable), configurable on Traditional', () => {
+ const validation = schema.object({
+ myProp: offeringBasedSchema({
+ serverless: schema.literal(false),
+ traditional: schema.boolean({ defaultValue: true }),
+ options: { defaultValue: false },
+ }),
+ });
+
+ test('it uses the non-serverless validation when the context is not present', () => {
+ expect(validation.validate({})).toEqual({ myProp: true });
+ });
+
+ test('it uses the non-serverless validation when context claims "not in serverless"', () => {
+ expect(validation.validate({}, { serverless: false })).toEqual({ myProp: true });
+ });
+
+ test('it uses serverless validation when context claims "in serverless"', () => {
+ expect(validation.validate({}, { serverless: true })).toEqual({ myProp: false });
+ });
+
+ test('it allows changing the flag when context claims "not in serverless"', () => {
+ expect(validation.validate({ myProp: false }, { serverless: false })).toEqual({
+ myProp: false,
+ });
+ });
+
+ test('it does not allow changing the flag when context claims "in serverless"', () => {
+ expect(() =>
+ validation.validate({ myProp: true }, { serverless: true })
+ ).toThrowErrorMatchingInlineSnapshot(`"[myProp]: expected value to equal [false]"`);
+ });
+ });
+
+ describe('Example: Setting is changeable on all offerings but with different defaults', () => {
+ const validation = schema.object({
+ myProp: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: true }),
+ traditional: schema.boolean({ defaultValue: false }),
+ }),
+ });
+
+ test('it uses the non-serverless validation when the context is not present', () => {
+ expect(validation.validate({})).toEqual({ myProp: false });
+ });
+
+ test('it uses the non-serverless validation when context claims "not in serverless"', () => {
+ expect(validation.validate({}, { serverless: false })).toEqual({ myProp: false });
+ });
+
+ test('it uses serverless validation when context claims "in serverless"', () => {
+ expect(validation.validate({}, { serverless: true })).toEqual({ myProp: true });
+ });
+
+ test('it allows changing the flag when context claims "not in serverless"', () => {
+ expect(validation.validate({ myProp: true }, { serverless: false })).toEqual({
+ myProp: true,
+ });
+ });
+
+ test('it allows changing the flag when context claims "in serverless"', () => {
+ expect(validation.validate({ myProp: false }, { serverless: true })).toEqual({
+ myProp: false,
+ });
+ });
+ });
+
+ test('TS enforces the same types on both entries', () => {
+ schema.object({
+ myProp: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: true }),
+ // @ts-expect-error
+ traditional: schema.string({ defaultValue: 'not on serverless' }),
+ }),
+ });
+ });
+});
diff --git a/packages/kbn-config-schema/src/helpers/offering_based_schema.ts b/packages/kbn-config-schema/src/helpers/offering_based_schema.ts
new file mode 100644
index 0000000000000..09ddfc3a75644
--- /dev/null
+++ b/packages/kbn-config-schema/src/helpers/offering_based_schema.ts
@@ -0,0 +1,59 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0 and the Server Side Public License, v 1; you may not use this file except
+ * in compliance with, at your election, the Elastic License 2.0 or the Server
+ * Side Public License, v 1.
+ */
+
+import { schema } from '../..';
+import { Type, TypeOptions } from '../types';
+
+/**
+ * Helper to apply different validations depending on whether Kibana is running the Serverless or Traditional offering.
+ *
+ * @example Only allow the setting on Serverless
+ * const config = schema.object({
+ * myProp: offeringBasedSchema({ serverless: schema.boolean({ defaultValue: true }) }),
+ * });
+ *
+ * @example Only allow the setting on Traditional
+ * const config = schema.object({
+ * myProp: offeringBasedSchema({ fullyManaged: schema.boolean({ defaultValue: true }) }),
+ * });
+ *
+ * @example Fixed value on Traditional, configurable on Serverless
+ * const config = schema.object({
+ * myProp: offeringBasedSchema({
+ * serverless: schema.boolean({ defaultValue: true }),
+ * traditional: schema.literal(false), // this can be skipped if users can't specify it in the config
+ * options: { defaultValue: false },
+ * }),
+ * });
+ *
+ * @example Setting is changeable on all offerings but with different defaults
+ * const config = schema.object({
+ * myProp: offeringBasedSchema({
+ * serverless: schema.boolean({ defaultValue: true }),
+ * traditional: schema.boolean({ defaultValue: false }),
+ * }),
+ * });
+ *
+ * @param opts.serverless The validation to apply in the Serverless offering. If not provided, it doesn't allow the setting to be set in this offering.
+ * @param opts.traditional The validation to apply in the Traditional offering. If not provided, it doesn't allow the setting to be set in this offering.
+ * @param opts.options Any options to pass down in the types.
+ */
+export function offeringBasedSchema(opts: {
+ serverless?: Type;
+ traditional?: Type;
+ options?: TypeOptions;
+}) {
+ const { serverless = schema.never(), traditional = schema.never(), options } = opts;
+ return schema.conditional(
+ schema.contextRef('serverless'),
+ true,
+ serverless,
+ traditional,
+ options
+ );
+}
diff --git a/src/plugins/input_control_vis/config.ts b/src/plugins/input_control_vis/config.ts
index cfbc9e7c19fe9..364ff6d24d9bb 100644
--- a/src/plugins/input_control_vis/config.ts
+++ b/src/plugins/input_control_vis/config.ts
@@ -6,15 +6,12 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { schema, TypeOf, offeringBasedSchema } from '@kbn/config-schema';
export const configSchema = schema.object({
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type InputControlConfig = TypeOf;
diff --git a/src/plugins/telemetry/server/config/config.ts b/src/plugins/telemetry/server/config/config.ts
index 96c195864af7a..9ac63b8937ba3 100644
--- a/src/plugins/telemetry/server/config/config.ts
+++ b/src/plugins/telemetry/server/config/config.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf, Type } from '@kbn/config-schema';
+import { schema, TypeOf, Type, offeringBasedSchema } from '@kbn/config-schema';
import { getConfigPath } from '@kbn/utils';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { labelsSchema } from './telemetry_labels';
@@ -33,13 +33,11 @@ const configSchema = schema.object({
sendUsageFrom: schema.oneOf([schema.literal('server'), schema.literal('browser')], {
defaultValue: 'server',
}),
- appendServerlessChannelsSuffix: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.literal(true),
- schema.literal(false),
- { defaultValue: schema.contextRef('serverless') }
- ),
+ appendServerlessChannelsSuffix: offeringBasedSchema({
+ serverless: schema.literal(true),
+ traditional: schema.literal(false),
+ options: { defaultValue: schema.contextRef('serverless') },
+ }),
// Used for extra enrichment of telemetry
labels: labelsSchema,
});
diff --git a/src/plugins/telemetry/server/config/telemetry_labels.ts b/src/plugins/telemetry/server/config/telemetry_labels.ts
index 5efc97235f064..f78b216b214e8 100644
--- a/src/plugins/telemetry/server/config/telemetry_labels.ts
+++ b/src/plugins/telemetry/server/config/telemetry_labels.ts
@@ -6,7 +6,7 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
/**
* Labels to enrich the context of the telemetry generated.
@@ -31,9 +31,7 @@ export const labelsSchema = schema.object(
* The serverless project type.
* Flagging it as maybe because these settings should never affect how Kibana runs.
*/
- serverless: schema.maybe(
- schema.conditional(schema.contextRef('serverless'), true, schema.string(), schema.never())
- ),
+ serverless: offeringBasedSchema({ serverless: schema.maybe(schema.string()) }),
},
{ defaultValue: {} }
);
diff --git a/src/plugins/vis_types/gauge/config.ts b/src/plugins/vis_types/gauge/config.ts
index eba3a30d74c99..be6ab1774da9b 100644
--- a/src/plugins/vis_types/gauge/config.ts
+++ b/src/plugins/vis_types/gauge/config.ts
@@ -6,17 +6,14 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type GaugeConfig = TypeOf;
diff --git a/src/plugins/vis_types/heatmap/config.ts b/src/plugins/vis_types/heatmap/config.ts
index c4bda4a46efc6..33ee2cf50f070 100644
--- a/src/plugins/vis_types/heatmap/config.ts
+++ b/src/plugins/vis_types/heatmap/config.ts
@@ -6,17 +6,14 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type HeatmapConfig = TypeOf;
diff --git a/src/plugins/vis_types/metric/config.ts b/src/plugins/vis_types/metric/config.ts
index 3e0ea58f01c2e..d87451b96ece8 100644
--- a/src/plugins/vis_types/metric/config.ts
+++ b/src/plugins/vis_types/metric/config.ts
@@ -6,17 +6,14 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type MetricConfig = TypeOf;
diff --git a/src/plugins/vis_types/pie/config.ts b/src/plugins/vis_types/pie/config.ts
index 6562ed8c8588d..6132bf85327d1 100644
--- a/src/plugins/vis_types/pie/config.ts
+++ b/src/plugins/vis_types/pie/config.ts
@@ -6,17 +6,14 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type PieConfig = TypeOf;
diff --git a/src/plugins/vis_types/table/config.ts b/src/plugins/vis_types/table/config.ts
index a4d7bf306f51e..3e9d2a8d226a3 100644
--- a/src/plugins/vis_types/table/config.ts
+++ b/src/plugins/vis_types/table/config.ts
@@ -6,17 +6,14 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type TableConfig = TypeOf;
diff --git a/src/plugins/vis_types/tagcloud/config.ts b/src/plugins/vis_types/tagcloud/config.ts
index 2eba190000aef..d0c0ed59a2a08 100644
--- a/src/plugins/vis_types/tagcloud/config.ts
+++ b/src/plugins/vis_types/tagcloud/config.ts
@@ -6,17 +6,14 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type TagcloudConfig = TypeOf;
diff --git a/src/plugins/vis_types/timelion/config.ts b/src/plugins/vis_types/timelion/config.ts
index 620a2913607b7..6f295b80af748 100644
--- a/src/plugins/vis_types/timelion/config.ts
+++ b/src/plugins/vis_types/timelion/config.ts
@@ -6,18 +6,15 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
graphiteUrls: schema.maybe(schema.arrayOf(schema.string())),
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type TimelionConfig = TypeOf;
diff --git a/src/plugins/vis_types/timeseries/config.ts b/src/plugins/vis_types/timeseries/config.ts
index 7b3dbbb0d6c2d..ce20a8eaf609e 100644
--- a/src/plugins/vis_types/timeseries/config.ts
+++ b/src/plugins/vis_types/timeseries/config.ts
@@ -6,17 +6,14 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const config = schema.object({
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
/** @deprecated **/
chartResolution: schema.number({ defaultValue: 150 }),
diff --git a/src/plugins/vis_types/vislib/config.ts b/src/plugins/vis_types/vislib/config.ts
index 70ae5ccf5fd20..31568aff8a70b 100644
--- a/src/plugins/vis_types/vislib/config.ts
+++ b/src/plugins/vis_types/vislib/config.ts
@@ -6,17 +6,14 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type VislibConfig = TypeOf;
diff --git a/src/plugins/vis_types/xy/config.ts b/src/plugins/vis_types/xy/config.ts
index 51506b7877329..e59147775f356 100644
--- a/src/plugins/vis_types/xy/config.ts
+++ b/src/plugins/vis_types/xy/config.ts
@@ -6,17 +6,14 @@
* Side Public License, v 1.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
export const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
- readOnly: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: false })),
- schema.never()
- ),
+ readOnly: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
});
export type XyConfig = TypeOf;
diff --git a/x-pack/plugins/apm/server/index.ts b/x-pack/plugins/apm/server/index.ts
index decff8d362dfe..1b8f8cb7c237e 100644
--- a/x-pack/plugins/apm/server/index.ts
+++ b/x-pack/plugins/apm/server/index.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import {
PluginConfigDescriptor,
PluginInitializerContext,
@@ -14,14 +14,12 @@ import { maxSuggestions } from '@kbn/observability-plugin/common';
import { SearchAggregatedTransactionSetting } from '../common/aggregated_transactions';
import { APMPlugin } from './plugin';
-const disabledOnServerless = schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.boolean({
+const disabledOnServerless = offeringBasedSchema({
+ serverless: schema.boolean({
defaultValue: false,
}),
- schema.oneOf([schema.literal(true)], { defaultValue: true })
-);
+ traditional: schema.oneOf([schema.literal(true)], { defaultValue: true }),
+});
// All options should be documented in the APM configuration settings: https://github.com/elastic/kibana/blob/main/docs/settings/apm-settings.asciidoc
// and be included on cloud allow list unless there are specific reasons not to
@@ -61,18 +59,12 @@ const configSchema = schema.object({
defaultValue: 'https://apm-agent-versions.elastic.co/versions.json',
}),
enabled: schema.boolean({ defaultValue: true }),
- serverlessOnboarding: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.boolean({ defaultValue: false }),
- schema.never()
- ),
- managedServiceUrl: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.string({ defaultValue: '' }),
- schema.never()
- ),
+ serverlessOnboarding: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ }),
+ managedServiceUrl: offeringBasedSchema({
+ serverless: schema.string({ defaultValue: '' }),
+ }),
featureFlags: schema.object({
agentConfigurationAvailable: disabledOnServerless,
configurableIndicesAvailable: disabledOnServerless,
@@ -83,13 +75,10 @@ const configSchema = schema.object({
storageExplorerAvailable: disabledOnServerless,
}),
serverless: schema.object({
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.literal(true),
- schema.never(),
- { defaultValue: schema.contextRef('serverless') }
- ),
+ enabled: offeringBasedSchema({
+ serverless: schema.literal(true),
+ options: { defaultValue: schema.contextRef('serverless') },
+ }),
}),
});
diff --git a/x-pack/plugins/cloud/server/config.ts b/x-pack/plugins/cloud/server/config.ts
index 1efd9b50fc421..d1fb2bb1f44ab 100644
--- a/x-pack/plugins/cloud/server/config.ts
+++ b/x-pack/plugins/cloud/server/config.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
const apmConfigSchema = schema.object({
@@ -29,12 +29,7 @@ const configSchema = schema.object({
users_and_roles_url: schema.maybe(schema.string()),
organization_url: schema.maybe(schema.string()),
profile_url: schema.maybe(schema.string()),
- projects_url: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.string({ defaultValue: '/projects/' }),
- schema.never()
- ),
+ projects_url: offeringBasedSchema({ serverless: schema.string({ defaultValue: '/projects/' }) }),
trial_end_date: schema.maybe(schema.string()),
is_elastic_staff_owned: schema.maybe(schema.boolean()),
serverless: schema.maybe(
diff --git a/x-pack/plugins/cloud_integrations/cloud_data_migration/server/config.ts b/x-pack/plugins/cloud_integrations/cloud_data_migration/server/config.ts
index e6a7fce2541f2..9d7c102a1bb5c 100644
--- a/x-pack/plugins/cloud_integrations/cloud_data_migration/server/config.ts
+++ b/x-pack/plugins/cloud_integrations/cloud_data_migration/server/config.ts
@@ -5,18 +5,15 @@
* 2.0.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core-plugins-server';
const configSchema = schema.object({
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enabled: offeringBasedSchema({
// cloud_data_migration is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
});
export type CloudDataMigrationConfig = TypeOf;
diff --git a/x-pack/plugins/cross_cluster_replication/server/config.ts b/x-pack/plugins/cross_cluster_replication/server/config.ts
index 1d83f53920576..6403382b6bc75 100644
--- a/x-pack/plugins/cross_cluster_replication/server/config.ts
+++ b/x-pack/plugins/cross_cluster_replication/server/config.ts
@@ -7,7 +7,7 @@
import { SemVer } from 'semver';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { MAJOR_VERSION } from '../common/constants';
@@ -26,14 +26,11 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enabled: offeringBasedSchema({
// CCR is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/discover_log_explorer/server/config.ts b/x-pack/plugins/discover_log_explorer/server/config.ts
index 4fe008fbd7399..0fece328c2964 100644
--- a/x-pack/plugins/discover_log_explorer/server/config.ts
+++ b/x-pack/plugins/discover_log_explorer/server/config.ts
@@ -5,22 +5,19 @@
* 2.0.
*/
-import { schema } from '@kbn/config-schema';
+import { schema, offeringBasedSchema } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { DiscoverLogExplorerConfig } from '../common/plugin_config';
export const configSchema = schema.object({
featureFlags: schema.object({
- deepLinkVisible: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.boolean(),
- schema.never(),
- {
+ deepLinkVisible: offeringBasedSchema({
+ serverless: schema.boolean(),
+ options: {
defaultValue: false,
- }
- ),
+ },
+ }),
}),
});
diff --git a/x-pack/plugins/graph/config.ts b/x-pack/plugins/graph/config.ts
index 75daa64230c48..d31d53363549e 100644
--- a/x-pack/plugins/graph/config.ts
+++ b/x-pack/plugins/graph/config.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { schema, TypeOf, offeringBasedSchema } from '@kbn/config-schema';
export const configSchema = schema.object({
savePolicy: schema.oneOf(
@@ -18,12 +18,7 @@ export const configSchema = schema.object({
{ defaultValue: 'configAndData' }
),
canEditDrillDownUrls: schema.boolean({ defaultValue: true }),
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.maybe(schema.boolean({ defaultValue: true })),
- schema.never()
- ),
+ enabled: offeringBasedSchema({ serverless: schema.boolean({ defaultValue: true }) }),
});
export type ConfigSchema = TypeOf;
diff --git a/x-pack/plugins/index_lifecycle_management/server/config.ts b/x-pack/plugins/index_lifecycle_management/server/config.ts
index 5a02e404ad2b7..f04c3cd062f5f 100644
--- a/x-pack/plugins/index_lifecycle_management/server/config.ts
+++ b/x-pack/plugins/index_lifecycle_management/server/config.ts
@@ -7,7 +7,7 @@
import { SemVer } from 'semver';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { MAJOR_VERSION } from '../common/constants';
@@ -28,14 +28,11 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enabled: offeringBasedSchema({
// ILM is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/index_management/server/config.ts b/x-pack/plugins/index_management/server/config.ts
index 1ffbab8b43103..f21952899d6e3 100644
--- a/x-pack/plugins/index_management/server/config.ts
+++ b/x-pack/plugins/index_management/server/config.ts
@@ -7,7 +7,7 @@
import { SemVer } from 'semver';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { MAJOR_VERSION } from '../common/constants';
@@ -22,22 +22,16 @@ const schemaLatest = schema.object(
ui: schema.object({
enabled: schema.boolean({ defaultValue: true }),
}),
- enableIndexActions: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enableIndexActions: offeringBasedSchema({
// Index actions are disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) for serverless config across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
- enableLegacyTemplates: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
+ enableLegacyTemplates: offeringBasedSchema({
// Legacy templates functionality is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) for serverless config across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
dev: schema.object({ enableIndexDetailsPage: schema.boolean({ defaultValue: false }) }),
},
{ defaultValue: undefined }
diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts
index 3655a65f706d3..8a91d5685daa3 100644
--- a/x-pack/plugins/infra/server/plugin.ts
+++ b/x-pack/plugins/infra/server/plugin.ts
@@ -6,7 +6,7 @@
*/
import { Server } from '@hapi/hapi';
-import { schema } from '@kbn/config-schema';
+import { offeringBasedSchema, schema } from '@kbn/config-schema';
import {
CoreStart,
Plugin,
@@ -62,20 +62,17 @@ export const config: PluginConfigDescriptor = {
schema: schema.object({
enabled: schema.boolean({ defaultValue: true }),
// Setting variants only allowed in the Serverless offering, otherwise always default `logs-ui` value
- logs: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.object({
+ logs: offeringBasedSchema({
+ serverless: schema.object({
app_target: schema.oneOf(
[schema.literal(LOGS_APP_TARGET), schema.literal(DISCOVER_APP_TARGET)],
{ defaultValue: LOGS_APP_TARGET }
),
}),
- schema.never(),
- {
- defaultValue: { app_target: LOGS_APP_TARGET },
- }
- ),
+ options: {
+ defaultValue: { app_target: LOGS_APP_TARGET } as const, // "as const" is required for TS to not generalize `app_target: string`
+ },
+ }),
alerting: schema.object({
inventory_threshold: schema.object({
group_by_page_size: schema.number({ defaultValue: 5_000 }),
diff --git a/x-pack/plugins/license_management/server/config.ts b/x-pack/plugins/license_management/server/config.ts
index f413335cc23ef..648a8f53b5e6d 100644
--- a/x-pack/plugins/license_management/server/config.ts
+++ b/x-pack/plugins/license_management/server/config.ts
@@ -7,7 +7,7 @@
import { SemVer } from 'semver';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { MAJOR_VERSION } from '../common/constants';
@@ -26,14 +26,11 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enabled: offeringBasedSchema({
// License Management is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/observability_onboarding/server/index.ts b/x-pack/plugins/observability_onboarding/server/index.ts
index 922c8142998a2..ddc1c0ac79842 100644
--- a/x-pack/plugins/observability_onboarding/server/index.ts
+++ b/x-pack/plugins/observability_onboarding/server/index.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import {
PluginConfigDescriptor,
PluginInitializerContext,
@@ -17,13 +17,10 @@ const configSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
}),
serverless: schema.object({
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.literal(true),
- schema.never(),
- { defaultValue: schema.contextRef('serverless') }
- ),
+ enabled: offeringBasedSchema({
+ serverless: schema.literal(true),
+ options: { defaultValue: schema.contextRef('serverless') },
+ }),
}),
});
diff --git a/x-pack/plugins/remote_clusters/server/config.ts b/x-pack/plugins/remote_clusters/server/config.ts
index 12275985a3aa9..12f88ba92e832 100644
--- a/x-pack/plugins/remote_clusters/server/config.ts
+++ b/x-pack/plugins/remote_clusters/server/config.ts
@@ -7,7 +7,7 @@
import { SemVer } from 'semver';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { MAJOR_VERSION } from '../common/constants';
@@ -26,14 +26,11 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enabled: offeringBasedSchema({
// Remote Clusters is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/reporting/server/config/schema.ts b/x-pack/plugins/reporting/server/config/schema.ts
index 4790a3fb6b7aa..966f4f20ff313 100644
--- a/x-pack/plugins/reporting/server/config/schema.ts
+++ b/x-pack/plugins/reporting/server/config/schema.ts
@@ -5,7 +5,7 @@
* 2.0.
*/
-import { ByteSizeValue, schema, TypeOf } from '@kbn/config-schema';
+import { ByteSizeValue, offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import ipaddr from 'ipaddr.js';
import { sum } from 'lodash';
import moment from 'moment';
@@ -84,18 +84,14 @@ const EncryptionKeySchema = schema.conditional(
);
const RolesSchema = schema.object({
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.boolean({ defaultValue: false }),
- schema.boolean({ defaultValue: true })
- ), // true: use ES API for access control (deprecated in 7.x). false: use Kibana API for application features (8.0)
- allow: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.arrayOf(schema.string(), { defaultValue: [] }),
- schema.arrayOf(schema.string(), { defaultValue: ['reporting_user'] })
- ),
+ enabled: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ traditional: schema.boolean({ defaultValue: true }),
+ }), // true: use ES API for access control (deprecated in 7.x). false: use Kibana API for application features (8.0)
+ allow: offeringBasedSchema({
+ serverless: schema.arrayOf(schema.string(), { defaultValue: [] }),
+ traditional: schema.arrayOf(schema.string(), { defaultValue: ['reporting_user'] }),
+ }),
});
// Browser side polling: job completion notifier, management table auto-refresh
@@ -118,21 +114,17 @@ const ExportTypeSchema = schema.object({
}),
// Png reports are disabled in serverless
png: schema.object({
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.boolean({ defaultValue: false }),
- schema.boolean({ defaultValue: true })
- ),
+ enabled: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ traditional: schema.boolean({ defaultValue: true }),
+ }),
}),
// Pdf reports are disabled in serverless
pdf: schema.object({
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.boolean({ defaultValue: false }),
- schema.boolean({ defaultValue: true })
- ),
+ enabled: offeringBasedSchema({
+ serverless: schema.boolean({ defaultValue: false }),
+ traditional: schema.boolean({ defaultValue: true }),
+ }),
}),
});
diff --git a/x-pack/plugins/rollup/server/config.ts b/x-pack/plugins/rollup/server/config.ts
index c0d5c1fbe92ee..a671dab0d0cb6 100644
--- a/x-pack/plugins/rollup/server/config.ts
+++ b/x-pack/plugins/rollup/server/config.ts
@@ -7,7 +7,7 @@
import { SemVer } from 'semver';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { MAJOR_VERSION } from '../common';
@@ -26,14 +26,11 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enabled: offeringBasedSchema({
// Rollups is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/security/server/config.ts b/x-pack/plugins/security/server/config.ts
index 5b65dc3bb1ebd..15cb6461b97b5 100644
--- a/x-pack/plugins/security/server/config.ts
+++ b/x-pack/plugins/security/server/config.ts
@@ -10,7 +10,7 @@ import type { Duration } from 'moment';
import path from 'path';
import type { Type, TypeOf } from '@kbn/config-schema';
-import { schema } from '@kbn/config-schema';
+import { offeringBasedSchema, schema } from '@kbn/config-schema';
import type { AppenderConfigType, Logger } from '@kbn/core/server';
import { config as coreConfig } from '@kbn/core/server';
import { i18n } from '@kbn/i18n';
@@ -299,16 +299,13 @@ export const ConfigSchema = schema.object({
enabled: schema.boolean({ defaultValue: true }),
// Setting only allowed in the Serverless offering
- ui: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.object({
+ ui: offeringBasedSchema({
+ serverless: schema.object({
userManagementEnabled: schema.boolean({ defaultValue: true }),
roleManagementEnabled: schema.boolean({ defaultValue: true }),
roleMappingManagementEnabled: schema.boolean({ defaultValue: true }),
}),
- schema.never()
- ),
+ }),
});
export function createConfig(
diff --git a/x-pack/plugins/snapshot_restore/server/config.ts b/x-pack/plugins/snapshot_restore/server/config.ts
index e712f33eb0cbd..5e2eb6eb2885c 100644
--- a/x-pack/plugins/snapshot_restore/server/config.ts
+++ b/x-pack/plugins/snapshot_restore/server/config.ts
@@ -7,7 +7,7 @@
import { SemVer } from 'semver';
import { i18n } from '@kbn/i18n';
import { get } from 'lodash';
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
import { MAJOR_VERSION } from '../common/constants';
@@ -29,14 +29,11 @@ const schemaLatest = schema.object(
* Disables the plugin.
* Added back in 8.8.
*/
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enabled: offeringBasedSchema({
// Snapshot & Restore is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
},
{ defaultValue: undefined }
);
diff --git a/x-pack/plugins/spaces/server/config.ts b/x-pack/plugins/spaces/server/config.ts
index e4a2852a01dc8..52f63f3526904 100644
--- a/x-pack/plugins/spaces/server/config.ts
+++ b/x-pack/plugins/spaces/server/config.ts
@@ -8,7 +8,7 @@
import type { Observable } from 'rxjs';
import type { TypeOf } from '@kbn/config-schema';
-import { schema } from '@kbn/config-schema';
+import { offeringBasedSchema, schema } from '@kbn/config-schema';
import type { PluginInitializerContext } from '@kbn/core/server';
export const ConfigSchema = schema.object({
@@ -26,11 +26,9 @@ export const ConfigSchema = schema.object({
})
),
maxSpaces: schema.number({ defaultValue: 1000 }),
- allowFeatureVisibility: schema.conditional(
- schema.contextRef('serverless'),
- true,
- schema.literal(false),
- schema.boolean({
+ allowFeatureVisibility: offeringBasedSchema({
+ serverless: schema.literal(false),
+ traditional: schema.boolean({
validate: (rawValue) => {
// This setting should not be configurable on-prem to avoid bugs when e.g. existing spaces
// have feature visibility customized but admins would be unable to change them back if the
@@ -40,8 +38,8 @@ export const ConfigSchema = schema.object({
}
},
defaultValue: true,
- })
- ),
+ }),
+ }),
});
export function createConfig$(context: PluginInitializerContext) {
diff --git a/x-pack/plugins/upgrade_assistant/server/config.ts b/x-pack/plugins/upgrade_assistant/server/config.ts
index 76820c5121765..e603780be785b 100644
--- a/x-pack/plugins/upgrade_assistant/server/config.ts
+++ b/x-pack/plugins/upgrade_assistant/server/config.ts
@@ -4,7 +4,7 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
-import { schema, TypeOf } from '@kbn/config-schema';
+import { offeringBasedSchema, schema, TypeOf } from '@kbn/config-schema';
import { PluginConfigDescriptor } from '@kbn/core/server';
// -------------------------------
@@ -15,14 +15,11 @@ const configSchema = schema.object({
/**
* Disables the plugin.
*/
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enabled: offeringBasedSchema({
// Upgrade Assistant is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
featureSet: schema.object({
/**
diff --git a/x-pack/plugins/watcher/server/index.ts b/x-pack/plugins/watcher/server/index.ts
index 874575ef9c122..42a76820f0c20 100644
--- a/x-pack/plugins/watcher/server/index.ts
+++ b/x-pack/plugins/watcher/server/index.ts
@@ -6,7 +6,7 @@
*/
import { PluginInitializerContext } from '@kbn/core/server';
-import { schema } from '@kbn/config-schema';
+import { offeringBasedSchema, schema } from '@kbn/config-schema';
import { WatcherServerPlugin } from './plugin';
@@ -14,13 +14,10 @@ export const plugin = (ctx: PluginInitializerContext) => new WatcherServerPlugin
export const config = {
schema: schema.object({
- enabled: schema.conditional(
- schema.contextRef('serverless'),
- true,
+ enabled: offeringBasedSchema({
// Watcher is disabled in serverless; refer to the serverless.yml file as the source of truth
// We take this approach in order to have a central place (serverless.yml) to view disabled plugins across Kibana
- schema.boolean({ defaultValue: true }),
- schema.never()
- ),
+ serverless: schema.boolean({ defaultValue: true }),
+ }),
}),
};
From 327af6ca2e92ad57a99d18b06a0bf03e8f08b59b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mike=20C=C3=B4t=C3=A9?=
Date: Tue, 22 Aug 2023 07:01:29 -0400
Subject: [PATCH 15/26] Add warning for max alerts circuit breaker (#164217)
In this PR, I'm adding a warning message to the docs for the
`xpack.alerting.rules.run.alerts.max` setting that indicates the
consequences when setting a value higher than the default, while also
indicating it's not supported.
cc @lcawl
---------
Co-authored-by: Lisa Cawley
---
docs/settings/alert-action-settings.asciidoc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/docs/settings/alert-action-settings.asciidoc b/docs/settings/alert-action-settings.asciidoc
index 49ff0673386f7..692b309191b02 100644
--- a/docs/settings/alert-action-settings.asciidoc
+++ b/docs/settings/alert-action-settings.asciidoc
@@ -245,6 +245,8 @@ Specifies the maximum number of actions that a rule can generate each time detec
`xpack.alerting.rules.run.alerts.max` {ess-icon}::
Specifies the maximum number of alerts that a rule can generate each time detection checks run. Default: 1000.
++
+WARNING: The exact number of alerts your cluster can safely handle depends on your cluster configuration and workload, however setting a value higher than the default (`1000`) is not recommended or supported. Doing so could strain system resources and lead to performance issues, delays in alert processing, and potential disruptions during high alert activity periods.
`xpack.alerting.rules.run.timeout` {ess-icon}::
Specifies the default timeout for tasks associated with all types of rules.
From 79f8dcd90ceaddd0a0f9cc32440a954ae12b5357 Mon Sep 17 00:00:00 2001
From: Luca Belluccini
Date: Tue, 22 Aug 2023 13:03:22 +0200
Subject: [PATCH 16/26] Fleet - Turn some error messages in info (#164333)
## Summary
Proposal to fix https://github.com/elastic/kibana/issues/164270
### Checklist
- [ ] Possibly evaluate the "verbosity" vs "troubleshoot-ability"
- [ ] Backport
Co-authored-by: Julia Bardi <90178898+juliaElastic@users.noreply.github.com>
---
.../server/services/epm/elasticsearch/template/template.ts | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts
index e1a116f9a8023..7949c9ab98a71 100644
--- a/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts
+++ b/x-pack/plugins/fleet/server/services/epm/elasticsearch/template/template.ts
@@ -776,7 +776,7 @@ const updateExistingDataStream = async ({
delete mappings.properties.data_stream;
}
- logger.debug(`Updating mappings for ${dataStreamName}`);
+ logger.info(`Attempt to update the mappings for the ${dataStreamName} (write_index_only)`);
await retryTransientEsErrors(
() =>
esClient.indices.putMapping({
@@ -789,9 +789,8 @@ const updateExistingDataStream = async ({
// if update fails, rollover data stream and bail out
} catch (err) {
- logger.error(`Mappings update for ${dataStreamName} failed`);
- logger.error(err);
-
+ logger.info(`Mappings update for ${dataStreamName} failed due to ${err}`);
+ logger.info(`Triggering a rollover for ${dataStreamName}`);
await rolloverDataStream(dataStreamName, esClient);
return;
}
From 3458d7bf5be65bf6c2a6c93e6addd13140dd9dae Mon Sep 17 00:00:00 2001
From: Anton Dosov
Date: Tue, 22 Aug 2023 13:03:46 +0200
Subject: [PATCH 17/26] Unskip Serverless Observability Tests / serverless
observability UI navigation active sidenav section is auto opened on load
(#162323)
## Summary
close https://github.com/elastic/kibana/issues/162781
Simulating flaky test run with for loop:
https://github.com/elastic/kibana/pull/162323#issuecomment-1686262923
---
.../functional/page_objects/svl_common_navigation.ts | 12 ++++++++----
.../test_suites/observability/navigation.ts | 3 +--
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/x-pack/test_serverless/functional/page_objects/svl_common_navigation.ts b/x-pack/test_serverless/functional/page_objects/svl_common_navigation.ts
index 60964a820ac75..8d3edb04d640a 100644
--- a/x-pack/test_serverless/functional/page_objects/svl_common_navigation.ts
+++ b/x-pack/test_serverless/functional/page_objects/svl_common_navigation.ts
@@ -104,13 +104,17 @@ export function SvlCommonNavigationProvider(ctx: FtrProviderContext) {
},
async expectSectionOpen(sectionId: NavigationId) {
await this.expectSectionExists(sectionId);
- const isOpen = await this.isSectionOpen(sectionId);
- expect(isOpen).to.be(true);
+ await retry.waitFor(`section ${sectionId} to be open`, async () => {
+ const isOpen = await this.isSectionOpen(sectionId);
+ return isOpen;
+ });
},
async expectSectionClosed(sectionId: NavigationId) {
await this.expectSectionExists(sectionId);
- const isOpen = await this.isSectionOpen(sectionId);
- expect(isOpen).to.be(false);
+ await retry.waitFor(`section ${sectionId} to be closed`, async () => {
+ const isOpen = await this.isSectionOpen(sectionId);
+ return !isOpen;
+ });
},
async openSection(sectionId: NavigationId) {
await this.expectSectionExists(sectionId);
diff --git a/x-pack/test_serverless/functional/test_suites/observability/navigation.ts b/x-pack/test_serverless/functional/test_suites/observability/navigation.ts
index 2054e8eb011f6..eb56af9f88688 100644
--- a/x-pack/test_serverless/functional/test_suites/observability/navigation.ts
+++ b/x-pack/test_serverless/functional/test_suites/observability/navigation.ts
@@ -69,8 +69,7 @@ export default function ({ getPageObject, getService }: FtrProviderContext) {
await expectNoPageReload();
});
- // FLAKY/BUG?: https://github.com/elastic/kibana/issues/162781
- it.skip('active sidenav section is auto opened on load', async () => {
+ it('active sidenav section is auto opened on load', async () => {
await svlCommonNavigation.sidenav.openSection('project_settings_project_nav');
await svlCommonNavigation.sidenav.clickLink({ deepLinkId: 'management' });
await browser.refresh();
From e5f6c1a57fba126d672608cdb5f175757722f7e8 Mon Sep 17 00:00:00 2001
From: Kevin Logan <56395104+kevinlog@users.noreply.github.com>
Date: Tue, 22 Aug 2023 07:15:51 -0400
Subject: [PATCH 18/26] [Fleet] Update docs links for Logstash and Kafka to
point to new pages (#164335)
## Summary
Updates the docs links for Logstash and Kafka to point to new docs
pages.
Logstash docs link:
![image](https://github.com/elastic/kibana/assets/56395104/4b5c6962-bc2b-44f2-b2f3-ba15a9a57035)
![image](https://github.com/elastic/kibana/assets/56395104/862fa63b-9d3f-43ef-93d9-0e66f0913ffc)
Kafka docs link:
![image](https://github.com/elastic/kibana/assets/56395104/967c30d5-2354-4153-a2d6-3202a1e3f02f)
![image](https://github.com/elastic/kibana/assets/56395104/dae2d5d7-2083-43dc-8f55-c1b73a0ff19a)
### Checklist
- [x]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
---------
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
---
packages/kbn-doc-links/src/get_doc_links.ts | 2 ++
packages/kbn-doc-links/src/types.ts | 2 ++
.../sections/settings/components/edit_output_flyout/index.tsx | 2 +-
.../components/edit_output_flyout/output_form_kafka.tsx | 2 +-
4 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/packages/kbn-doc-links/src/get_doc_links.ts b/packages/kbn-doc-links/src/get_doc_links.ts
index 23121d9fa5e9d..a3aebffc12b55 100644
--- a/packages/kbn-doc-links/src/get_doc_links.ts
+++ b/packages/kbn-doc-links/src/get_doc_links.ts
@@ -722,6 +722,8 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
fleetServer: `${FLEET_DOCS}fleet-server.html`,
fleetServerAddFleetServer: `${FLEET_DOCS}add-a-fleet-server.html`,
settings: `${FLEET_DOCS}fleet-settings.html`,
+ kafkaSettings: `${FLEET_DOCS}kafka-output-settings.html`,
+ logstashSettings: `${FLEET_DOCS}ls-output-settings.html`,
settingsFleetServerHostSettings: `${FLEET_DOCS}fleet-settings.html#fleet-server-hosts-setting`,
settingsFleetServerProxySettings: `${KIBANA_DOCS}fleet-settings-kb.html#fleet-data-visualizer-settings`,
troubleshooting: `${FLEET_DOCS}fleet-troubleshooting.html`,
diff --git a/packages/kbn-doc-links/src/types.ts b/packages/kbn-doc-links/src/types.ts
index 6dd1fc6d2cea0..1a6726b743949 100644
--- a/packages/kbn-doc-links/src/types.ts
+++ b/packages/kbn-doc-links/src/types.ts
@@ -488,6 +488,8 @@ export interface DocLinks {
fleetServer: string;
fleetServerAddFleetServer: string;
settings: string;
+ logstashSettings: string;
+ kafkaSettings: string;
settingsFleetServerHostSettings: string;
settingsFleetServerProxySettings: string;
troubleshooting: string;
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx
index e764e93527b34..3270facd176b9 100644
--- a/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx
+++ b/x-pack/plugins/fleet/public/applications/fleet/sections/settings/components/edit_output_flyout/index.tsx
@@ -107,7 +107,7 @@ export const EditOutputFlyout: React.FunctionComponent =
defaultMessage="Specify the addresses that your agents will use to connect to Logstash. {guideLink}."
values={{
guideLink: (
-
+
= (props) =>
defaultMessage="Specify the URLs that your agents will use to connect to Kafka. {guideLink}."
values={{
guideLink: (
-
+
Date: Tue, 22 Aug 2023 13:35:30 +0200
Subject: [PATCH 19/26] [Enterprise Search] Fix styling for product selector.
(#164307)
## Summary
Fixes a visual bug on product selector
![Screenshot 2023-08-21 at 15 24
23](https://github.com/elastic/kibana/assets/1410658/a51114a8-531f-46b4-aa0c-b027ff86c723)
### Checklist
Delete any items that are not applicable to this PR.
- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [ ] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [ ] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [ ] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [ ] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### Risk Matrix
Delete this section if it is not applicable to this PR.
Before closing this PR, invite QA, stakeholders, and other developers to
identify risks that should be tested prior to the change/feature
release.
When forming the risk matrix, consider some of the following examples
and how they may potentially impact the change:
| Risk | Probability | Severity | Mitigation/Notes |
|---------------------------|-------------|----------|-------------------------|
| Multiple Spaces—unexpected behavior in non-default Kibana Space.
| Low | High | Integration tests will verify that all features are still
supported in non-default Kibana Space and when user switches between
spaces. |
| Multiple nodes—Elasticsearch polling might have race conditions
when multiple Kibana nodes are polling for the same tasks. | High | Low
| Tasks are idempotent, so executing them multiple times will not result
in logical error, but will degrade performance. To test for this case we
add plenty of unit tests around this logic and document manual testing
procedure. |
| Code should gracefully handle cases when feature X or plugin Y are
disabled. | Medium | High | Unit tests will verify that any feature flag
or plugin combination still results in our service operational. |
| [See more potential risk
examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) |
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---
.../product_selector/product_selector.tsx | 139 ++++++++++--------
1 file changed, 74 insertions(+), 65 deletions(-)
diff --git a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx
index 001d34c1c5ad6..c26dce2885b0a 100644
--- a/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx
+++ b/x-pack/plugins/enterprise_search/public/applications/enterprise_search_overview/components/product_selector/product_selector.tsx
@@ -49,80 +49,89 @@ export const ProductSelector: React.FC = () => {
return (
<>
-
-
-
+
-
-
-
- {i18n.translate('xpack.enterpriseSearch.productSelector.overview.title', {
- defaultMessage: 'Ingest your content',
- })}
-
-
-
-
-
- {i18n.translate('xpack.enterpriseSearch.productSelector.overview.description', {
- defaultMessage:
- 'The first step in building your search experience is to create a search-optimized Elasticsearch index and import your content into it. Elasticsearch offers several user-friendly options you can choose from that best match your technical expertise and data sources.',
- })}
-
-
-
-
-
-
- {showErrorConnecting && (
- <>
-
-
- >
- )}
-
-
-
-
- {i18n.translate('xpack.enterpriseSearch.productSelector.overview.createCustom.title', {
- defaultMessage: 'Create a custom search experience',
- })}
-
-
-
-
-
- {i18n.translate(
- 'xpack.enterpriseSearch.productSelector.overview.createCustom.description',
- {
+
+
+
+
+
+
+
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.productSelector.overview.title', {
+ defaultMessage: 'Ingest your content',
+ })}
+
+
+
+
+
+ {i18n.translate('xpack.enterpriseSearch.productSelector.overview.description', {
defaultMessage:
- "Once your index is created and populated, you'll be ready to use the full power of Elasticsearch. Build search applications using our out-of-the-box tools and programming language clients, all backed by a robust set of APIs.",
- }
- )}
-
-
-
-
-
-
-
-
-
-
-
-
- {!config.host && config.canDeployEntSearch && (
+ 'The first step in building your search experience is to create a search-optimized Elasticsearch index and import your content into it. Elasticsearch offers several user-friendly options you can choose from that best match your technical expertise and data sources.',
+ })}
+
+
+
+
+
+
+ {showErrorConnecting && (
+ <>
+
+
+ >
+ )}
+
+
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.productSelector.overview.createCustom.title',
+ {
+ defaultMessage: 'Create a custom search experience',
+ }
+ )}
+
+
+
+
+
+ {i18n.translate(
+ 'xpack.enterpriseSearch.productSelector.overview.createCustom.description',
+ {
+ defaultMessage:
+ "Once your index is created and populated, you'll be ready to use the full power of Elasticsearch. Build search applications using our out-of-the-box tools and programming language clients, all backed by a robust set of APIs.",
+ }
+ )}
+
+
+
+
+
+
-
+
- )}
-
-
+
+
+
+ {!config.host && config.canDeployEntSearch && (
+
+
+
+ )}
+
+
+
>
);
From 546a3cb1afa376048ba90372dac23a50c6e4a84d Mon Sep 17 00:00:00 2001
From: Dima Arnautov
Date: Tue, 22 Aug 2023 14:01:34 +0200
Subject: [PATCH 20/26] [ML] AIOps: Update assertion for the change point
detection tests (#164404)
## Summary
Closes https://github.com/elastic/kibana/issues/158851
Updates assertion for the split field test.
---
x-pack/test/functional/apps/aiops/change_point_detection.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/x-pack/test/functional/apps/aiops/change_point_detection.ts b/x-pack/test/functional/apps/aiops/change_point_detection.ts
index 0c55e081afc92..f52e00892acb9 100644
--- a/x-pack/test/functional/apps/aiops/change_point_detection.ts
+++ b/x-pack/test/functional/apps/aiops/change_point_detection.ts
@@ -16,8 +16,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
// aiops lives in the ML UI so we need some related services.
const ml = getService('ml');
- // Failing: See https://github.com/elastic/kibana/issues/158851
- describe.skip('change point detection', async function () {
+ describe('change point detection', async function () {
before(async () => {
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/ecommerce');
await ml.testResources.createIndexPatternIfNeeded('ft_ecommerce', 'order_date');
@@ -66,7 +65,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await aiops.changePointDetectionPage.selectSplitField(0, 'geoip.city_name');
await aiops.changePointDetectionPage.getTable(0).waitForTableToLoad();
const result = await aiops.changePointDetectionPage.getTable(0).parseTable();
- expect(result.length).to.be(7);
+ // the aggregation may return different results (+-1)
+ expect(result.length).to.be.above(5);
// assert asc sorting by p_value is applied
expect(parseFloat(result[0].pValue)).to.be.lessThan(parseFloat(result[4].pValue));
});
From 7ece4e5df3e6f8934c6ad1f8b462762431efeb9f Mon Sep 17 00:00:00 2001
From: Dzmitry Lemechko
Date: Tue, 22 Aug 2023 14:09:41 +0200
Subject: [PATCH 21/26] [FTR] Move serverless tests depending on feature flag
to its own config file (#163929)
## Summary
It seems beneficial to have feature flag tests in a separate test config
file
- tests are still run on Kibana CI automatically
- tests are not run on MKI projects automatically, but you can deploy
custom project and run tests via feature flags config
All the feature flags within the same project should be places in the
same config to make sure there is no arguments conflict.
When the flag is moved to the yml configuration, we can rely on Kibana
CI and manually triggered deployment to make sure projects are
functioning correctly.
---------
Co-authored-by: Robert Oskamp
---
.buildkite/ftr_configs.yml | 6 ++
.../steps/functional/serverless_ftr.sh | 3 +
x-pack/test_serverless/README.md | 27 ++++++
.../api_integration/config.base.ts | 4 +-
.../api_integration/services/alerting_api.ts | 54 +++++++++++
.../api_integration/services/data_view_api.ts | 52 +++++++++++
.../api_integration/services/index.ts | 2 +
.../test_suites/observability/cases/index.ts | 16 ++++
.../observability/config.feature_flags.ts | 26 ++++++
.../observability/{ => fleet}/fleet.ts | 2 +-
.../helpers/alerting_api_helper.ts | 71 ---------------
.../helpers/alerting_wait_for_helpers.ts | 90 -------------------
.../observability/helpers/data_view.ts | 61 -------------
.../observability/index.feature_flags.ts | 14 +++
.../test_suites/observability/index.ts | 15 +---
.../{ => telemetry}/snapshot_telemetry.ts | 4 +-
.../threshold_rule/avg_pct_fired.ts | 15 ++--
.../threshold_rule/avg_pct_no_data.ts | 15 ++--
.../custom_eq_avg_bytes_fired.ts | 15 ++--
.../threshold_rule/documents_count_fired.ts | 15 ++--
.../threshold_rule/group_by_fired.ts | 19 ++--
.../observability/threshold_rule/index.ts | 18 ++++
.../search/config.feature_flags.ts | 24 +++++
.../test_suites/search/index.feature_flags.ts | 13 +++
.../test_suites/search/index.ts | 6 +-
.../{ => telemetry}/snapshot_telemetry.ts | 4 +-
.../test_suites/security/cases/index.ts | 16 ++++
.../security/config.feature_flags.ts | 24 +++++
.../test_suites/security/{ => fleet}/fleet.ts | 2 +-
.../security/index.feature_flags.ts | 13 +++
.../test_suites/security/index.ts | 10 +--
.../{ => telemetry}/snapshot_telemetry.ts | 4 +-
.../observability/config.feature_flags.ts | 24 +++++
.../observability/index.feature_flags.ts | 13 +++
.../search/config.feature_flags.ts | 24 +++++
.../test_suites/search/index.feature_flags.ts | 13 +++
.../security/config.feature_flags.ts | 24 +++++
.../security/index.feature_flags.ts | 13 +++
x-pack/test_serverless/shared/config.base.ts | 1 +
x-pack/test_serverless/shared/types/index.ts | 1 +
40 files changed, 469 insertions(+), 304 deletions(-)
create mode 100644 x-pack/test_serverless/api_integration/services/data_view_api.ts
create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/cases/index.ts
create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/config.feature_flags.ts
rename x-pack/test_serverless/api_integration/test_suites/observability/{ => fleet}/fleet.ts (95%)
delete mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/helpers/alerting_api_helper.ts
delete mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/helpers/alerting_wait_for_helpers.ts
delete mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/helpers/data_view.ts
create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/index.feature_flags.ts
rename x-pack/test_serverless/api_integration/test_suites/observability/{ => telemetry}/snapshot_telemetry.ts (94%)
create mode 100644 x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/index.ts
create mode 100644 x-pack/test_serverless/api_integration/test_suites/search/config.feature_flags.ts
create mode 100644 x-pack/test_serverless/api_integration/test_suites/search/index.feature_flags.ts
rename x-pack/test_serverless/api_integration/test_suites/search/{ => telemetry}/snapshot_telemetry.ts (94%)
create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/cases/index.ts
create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/config.feature_flags.ts
rename x-pack/test_serverless/api_integration/test_suites/security/{ => fleet}/fleet.ts (95%)
create mode 100644 x-pack/test_serverless/api_integration/test_suites/security/index.feature_flags.ts
rename x-pack/test_serverless/api_integration/test_suites/security/{ => telemetry}/snapshot_telemetry.ts (94%)
create mode 100644 x-pack/test_serverless/functional/test_suites/observability/config.feature_flags.ts
create mode 100644 x-pack/test_serverless/functional/test_suites/observability/index.feature_flags.ts
create mode 100644 x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts
create mode 100644 x-pack/test_serverless/functional/test_suites/search/index.feature_flags.ts
create mode 100644 x-pack/test_serverless/functional/test_suites/security/config.feature_flags.ts
create mode 100644 x-pack/test_serverless/functional/test_suites/security/index.feature_flags.ts
diff --git a/.buildkite/ftr_configs.yml b/.buildkite/ftr_configs.yml
index 616f32285c99a..b26b54b767658 100644
--- a/.buildkite/ftr_configs.yml
+++ b/.buildkite/ftr_configs.yml
@@ -81,12 +81,18 @@ disabled:
# Serverless configs, currently only for manual tests runs, CI integration planned
- x-pack/test_serverless/api_integration/test_suites/common/config.ts
- x-pack/test_serverless/api_integration/test_suites/observability/config.ts
+ - x-pack/test_serverless/api_integration/test_suites/observability/config.feature_flags.ts
- x-pack/test_serverless/api_integration/test_suites/search/config.ts
+ - x-pack/test_serverless/api_integration/test_suites/search/config.feature_flags.ts
- x-pack/test_serverless/api_integration/test_suites/security/config.ts
+ - x-pack/test_serverless/api_integration/test_suites/security/config.feature_flags.ts
- x-pack/test_serverless/functional/test_suites/common/config.ts
- x-pack/test_serverless/functional/test_suites/observability/config.ts
+ - x-pack/test_serverless/functional/test_suites/observability/config.feature_flags.ts
- x-pack/test_serverless/functional/test_suites/search/config.ts
+ - x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts
- x-pack/test_serverless/functional/test_suites/security/config.ts
+ - x-pack/test_serverless/functional/test_suites/security/config.feature_flags.ts
defaultQueue: 'n2-4-spot'
enabled:
diff --git a/.buildkite/scripts/steps/functional/serverless_ftr.sh b/.buildkite/scripts/steps/functional/serverless_ftr.sh
index 51eee3307e0b3..ba75fe6034cae 100755
--- a/.buildkite/scripts/steps/functional/serverless_ftr.sh
+++ b/.buildkite/scripts/steps/functional/serverless_ftr.sh
@@ -9,17 +9,20 @@ export JOB="kibana-serverless-$SERVERLESS_ENVIRONMENT"
if [[ "$SERVERLESS_ENVIRONMENT" == "search" ]]; then
SERVERLESS_CONFIGS=(
"x-pack/test_serverless/api_integration/test_suites/search/config.ts"
+ "x-pack/test_serverless/api_integration/test_suites/search/config.feature_flags.ts"
"x-pack/test_serverless/functional/test_suites/search/config.ts"
)
elif [[ "$SERVERLESS_ENVIRONMENT" == "observability" ]]; then
SERVERLESS_CONFIGS=(
"x-pack/test_serverless/api_integration/test_suites/observability/config.ts"
+ "x-pack/test_serverless/api_integration/test_suites/observability/config.feature_flags.ts"
"x-pack/test_serverless/functional/test_suites/observability/config.ts"
"x-pack/test_serverless/functional/test_suites/observability/cypress/config_headless.ts"
)
elif [[ "$SERVERLESS_ENVIRONMENT" == "security" ]]; then
SERVERLESS_CONFIGS=(
"x-pack/test_serverless/api_integration/test_suites/security/config.ts"
+ "x-pack/test_serverless/api_integration/test_suites/security/config.feature_flags.ts"
"x-pack/test_serverless/functional/test_suites/security/config.ts"
)
fi
diff --git a/x-pack/test_serverless/README.md b/x-pack/test_serverless/README.md
index 9223dee92a2b9..84b1aaab676d6 100644
--- a/x-pack/test_serverless/README.md
+++ b/x-pack/test_serverless/README.md
@@ -97,6 +97,33 @@ tests that should run in a serverless environment have to be added to the
Tests in this area should be clearly designed for the serverless environment,
particularly when it comes to timing for API requests and UI interaction.
+### Testing with feature flags
+
+**tl;dr:** Tests specific to functionality behind a feature flag need special
+handling and are by default only tested locally / in CI but excluded from regular
+test runs in MKI.
+
+New features might be gated behind a feature flag and can only be enabled
+through a yml configuration entry. By default, these features are not enabled
+so they're not available in a regular serverless MKI project, which would make
+end-to-end tests for such a feature fail. In order to still have tests for
+features behind a feature flag, these tests need to be separated from the
+regular tests.
+
+For every project's `test_suites` directory, there are feature flags specific
+config (`config.feature_flags.ts`) and index (`index.feature_flags.ts`) files
+next to the regular `config.ts` and `index.ts`. These extra files are used to
+cover all feature flag tests of the respective area.
+If you want to add feature flag specific tests:
+- Add your feature flag(s) to the `kbnServerArgs` in the `config.feature_flags.ts` file
+- Load your test file(s) in the `index.feature_flags.ts` file
+
+As mentioned above, these tests are not part of the regular test run against MKI
+projects. If you still want to run feature flag tests against an MKI project,
+this requires a Kibana docker build that has the feature flags enabled by default.
+This docker image can then be used to create a project in serverless QA and the
+feature flags tests can be pointed to the project.
+
## Run tests
Similar to how functional tests are run in `x-pack/test`, you can point the
functional tests server and test runner to config files in this `x-pack/test_serverless`
diff --git a/x-pack/test_serverless/api_integration/config.base.ts b/x-pack/test_serverless/api_integration/config.base.ts
index 447950aff50cc..4ffdbfeef108a 100644
--- a/x-pack/test_serverless/api_integration/config.base.ts
+++ b/x-pack/test_serverless/api_integration/config.base.ts
@@ -25,9 +25,7 @@ export function createTestConfig(options: CreateTestConfigOptions) {
serverArgs: [
...svlSharedConfig.get('kbnTestServer.serverArgs'),
`--serverless=${options.serverlessProject}`,
- `--xpack.alerting.enableFrameworkAlerts=true`,
- '--xpack.observability.unsafe.thresholdRule.enabled=true',
- '--server.publicBaseUrl=https://localhost:5601',
+ ...(options.kbnServerArgs || []),
],
},
testFiles: options.testFiles,
diff --git a/x-pack/test_serverless/api_integration/services/alerting_api.ts b/x-pack/test_serverless/api_integration/services/alerting_api.ts
index 33d8b224561cc..8eb771d7eb11d 100644
--- a/x-pack/test_serverless/api_integration/services/alerting_api.ts
+++ b/x-pack/test_serverless/api_integration/services/alerting_api.ts
@@ -10,6 +10,9 @@ import type {
SearchResponse,
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
+import { MetricThresholdParams } from '@kbn/infra-plugin/common/alerting/metrics';
+import { ThresholdParams } from '@kbn/observability-plugin/common/threshold_rule/types';
+
import { FtrProviderContext } from '../ftr_provider_context';
export function AlertingApiProvider({ getService }: FtrProviderContext) {
@@ -86,5 +89,56 @@ export function AlertingApiProvider({ getService }: FtrProviderContext) {
return response;
});
},
+
+ async createIndexConnector({ name, indexName }: { name: string; indexName: string }) {
+ const { body } = await supertest
+ .post(`/api/actions/connector`)
+ .set('kbn-xsrf', 'foo')
+ .set('x-elastic-internal-origin', 'foo')
+ .send({
+ name,
+ config: {
+ index: indexName,
+ refresh: true,
+ },
+ connector_type_id: '.index',
+ });
+ return body.id as string;
+ },
+
+ async createRule({
+ name,
+ ruleTypeId,
+ params,
+ actions = [],
+ tags = [],
+ schedule,
+ consumer,
+ }: {
+ ruleTypeId: string;
+ name: string;
+ params: MetricThresholdParams | ThresholdParams;
+ actions?: any[];
+ tags?: any[];
+ schedule?: { interval: string };
+ consumer: string;
+ }) {
+ const { body } = await supertest
+ .post(`/api/alerting/rule`)
+ .set('kbn-xsrf', 'foo')
+ .set('x-elastic-internal-origin', 'foo')
+ .send({
+ params,
+ consumer,
+ schedule: schedule || {
+ interval: '5m',
+ },
+ tags,
+ name,
+ rule_type_id: ruleTypeId,
+ actions,
+ });
+ return body;
+ },
};
}
diff --git a/x-pack/test_serverless/api_integration/services/data_view_api.ts b/x-pack/test_serverless/api_integration/services/data_view_api.ts
new file mode 100644
index 0000000000000..430ff60aac1e2
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/services/data_view_api.ts
@@ -0,0 +1,52 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { FtrProviderContext } from '../ftr_provider_context';
+
+export function DataViewApiProvider({ getService }: FtrProviderContext) {
+ const supertest = getService('supertest');
+
+ return {
+ async create({ id, name, title }: { id: string; name: string; title: string }) {
+ const { body } = await supertest
+ .post(`/api/content_management/rpc/create`)
+ .set('kbn-xsrf', 'foo')
+ .set('x-elastic-internal-origin', 'foo')
+ .send({
+ contentTypeId: 'index-pattern',
+ data: {
+ fieldAttrs: '{}',
+ title,
+ timeFieldName: '@timestamp',
+ sourceFilters: '[]',
+ fields: '[]',
+ fieldFormatMap: '{}',
+ typeMeta: '{}',
+ runtimeFieldMap: '{}',
+ name,
+ },
+ options: { id },
+ version: 1,
+ });
+ return body;
+ },
+
+ async delete({ id }: { id: string }) {
+ const { body } = await supertest
+ .post(`/api/content_management/rpc/delete`)
+ .set('kbn-xsrf', 'foo')
+ .set('x-elastic-internal-origin', 'foo')
+ .send({
+ contentTypeId: 'index-pattern',
+ id,
+ options: { force: true },
+ version: 1,
+ });
+ return body;
+ },
+ };
+}
diff --git a/x-pack/test_serverless/api_integration/services/index.ts b/x-pack/test_serverless/api_integration/services/index.ts
index bab7b001b5982..8102eeb9f4c1b 100644
--- a/x-pack/test_serverless/api_integration/services/index.ts
+++ b/x-pack/test_serverless/api_integration/services/index.ts
@@ -12,6 +12,7 @@ import { services as svlSharedServices } from '../../shared/services';
import { SvlCommonApiServiceProvider } from './svl_common_api';
import { AlertingApiProvider } from './alerting_api';
+import { DataViewApiProvider } from './data_view_api';
export const services = {
...xpackApiIntegrationServices,
@@ -19,6 +20,7 @@ export const services = {
svlCommonApi: SvlCommonApiServiceProvider,
alertingApi: AlertingApiProvider,
+ dataViewApi: DataViewApiProvider,
};
export type InheritedFtrProviderContext = GenericFtrProviderContext;
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/cases/index.ts b/x-pack/test_serverless/api_integration/test_suites/observability/cases/index.ts
new file mode 100644
index 0000000000000..97e56b4220124
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/cases/index.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ loadTestFile }: FtrProviderContext) {
+ describe('Cases', function () {
+ loadTestFile(require.resolve('./get_case'));
+ loadTestFile(require.resolve('./find_cases'));
+ loadTestFile(require.resolve('./post_case'));
+ });
+}
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/config.feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/observability/config.feature_flags.ts
new file mode 100644
index 0000000000000..1e092616323f1
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/config.feature_flags.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { createTestConfig } from '../../config.base';
+import { services } from './apm_api_integration/common/services';
+
+/**
+ * Make sure to create a MKI deployment with custom Kibana image, that includes feature flags arguments
+ * This tests most likely will fail on default MKI project
+ */
+export default createTestConfig({
+ serverlessProject: 'oblt',
+ junit: {
+ reportName: 'Serverless Observability Feature Flags API Integration Tests',
+ },
+ suiteTags: { exclude: ['skipSvlOblt'] },
+ services,
+ // add feature flags
+ kbnServerArgs: ['--xpack.observability.unsafe.thresholdRule.enabled=true'],
+ // load tests in the index file
+ testFiles: [require.resolve('./index.feature_flags.ts')],
+});
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/fleet.ts b/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts
similarity index 95%
rename from x-pack/test_serverless/api_integration/test_suites/observability/fleet.ts
rename to x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts
index ea5ca79cbefb9..24f5e9cde9177 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/fleet.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/fleet/fleet.ts
@@ -6,7 +6,7 @@
*/
import expect from 'expect';
-import { FtrProviderContext } from '../../ftr_provider_context';
+import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const svlCommonApi = getService('svlCommonApi');
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/helpers/alerting_api_helper.ts b/x-pack/test_serverless/api_integration/test_suites/observability/helpers/alerting_api_helper.ts
deleted file mode 100644
index 5229cfcfc8db8..0000000000000
--- a/x-pack/test_serverless/api_integration/test_suites/observability/helpers/alerting_api_helper.ts
+++ /dev/null
@@ -1,71 +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 { MetricThresholdParams } from '@kbn/infra-plugin/common/alerting/metrics';
-import { ThresholdParams } from '@kbn/observability-plugin/common/threshold_rule/types';
-import type { SuperTest, Test } from 'supertest';
-
-export async function createIndexConnector({
- supertest,
- name,
- indexName,
-}: {
- supertest: SuperTest;
- name: string;
- indexName: string;
-}) {
- const { body } = await supertest
- .post(`/api/actions/connector`)
- .set('kbn-xsrf', 'foo')
- .set('x-elastic-internal-origin', 'foo')
- .send({
- name,
- config: {
- index: indexName,
- refresh: true,
- },
- connector_type_id: '.index',
- });
- return body.id as string;
-}
-
-export async function createRule({
- supertest,
- name,
- ruleTypeId,
- params,
- actions = [],
- tags = [],
- schedule,
- consumer,
-}: {
- supertest: SuperTest;
- ruleTypeId: string;
- name: string;
- params: MetricThresholdParams | ThresholdParams;
- actions?: any[];
- tags?: any[];
- schedule?: { interval: string };
- consumer: string;
-}) {
- const { body } = await supertest
- .post(`/api/alerting/rule`)
- .set('kbn-xsrf', 'foo')
- .set('x-elastic-internal-origin', 'foo')
- .send({
- params,
- consumer,
- schedule: schedule || {
- interval: '5m',
- },
- tags,
- name,
- rule_type_id: ruleTypeId,
- actions,
- });
- return body;
-}
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/helpers/alerting_wait_for_helpers.ts b/x-pack/test_serverless/api_integration/test_suites/observability/helpers/alerting_wait_for_helpers.ts
deleted file mode 100644
index fab50cdc92da3..0000000000000
--- a/x-pack/test_serverless/api_integration/test_suites/observability/helpers/alerting_wait_for_helpers.ts
+++ /dev/null
@@ -1,90 +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 pRetry from 'p-retry';
-
-import type SuperTest from 'supertest';
-import type { Client } from '@elastic/elasticsearch';
-import type {
- AggregationsAggregate,
- SearchResponse,
-} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
-
-export async function waitForRuleStatus({
- id,
- expectedStatus,
- supertest,
-}: {
- id: string;
- expectedStatus: string;
- supertest: SuperTest.SuperTest;
-}): Promise> {
- return pRetry(
- async () => {
- const response = await supertest
- .get(`/api/alerting/rule/${id}`)
- .set('kbn-xsrf', 'foo')
- .set('x-elastic-internal-origin', 'foo');
- const { execution_status: executionStatus } = response.body || {};
- const { status } = executionStatus || {};
- if (status !== expectedStatus) {
- throw new Error(`waitForStatus(${expectedStatus}): got ${status}`);
- }
- return executionStatus;
- },
- { retries: 10 }
- );
-}
-
-export async function waitForDocumentInIndex({
- esClient,
- indexName,
-}: {
- esClient: Client;
- indexName: string;
-}): Promise>> {
- return pRetry(
- async () => {
- const response = await esClient.search({ index: indexName });
- if (response.hits.hits.length === 0) {
- throw new Error('No hits found');
- }
- return response;
- },
- { retries: 10 }
- );
-}
-
-export async function waitForAlertInIndex({
- esClient,
- indexName,
- ruleId,
-}: {
- esClient: Client;
- indexName: string;
- ruleId: string;
-}): Promise>> {
- return pRetry(
- async () => {
- const response = await esClient.search({
- index: indexName,
- body: {
- query: {
- term: {
- 'kibana.alert.rule.uuid': ruleId,
- },
- },
- },
- });
- if (response.hits.hits.length === 0) {
- throw new Error('No hits found');
- }
- return response;
- },
- { retries: 10 }
- );
-}
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/helpers/data_view.ts b/x-pack/test_serverless/api_integration/test_suites/observability/helpers/data_view.ts
deleted file mode 100644
index 534bc1446fd3e..0000000000000
--- a/x-pack/test_serverless/api_integration/test_suites/observability/helpers/data_view.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 { SuperTest, Test } from 'supertest';
-
-export const createDataView = async ({
- supertest,
- id,
- name,
- title,
-}: {
- supertest: SuperTest;
- id: string;
- name: string;
- title: string;
-}) => {
- const { body } = await supertest
- .post(`/api/content_management/rpc/create`)
- .set('kbn-xsrf', 'foo')
- .set('x-elastic-internal-origin', 'foo')
- .send({
- contentTypeId: 'index-pattern',
- data: {
- fieldAttrs: '{}',
- title,
- timeFieldName: '@timestamp',
- sourceFilters: '[]',
- fields: '[]',
- fieldFormatMap: '{}',
- typeMeta: '{}',
- runtimeFieldMap: '{}',
- name,
- },
- options: { id },
- version: 1,
- });
- return body;
-};
-export const deleteDataView = async ({
- supertest,
- id,
-}: {
- supertest: SuperTest;
- id: string;
-}) => {
- const { body } = await supertest
- .post(`/api/content_management/rpc/delete`)
- .set('kbn-xsrf', 'foo')
- .set('x-elastic-internal-origin', 'foo')
- .send({
- contentTypeId: 'index-pattern',
- id,
- options: { force: true },
- version: 1,
- });
- return body;
-};
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/index.feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/observability/index.feature_flags.ts
new file mode 100644
index 0000000000000..d9643f91d70ae
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/index.feature_flags.ts
@@ -0,0 +1,14 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { FtrProviderContext } from '../../ftr_provider_context';
+
+export default function ({ loadTestFile }: FtrProviderContext) {
+ describe('Serverless observability API - feature flags', function () {
+ loadTestFile(require.resolve('./threshold_rule'));
+ });
+}
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/index.ts b/x-pack/test_serverless/api_integration/test_suites/observability/index.ts
index 443c9366d751b..36907484f13d3 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/index.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/index.ts
@@ -8,17 +8,10 @@
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ loadTestFile }: FtrProviderContext) {
- describe('serverless observability API', function () {
- loadTestFile(require.resolve('./fleet'));
- loadTestFile(require.resolve('./snapshot_telemetry'));
+ describe('Serverless observability API', function () {
+ loadTestFile(require.resolve('./fleet/fleet'));
+ loadTestFile(require.resolve('./telemetry/snapshot_telemetry'));
loadTestFile(require.resolve('./apm_api_integration/feature_flags.ts'));
- loadTestFile(require.resolve('./threshold_rule/avg_pct_fired'));
- loadTestFile(require.resolve('./threshold_rule/avg_pct_no_data'));
- loadTestFile(require.resolve('./threshold_rule/documents_count_fired'));
- loadTestFile(require.resolve('./threshold_rule/custom_eq_avg_bytes_fired'));
- loadTestFile(require.resolve('./threshold_rule/group_by_fired'));
- loadTestFile(require.resolve('./cases/post_case'));
- loadTestFile(require.resolve('./cases/find_cases'));
- loadTestFile(require.resolve('./cases/get_case'));
+ loadTestFile(require.resolve('./cases'));
});
}
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/snapshot_telemetry.ts b/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/snapshot_telemetry.ts
similarity index 94%
rename from x-pack/test_serverless/api_integration/test_suites/observability/snapshot_telemetry.ts
rename to x-pack/test_serverless/api_integration/test_suites/observability/telemetry/snapshot_telemetry.ts
index fa423505bf9f9..f0fc2a357156e 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/snapshot_telemetry.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/telemetry/snapshot_telemetry.ts
@@ -12,8 +12,8 @@ import xpackRootTelemetrySchema from '@kbn/telemetry-collection-xpack-plugin/sch
import ossPluginsTelemetrySchema from '@kbn/telemetry-plugin/schema/oss_plugins.json';
import xpackPluginsTelemetrySchema from '@kbn/telemetry-collection-xpack-plugin/schema/xpack_plugins.json';
import { assertTelemetryPayload } from '@kbn/telemetry-tools';
-import { FtrProviderContext } from '../../ftr_provider_context';
-import type { UsageStatsPayloadTestFriendly } from '../../../../test/api_integration/services/usage_api';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+import type { UsageStatsPayloadTestFriendly } from '../../../../../test/api_integration/services/usage_api';
export default function ({ getService }: FtrProviderContext) {
const usageApi = getService('usageAPI');
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/avg_pct_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/avg_pct_fired.ts
index eaf12f3c69e5f..4830f4915b37c 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/avg_pct_fired.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/avg_pct_fired.ts
@@ -11,14 +11,13 @@ import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/thr
import expect from '@kbn/expect';
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/observability-plugin/common/constants';
import { FtrProviderContext } from '../../../ftr_provider_context';
-import { createIndexConnector, createRule } from '../helpers/alerting_api_helper';
-import { createDataView, deleteDataView } from '../helpers/data_view';
export default function ({ getService }: FtrProviderContext) {
const esClient = getService('es');
const supertest = getService('supertest');
const esDeleteAllIndices = getService('esDeleteAllIndices');
const alertingApi = getService('alertingApi');
+ const dataViewApi = getService('dataViewApi');
const logger = getService('log');
describe('Threshold rule - AVG - PCT - FIRED', () => {
@@ -31,8 +30,7 @@ export default function ({ getService }: FtrProviderContext) {
before(async () => {
infraDataIndex = await generate({ esClient, lookback: 'now-15m', logger });
- await createDataView({
- supertest,
+ await dataViewApi.create({
name: 'metrics-fake_hosts',
id: DATA_VIEW_ID,
title: 'metrics-fake_hosts',
@@ -56,8 +54,7 @@ export default function ({ getService }: FtrProviderContext) {
index: '.kibana-event-log-*',
query: { term: { 'kibana.alert.rule.consumer': 'alerts' } },
});
- await deleteDataView({
- supertest,
+ await dataViewApi.delete({
id: DATA_VIEW_ID,
});
await esDeleteAllIndices([ALERT_ACTION_INDEX, infraDataIndex]);
@@ -66,14 +63,12 @@ export default function ({ getService }: FtrProviderContext) {
describe('Rule creation', () => {
it('creates rule successfully', async () => {
- actionId = await createIndexConnector({
- supertest,
+ actionId = await alertingApi.createIndexConnector({
name: 'Index Connector: Threshold API test',
indexName: ALERT_ACTION_INDEX,
});
- const createdRule = await createRule({
- supertest,
+ const createdRule = await alertingApi.createRule({
tags: ['observability'],
consumer: 'alerts',
name: 'Threshold rule',
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/avg_pct_no_data.ts b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/avg_pct_no_data.ts
index c101af3bc9aa8..4ff0393e273a6 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/avg_pct_no_data.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/avg_pct_no_data.ts
@@ -10,13 +10,12 @@ import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/thr
import expect from '@kbn/expect';
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/observability-plugin/common/constants';
import { FtrProviderContext } from '../../../ftr_provider_context';
-import { createIndexConnector, createRule } from '../helpers/alerting_api_helper';
-import { createDataView, deleteDataView } from '../helpers/data_view';
export default function ({ getService }: FtrProviderContext) {
const esClient = getService('es');
const supertest = getService('supertest');
const alertingApi = getService('alertingApi');
+ const dataViewApi = getService('dataViewApi');
describe('Threshold rule - AVG - PCT - NoData', () => {
const THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default';
@@ -26,8 +25,7 @@ export default function ({ getService }: FtrProviderContext) {
let ruleId: string;
before(async () => {
- await createDataView({
- supertest,
+ await dataViewApi.create({
name: 'no-data-pattern',
id: DATA_VIEW_ID,
title: 'no-data-pattern',
@@ -51,22 +49,19 @@ export default function ({ getService }: FtrProviderContext) {
index: '.kibana-event-log-*',
query: { term: { 'kibana.alert.rule.consumer': 'alerts' } },
});
- await deleteDataView({
- supertest,
+ await dataViewApi.delete({
id: DATA_VIEW_ID,
});
});
describe('Rule creation', () => {
it('creates rule successfully', async () => {
- actionId = await createIndexConnector({
- supertest,
+ actionId = await alertingApi.createIndexConnector({
name: 'Index Connector: Threshold API test',
indexName: ALERT_ACTION_INDEX,
});
- const createdRule = await createRule({
- supertest,
+ const createdRule = await alertingApi.createRule({
tags: ['observability'],
consumer: 'alerts',
name: 'Threshold rule',
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/custom_eq_avg_bytes_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/custom_eq_avg_bytes_fired.ts
index a963245651d7a..7b2aea23f238a 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/custom_eq_avg_bytes_fired.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/custom_eq_avg_bytes_fired.ts
@@ -17,8 +17,6 @@ import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/thr
import expect from '@kbn/expect';
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/observability-plugin/common/constants';
import { FtrProviderContext } from '../../../ftr_provider_context';
-import { createIndexConnector, createRule } from '../helpers/alerting_api_helper';
-import { createDataView, deleteDataView } from '../helpers/data_view';
export default function ({ getService }: FtrProviderContext) {
const esClient = getService('es');
@@ -26,6 +24,7 @@ export default function ({ getService }: FtrProviderContext) {
const esDeleteAllIndices = getService('esDeleteAllIndices');
const logger = getService('log');
const alertingApi = getService('alertingApi');
+ const dataViewApi = getService('dataViewApi');
describe('Threshold rule - CUSTOM_EQ - AVG - BYTES - FIRED', () => {
const THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default';
@@ -37,8 +36,7 @@ export default function ({ getService }: FtrProviderContext) {
before(async () => {
infraDataIndex = await generate({ esClient, lookback: 'now-15m', logger });
- await createDataView({
- supertest,
+ await dataViewApi.create({
name: 'metrics-fake_hosts',
id: DATA_VIEW_ID,
title: 'metrics-fake_hosts',
@@ -62,8 +60,7 @@ export default function ({ getService }: FtrProviderContext) {
index: '.kibana-event-log-*',
query: { term: { 'kibana.alert.rule.consumer': 'alerts' } },
});
- await deleteDataView({
- supertest,
+ await dataViewApi.delete({
id: DATA_VIEW_ID,
});
await esDeleteAllIndices([ALERT_ACTION_INDEX, infraDataIndex]);
@@ -72,14 +69,12 @@ export default function ({ getService }: FtrProviderContext) {
describe('Rule creation', () => {
it('creates rule successfully', async () => {
- actionId = await createIndexConnector({
- supertest,
+ actionId = await alertingApi.createIndexConnector({
name: 'Index Connector: Threshold API test',
indexName: ALERT_ACTION_INDEX,
});
- const createdRule = await createRule({
- supertest,
+ const createdRule = await alertingApi.createRule({
tags: ['observability'],
consumer: 'alerts',
name: 'Threshold rule',
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/documents_count_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/documents_count_fired.ts
index eacdf7b34fa4f..bd1fed6a6bd5d 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/documents_count_fired.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/documents_count_fired.ts
@@ -11,8 +11,6 @@ import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/thr
import expect from '@kbn/expect';
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/observability-plugin/common/constants';
import { FtrProviderContext } from '../../../ftr_provider_context';
-import { createIndexConnector, createRule } from '../helpers/alerting_api_helper';
-import { createDataView, deleteDataView } from '../helpers/data_view';
export default function ({ getService }: FtrProviderContext) {
const esClient = getService('es');
@@ -20,6 +18,7 @@ export default function ({ getService }: FtrProviderContext) {
const esDeleteAllIndices = getService('esDeleteAllIndices');
const logger = getService('log');
const alertingApi = getService('alertingApi');
+ const dataViewApi = getService('dataViewApi');
describe('Threshold rule - DOCUMENTS_COUNT - FIRED', () => {
const THRESHOLD_RULE_ALERT_INDEX = '.alerts-observability.threshold.alerts-default';
@@ -31,8 +30,7 @@ export default function ({ getService }: FtrProviderContext) {
before(async () => {
infraDataIndex = await generate({ esClient, lookback: 'now-15m', logger });
- await createDataView({
- supertest,
+ await dataViewApi.create({
name: 'metrics-fake_hosts',
id: DATA_VIEW_ID,
title: 'metrics-fake_hosts',
@@ -56,8 +54,7 @@ export default function ({ getService }: FtrProviderContext) {
index: '.kibana-event-log-*',
query: { term: { 'kibana.alert.rule.consumer': 'alerts' } },
});
- await deleteDataView({
- supertest,
+ await dataViewApi.delete({
id: DATA_VIEW_ID,
});
await esDeleteAllIndices([ALERT_ACTION_INDEX, infraDataIndex]);
@@ -66,14 +63,12 @@ export default function ({ getService }: FtrProviderContext) {
describe('Rule creation', () => {
it('creates rule successfully', async () => {
- actionId = await createIndexConnector({
- supertest,
+ actionId = await alertingApi.createIndexConnector({
name: 'Index Connector: Threshold API test',
indexName: ALERT_ACTION_INDEX,
});
- const createdRule = await createRule({
- supertest,
+ const createdRule = await alertingApi.createRule({
tags: ['observability'],
consumer: 'alerts',
name: 'Threshold rule',
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/group_by_fired.ts b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/group_by_fired.ts
index a78a008f93e61..244656dd97d9d 100644
--- a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/group_by_fired.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/group_by_fired.ts
@@ -11,6 +11,7 @@
* 2.0.
*/
+import { kbnTestConfig } from '@kbn/test';
import moment from 'moment';
import { cleanup, generate } from '@kbn/infra-forge';
import { Aggregators, Comparator } from '@kbn/observability-plugin/common/threshold_rule/types';
@@ -18,8 +19,6 @@ import { FIRED_ACTIONS_ID } from '@kbn/observability-plugin/server/lib/rules/thr
import expect from '@kbn/expect';
import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/observability-plugin/common/constants';
import { FtrProviderContext } from '../../../ftr_provider_context';
-import { createIndexConnector, createRule } from '../helpers/alerting_api_helper';
-import { createDataView, deleteDataView } from '../helpers/data_view';
export default function ({ getService }: FtrProviderContext) {
const esClient = getService('es');
@@ -27,6 +26,7 @@ export default function ({ getService }: FtrProviderContext) {
const esDeleteAllIndices = getService('esDeleteAllIndices');
const logger = getService('log');
const alertingApi = getService('alertingApi');
+ const dataViewApi = getService('dataViewApi');
let alertId: string;
let startedAt: string;
@@ -40,8 +40,7 @@ export default function ({ getService }: FtrProviderContext) {
before(async () => {
infraDataIndex = await generate({ esClient, lookback: 'now-15m', logger });
- await createDataView({
- supertest,
+ await dataViewApi.create({
name: 'metrics-fake_hosts',
id: DATA_VIEW_ID,
title: 'metrics-fake_hosts',
@@ -65,8 +64,7 @@ export default function ({ getService }: FtrProviderContext) {
index: '.kibana-event-log-*',
query: { term: { 'kibana.alert.rule.consumer': 'alerts' } },
});
- await deleteDataView({
- supertest,
+ await dataViewApi.delete({
id: DATA_VIEW_ID,
});
await esDeleteAllIndices([ALERT_ACTION_INDEX, infraDataIndex]);
@@ -75,14 +73,12 @@ export default function ({ getService }: FtrProviderContext) {
describe('Rule creation', () => {
it('creates rule successfully', async () => {
- actionId = await createIndexConnector({
- supertest,
+ actionId = await alertingApi.createIndexConnector({
name: 'Index Connector: Threshold API test',
indexName: ALERT_ACTION_INDEX,
});
- const createdRule = await createRule({
- supertest,
+ const createdRule = await alertingApi.createRule({
tags: ['observability'],
consumer: 'alerts',
name: 'Threshold rule',
@@ -217,10 +213,11 @@ export default function ({ getService }: FtrProviderContext) {
}>({
indexName: ALERT_ACTION_INDEX,
});
+ const { protocol, hostname, port } = kbnTestConfig.getUrlParts();
expect(resp.hits.hits[0]._source?.ruleType).eql('observability.rules.threshold');
expect(resp.hits.hits[0]._source?.alertDetailsUrl).eql(
- `https://localhost:5601/app/observability/alerts?_a=(kuery:%27kibana.alert.uuid:%20%22${alertId}%22%27%2CrangeFrom:%27${rangeFrom}%27%2CrangeTo:now%2Cstatus:all)`
+ `${protocol}://${hostname}:${port}/app/observability/alerts?_a=(kuery:%27kibana.alert.uuid:%20%22${alertId}%22%27%2CrangeFrom:%27${rangeFrom}%27%2CrangeTo:now%2Cstatus:all)`
);
expect(resp.hits.hits[0]._source?.reason).eql(
'Custom equation is 0.8 in the last 1 min for host-0. Alert when >= 0.2.'
diff --git a/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/index.ts b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/index.ts
new file mode 100644
index 0000000000000..dbb8968d2d946
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/observability/threshold_rule/index.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 { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ loadTestFile }: FtrProviderContext) {
+ describe('Threshold Rule', function () {
+ loadTestFile(require.resolve('./avg_pct_fired'));
+ loadTestFile(require.resolve('./avg_pct_no_data'));
+ loadTestFile(require.resolve('./documents_count_fired'));
+ loadTestFile(require.resolve('./custom_eq_avg_bytes_fired'));
+ loadTestFile(require.resolve('./group_by_fired'));
+ });
+}
diff --git a/x-pack/test_serverless/api_integration/test_suites/search/config.feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/search/config.feature_flags.ts
new file mode 100644
index 0000000000000..9a9d0064bc5e6
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/search/config.feature_flags.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { createTestConfig } from '../../config.base';
+
+/**
+ * Make sure to create a MKI deployment with custom Kibana image, that includes feature flags arguments
+ * This tests most likely will fail on default MKI project
+ */
+export default createTestConfig({
+ serverlessProject: 'es',
+ junit: {
+ reportName: 'Serverless Search Feature Flags API Integration Tests',
+ },
+ suiteTags: { exclude: ['skipSvlSearch'] },
+ // add feature flags
+ kbnServerArgs: [],
+ // load tests in the index file
+ testFiles: [require.resolve('./index.feature_flags.ts')],
+});
diff --git a/x-pack/test_serverless/api_integration/test_suites/search/index.feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/search/index.feature_flags.ts
new file mode 100644
index 0000000000000..d388b06cef577
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/search/index.feature_flags.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export default function () {
+ describe('Serverless search API - feature flags', function () {
+ // add tests that require feature flags, defined in config.feature_flags.ts
+ // loadTestFile(require.resolve());
+ });
+}
diff --git a/x-pack/test_serverless/api_integration/test_suites/search/index.ts b/x-pack/test_serverless/api_integration/test_suites/search/index.ts
index 13ddf80d5a950..78964aa73c786 100644
--- a/x-pack/test_serverless/api_integration/test_suites/search/index.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/search/index.ts
@@ -8,9 +8,9 @@
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ loadTestFile }: FtrProviderContext) {
- describe('serverless search API', function () {
- loadTestFile(require.resolve('./snapshot_telemetry'));
- loadTestFile(require.resolve('./cases/post_case'));
+ describe('Serverless search API', function () {
+ loadTestFile(require.resolve('./telemetry/snapshot_telemetry'));
loadTestFile(require.resolve('./cases/find_cases'));
+ loadTestFile(require.resolve('./cases/post_case'));
});
}
diff --git a/x-pack/test_serverless/api_integration/test_suites/search/snapshot_telemetry.ts b/x-pack/test_serverless/api_integration/test_suites/search/telemetry/snapshot_telemetry.ts
similarity index 94%
rename from x-pack/test_serverless/api_integration/test_suites/search/snapshot_telemetry.ts
rename to x-pack/test_serverless/api_integration/test_suites/search/telemetry/snapshot_telemetry.ts
index 39608bba1fe62..fd4893d5e9e49 100644
--- a/x-pack/test_serverless/api_integration/test_suites/search/snapshot_telemetry.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/search/telemetry/snapshot_telemetry.ts
@@ -12,8 +12,8 @@ import ossRootTelemetrySchema from '@kbn/telemetry-plugin/schema/oss_root.json';
import ossPluginsTelemetrySchema from '@kbn/telemetry-plugin/schema/oss_plugins.json';
import xpackRootTelemetrySchema from '@kbn/telemetry-collection-xpack-plugin/schema/xpack_root.json';
import xpackPluginsTelemetrySchema from '@kbn/telemetry-collection-xpack-plugin/schema/xpack_plugins.json';
-import type { FtrProviderContext } from '../../ftr_provider_context';
-import type { UsageStatsPayloadTestFriendly } from '../../../../test/api_integration/services/usage_api';
+import type { FtrProviderContext } from '../../../ftr_provider_context';
+import type { UsageStatsPayloadTestFriendly } from '../../../../../test/api_integration/services/usage_api';
export default function ({ getService }: FtrProviderContext) {
const usageApi = getService('usageAPI');
diff --git a/x-pack/test_serverless/api_integration/test_suites/security/cases/index.ts b/x-pack/test_serverless/api_integration/test_suites/security/cases/index.ts
new file mode 100644
index 0000000000000..97e56b4220124
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/security/cases/index.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { FtrProviderContext } from '../../../ftr_provider_context';
+
+export default function ({ loadTestFile }: FtrProviderContext) {
+ describe('Cases', function () {
+ loadTestFile(require.resolve('./get_case'));
+ loadTestFile(require.resolve('./find_cases'));
+ loadTestFile(require.resolve('./post_case'));
+ });
+}
diff --git a/x-pack/test_serverless/api_integration/test_suites/security/config.feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/security/config.feature_flags.ts
new file mode 100644
index 0000000000000..20bce40a9f205
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/security/config.feature_flags.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { createTestConfig } from '../../config.base';
+
+/**
+ * Make sure to create a MKI deployment with custom Kibana image, that includes feature flags arguments
+ * This tests most likely will fail on default MKI project
+ */
+export default createTestConfig({
+ serverlessProject: 'security',
+ junit: {
+ reportName: 'Serverless Security Feature Flags API Integration Tests',
+ },
+ suiteTags: { exclude: ['skipSvlSec'] },
+ // add feature flags
+ kbnServerArgs: [],
+ // load tests in the index file
+ testFiles: [require.resolve('./index.feature_flags.ts')],
+});
diff --git a/x-pack/test_serverless/api_integration/test_suites/security/fleet.ts b/x-pack/test_serverless/api_integration/test_suites/security/fleet/fleet.ts
similarity index 95%
rename from x-pack/test_serverless/api_integration/test_suites/security/fleet.ts
rename to x-pack/test_serverless/api_integration/test_suites/security/fleet/fleet.ts
index ea5ca79cbefb9..24f5e9cde9177 100644
--- a/x-pack/test_serverless/api_integration/test_suites/security/fleet.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/security/fleet/fleet.ts
@@ -6,7 +6,7 @@
*/
import expect from 'expect';
-import { FtrProviderContext } from '../../ftr_provider_context';
+import { FtrProviderContext } from '../../../ftr_provider_context';
export default function ({ getService }: FtrProviderContext) {
const svlCommonApi = getService('svlCommonApi');
diff --git a/x-pack/test_serverless/api_integration/test_suites/security/index.feature_flags.ts b/x-pack/test_serverless/api_integration/test_suites/security/index.feature_flags.ts
new file mode 100644
index 0000000000000..ef8d2a7a43844
--- /dev/null
+++ b/x-pack/test_serverless/api_integration/test_suites/security/index.feature_flags.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export default function () {
+ describe('Serverless security API - feature flags', function () {
+ // add tests that require feature flags, defined in config.feature_flags.ts
+ // loadTestFile(require.resolve());
+ });
+}
diff --git a/x-pack/test_serverless/api_integration/test_suites/security/index.ts b/x-pack/test_serverless/api_integration/test_suites/security/index.ts
index 294f4b32af5e6..eaf193c5f659c 100644
--- a/x-pack/test_serverless/api_integration/test_suites/security/index.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/security/index.ts
@@ -8,11 +8,9 @@
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ loadTestFile }: FtrProviderContext) {
- describe('serverless security API', function () {
- loadTestFile(require.resolve('./fleet'));
- loadTestFile(require.resolve('./snapshot_telemetry'));
- loadTestFile(require.resolve('./cases/post_case'));
- loadTestFile(require.resolve('./cases/find_cases'));
- loadTestFile(require.resolve('./cases/get_case'));
+ describe('Serverless security API', function () {
+ loadTestFile(require.resolve('./telemetry/snapshot_telemetry'));
+ loadTestFile(require.resolve('./fleet/fleet'));
+ loadTestFile(require.resolve('./cases'));
});
}
diff --git a/x-pack/test_serverless/api_integration/test_suites/security/snapshot_telemetry.ts b/x-pack/test_serverless/api_integration/test_suites/security/telemetry/snapshot_telemetry.ts
similarity index 94%
rename from x-pack/test_serverless/api_integration/test_suites/security/snapshot_telemetry.ts
rename to x-pack/test_serverless/api_integration/test_suites/security/telemetry/snapshot_telemetry.ts
index 7d6e5abb2e063..1fdc341454e3c 100644
--- a/x-pack/test_serverless/api_integration/test_suites/security/snapshot_telemetry.ts
+++ b/x-pack/test_serverless/api_integration/test_suites/security/telemetry/snapshot_telemetry.ts
@@ -12,8 +12,8 @@ import xpackRootTelemetrySchema from '@kbn/telemetry-collection-xpack-plugin/sch
import ossPluginsTelemetrySchema from '@kbn/telemetry-plugin/schema/oss_plugins.json';
import xpackPluginsTelemetrySchema from '@kbn/telemetry-collection-xpack-plugin/schema/xpack_plugins.json';
import { assertTelemetryPayload } from '@kbn/telemetry-tools';
-import { FtrProviderContext } from '../../ftr_provider_context';
-import type { UsageStatsPayloadTestFriendly } from '../../../../test/api_integration/services/usage_api';
+import { FtrProviderContext } from '../../../ftr_provider_context';
+import type { UsageStatsPayloadTestFriendly } from '../../../../../test/api_integration/services/usage_api';
export default function ({ getService }: FtrProviderContext) {
const usageApi = getService('usageAPI');
diff --git a/x-pack/test_serverless/functional/test_suites/observability/config.feature_flags.ts b/x-pack/test_serverless/functional/test_suites/observability/config.feature_flags.ts
new file mode 100644
index 0000000000000..31995ad616ca4
--- /dev/null
+++ b/x-pack/test_serverless/functional/test_suites/observability/config.feature_flags.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { createTestConfig } from '../../config.base';
+
+/**
+ * Make sure to create a MKI deployment with custom Kibana image, that includes feature flags arguments
+ * This tests most likely will fail on default MKI project
+ */
+export default createTestConfig({
+ serverlessProject: 'oblt',
+ junit: {
+ reportName: 'Serverless Observability Feature Flags Functional Tests',
+ },
+ suiteTags: { exclude: ['skipSvlOblt'] },
+ // add feature flags
+ kbnServerArgs: [],
+ // load tests in the index file
+ testFiles: [require.resolve('./index.feature_flags.ts')],
+});
diff --git a/x-pack/test_serverless/functional/test_suites/observability/index.feature_flags.ts b/x-pack/test_serverless/functional/test_suites/observability/index.feature_flags.ts
new file mode 100644
index 0000000000000..1212d6a734403
--- /dev/null
+++ b/x-pack/test_serverless/functional/test_suites/observability/index.feature_flags.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export default function () {
+ describe('serverless observability UI - feature flags', function () {
+ // add tests that require feature flags, defined in config.feature_flags.ts
+ // loadTestFile(require.resolve());
+ });
+}
diff --git a/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts b/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts
new file mode 100644
index 0000000000000..e93c3ff2f02e5
--- /dev/null
+++ b/x-pack/test_serverless/functional/test_suites/search/config.feature_flags.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { createTestConfig } from '../../config.base';
+
+/**
+ * Make sure to create a MKI deployment with custom Kibana image, that includes feature flags arguments
+ * This tests most likely will fail on default MKI project
+ */
+export default createTestConfig({
+ serverlessProject: 'es',
+ junit: {
+ reportName: 'Serverless Search Feature Flags Functional Tests',
+ },
+ suiteTags: { exclude: ['skipSvlSearch'] },
+ // add feature flags
+ kbnServerArgs: [],
+ // load tests in the index file
+ testFiles: [require.resolve('./index.feature_flags.ts')],
+});
diff --git a/x-pack/test_serverless/functional/test_suites/search/index.feature_flags.ts b/x-pack/test_serverless/functional/test_suites/search/index.feature_flags.ts
new file mode 100644
index 0000000000000..a609860a6a746
--- /dev/null
+++ b/x-pack/test_serverless/functional/test_suites/search/index.feature_flags.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export default function () {
+ describe('serverless search UI - feature flags', function () {
+ // add tests that require feature flags, defined in config.feature_flags.ts
+ // loadTestFile(require.resolve());
+ });
+}
diff --git a/x-pack/test_serverless/functional/test_suites/security/config.feature_flags.ts b/x-pack/test_serverless/functional/test_suites/security/config.feature_flags.ts
new file mode 100644
index 0000000000000..735c8a8765d16
--- /dev/null
+++ b/x-pack/test_serverless/functional/test_suites/security/config.feature_flags.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+import { createTestConfig } from '../../config.base';
+
+/**
+ * Make sure to create a MKI deployment with custom Kibana image, that includes feature flags arguments
+ * This tests most likely will fail on default MKI project
+ */
+export default createTestConfig({
+ serverlessProject: 'security',
+ junit: {
+ reportName: 'Serverless Security Feature Flags Functional Tests',
+ },
+ suiteTags: { exclude: ['skipSvlSec'] },
+ // add feature flags
+ kbnServerArgs: [],
+ // load tests in the index file
+ testFiles: [require.resolve('./index.feature_flags.ts')],
+});
diff --git a/x-pack/test_serverless/functional/test_suites/security/index.feature_flags.ts b/x-pack/test_serverless/functional/test_suites/security/index.feature_flags.ts
new file mode 100644
index 0000000000000..8e28b53c18b22
--- /dev/null
+++ b/x-pack/test_serverless/functional/test_suites/security/index.feature_flags.ts
@@ -0,0 +1,13 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License
+ * 2.0; you may not use this file except in compliance with the Elastic License
+ * 2.0.
+ */
+
+export default function () {
+ describe('serverless security UI - feature flags', function () {
+ // add tests that require feature flags, defined in config.feature_flags.ts
+ // loadTestFile(require.resolve());
+ });
+}
diff --git a/x-pack/test_serverless/shared/config.base.ts b/x-pack/test_serverless/shared/config.base.ts
index 35c4320a7f17f..3cd2f21310809 100644
--- a/x-pack/test_serverless/shared/config.base.ts
+++ b/x-pack/test_serverless/shared/config.base.ts
@@ -61,6 +61,7 @@ export default async () => {
},
])}`,
'--xpack.encryptedSavedObjects.encryptionKey="wuGNaIhoMpk5sO4UBxgr3NyW1sFcLgIf"',
+ `--server.publicBaseUrl=${servers.kibana.protocol}://${servers.kibana.hostname}:${servers.kibana.port}`,
],
},
diff --git a/x-pack/test_serverless/shared/types/index.ts b/x-pack/test_serverless/shared/types/index.ts
index 8dfb1a978699d..0a36e71db7c39 100644
--- a/x-pack/test_serverless/shared/types/index.ts
+++ b/x-pack/test_serverless/shared/types/index.ts
@@ -9,6 +9,7 @@ import { InheritedServices } from '../../api_integration/services';
export interface CreateTestConfigOptions {
serverlessProject: 'es' | 'oblt' | 'security';
+ kbnServerArgs?: string[];
testFiles: string[];
junit: { reportName: string };
suiteTags?: { include?: string[]; exclude?: string[] };
From 635eedb31ba6a3ac1ac90e29ce9350a6b6f3ac64 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Loix?=
Date: Tue, 22 Aug 2023 13:13:48 +0100
Subject: [PATCH 22/26] [SavedObject tagging] Fix functional test for bulk
delete tags (#164321)
---
.../test/saved_object_tagging/functional/tests/bulk_actions.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/x-pack/test/saved_object_tagging/functional/tests/bulk_actions.ts b/x-pack/test/saved_object_tagging/functional/tests/bulk_actions.ts
index f0f2d3aa980ac..d4aef2d44856f 100644
--- a/x-pack/test/saved_object_tagging/functional/tests/bulk_actions.ts
+++ b/x-pack/test/saved_object_tagging/functional/tests/bulk_actions.ts
@@ -29,6 +29,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
describe('bulk delete', () => {
it('deletes multiple tags', async () => {
+ const initialDisplayedTags = await tagManagementPage.getDisplayedTagNames();
await tagManagementPage.selectTagByName('tag-1');
await tagManagementPage.selectTagByName('tag-3');
@@ -38,7 +39,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
await tagManagementPage.waitUntilTableIsLoaded();
const displayedTags = await tagManagementPage.getDisplayedTagNames();
- expect(displayedTags.length).to.be(3);
+ expect(displayedTags.length).to.be(initialDisplayedTags.length - 2);
expect(displayedTags).to.eql(['my-favorite-tag', 'tag with whitespace', 'tag-2']);
});
});
From 5eeb3f7c47a2a8f18ec08f36cbbd71ff8724eea6 Mon Sep 17 00:00:00 2001
From: GitStart <1501599+gitstart@users.noreply.github.com>
Date: Tue, 22 Aug 2023 13:14:38 +0100
Subject: [PATCH 23/26] [ILM] Migrate all usages of EuiPage*_Deprecated
(#163132)
---
.../__snapshots__/policy_table.test.tsx.snap | 91 ++++++++++---------
.../edit_policy/edit_policy.container.tsx | 76 +++++++---------
.../policy_list/policy_list.container.tsx | 76 +++++++---------
.../sections/policy_list/policy_list.tsx | 50 +++++-----
4 files changed, 136 insertions(+), 157 deletions(-)
diff --git a/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/policy_table.test.tsx.snap b/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/policy_table.test.tsx.snap
index 6c991799a115b..aeae7b28f0b88 100644
--- a/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/policy_table.test.tsx.snap
+++ b/x-pack/plugins/index_lifecycle_management/__jest__/__snapshots__/policy_table.test.tsx.snap
@@ -37,68 +37,71 @@ Array [
`;
exports[`policy table shows empty state when there are no policies 1`] = `
-
-
-
-
-
- Create your first index lifecycle policy
-
-
+
+
-
- An index lifecycle policy helps you manage your indices as they age.
-
-
-
-
-
+ Create your first index lifecycle policy
+
+
+
+
+ An index lifecycle policy helps you manage your indices as they age.
+
+
+
+
- Create policy
-
-
+ class="emotion-euiButtonDisplayContent"
+ >
+
+ Create policy
+
+
+
-
+
`;
exports[`policy table sorts when linked index templates header is clicked 1`] = `
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx
index 1290304ef6165..2bad87b149e0f 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/edit_policy/edit_policy.container.tsx
@@ -7,12 +7,7 @@
import React, { useEffect } from 'react';
import { RouteComponentProps } from 'react-router-dom';
-import {
- EuiButton,
- EuiEmptyPrompt,
- EuiLoadingSpinner,
- EuiPageContent_Deprecated as EuiPageContent,
-} from '@elastic/eui';
+import { EuiButton, EuiLoadingSpinner, EuiPageTemplate } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { MIN_SEARCHABLE_SNAPSHOT_LICENSE } from '../../../../common/constants';
@@ -45,47 +40,44 @@ export const EditPolicy: React.FunctionComponent
- }
- body={
-
- }
- />
-
+ }
+ body={
+
+ }
+ />
);
}
if (error || !policies) {
const { statusCode, message } = error ? error : { statusCode: '', message: '' };
return (
-
-
-
-
- }
- body={
-
- {message} ({statusCode})
-
- }
- actions={
-
-
-
- }
- />
-
+
+
+
+ }
+ body={
+
+ {message} ({statusCode})
+
+ }
+ actions={
+
+
+
+ }
+ />
);
}
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_list.container.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_list.container.tsx
index 7113b00cf4ec2..669f22ccb9b3f 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_list.container.tsx
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_list.container.tsx
@@ -6,12 +6,7 @@
*/
import React, { useEffect } from 'react';
-import {
- EuiButton,
- EuiEmptyPrompt,
- EuiLoadingSpinner,
- EuiPageContent_Deprecated as EuiPageContent,
-} from '@elastic/eui';
+import { EuiButton, EuiLoadingSpinner, EuiPageTemplate } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import { PolicyList as PresentationComponent } from './policy_list';
import { useKibana } from '../../../shared_imports';
@@ -30,47 +25,44 @@ export const PolicyList: React.FunctionComponent = () => {
if (isLoading) {
return (
-
- }
- body={
-
- }
- />
-
+ }
+ body={
+
+ }
+ />
);
}
if (error) {
const { statusCode, message } = error ? error : { statusCode: '', message: '' };
return (
-
-
-
-
- }
- body={
-
- {message} ({statusCode})
-
- }
- actions={
-
-
-
- }
- />
-
+
+
+
+ }
+ body={
+
+ {message} ({statusCode})
+
+ }
+ actions={
+
+
+
+ }
+ />
);
}
diff --git a/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_list.tsx b/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_list.tsx
index 09fbc2d1c41c6..0a81f6b16bf43 100644
--- a/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_list.tsx
+++ b/x-pack/plugins/index_lifecycle_management/public/application/sections/policy_list/policy_list.tsx
@@ -8,13 +8,7 @@
import React, { Fragment } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
-import {
- EuiButton,
- EuiEmptyPrompt,
- EuiSpacer,
- EuiPageHeader,
- EuiPageContent_Deprecated as EuiPageContent,
-} from '@elastic/eui';
+import { EuiButton, EuiSpacer, EuiPageHeader, EuiPageTemplate } from '@elastic/eui';
import { useHistory } from 'react-router-dom';
import { reactRouterNavigate } from '@kbn/kibana-react-plugin/public';
import { PolicyFromES } from '../../../../common/types';
@@ -46,30 +40,28 @@ export const PolicyList: React.FunctionComponent = ({ policies, updatePol
if (policies.length === 0) {
return (
-
-
+
+
+
+ }
+ body={
+
+
-
- }
- body={
-
-
-
-
-
- }
- actions={createPolicyButton}
- />
-
+
+
+ }
+ actions={createPolicyButton}
+ />
);
}
From 58334b54ac199744cae16d4b9f690dcb01ae6b88 Mon Sep 17 00:00:00 2001
From: Isaac Karrer
Date: Tue, 22 Aug 2023 07:30:08 -0500
Subject: [PATCH 24/26] Kibana QualityGate Scaffold (#163831)
The main question is here did I get the github team names correct for
fleet and security? Are there any other groups I am missing who will
have quality gates they want to see execute on every kibana release?
- The PR which registered the repo and controls who can write secrets to
vault was merged
[here](https://github.com/elastic/catalog-info/pull/488/files)
- Quality gate registration with argo deploy pipeline
[here](https://github.com/elastic/serverless-gitops/pull/586). Should
merge after this and pipelines are working.
- [this one](https://github.com/elastic/catalog-info/pull/485/files)
merges last and tells terrazzo about the catalog-info.yaml file with our
pipeline. Other pipelines should be migrated over but are not included
here.
Rel: https://github.com/elastic/ingest-dev/issues/2201
Rel: https://elasticco.atlassian.net/browse/QX-282
---------
Co-authored-by: Ramon Butter
---
.../quality-gates/pipeline.kibana-tests.yaml | 10 +++
.../pipeline.tests-production.yaml | 15 ++++
.../quality-gates/pipeline.tests-qa.yaml | 15 ++++
.../quality-gates/pipeline.tests-staging.yaml | 15 ++++
.github/CODEOWNERS | 1 +
catalog-info.yaml | 70 +++++++++++++++++++
src/dev/precommit_hook/casing_check_config.js | 3 +
7 files changed, 129 insertions(+)
create mode 100644 .buildkite/pipelines/quality-gates/pipeline.kibana-tests.yaml
create mode 100644 .buildkite/pipelines/quality-gates/pipeline.tests-production.yaml
create mode 100644 .buildkite/pipelines/quality-gates/pipeline.tests-qa.yaml
create mode 100644 .buildkite/pipelines/quality-gates/pipeline.tests-staging.yaml
create mode 100644 catalog-info.yaml
diff --git a/.buildkite/pipelines/quality-gates/pipeline.kibana-tests.yaml b/.buildkite/pipelines/quality-gates/pipeline.kibana-tests.yaml
new file mode 100644
index 0000000000000..27e55dfced9d7
--- /dev/null
+++ b/.buildkite/pipelines/quality-gates/pipeline.kibana-tests.yaml
@@ -0,0 +1,10 @@
+env:
+ ENVIRONMENT: ${ENVIRONMENT?}
+
+steps:
+ - label: ":pipeline::grey_question::seedling: Trigger Kibana Tests for ${ENVIRONMENT}"
+ env:
+ QG_PIPELINE_LOCATION: ".buildkite/pipelines/quality-gates"
+ command: "make -C /agent run-environment-tests"
+ agents:
+ image: "docker.elastic.co/ci-agent-images/quality-gate-seedling:0.0.2"
diff --git a/.buildkite/pipelines/quality-gates/pipeline.tests-production.yaml b/.buildkite/pipelines/quality-gates/pipeline.tests-production.yaml
new file mode 100644
index 0000000000000..483532b9c7435
--- /dev/null
+++ b/.buildkite/pipelines/quality-gates/pipeline.tests-production.yaml
@@ -0,0 +1,15 @@
+steps:
+ - label: ":pipeline::kibana::seedling: Trigger Kibana Tests for ${ENVIRONMENT}"
+ command: echo "replace me with Kibana specific tests"
+ agent:
+ image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364"
+
+ - label: ":pipeline::fleet::seedling: Trigger Fleet Kibana Tests for ${ENVIRONMENT}"
+ command: echo "replace me with Fleet specific Kibana tests"
+ agent:
+ image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364"
+
+ - label: ":pipeline::lock::seedling: Trigger Security Kibana Tests for ${ENVIRONMENT}"
+ command: echo "replace me with Security specific Kibana tests"
+ agent:
+ image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364"
diff --git a/.buildkite/pipelines/quality-gates/pipeline.tests-qa.yaml b/.buildkite/pipelines/quality-gates/pipeline.tests-qa.yaml
new file mode 100644
index 0000000000000..483532b9c7435
--- /dev/null
+++ b/.buildkite/pipelines/quality-gates/pipeline.tests-qa.yaml
@@ -0,0 +1,15 @@
+steps:
+ - label: ":pipeline::kibana::seedling: Trigger Kibana Tests for ${ENVIRONMENT}"
+ command: echo "replace me with Kibana specific tests"
+ agent:
+ image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364"
+
+ - label: ":pipeline::fleet::seedling: Trigger Fleet Kibana Tests for ${ENVIRONMENT}"
+ command: echo "replace me with Fleet specific Kibana tests"
+ agent:
+ image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364"
+
+ - label: ":pipeline::lock::seedling: Trigger Security Kibana Tests for ${ENVIRONMENT}"
+ command: echo "replace me with Security specific Kibana tests"
+ agent:
+ image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364"
diff --git a/.buildkite/pipelines/quality-gates/pipeline.tests-staging.yaml b/.buildkite/pipelines/quality-gates/pipeline.tests-staging.yaml
new file mode 100644
index 0000000000000..483532b9c7435
--- /dev/null
+++ b/.buildkite/pipelines/quality-gates/pipeline.tests-staging.yaml
@@ -0,0 +1,15 @@
+steps:
+ - label: ":pipeline::kibana::seedling: Trigger Kibana Tests for ${ENVIRONMENT}"
+ command: echo "replace me with Kibana specific tests"
+ agent:
+ image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364"
+
+ - label: ":pipeline::fleet::seedling: Trigger Fleet Kibana Tests for ${ENVIRONMENT}"
+ command: echo "replace me with Fleet specific Kibana tests"
+ agent:
+ image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364"
+
+ - label: ":pipeline::lock::seedling: Trigger Security Kibana Tests for ${ENVIRONMENT}"
+ command: echo "replace me with Security specific Kibana tests"
+ agent:
+ image: "docker.elastic.co/ci-agent-images/basic-buildkite-agent:1688566364"
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 650c71e26c93b..eecffc061f483 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -988,6 +988,7 @@ x-pack/plugins/infra/server/lib/alerting @elastic/actionable-observability
/.buildkite/ @elastic/kibana-operations
/kbn_pm/ @elastic/kibana-operations
/x-pack/dev-tools @elastic/kibana-operations
+catalog-info.yaml @elastic/kibana-operations @elastic/kibana-tech-leads
# Appex QA
/src/dev/code_coverage @elastic/appex-qa
diff --git a/catalog-info.yaml b/catalog-info.yaml
new file mode 100644
index 0000000000000..534e34ba27008
--- /dev/null
+++ b/catalog-info.yaml
@@ -0,0 +1,70 @@
+---
+apiVersion: backstage.io/v1alpha1
+kind: Component
+metadata:
+ name: kibana
+ description: Kibana is a user interface that lets you visualize your Elasticsearch data and navigate the Elastic Stack.
+
+ annotations:
+ backstage.io/source-location: url:https://github.com/elastic/kibana/tree/main
+ github.com/project-slug: elastic/kibana
+ github.com/team-slug: elastic/kibana-tech-leads
+ buildkite.com/project-slug: elastic/kibana
+
+ tags:
+ - typescript
+ - javascript
+ - dashboards
+ - metrics
+ - visualizations
+ - observability
+
+ links:
+ - title: Documentation
+ url: https://www.elastic.co/guide/en/kibana/current/index.html
+
+spec:
+ type: monorepo
+ owner: group:kibana-tech-leads
+ lifecycle: production
+
+---
+
+apiVersion: backstage.io/v1alpha1
+kind: Resource
+metadata:
+ name: kibana-tests-pipeline
+ description: Definition of the kibana pipeline
+ links:
+ - title: Pipeline
+ url: https://buildkite.com/elastic/kibana-tests
+spec:
+ type: buildkite-pipeline
+ owner: group:kibana-tech-leads
+ system: buildkite
+ implementation:
+ apiVersion: buildkite.elastic.dev/v1
+ kind: Pipeline
+ metadata:
+ name: kibana-tests
+ description: Pipeline that tests the service integration in various environments
+ spec:
+ repository: elastic/kibana
+ pipeline_file: ./.buildkite/pipelines/pipeline.kibana-tests.yaml
+ provider_settings:
+ trigger_mode: none
+ teams:
+ kibana-operations:
+ access_level: MANAGE_BUILD_AND_READ
+ security-engineering-productivity:
+ access_level: BUILD_AND_READ
+ fleet:
+ access_level: BUILD_AND_READ
+ kibana-tech-leads:
+ access_level: BUILD_AND_READ
+ kibana-core:
+ access_level: BUILD_AND_READ
+ cloud-tooling:
+ access_level: BUILD_AND_READ
+ everyone:
+ access_level: READ_ONLY
diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js
index c3b1a27491e67..93eba1bb171b2 100644
--- a/src/dev/precommit_hook/casing_check_config.js
+++ b/src/dev/precommit_hook/casing_check_config.js
@@ -50,6 +50,9 @@ export const IGNORE_FILE_GLOBS = [
// Required to match the name in the docs.elastic.dev repo.
'nav-kibana-dev.docnav.json',
+ // Match elastic wide naming convention for catalog-info.yaml
+ 'catalog-info.yaml',
+
// filename must match language code which requires capital letters
'**/translations/*.json',
From 9ad81fcce8c88162e89cb0fd04a0b3736bd65462 Mon Sep 17 00:00:00 2001
From: James Gowdy
Date: Tue, 22 Aug 2023 13:39:04 +0100
Subject: [PATCH 25/26] Update
x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx
Co-authored-by: Dima Arnautov
---
.../ml/date_picker/src/hooks/use_date_picker_context.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx b/x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx
index 05b0fbc1237fb..28ad6a12de745 100644
--- a/x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx
+++ b/x-pack/packages/ml/date_picker/src/hooks/use_date_picker_context.tsx
@@ -41,7 +41,7 @@ export interface DatePickerDependencies {
*/
uiSettingsKeys: typeof UI_SETTINGS;
/**
- * Tnternationalisation service
+ * Internationalisation service
*/
i18n: I18nStart;
}
From 83a0eecf25bd6cb5adf71251ceb81ef8ef429ba5 Mon Sep 17 00:00:00 2001
From: Tiago Costa
Date: Tue, 22 Aug 2023 13:53:50 +0100
Subject: [PATCH 26/26] skip flaky suite (#164381)
---
.../apps/ml/anomaly_detection_result_views/forecasts.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/forecasts.ts b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/forecasts.ts
index 93ec331230a8a..63f72381d0185 100644
--- a/x-pack/test/functional/apps/ml/anomaly_detection_result_views/forecasts.ts
+++ b/x-pack/test/functional/apps/ml/anomaly_detection_result_views/forecasts.ts
@@ -42,7 +42,8 @@ export default function ({ getService }: FtrProviderContext) {
describe('forecasts', function () {
this.tags(['ml']);
- describe('with single metric job', function () {
+ // FLAKY: https://github.com/elastic/kibana/issues/164381
+ describe.skip('with single metric job', function () {
before(async () => {
await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote');
await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp');