diff --git a/x-pack/plugins/apm/common/fleet.ts b/x-pack/plugins/apm/common/fleet.ts index 46ec9be784f43..ed148b2230011 100644 --- a/x-pack/plugins/apm/common/fleet.ts +++ b/x-pack/plugins/apm/common/fleet.ts @@ -4,14 +4,61 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import semverParse from 'semver/functions/parse'; - export const POLICY_ELASTIC_AGENT_ON_CLOUD = 'policy-elastic-agent-on-cloud'; -export const SUPPORTED_APM_PACKAGE_VERSION = '8.1.0'; +export const INPUT_VAR_NAME_TO_SCHEMA_PATH: Record = { + host: 'apm-server.host', + url: 'apm-server.url', + enable_rum: 'apm-server.rum.enabled', + default_service_environment: 'apm-server.default_service_environment', + rum_allow_origins: 'apm-server.rum.allow_origins', + rum_allow_headers: 'apm-server.rum.allow_headers', + rum_event_rate_limit: 'apm-server.rum.event_rate.limit', + rum_allow_service_names: 'apm-server.rum.allow_service_names', + rum_event_rate_lru_size: 'apm-server.rum.event_rate.lru_size', + rum_response_headers: 'apm-server.rum.response_headers', + rum_library_pattern: 'apm-server.rum.library_pattern', + rum_exclude_from_grouping: 'apm-server.rum.exclude_from_grouping', + max_event_bytes: 'apm-server.max_event_size', + capture_personal_data: 'apm-server.capture_personal_data', + max_header_bytes: 'apm-server.max_header_size', + idle_timeout: 'apm-server.idle_timeout', + read_timeout: 'apm-server.read_timeout', + shutdown_timeout: 'apm-server.shutdown_timeout', + write_timeout: 'apm-server.write_timeout', + max_connections: 'apm-server.max_connections', + response_headers: 'apm-server.response_headers', + expvar_enabled: 'apm-server.expvar.enabled', + tls_enabled: 'apm-server.ssl.enabled', + tls_certificate: 'apm-server.ssl.certificate', + tls_key: 'apm-server.ssl.key', + tls_supported_protocols: 'apm-server.ssl.supported_protocols', + tls_cipher_suites: 'apm-server.ssl.cipher_suites', + tls_curve_types: 'apm-server.ssl.curve_types', + secret_token: 'apm-server.auth.secret_token', + api_key_enabled: 'apm-server.auth.api_key.enabled', + api_key_limit: 'apm-server.auth.api_key.limit', + anonymous_enabled: 'apm-server.auth.anonymous.enabled', + anonymous_allow_agent: 'apm-server.auth.anonymous.allow_agent', + anonymous_allow_service: 'apm-server.auth.anonymous.allow_service', + anonymous_rate_limit_ip_limit: + 'apm-server.auth.anonymous.rate_limit.ip_limit', + anonymous_rate_limit_event_limit: + 'apm-server.auth.anonymous.rate_limit.event_limit', + tail_sampling_enabled: 'apm-server.sampling.tail.enabled', + tail_sampling_interval: 'apm-server.sampling.tail.interval', + tail_sampling_policies: 'apm-server.sampling.tail.policies', +}; -export function isPrereleaseVersion(version: string) { - return semverParse(version)?.prerelease?.length ?? 0 > 0; -} +export const LEGACY_TO_CURRENT_SCHEMA_PATHS: Record = { + 'apm-server.rum.event_rate.limit': + 'apm-server.auth.anonymous.rate_limit.event_limit', + 'apm-server.rum.event_rate.lru_size': + 'apm-server.auth.anonymous.rate_limit.ip_limit', + 'apm-server.rum.allow_service_names': + 'apm-server.auth.anonymous.allow_service', + 'apm-server.secret_token': 'apm-server.auth.secret_token', + 'apm-server.api_key.enabled': 'apm-server.auth.api_key.enabled', +}; export const ELASTIC_CLOUD_APM_AGENT_POLICY_ID = 'elastic-cloud-apm'; diff --git a/x-pack/plugins/apm/public/components/app/settings/schema/index.tsx b/x-pack/plugins/apm/public/components/app/settings/schema/index.tsx index 0ea03cb0614d4..41d99e4551cc0 100644 --- a/x-pack/plugins/apm/public/components/app/settings/schema/index.tsx +++ b/x-pack/plugins/apm/public/components/app/settings/schema/index.tsx @@ -56,6 +56,7 @@ export function Schema() { const cloudApmPackagePolicy = data.cloud_apm_package_policy; const hasCloudApmPackagePolicy = !!cloudApmPackagePolicy; const hasRequiredRole = !!data.has_required_role; + const latestApmPackageVersion = data.latest_apm_package_version; function updateLocalStorage(newStatus: FETCH_STATUS) { setApmDataStreamsMigrationStatus({ @@ -91,6 +92,7 @@ export function Schema() { hasCloudAgentPolicy={hasCloudAgentPolicy} hasRequiredRole={hasRequiredRole} cloudApmPackagePolicy={cloudApmPackagePolicy} + latestApmPackageVersion={latestApmPackageVersion} /> {isSwitchActive && ( {i18n.translate( 'xpack.apm.tutorial.apmServer.fleet.manageApmIntegration.button', diff --git a/x-pack/plugins/apm/server/routes/fleet/create_cloud_apm_package_policy.ts b/x-pack/plugins/apm/server/routes/fleet/create_cloud_apm_package_policy.ts index 34a6de753d910..797bce77facdb 100644 --- a/x-pack/plugins/apm/server/routes/fleet/create_cloud_apm_package_policy.ts +++ b/x-pack/plugins/apm/server/routes/fleet/create_cloud_apm_package_policy.ts @@ -9,6 +9,7 @@ import { ElasticsearchClient, SavedObjectsClientContract, Logger, + KibanaRequest, } from 'kibana/server'; import { PackagePolicy } from '../../../../fleet/common'; import { @@ -30,7 +31,7 @@ export async function createCloudApmPackgePolicy({ esClient, logger, setup, - kibanaVersion, + request, }: { cloudPluginSetup: APMPluginSetupDependencies['cloud']; fleetPluginStart: NonNullable; @@ -38,7 +39,7 @@ export async function createCloudApmPackgePolicy({ esClient: ElasticsearchClient; logger: Logger; setup: Setup; - kibanaVersion: string; + request: KibanaRequest; }): Promise { const { attributes } = await savedObjectsClient.get( APM_SERVER_SCHEMA_SAVED_OBJECT_TYPE, @@ -52,7 +53,7 @@ export async function createCloudApmPackgePolicy({ apmServerSchema, cloudPluginSetup, fleetPluginStart, - kibanaVersion, + request, }); const mergedAPMPackagePolicy = await mergePackagePolicyWithApm({ setup, diff --git a/x-pack/plugins/apm/server/routes/fleet/get_apm_package_policy_definition.ts b/x-pack/plugins/apm/server/routes/fleet/get_apm_package_policy_definition.ts index 6d4af4e33ad5b..85ac03697019c 100644 --- a/x-pack/plugins/apm/server/routes/fleet/get_apm_package_policy_definition.ts +++ b/x-pack/plugins/apm/server/routes/fleet/get_apm_package_policy_definition.ts @@ -5,29 +5,35 @@ * 2.0. */ +import { KibanaRequest } from 'kibana/server'; +import { RegistryVarsEntry } from '../../../../fleet/common'; import { - isPrereleaseVersion, POLICY_ELASTIC_AGENT_ON_CLOUD, - SUPPORTED_APM_PACKAGE_VERSION, + INPUT_VAR_NAME_TO_SCHEMA_PATH, ELASTIC_CLOUD_APM_AGENT_POLICY_ID, } from '../../../common/fleet'; import { APMPluginSetupDependencies, APMPluginStartDependencies, } from '../../types'; -import { APM_PACKAGE_NAME } from './get_cloud_apm_package_policy'; +import { getLatestApmPackage } from './get_latest_apm_package'; +import { translateLegacySchemaPaths } from './translate_legacy_schema_paths'; -interface GetApmPackagePolicyDefinitionOptions { +export async function getApmPackagePolicyDefinition({ + apmServerSchema, + cloudPluginSetup, + fleetPluginStart, + request, +}: { apmServerSchema: Record; cloudPluginSetup: APMPluginSetupDependencies['cloud']; - fleetPluginStart: APMPluginStartDependencies['fleet']; - kibanaVersion: string; -} -export async function getApmPackagePolicyDefinition( - options: GetApmPackagePolicyDefinitionOptions -) { - const { apmServerSchema, cloudPluginSetup, fleetPluginStart, kibanaVersion } = - options; + fleetPluginStart: NonNullable; + request: KibanaRequest; +}) { + const latestApmPackage = await getLatestApmPackage({ + fleetPluginStart, + request, + }); return { id: ELASTIC_CLOUD_APM_AGENT_POLICY_ID, @@ -42,255 +48,45 @@ export async function getApmPackagePolicyDefinition( enabled: true, streams: [], vars: getApmPackageInputVars({ + policyTemplateInputVars: latestApmPackage.policyTemplateInputVars, + apmServerSchema: translateLegacySchemaPaths(apmServerSchema), cloudPluginSetup, - fleetPluginStart, - apmServerSchema: preprocessLegacyFields({ apmServerSchema }), - kibanaVersion, }), }, ], package: { - name: APM_PACKAGE_NAME, - version: await getApmPackageVersion(fleetPluginStart, kibanaVersion), - title: 'Elastic APM', + name: latestApmPackage.package.name, + version: latestApmPackage.package.version, + title: latestApmPackage.package.title, }, }; } -async function getApmPackageVersion( - fleetPluginStart: APMPluginStartDependencies['fleet'], - kibanaVersion: string -) { - if (fleetPluginStart && isPrereleaseVersion(kibanaVersion)) { - try { - const latestApmPackage = - await fleetPluginStart.packageService.asInternalUser.fetchFindLatestPackage( - 'apm' - ); - return latestApmPackage.version; - } catch (error) { - return SUPPORTED_APM_PACKAGE_VERSION; - } - } - return SUPPORTED_APM_PACKAGE_VERSION; -} - -export function preprocessLegacyFields({ +function getApmPackageInputVars({ + policyTemplateInputVars, apmServerSchema, + cloudPluginSetup, }: { + policyTemplateInputVars: RegistryVarsEntry[]; apmServerSchema: Record; -}) { - const copyOfApmServerSchema = { ...apmServerSchema }; - [ - { - key: 'apm-server.auth.anonymous.rate_limit.event_limit', - legacyKey: 'apm-server.rum.event_rate.limit', - }, - { - key: 'apm-server.auth.anonymous.rate_limit.ip_limit', - legacyKey: 'apm-server.rum.event_rate.lru_size', - }, - { - key: 'apm-server.auth.anonymous.allow_service', - legacyKey: 'apm-server.rum.allow_service_names', - }, - { - key: 'apm-server.auth.secret_token', - legacyKey: 'apm-server.secret_token', - }, - { - key: 'apm-server.auth.api_key.enabled', - legacyKey: 'apm-server.api_key.enabled', - }, - ].forEach(({ key, legacyKey }) => { - if (!copyOfApmServerSchema[key]) { - copyOfApmServerSchema[key] = copyOfApmServerSchema[legacyKey]; - delete copyOfApmServerSchema[legacyKey]; - } - }); - return copyOfApmServerSchema; -} - -function getApmPackageInputVars(options: GetApmPackagePolicyDefinitionOptions) { - const { apmServerSchema } = options; - const apmServerConfigs = Object.entries(apmConfigMapping).map( - ([key, { name, type, getValue }]) => ({ key, name, type, getValue }) - ); + cloudPluginSetup: APMPluginSetupDependencies['cloud']; +}): Record { + const overrideValues: Record = { + url: cloudPluginSetup?.apm?.url, // overrides 'apm-server.url' to be the cloud APM host + }; - const inputVars: Record = - apmServerConfigs.reduce((acc, { key, name, type, getValue }) => { - const value = (getValue ? getValue(options) : apmServerSchema[key]) ?? ''; // defaults to an empty string to be edited in Fleet UI - return { - ...acc, - [name]: { type, value }, - }; - }, {}); - return inputVars; + return policyTemplateInputVars.reduce((acc, registryVarsEntry) => { + const { name, type, default: defaultValue } = registryVarsEntry; + return { + ...acc, + [name]: { + type, + value: + overrideValues[name] ?? + apmServerSchema[INPUT_VAR_NAME_TO_SCHEMA_PATH[name]] ?? + defaultValue ?? + '', + }, + }; + }, {}); } - -export const apmConfigMapping: Record< - string, - { - name: string; - type: string; - getValue?: (options: GetApmPackagePolicyDefinitionOptions) => any; - } -> = { - 'apm-server.host': { - name: 'host', - type: 'text', - }, - 'apm-server.url': { - name: 'url', - type: 'text', - getValue: ({ cloudPluginSetup }) => cloudPluginSetup?.apm?.url, - }, - 'apm-server.rum.enabled': { - name: 'enable_rum', - type: 'bool', - }, - 'apm-server.default_service_environment': { - name: 'default_service_environment', - type: 'text', - }, - 'apm-server.rum.allow_origins': { - name: 'rum_allow_origins', - type: 'text', - }, - 'apm-server.rum.allow_headers': { - name: 'rum_allow_headers', - type: 'text', - }, - 'apm-server.rum.event_rate.limit': { - name: 'rum_event_rate_limit', - type: 'integer', - }, - 'apm-server.rum.allow_service_names': { - name: 'rum_allow_service_names', - type: 'text', - }, - 'apm-server.rum.event_rate.lru_size': { - name: 'rum_event_rate_lru_size', - type: 'integer', - }, - 'apm-server.rum.response_headers': { - name: 'rum_response_headers', - type: 'yaml', - }, - 'apm-server.rum.library_pattern': { - name: 'rum_library_pattern', - type: 'text', - }, - 'apm-server.rum.exclude_from_grouping': { - name: 'rum_exclude_from_grouping', - type: 'text', - }, - 'apm-server.max_event_size': { - name: 'max_event_bytes', - type: 'integer', - }, - 'apm-server.capture_personal_data': { - name: 'capture_personal_data', - type: 'bool', - }, - 'apm-server.max_header_size': { - name: 'max_header_bytes', - type: 'integer', - }, - 'apm-server.idle_timeout': { - name: 'idle_timeout', - type: 'text', - }, - 'apm-server.read_timeout': { - name: 'read_timeout', - type: 'text', - }, - 'apm-server.shutdown_timeout': { - name: 'shutdown_timeout', - type: 'text', - }, - 'apm-server.write_timeout': { - name: 'write_timeout', - type: 'text', - }, - 'apm-server.max_connections': { - name: 'max_connections', - type: 'integer', - }, - 'apm-server.response_headers': { - name: 'response_headers', - type: 'yaml', - }, - 'apm-server.expvar.enabled': { - name: 'expvar_enabled', - type: 'bool', - }, - 'apm-server.ssl.enabled': { - name: 'tls_enabled', - type: 'bool', - }, - 'apm-server.ssl.certificate': { - name: 'tls_certificate', - type: 'text', - }, - 'apm-server.ssl.key': { - name: 'tls_key', - type: 'text', - }, - 'apm-server.ssl.supported_protocols': { - name: 'tls_supported_protocols', - type: 'text', - }, - 'apm-server.ssl.cipher_suites': { - name: 'tls_cipher_suites', - type: 'text', - }, - 'apm-server.ssl.curve_types': { - name: 'tls_curve_types', - type: 'text', - }, - 'apm-server.auth.secret_token': { - name: 'secret_token', - type: 'text', - }, - 'apm-server.auth.api_key.enabled': { - name: 'api_key_enabled', - type: 'bool', - }, - 'apm-server.auth.api_key.limit': { - name: 'api_key_limit', - type: 'bool', - }, - 'apm-server.auth.anonymous.enabled': { - name: 'anonymous_enabled', - type: 'bool', - }, - 'apm-server.auth.anonymous.allow_agent': { - name: 'anonymous_allow_agent', - type: 'text', - }, - 'apm-server.auth.anonymous.allow_service': { - name: 'anonymous_allow_service', - type: 'text', - }, - 'apm-server.auth.anonymous.rate_limit.ip_limit': { - name: 'anonymous_rate_limit_ip_limit', - type: 'integer', - }, - 'apm-server.auth.anonymous.rate_limit.event_limit': { - name: 'anonymous_rate_limit_event_limit', - type: 'integer', - }, - 'apm-server.sampling.tail.enabled': { - name: 'tail_sampling_enabled', - type: 'bool', - }, - 'apm-server.sampling.tail.interval': { - name: 'tail_sampling_interval', - type: 'text', - }, - 'apm-server.sampling.tail.policies': { - name: 'tail_sampling_policies', - type: 'yaml', - }, -}; diff --git a/x-pack/plugins/apm/server/routes/fleet/get_latest_apm_package.ts b/x-pack/plugins/apm/server/routes/fleet/get_latest_apm_package.ts new file mode 100644 index 0000000000000..ba5b9f4b919e9 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/fleet/get_latest_apm_package.ts @@ -0,0 +1,28 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { KibanaRequest } from 'kibana/server'; +import { APMPluginStartDependencies } from '../../types'; +import { APM_PACKAGE_NAME } from './get_cloud_apm_package_policy'; + +export async function getLatestApmPackage({ + fleetPluginStart, + request, +}: { + fleetPluginStart: NonNullable; + request: KibanaRequest; +}) { + const packageClient = fleetPluginStart.packageService.asScoped(request); + const { name, version } = await packageClient.fetchFindLatestPackage( + APM_PACKAGE_NAME + ); + const registryPackage = await packageClient.getRegistryPackage(name, version); + const { title, policy_templates: policyTemplates } = + registryPackage.packageInfo; + const policyTemplateInputVars = policyTemplates?.[0].inputs?.[0].vars ?? []; + return { package: { name, version, title }, policyTemplateInputVars }; +} diff --git a/x-pack/plugins/apm/server/routes/fleet/get_unsupported_apm_server_schema.ts b/x-pack/plugins/apm/server/routes/fleet/get_unsupported_apm_server_schema.ts index 2ced15245b593..fa2b4c585cb9d 100644 --- a/x-pack/plugins/apm/server/routes/fleet/get_unsupported_apm_server_schema.ts +++ b/x-pack/plugins/apm/server/routes/fleet/get_unsupported_apm_server_schema.ts @@ -6,14 +6,12 @@ */ import { SavedObjectsClientContract } from 'kibana/server'; +import { INPUT_VAR_NAME_TO_SCHEMA_PATH } from '../../../common/fleet'; import { APM_SERVER_SCHEMA_SAVED_OBJECT_TYPE, APM_SERVER_SCHEMA_SAVED_OBJECT_ID, } from '../../../common/apm_saved_object_constants'; -import { - apmConfigMapping, - preprocessLegacyFields, -} from './get_apm_package_policy_definition'; +import { translateLegacySchemaPaths } from './translate_legacy_schema_paths'; export async function getUnsupportedApmServerSchema({ savedObjectsClient, @@ -27,10 +25,9 @@ export async function getUnsupportedApmServerSchema({ const apmServerSchema: Record = JSON.parse( (attributes as { schemaJson: string }).schemaJson ); - const preprocessedApmServerSchema = preprocessLegacyFields({ - apmServerSchema, - }); - return Object.entries(preprocessedApmServerSchema) - .filter(([name]) => !(name in apmConfigMapping)) + const translatedApmServerSchema = translateLegacySchemaPaths(apmServerSchema); + const supportedSchemaPaths = Object.values(INPUT_VAR_NAME_TO_SCHEMA_PATH); + return Object.entries(translatedApmServerSchema) + .filter(([name]) => !supportedSchemaPaths.includes(name)) .map(([key, value]) => ({ key, value })); } diff --git a/x-pack/plugins/apm/server/routes/fleet/route.ts b/x-pack/plugins/apm/server/routes/fleet/route.ts index 97949dfc7d0c3..2b6412647641c 100644 --- a/x-pack/plugins/apm/server/routes/fleet/route.ts +++ b/x-pack/plugins/apm/server/routes/fleet/route.ts @@ -25,6 +25,7 @@ import { isSuperuser } from './is_superuser'; import { getInternalSavedObjectsClient } from '../../lib/helpers/get_internal_saved_objects_client'; import { setupRequest } from '../../lib/helpers/setup_request'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; +import { getLatestApmPackage } from './get_latest_apm_package'; const hasFleetDataRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/fleet/has_apm_policies', @@ -177,6 +178,7 @@ const getMigrationCheckRoute = createApmServerRoute({ | import('./../../../../fleet/common/index').PackagePolicy | undefined; has_apm_integrations: boolean; + latest_apm_package_version: string; }> => { const { core, plugins, context, config, request } = resources; const cloudApmMigrationEnabled = config.agent.migrations.enabled; @@ -200,6 +202,10 @@ const getMigrationCheckRoute = createApmServerRoute({ core, fleetPluginStart, }); + const latestApmPackage = await getLatestApmPackage({ + fleetPluginStart, + request, + }); return { has_cloud_agent_policy: !!cloudAgentPolicy, has_cloud_apm_package_policy: !!apmPackagePolicy, @@ -207,6 +213,7 @@ const getMigrationCheckRoute = createApmServerRoute({ has_required_role: hasRequiredRole, cloud_apm_package_policy: apmPackagePolicy, has_apm_integrations: packagePolicies.total > 0, + latest_apm_package_version: latestApmPackage.package.version, }; }, }); @@ -219,8 +226,7 @@ const createCloudApmPackagePolicyRoute = createApmServerRoute({ ): Promise<{ cloudApmPackagePolicy: import('./../../../../fleet/common/index').PackagePolicy; }> => { - const { plugins, context, config, request, logger, kibanaVersion } = - resources; + const { plugins, context, config, request, logger } = resources; const cloudApmMigrationEnabled = config.agent.migrations.enabled; if (!plugins.fleet || !plugins.security) { throw Boom.internal(FLEET_SECURITY_REQUIRED_MESSAGE); @@ -247,7 +253,7 @@ const createCloudApmPackagePolicyRoute = createApmServerRoute({ esClient, logger, setup, - kibanaVersion, + request, }); return { cloudApmPackagePolicy }; diff --git a/x-pack/plugins/apm/server/routes/fleet/get_apm_package_policy_definition.test.ts b/x-pack/plugins/apm/server/routes/fleet/translate_legacy_schema_paths.test.ts similarity index 91% rename from x-pack/plugins/apm/server/routes/fleet/get_apm_package_policy_definition.test.ts rename to x-pack/plugins/apm/server/routes/fleet/translate_legacy_schema_paths.test.ts index 805099d87e1c6..09cab871d3a5b 100644 --- a/x-pack/plugins/apm/server/routes/fleet/get_apm_package_policy_definition.test.ts +++ b/x-pack/plugins/apm/server/routes/fleet/translate_legacy_schema_paths.test.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { preprocessLegacyFields } from './get_apm_package_policy_definition'; +import { translateLegacySchemaPaths } from './translate_legacy_schema_paths'; const apmServerSchema = { 'apm-server.host': '0.0.0.0:8200', @@ -24,7 +24,7 @@ const apmServerSchema = { describe('get_apm_package_policy_definition', () => { describe('preprocessLegacyFields', () => { it('should replace legacy fields with supported fields', () => { - const result = preprocessLegacyFields({ apmServerSchema }); + const result = translateLegacySchemaPaths(apmServerSchema); expect(result).toMatchInlineSnapshot(` Object { "apm-server.auth.anonymous.allow_service": "opbeans-test", diff --git a/x-pack/plugins/apm/server/routes/fleet/translate_legacy_schema_paths.ts b/x-pack/plugins/apm/server/routes/fleet/translate_legacy_schema_paths.ts new file mode 100644 index 0000000000000..ca8de7d6e7a62 --- /dev/null +++ b/x-pack/plugins/apm/server/routes/fleet/translate_legacy_schema_paths.ts @@ -0,0 +1,21 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { LEGACY_TO_CURRENT_SCHEMA_PATHS } from '../../../common/fleet'; + +export function translateLegacySchemaPaths( + apmServerSchema: Record +) { + return Object.keys(apmServerSchema).reduce((acc, apmServerSchemaKey) => { + const currentSchemaPath = + LEGACY_TO_CURRENT_SCHEMA_PATHS[apmServerSchemaKey] || apmServerSchemaKey; + return { + ...acc, + [currentSchemaPath]: apmServerSchema[apmServerSchemaKey], + }; + }, {}); +}