From b7d76fec02425e2760d9de9e5d997f04b437f1f0 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 14 Oct 2021 15:48:05 -0500 Subject: [PATCH 1/5] [Logs/Metrics UI] Add deprecated field configuration to Deprecations API --- x-pack/plugins/infra/server/deprecations.ts | 187 ++++++++++++++++++++ x-pack/plugins/infra/server/plugin.ts | 8 +- 2 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 x-pack/plugins/infra/server/deprecations.ts diff --git a/x-pack/plugins/infra/server/deprecations.ts b/x-pack/plugins/infra/server/deprecations.ts new file mode 100644 index 0000000000000..3125ad8fc4b7c --- /dev/null +++ b/x-pack/plugins/infra/server/deprecations.ts @@ -0,0 +1,187 @@ +/* + * 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 { get } from 'lodash'; +import { + ConfigDeprecationProvider, + ConfigDeprecation, + DeprecationsDetails, + GetDeprecationsContext, +} from 'src/core/server'; +import { InfraSources } from './lib/sources'; + +const deprecatedFieldMessage = (fieldName: string, defaultValue: string, configNames: string[]) => + i18n.translate('xpack.infra.deprecations.deprecatedFieldDescription', { + defaultMessage: + 'Configuring the "{fieldName}" field has been deprecated and will be removed in 8.0.0. This plugin is designed to work with ECS, and expects this field to have a value of `{defaultValue}`. It has a different value configured in Source {configCount, plural, one {Configuration} other {Configurations}}: {configNames}', + values: { + fieldName, + defaultValue, + configNames: configNames.join(', '), + configCount: configNames.length, + }, + }); + +const DEFAULT_VALUES = { + timestamp: '@timestamp', + tiebreaker: '_doc', + container: 'container.id', + host: 'host.name', + pod: 'kubernetes.pod.uid', +}; + +const FIELD_DEPRECATION_FACTORIES: Record DeprecationsDetails> = + { + timestamp: (configNames) => ({ + level: 'critical', + title: i18n.translate('xpack.infra.deprecations.timestampFieldTitle', { + defaultMessage: 'Source configuration field "timestamp" is deprecated.', + }), + message: deprecatedFieldMessage( + i18n.translate('xpack.infra.deprecations.timestampFieldName', { + defaultMessage: 'timestamp', + }), + DEFAULT_VALUES.timestamp, + configNames + ), + correctiveActions: { + manualSteps: [], + }, + }), + tiebreaker: (configNames) => ({ + level: 'critical', + title: i18n.translate('xpack.infra.deprecations.tiebreakerFieldTitle', { + defaultMessage: 'Source configuration field "tiebreaker" is deprecated.', + }), + message: deprecatedFieldMessage( + i18n.translate('xpack.infra.deprecations.tiebreakerFieldName', { + defaultMessage: 'tiebreaker', + }), + DEFAULT_VALUES.tiebreaker, + configNames + ), + correctiveActions: { + manualSteps: [], + }, + }), + host: (configNames) => ({ + level: 'critical', + title: i18n.translate('xpack.infra.deprecations.hostnameFieldTitle', { + defaultMessage: 'Source configuration field "host name" is deprecated.', + }), + message: deprecatedFieldMessage( + i18n.translate('xpack.infra.deprecations.hostnameFieldName', { + defaultMessage: 'host name', + }), + DEFAULT_VALUES.host, + configNames + ), + correctiveActions: { + manualSteps: [], + }, + }), + pod: (configNames) => ({ + level: 'critical', + title: i18n.translate('xpack.infra.deprecations.podIdFieldTitle', { + defaultMessage: 'Source configuration field "pod ID" is deprecated.', + }), + message: deprecatedFieldMessage( + i18n.translate('xpack.infra.deprecations.podIdFieldName', { defaultMessage: 'pod ID' }), + DEFAULT_VALUES.pod, + configNames + ), + correctiveActions: { + manualSteps: [], + }, + }), + container: (configNames) => ({ + level: 'critical', + title: i18n.translate('xpack.infra.deprecations.containerIdFieldTitle', { + defaultMessage: 'Source configuration field "container ID" is deprecated.', + }), + message: deprecatedFieldMessage( + i18n.translate('xpack.infra.deprecations.containerIdFieldName', { + defaultMessage: 'container ID', + }), + DEFAULT_VALUES.container, + configNames + ), + correctiveActions: { + manualSteps: [], + }, + }), + }; + +export const configDeprecations: ConfigDeprecationProvider = ({ deprecate }) => [ + deprecate('enabled', '8.0.0'), + ...Object.keys(FIELD_DEPRECATION_FACTORIES).map( + (key): ConfigDeprecation => + (completeConfig, rootPath, addDeprecation) => { + const configuredValue = get(completeConfig, `xpack.infra.sources.default.fields.${key}`); + if (typeof configuredValue === 'undefined') { + return completeConfig; + } + addDeprecation({ + title: i18n.translate('xpack.infra.deprecations.deprecatedFieldConfigTitle', { + defaultMessage: '"{fieldKey}" is deprecated.', + values: { + fieldKey: key, + }, + }), + message: i18n.translate('xpack.infra.deprecations.deprecatedFieldConfigDescription', { + defaultMessage: + 'Configuring "xpack.infra.sources.default.fields.{fieldKey}" has been deprecated and will be removed in 8.0.0.', + values: { + fieldKey: key, + }, + }), + level: 'warning', + correctiveActions: { + manualSteps: [ + i18n.translate('xpack.infra.deprecations.removeConfigField', { + defaultMessage: + 'Remove "xpack.infra.sources.default.fields.{fieldKey}" from your Kibana configuration.', + values: { fieldKey: key }, + }), + ], + }, + } as Parameters[0]); + + return completeConfig; + } + ), +]; + +export const getInfraDeprecationsFactory = + (sources: InfraSources) => + async ({ savedObjectsClient }: GetDeprecationsContext) => { + const deprecatedFieldsToSourceConfigMap: Map = new Map(); + const sourceConfigurations = await sources.getAllSourceConfigurations(savedObjectsClient); + + for (const { configuration } of sourceConfigurations) { + const { name, fields } = configuration; + for (const [key, defaultValue] of Object.entries(DEFAULT_VALUES)) { + const configuredValue = Reflect.get(fields, key); + if (configuredValue !== defaultValue) { + const affectedConfigNames = deprecatedFieldsToSourceConfigMap.get(key) ?? []; + affectedConfigNames.push(name); + deprecatedFieldsToSourceConfigMap.set(key, affectedConfigNames); + } + } + } + + const deprecations: DeprecationsDetails[] = []; + if (deprecatedFieldsToSourceConfigMap.size > 0) { + for (const [fieldName, affectedConfigNames] of deprecatedFieldsToSourceConfigMap.entries()) { + const deprecationFactory = Reflect.get(FIELD_DEPRECATION_FACTORIES, fieldName); + deprecations.push(deprecationFactory(affectedConfigNames)); + } + } + + return deprecations; + }; diff --git a/x-pack/plugins/infra/server/plugin.ts b/x-pack/plugins/infra/server/plugin.ts index b77b81cf41ee1..34ac45222bb3f 100644 --- a/x-pack/plugins/infra/server/plugin.ts +++ b/x-pack/plugins/infra/server/plugin.ts @@ -40,6 +40,7 @@ import { UsageCollector } from './usage/usage_collector'; import { createGetLogQueryFields } from './services/log_queries/get_log_query_fields'; import { handleEsError } from '../../../../src/plugins/es_ui_shared/server'; import { RulesService } from './services/rules'; +import { configDeprecations, getInfraDeprecationsFactory } from './deprecations'; export const config: PluginConfigDescriptor = { schema: schema.object({ @@ -68,7 +69,7 @@ export const config: PluginConfigDescriptor = { }) ), }), - deprecations: ({ deprecate }) => [deprecate('enabled', '8.0.0')], + deprecations: configDeprecations, }; export type InfraConfig = TypeOf; @@ -193,6 +194,11 @@ export class InfraServerPlugin implements Plugin { const logEntriesService = new LogEntriesService(); logEntriesService.setup(core, { ...plugins, sources }); + // register deprecated source configuration fields + core.deprecations.registerDeprecations({ + getDeprecations: getInfraDeprecationsFactory(sources), + }); + return { defineInternalSourceConfiguration(sourceId, sourceProperties) { sources.defineInternalSourceConfiguration(sourceId, sourceProperties); From a30ebb6561e4df2e909b5b08b12fd049e849c75a Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 14 Oct 2021 15:56:07 -0500 Subject: [PATCH 2/5] Add correction steps --- x-pack/plugins/infra/server/deprecations.ts | 32 +++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/infra/server/deprecations.ts b/x-pack/plugins/infra/server/deprecations.ts index 3125ad8fc4b7c..790889711ec87 100644 --- a/x-pack/plugins/infra/server/deprecations.ts +++ b/x-pack/plugins/infra/server/deprecations.ts @@ -50,7 +50,11 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep configNames ), correctiveActions: { - manualSteps: [], + manualSteps: [ + i18n.translate('xpack.infra.deprecations.timestampAdjustIndexing', { + defaultMessage: 'Adjust your indexing to use "@timestamp" as a timestamp.', + }), + ], }, }), tiebreaker: (configNames) => ({ @@ -66,7 +70,11 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep configNames ), correctiveActions: { - manualSteps: [], + manualSteps: [ + i18n.translate('xpack.infra.deprecations.tiebreakerAdjustIndexing', { + defaultMessage: 'Adjust your indexing to use "_doc" as a tiebreaker.', + }), + ], }, }), host: (configNames) => ({ @@ -82,7 +90,11 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep configNames ), correctiveActions: { - manualSteps: [], + manualSteps: [ + i18n.translate('xpack.infra.deprecations.hostAdjustIndexing', { + defaultMessage: 'Adjust your indexing to identify hosts using "host.name"', + }), + ], }, }), pod: (configNames) => ({ @@ -96,7 +108,12 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep configNames ), correctiveActions: { - manualSteps: [], + manualSteps: [ + i18n.translate('xpack.infra.deprecations.podAdjustIndexing', { + defaultMessage: + 'Adjust your indexing to identify Kubernetes pods using "kubernetes.pod.uid"', + }), + ], }, }), container: (configNames) => ({ @@ -112,7 +129,12 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep configNames ), correctiveActions: { - manualSteps: [], + manualSteps: [ + i18n.translate('xpack.infra.deprecations.containerAdjustIndexing', { + defaultMessage: + 'Adjust your indexing to identify Docker containers using "container.id"', + }), + ], }, }), }; From 5112efc121f9ad1e9ffe07a8f278c794c2ac39a0 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Fri, 15 Oct 2021 10:46:46 -0500 Subject: [PATCH 3/5] Add unit test for source config deprecations --- .../plugins/infra/server/deprecations.test.ts | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 x-pack/plugins/infra/server/deprecations.test.ts diff --git a/x-pack/plugins/infra/server/deprecations.test.ts b/x-pack/plugins/infra/server/deprecations.test.ts new file mode 100644 index 0000000000000..318f1e50d6662 --- /dev/null +++ b/x-pack/plugins/infra/server/deprecations.test.ts @@ -0,0 +1,86 @@ +/* + * 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 { getInfraDeprecationsFactory } from './deprecations'; + +describe('Infra plugin deprecations', () => { + describe('Source configuration deprecations', () => { + test('returns no deprecations when all fields are set to the default values', async () => { + const sources = { + getAllSourceConfigurations: () => [ + { + configuration: { + name: 'Default', + fields: { + timestamp: '@timestamp', + tiebreaker: '_doc', + container: 'container.id', + host: 'host.name', + pod: 'kubernetes.pod.uid', + }, + }, + }, + { + configuration: { + name: 'Alternate', + fields: { + timestamp: '@timestamp', + tiebreaker: '_doc', + container: 'container.id', + host: 'host.name', + pod: 'kubernetes.pod.uid', + }, + }, + }, + ], + }; + const getDeprecations = getInfraDeprecationsFactory(sources as any); + const deprecations = await getDeprecations({} as any); + expect(deprecations.length).toBe(0); + }); + }); + test('returns expected deprecations when some fields are not set to default values in one or more source configurations', async () => { + const sources = { + getAllSourceConfigurations: () => [ + { + configuration: { + name: 'Default', + fields: { + timestamp: 'not-@timestamp', + tiebreaker: '_doc', + container: 'not-container.id', + host: 'host.name', + pod: 'not-kubernetes.pod.uid', + }, + }, + }, + { + configuration: { + name: 'Alternate', + fields: { + timestamp: 'not-@timestamp', + tiebreaker: 'not-_doc', + container: 'container.id', + host: 'not-host.name', + pod: 'kubernetes.pod.uid', + }, + }, + }, + ], + }; + const getDeprecations = getInfraDeprecationsFactory(sources as any); + const deprecations = await getDeprecations({} as any); + expect(deprecations.length).toBe(5); + expect( + deprecations.map((d) => + d.title.replace(/Source configuration field "(.*)" is deprecated./, '$1') + ) + ).toEqual( + expect.arrayContaining(['timestamp', 'tiebreaker', 'container ID', 'host name', 'pod ID']) + ); + }); +}); From 1468fc97e5fd3be1ee9ef925ce63f52a9e344d44 Mon Sep 17 00:00:00 2001 From: Zacqary Adam Xeper Date: Fri, 15 Oct 2021 16:59:05 -0500 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Chris Cowan --- x-pack/plugins/infra/server/deprecations.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/infra/server/deprecations.ts b/x-pack/plugins/infra/server/deprecations.ts index 790889711ec87..64171c799af28 100644 --- a/x-pack/plugins/infra/server/deprecations.ts +++ b/x-pack/plugins/infra/server/deprecations.ts @@ -52,7 +52,8 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep correctiveActions: { manualSteps: [ i18n.translate('xpack.infra.deprecations.timestampAdjustIndexing', { - defaultMessage: 'Adjust your indexing to use "@timestamp" as a timestamp.', + defaultMessage: 'Adjust your indexing to use "{field}" as a timestamp.', + values: { field: '@timestamp' }, }), ], }, @@ -72,7 +73,8 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep correctiveActions: { manualSteps: [ i18n.translate('xpack.infra.deprecations.tiebreakerAdjustIndexing', { - defaultMessage: 'Adjust your indexing to use "_doc" as a tiebreaker.', + defaultMessage: 'Adjust your indexing to use "{field}" as a tiebreaker.', + values: { field: '_doc' }, }), ], }, @@ -92,7 +94,8 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep correctiveActions: { manualSteps: [ i18n.translate('xpack.infra.deprecations.hostAdjustIndexing', { - defaultMessage: 'Adjust your indexing to identify hosts using "host.name"', + defaultMessage: 'Adjust your indexing to identify hosts using "{field}"', + values: { field: 'host.name' }, }), ], }, @@ -111,7 +114,8 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep manualSteps: [ i18n.translate('xpack.infra.deprecations.podAdjustIndexing', { defaultMessage: - 'Adjust your indexing to identify Kubernetes pods using "kubernetes.pod.uid"', + 'Adjust your indexing to identify Kubernetes pods using "{field}"', + values: { field: 'kubernetes.pod.uid' }, }), ], }, @@ -132,7 +136,8 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep manualSteps: [ i18n.translate('xpack.infra.deprecations.containerAdjustIndexing', { defaultMessage: - 'Adjust your indexing to identify Docker containers using "container.id"', + 'Adjust your indexing to identify Docker containers using "{field}"', + values: { field: 'container.id' }, }), ], }, From f1749331d3dcfde331e5ff7ea30dd18e692d1514 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 18 Oct 2021 10:36:53 -0500 Subject: [PATCH 5/5] Lint fix --- x-pack/plugins/infra/server/deprecations.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/infra/server/deprecations.ts b/x-pack/plugins/infra/server/deprecations.ts index 9b4226d4bcf57..27c2b235f769b 100644 --- a/x-pack/plugins/infra/server/deprecations.ts +++ b/x-pack/plugins/infra/server/deprecations.ts @@ -113,9 +113,8 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep correctiveActions: { manualSteps: [ i18n.translate('xpack.infra.deprecations.podAdjustIndexing', { - defaultMessage: - 'Adjust your indexing to identify Kubernetes pods using "{field}"', - values: { field: 'kubernetes.pod.uid' }, + defaultMessage: 'Adjust your indexing to identify Kubernetes pods using "{field}"', + values: { field: 'kubernetes.pod.uid' }, }), ], }, @@ -135,8 +134,7 @@ const FIELD_DEPRECATION_FACTORIES: Record Dep correctiveActions: { manualSteps: [ i18n.translate('xpack.infra.deprecations.containerAdjustIndexing', { - defaultMessage: - 'Adjust your indexing to identify Docker containers using "{field}"', + defaultMessage: 'Adjust your indexing to identify Docker containers using "{field}"', values: { field: 'container.id' }, }), ],