From 2399780d99a812a3d9a0c1957ea47582e0107072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20St=C3=BCrmer?= Date: Mon, 6 Jul 2020 17:37:28 +0200 Subject: [PATCH] [Logs + Metrics UI] Add index names for the new indexing strategy (#70245) This add support for the new index name patterns `logs-*` and `metrics-*` of the new indexing strategy to the Logs and Metrics UI source configurations in the form of a migration and changed defaults. --- .../add_log_column_popover.tsx | 161 --------- .../fields_configuration_panel.tsx | 328 +++++++----------- .../indices_configuration_panel.tsx | 136 +++----- .../log_columns_configuration_panel.tsx | 279 --------------- .../source_configuration_settings.tsx | 26 -- .../settings/indices_configuration_panel.tsx | 2 +- .../infra/public/pages/metrics/settings.tsx | 1 - .../infra/server/lib/sources/defaults.ts | 4 +- ..._new_indexing_strategy_index_names.test.ts | 131 +++++++ ...0_add_new_indexing_strategy_index_names.ts | 36 ++ .../server/lib/sources/saved_object_type.ts | 5 +- .../apis/metrics_ui/log_sources.ts | 6 +- .../apis/metrics_ui/sources.ts | 10 +- 13 files changed, 358 insertions(+), 767 deletions(-) delete mode 100644 x-pack/plugins/infra/public/components/source_configuration/add_log_column_popover.tsx delete mode 100644 x-pack/plugins/infra/public/components/source_configuration/log_columns_configuration_panel.tsx create mode 100644 x-pack/plugins/infra/server/lib/sources/migrations/7_9_0_add_new_indexing_strategy_index_names.test.ts create mode 100644 x-pack/plugins/infra/server/lib/sources/migrations/7_9_0_add_new_indexing_strategy_index_names.ts diff --git a/x-pack/plugins/infra/public/components/source_configuration/add_log_column_popover.tsx b/x-pack/plugins/infra/public/components/source_configuration/add_log_column_popover.tsx deleted file mode 100644 index 9f55126a1440..000000000000 --- a/x-pack/plugins/infra/public/components/source_configuration/add_log_column_popover.tsx +++ /dev/null @@ -1,161 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { EuiBadge, EuiButton, EuiPopover, EuiPopoverTitle, EuiSelectable } from '@elastic/eui'; -import { EuiSelectableOption } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; -import React, { useCallback, useMemo } from 'react'; -import { v4 as uuidv4 } from 'uuid'; - -import { LogColumnConfiguration } from '../../utils/source_configuration'; -import { useVisibilityState } from '../../utils/use_visibility_state'; -import { euiStyled } from '../../../../observability/public'; - -interface SelectableColumnOption { - optionProps: EuiSelectableOption; - columnConfiguration: LogColumnConfiguration; -} - -export const AddLogColumnButtonAndPopover: React.FunctionComponent<{ - addLogColumn: (logColumnConfiguration: LogColumnConfiguration) => void; - availableFields: string[]; - isDisabled?: boolean; -}> = ({ addLogColumn, availableFields, isDisabled }) => { - const { isVisible: isOpen, show: openPopover, hide: closePopover } = useVisibilityState(false); - - const availableColumnOptions = useMemo( - () => [ - { - optionProps: { - append: , - 'data-test-subj': 'addTimestampLogColumn', - // this key works around EuiSelectable using a lowercased label as - // key, which leads to conflicts with field names - key: 'timestamp', - label: 'Timestamp', - }, - columnConfiguration: { - timestampColumn: { - id: uuidv4(), - }, - }, - }, - { - optionProps: { - 'data-test-subj': 'addMessageLogColumn', - append: , - // this key works around EuiSelectable using a lowercased label as - // key, which leads to conflicts with field names - key: 'message', - label: 'Message', - }, - columnConfiguration: { - messageColumn: { - id: uuidv4(), - }, - }, - }, - ...availableFields.map((field) => ({ - optionProps: { - 'data-test-subj': `addFieldLogColumn addFieldLogColumn:${field}`, - // this key works around EuiSelectable using a lowercased label as - // key, which leads to conflicts with fields that only differ in the - // case (e.g. the metricbeat mongodb module) - key: `field-${field}`, - label: field, - }, - columnConfiguration: { - fieldColumn: { - id: uuidv4(), - field, - }, - }, - })), - ], - [availableFields] - ); - - const availableOptions = useMemo( - () => availableColumnOptions.map((availableColumnOption) => availableColumnOption.optionProps), - [availableColumnOptions] - ); - - const handleColumnSelection = useCallback( - (selectedOptions: EuiSelectableOption[]) => { - closePopover(); - - const selectedOptionIndex = selectedOptions.findIndex( - (selectedOption) => selectedOption.checked === 'on' - ); - const selectedOption = availableColumnOptions[selectedOptionIndex]; - - addLogColumn(selectedOption.columnConfiguration); - }, - [addLogColumn, availableColumnOptions, closePopover] - ); - - return ( - - - - } - closePopover={closePopover} - id="addLogColumn" - isOpen={isOpen} - ownFocus - panelPaddingSize="none" - > - - {(list, search) => ( - - {search} - {list} - - )} - - - ); -}; - -const searchProps = { - 'data-test-subj': 'fieldSearchInput', -}; - -const selectableListProps = { - showIcons: false, -}; - -const SystemColumnBadge: React.FunctionComponent = () => ( - - - -); - -const SelectableContent = euiStyled.div` - width: 400px; -`; diff --git a/x-pack/plugins/infra/public/components/source_configuration/fields_configuration_panel.tsx b/x-pack/plugins/infra/public/components/source_configuration/fields_configuration_panel.tsx index 369f07be67bf..5ad05deafd69 100644 --- a/x-pack/plugins/infra/public/components/source_configuration/fields_configuration_panel.tsx +++ b/x-pack/plugins/infra/public/components/source_configuration/fields_configuration_panel.tsx @@ -27,9 +27,7 @@ interface FieldsConfigurationPanelProps { isLoading: boolean; readOnly: boolean; podFieldProps: InputFieldProps; - tiebreakerFieldProps: InputFieldProps; timestampFieldProps: InputFieldProps; - displaySettings: 'metrics' | 'logs'; } export const FieldsConfigurationPanel = ({ @@ -38,15 +36,12 @@ export const FieldsConfigurationPanel = ({ isLoading, readOnly, podFieldProps, - tiebreakerFieldProps, timestampFieldProps, - displaySettings, }: FieldsConfigurationPanelProps) => { const isHostValueDefault = hostFieldProps.value === 'host.name'; const isContainerValueDefault = containerFieldProps.value === 'container.id'; const isPodValueDefault = podFieldProps.value === 'kubernetes.pod.uid'; const isTimestampValueDefault = timestampFieldProps.value === '@timestamp'; - const isTiebreakerValueDefault = tiebreakerFieldProps.value === '_doc'; return ( @@ -139,194 +134,141 @@ export const FieldsConfigurationPanel = ({ /> - {displaySettings === 'logs' && ( - <> - - - - } - description={ - - } - > - _doc, - }} - /> - } - isInvalid={tiebreakerFieldProps.isInvalid} - label={ - - } - > - - - - - )} - {displaySettings === 'metrics' && ( - <> - - - - } - description={ - - } - > - container.id, - }} - /> - } - isInvalid={containerFieldProps.isInvalid} - label={ - - } - > - - - - - - - } - description={ - - } - > - host.name, - }} - /> - } - isInvalid={hostFieldProps.isInvalid} - label={ - - } - > - - - - - - - } - description={ - - } - > - kubernetes.pod.uid, - }} - /> - } - isInvalid={podFieldProps.isInvalid} - label={ - - } - > - - - - - )} + + + + } + description={ + + } + > + container.id, + }} + /> + } + isInvalid={containerFieldProps.isInvalid} + label={ + + } + > + + + + + + + } + description={ + + } + > + host.name, + }} + /> + } + isInvalid={hostFieldProps.isInvalid} + label={ + + } + > + + + + + + + } + description={ + + } + > + kubernetes.pod.uid, + }} + /> + } + isInvalid={podFieldProps.isInvalid} + label={ + + } + > + + + ); }; diff --git a/x-pack/plugins/infra/public/components/source_configuration/indices_configuration_panel.tsx b/x-pack/plugins/infra/public/components/source_configuration/indices_configuration_panel.tsx index 1d634b781bd3..e9817331ace9 100644 --- a/x-pack/plugins/infra/public/components/source_configuration/indices_configuration_panel.tsx +++ b/x-pack/plugins/infra/public/components/source_configuration/indices_configuration_panel.tsx @@ -21,17 +21,13 @@ import { InputFieldProps } from './input_fields'; interface IndicesConfigurationPanelProps { isLoading: boolean; readOnly: boolean; - logAliasFieldProps: InputFieldProps; metricAliasFieldProps: InputFieldProps; - displaySettings: 'metrics' | 'logs'; } export const IndicesConfigurationPanel = ({ isLoading, readOnly, - logAliasFieldProps, metricAliasFieldProps, - displaySettings, }: IndicesConfigurationPanelProps) => ( @@ -43,101 +39,51 @@ export const IndicesConfigurationPanel = ({ - {displaySettings === 'metrics' && ( - - - - } - description={ + + + } + description={ + + } + > + metrics-*,metricbeat-*, + }} + /> + } + isInvalid={metricAliasFieldProps.isInvalid} + label={ + } > - metricbeat-*, - }} - /> - } - isInvalid={metricAliasFieldProps.isInvalid} - label={ - - } - > - - - - )} - {displaySettings === 'logs' && ( - - - - } - description={ - - } - > - filebeat-*, - }} - /> - } - isInvalid={logAliasFieldProps.isInvalid} - label={ - - } - > - - - - )} + disabled={isLoading} + readOnly={readOnly} + isLoading={isLoading} + {...metricAliasFieldProps} + /> + + ); diff --git a/x-pack/plugins/infra/public/components/source_configuration/log_columns_configuration_panel.tsx b/x-pack/plugins/infra/public/components/source_configuration/log_columns_configuration_panel.tsx deleted file mode 100644 index 46ab1e65c29d..000000000000 --- a/x-pack/plugins/infra/public/components/source_configuration/log_columns_configuration_panel.tsx +++ /dev/null @@ -1,279 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { - EuiButtonIcon, - EuiEmptyPrompt, - EuiForm, - EuiPanel, - EuiSpacer, - EuiText, - EuiTitle, - EuiFlexGroup, - EuiFlexItem, - EuiDragDropContext, - EuiDraggable, - EuiDroppable, - EuiIcon, -} from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; -import React, { useCallback } from 'react'; -import { DragHandleProps, DropResult } from '../../../../observability/public'; - -import { AddLogColumnButtonAndPopover } from './add_log_column_popover'; -import { - FieldLogColumnConfigurationProps, - LogColumnConfigurationProps, -} from './log_columns_configuration_form_state'; -import { LogColumnConfiguration } from '../../utils/source_configuration'; - -interface LogColumnsConfigurationPanelProps { - availableFields: string[]; - isLoading: boolean; - logColumnConfiguration: LogColumnConfigurationProps[]; - addLogColumn: (logColumn: LogColumnConfiguration) => void; - moveLogColumn: (sourceIndex: number, destinationIndex: number) => void; -} - -export const LogColumnsConfigurationPanel: React.FunctionComponent = ({ - addLogColumn, - moveLogColumn, - availableFields, - isLoading, - logColumnConfiguration, -}) => { - const onDragEnd = useCallback( - ({ source, destination }: DropResult) => - destination && moveLogColumn(source.index, destination.index), - [moveLogColumn] - ); - - return ( - - - - -

- -

-
-
- - - -
- {logColumnConfiguration.length > 0 ? ( - - - <> - {/* Fragment here necessary for typechecking */} - {logColumnConfiguration.map((column, index) => ( - - {(provided) => ( - - )} - - ))} - - - - ) : ( - - )} -
- ); -}; - -interface LogColumnConfigurationPanelProps { - logColumnConfigurationProps: LogColumnConfigurationProps; - dragHandleProps: DragHandleProps; -} - -const LogColumnConfigurationPanel: React.FunctionComponent = ( - props -) => ( - <> - - {props.logColumnConfigurationProps.type === 'timestamp' ? ( - - ) : props.logColumnConfigurationProps.type === 'message' ? ( - - ) : ( - - )} - -); - -const TimestampLogColumnConfigurationPanel: React.FunctionComponent = ({ - logColumnConfigurationProps, - dragHandleProps, -}) => ( - timestamp, - }} - /> - } - removeColumn={logColumnConfigurationProps.remove} - dragHandleProps={dragHandleProps} - /> -); - -const MessageLogColumnConfigurationPanel: React.FunctionComponent = ({ - logColumnConfigurationProps, - dragHandleProps, -}) => ( - - } - removeColumn={logColumnConfigurationProps.remove} - dragHandleProps={dragHandleProps} - /> -); - -const FieldLogColumnConfigurationPanel: React.FunctionComponent<{ - logColumnConfigurationProps: FieldLogColumnConfigurationProps; - dragHandleProps: DragHandleProps; -}> = ({ - logColumnConfigurationProps: { - logColumnConfiguration: { field }, - remove, - }, - dragHandleProps, -}) => { - const fieldLogColumnTitle = i18n.translate( - 'xpack.infra.sourceConfiguration.fieldLogColumnTitle', - { - defaultMessage: 'Field', - } - ); - return ( - - - -
- -
-
- {fieldLogColumnTitle} - - {field} - - - - -
-
- ); -}; - -const ExplainedLogColumnConfigurationPanel: React.FunctionComponent<{ - fieldName: React.ReactNode; - helpText: React.ReactNode; - removeColumn: () => void; - dragHandleProps: DragHandleProps; -}> = ({ fieldName, helpText, removeColumn, dragHandleProps }) => ( - - - -
- -
-
- {fieldName} - - - {helpText} - - - - - -
-
-); - -const RemoveLogColumnButton: React.FunctionComponent<{ - onClick?: () => void; - columnDescription: string; -}> = ({ onClick, columnDescription }) => { - const removeColumnLabel = i18n.translate( - 'xpack.infra.sourceConfiguration.removeLogColumnButtonLabel', - { - defaultMessage: 'Remove {columnDescription} column', - values: { columnDescription }, - } - ); - - return ( - - ); -}; - -const LogColumnConfigurationEmptyPrompt: React.FunctionComponent = () => ( - - - - } - body={ -

- -

- } - /> -); diff --git a/x-pack/plugins/infra/public/components/source_configuration/source_configuration_settings.tsx b/x-pack/plugins/infra/public/components/source_configuration/source_configuration_settings.tsx index 43bdc1f4cedc..53b62f8dda04 100644 --- a/x-pack/plugins/infra/public/components/source_configuration/source_configuration_settings.tsx +++ b/x-pack/plugins/infra/public/components/source_configuration/source_configuration_settings.tsx @@ -22,19 +22,16 @@ import { Source } from '../../containers/source'; import { FieldsConfigurationPanel } from './fields_configuration_panel'; import { IndicesConfigurationPanel } from './indices_configuration_panel'; import { NameConfigurationPanel } from './name_configuration_panel'; -import { LogColumnsConfigurationPanel } from './log_columns_configuration_panel'; import { useSourceConfigurationFormState } from './source_configuration_form_state'; import { SourceLoadingPage } from '../source_loading_page'; import { Prompt } from '../../utils/navigation_warning_prompt'; interface SourceConfigurationSettingsProps { shouldAllowEdit: boolean; - displaySettings: 'metrics' | 'logs'; } export const SourceConfigurationSettings = ({ shouldAllowEdit, - displaySettings, }: SourceConfigurationSettingsProps) => { const { createSourceConfiguration, @@ -45,16 +42,8 @@ export const SourceConfigurationSettings = ({ updateSourceConfiguration, } = useContext(Source.Context); - const availableFields = useMemo( - () => (source && source.status ? source.status.indexFields.map((field) => field.name) : []), - [source] - ); - const { - addLogColumn, - moveLogColumn, indicesConfigurationProps, - logColumnConfigurationProps, errors, resetForm, isFormDirty, @@ -119,10 +108,8 @@ export const SourceConfigurationSettings = ({ @@ -133,23 +120,10 @@ export const SourceConfigurationSettings = ({ isLoading={isLoading} podFieldProps={indicesConfigurationProps.podField} readOnly={!isWriteable} - tiebreakerFieldProps={indicesConfigurationProps.tiebreakerField} timestampFieldProps={indicesConfigurationProps.timestampField} - displaySettings={displaySettings} /> - {displaySettings === 'logs' && ( - - - - )} {errors.length > 0 ? ( <> diff --git a/x-pack/plugins/infra/public/pages/logs/settings/indices_configuration_panel.tsx b/x-pack/plugins/infra/public/pages/logs/settings/indices_configuration_panel.tsx index 83effaa3d51a..b1dc55fe5c18 100644 --- a/x-pack/plugins/infra/public/pages/logs/settings/indices_configuration_panel.tsx +++ b/x-pack/plugins/infra/public/pages/logs/settings/indices_configuration_panel.tsx @@ -62,7 +62,7 @@ export const IndicesConfigurationPanel = ({ id="xpack.infra.sourceConfiguration.logIndicesRecommendedValue" defaultMessage="The recommended value is {defaultValue}" values={{ - defaultValue: filebeat-*, + defaultValue: logs-*,filebeat-*, }} /> } diff --git a/x-pack/plugins/infra/public/pages/metrics/settings.tsx b/x-pack/plugins/infra/public/pages/metrics/settings.tsx index 7d4f35b19da7..b0aa67b5f081 100644 --- a/x-pack/plugins/infra/public/pages/metrics/settings.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/settings.tsx @@ -15,7 +15,6 @@ export const MetricsSettingsPage = () => { ); diff --git a/x-pack/plugins/infra/server/lib/sources/defaults.ts b/x-pack/plugins/infra/server/lib/sources/defaults.ts index ba22b4db62d6..b096bed84fa9 100644 --- a/x-pack/plugins/infra/server/lib/sources/defaults.ts +++ b/x-pack/plugins/infra/server/lib/sources/defaults.ts @@ -9,8 +9,8 @@ import { InfraSourceConfiguration } from '../../../common/http_api/source_api'; export const defaultSourceConfiguration: InfraSourceConfiguration = { name: 'Default', description: '', - metricAlias: 'metricbeat-*', - logAlias: 'filebeat-*,kibana_sample_data_logs*', + metricAlias: 'metrics-*,metricbeat-*', + logAlias: 'logs-*,filebeat-*,kibana_sample_data_logs*', fields: { container: 'container.id', host: 'host.name', diff --git a/x-pack/plugins/infra/server/lib/sources/migrations/7_9_0_add_new_indexing_strategy_index_names.test.ts b/x-pack/plugins/infra/server/lib/sources/migrations/7_9_0_add_new_indexing_strategy_index_names.test.ts new file mode 100644 index 000000000000..59a22d33de85 --- /dev/null +++ b/x-pack/plugins/infra/server/lib/sources/migrations/7_9_0_add_new_indexing_strategy_index_names.test.ts @@ -0,0 +1,131 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { migrationMocks } from 'src/core/server/mocks'; +import { addNewIndexingStrategyIndexNames } from './7_9_0_add_new_indexing_strategy_index_names'; +import { infraSourceConfigurationSavedObjectName } from '../saved_object_type'; + +describe('infra source configuration migration function for 7.9.0', () => { + test('adds "logs-*" when the logAlias contains "filebeat-*"', () => { + const unmigratedConfiguration = createTestSourceConfiguration( + 'filebeat-*,custom-log-index-*', + 'custom-metric-index-*' + ); + + const migratedConfiguration = addNewIndexingStrategyIndexNames( + unmigratedConfiguration, + migrationMocks.createContext() + ); + + expect(migratedConfiguration).toStrictEqual( + createTestSourceConfiguration('filebeat-*,custom-log-index-*,logs-*', 'custom-metric-index-*') + ); + }); + + test('doesn\'t add "logs-*" when the logAlias doesn\'t contain "filebeat-*"', () => { + const unmigratedConfiguration = createTestSourceConfiguration( + 'custom-log-index-*', + 'custom-metric-index-*' + ); + + const migratedConfiguration = addNewIndexingStrategyIndexNames( + unmigratedConfiguration, + migrationMocks.createContext() + ); + + expect(migratedConfiguration).toStrictEqual(unmigratedConfiguration); + }); + + test('doesn\'t add "logs-*" when the logAlias already contains it', () => { + const unmigratedConfiguration = createTestSourceConfiguration( + 'filebeat-*,logs-*,custom-log-index-*', + 'custom-metric-index-*' + ); + + const migratedConfiguration = addNewIndexingStrategyIndexNames( + unmigratedConfiguration, + migrationMocks.createContext() + ); + + expect(migratedConfiguration).toStrictEqual(unmigratedConfiguration); + }); + + test('adds "metrics-*" when the logAlias contains "metricbeat-*"', () => { + const unmigratedConfiguration = createTestSourceConfiguration( + 'custom-log-index-*', + 'metricbeat-*,custom-metric-index-*' + ); + + const migratedConfiguration = addNewIndexingStrategyIndexNames( + unmigratedConfiguration, + migrationMocks.createContext() + ); + + expect(migratedConfiguration).toStrictEqual( + createTestSourceConfiguration( + 'custom-log-index-*', + 'metricbeat-*,custom-metric-index-*,metrics-*' + ) + ); + }); + + test('doesn\'t add "metrics-*" when the logAlias doesn\'t contain "metricbeat-*"', () => { + const unmigratedConfiguration = createTestSourceConfiguration( + 'custom-log-index-*', + 'custom-metric-index-*' + ); + + const migratedConfiguration = addNewIndexingStrategyIndexNames( + unmigratedConfiguration, + migrationMocks.createContext() + ); + + expect(migratedConfiguration).toStrictEqual(unmigratedConfiguration); + }); + + test('doesn\'t add "metrics-*" when the metricAlias already contains it', () => { + const unmigratedConfiguration = createTestSourceConfiguration( + 'custom-log-index-*', + 'metrics-*,metricbeat-*,custom-metric-index-*' + ); + + const migratedConfiguration = addNewIndexingStrategyIndexNames( + unmigratedConfiguration, + migrationMocks.createContext() + ); + + expect(migratedConfiguration).toStrictEqual(unmigratedConfiguration); + }); +}); + +const createTestSourceConfiguration = (logAlias: string, metricAlias: string) => ({ + attributes: { + name: 'TEST CONFIGURATION', + description: '', + fields: { + pod: 'TEST POD FIELD', + host: 'TEST HOST FIELD', + message: ['TEST MESSAGE FIELD'], + container: 'TEST CONTAINER FIELD', + timestamp: 'TEST TIMESTAMP FIELD', + tiebreaker: 'TEST TIEBREAKER FIELD', + }, + inventoryDefaultView: '0', + metricsExplorerDefaultView: '0', + logColumns: [ + { + fieldColumn: { + id: 'TEST FIELD COLUMN ID', + field: 'TEST FIELD COLUMN FIELD', + }, + }, + ], + logAlias, + metricAlias, + }, + id: 'TEST_ID', + type: infraSourceConfigurationSavedObjectName, +}); diff --git a/x-pack/plugins/infra/server/lib/sources/migrations/7_9_0_add_new_indexing_strategy_index_names.ts b/x-pack/plugins/infra/server/lib/sources/migrations/7_9_0_add_new_indexing_strategy_index_names.ts new file mode 100644 index 000000000000..0d5563191d1b --- /dev/null +++ b/x-pack/plugins/infra/server/lib/sources/migrations/7_9_0_add_new_indexing_strategy_index_names.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SavedObjectMigrationFn } from 'src/core/server'; +import { InfraSourceConfiguration } from '../../../../common/http_api/source_api'; + +export const addNewIndexingStrategyIndexNames: SavedObjectMigrationFn< + InfraSourceConfiguration, + InfraSourceConfiguration +> = (sourceConfigurationDocument) => { + const oldLogAliasSegments = sourceConfigurationDocument.attributes.logAlias.split(','); + const oldMetricAliasSegments = sourceConfigurationDocument.attributes.metricAlias.split(','); + + const newLogAliasSegment = 'logs-*'; + const newMetricAliasSegment = 'metrics-*'; + + return { + ...sourceConfigurationDocument, + attributes: { + ...sourceConfigurationDocument.attributes, + logAlias: + oldLogAliasSegments.includes('filebeat-*') && + !oldLogAliasSegments.includes(newLogAliasSegment) + ? [...oldLogAliasSegments, newLogAliasSegment].join(',') + : sourceConfigurationDocument.attributes.logAlias, + metricAlias: + oldMetricAliasSegments.includes('metricbeat-*') && + !oldMetricAliasSegments.includes(newMetricAliasSegment) + ? [...oldMetricAliasSegments, newMetricAliasSegment].join(',') + : sourceConfigurationDocument.attributes.metricAlias, + }, + }; +}; diff --git a/x-pack/plugins/infra/server/lib/sources/saved_object_type.ts b/x-pack/plugins/infra/server/lib/sources/saved_object_type.ts index a36ef8d1a892..11db18d6bf79 100644 --- a/x-pack/plugins/infra/server/lib/sources/saved_object_type.ts +++ b/x-pack/plugins/infra/server/lib/sources/saved_object_type.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths import { SavedObjectsType } from 'src/core/server'; +import { addNewIndexingStrategyIndexNames } from './migrations/7_9_0_add_new_indexing_strategy_index_names'; export const infraSourceConfigurationSavedObjectName = 'infrastructure-ui-source'; @@ -86,4 +86,7 @@ export const infraSourceConfigurationSavedObjectType: SavedObjectsType = { }, }, }, + migrations: { + '7.9.0': addNewIndexingStrategyIndexNames, + }, }; diff --git a/x-pack/test/api_integration/apis/metrics_ui/log_sources.ts b/x-pack/test/api_integration/apis/metrics_ui/log_sources.ts index d4cdd7316b3f..00af3f8c2510 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/log_sources.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/log_sources.ts @@ -35,7 +35,7 @@ export default function ({ getService }: FtrProviderContext) { expect(origin).to.be('fallback'); expect(configuration.name).to.be('Default'); - expect(configuration.logAlias).to.be('filebeat-*,kibana_sample_data_logs*'); + expect(configuration.logAlias).to.be('logs-*,filebeat-*,kibana_sample_data_logs*'); expect(configuration.fields.timestamp).to.be('@timestamp'); expect(configuration.fields.tiebreaker).to.be('_doc'); expect(configuration.logColumns[0]).to.have.key('timestampColumn'); @@ -97,7 +97,7 @@ export default function ({ getService }: FtrProviderContext) { expect(configuration.name).to.be('Default'); expect(origin).to.be('stored'); - expect(configuration.logAlias).to.be('filebeat-*,kibana_sample_data_logs*'); + expect(configuration.logAlias).to.be('logs-*,filebeat-*,kibana_sample_data_logs*'); expect(configuration.fields.timestamp).to.be('@timestamp'); expect(configuration.fields.tiebreaker).to.be('_doc'); expect(configuration.logColumns).to.have.length(3); @@ -166,7 +166,7 @@ export default function ({ getService }: FtrProviderContext) { expect(configuration.name).to.be('NAME'); expect(origin).to.be('stored'); - expect(configuration.logAlias).to.be('filebeat-*,kibana_sample_data_logs*'); + expect(configuration.logAlias).to.be('logs-*,filebeat-*,kibana_sample_data_logs*'); expect(configuration.fields.timestamp).to.be('@timestamp'); expect(configuration.fields.tiebreaker).to.be('_doc'); expect(configuration.logColumns).to.have.length(3); diff --git a/x-pack/test/api_integration/apis/metrics_ui/sources.ts b/x-pack/test/api_integration/apis/metrics_ui/sources.ts index 5ed038776625..5908523af249 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/sources.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/sources.ts @@ -40,8 +40,8 @@ export default function ({ getService }: FtrProviderContext) { // shipped default values expect(sourceConfiguration.name).to.be('Default'); - expect(sourceConfiguration.metricAlias).to.be('metricbeat-*'); - expect(sourceConfiguration.logAlias).to.be('filebeat-*,kibana_sample_data_logs*'); + expect(sourceConfiguration.metricAlias).to.be('metrics-*,metricbeat-*'); + expect(sourceConfiguration.logAlias).to.be('logs-*,filebeat-*,kibana_sample_data_logs*'); expect(sourceConfiguration.fields.container).to.be('container.id'); expect(sourceConfiguration.fields.host).to.be('host.name'); expect(sourceConfiguration.fields.pod).to.be('kubernetes.pod.uid'); @@ -125,8 +125,8 @@ export default function ({ getService }: FtrProviderContext) { expect(updatedAt).to.be.greaterThan(0); expect(configuration.name).to.be('NAME'); expect(configuration.description).to.be(''); - expect(configuration.metricAlias).to.be('metricbeat-*'); - expect(configuration.logAlias).to.be('filebeat-*,kibana_sample_data_logs*'); + expect(configuration.metricAlias).to.be('metrics-*,metricbeat-*'); + expect(configuration.logAlias).to.be('logs-*,filebeat-*,kibana_sample_data_logs*'); expect(configuration.fields.container).to.be('container.id'); expect(configuration.fields.host).to.be('host.name'); expect(configuration.fields.pod).to.be('kubernetes.pod.uid'); @@ -283,7 +283,7 @@ export default function ({ getService }: FtrProviderContext) { expect(version).to.not.be(initialVersion); expect(updatedAt).to.be.greaterThan(createdAt); expect(configuration.metricAlias).to.be('metricbeat-**'); - expect(configuration.logAlias).to.be('filebeat-*,kibana_sample_data_logs*'); + expect(configuration.logAlias).to.be('logs-*,filebeat-*,kibana_sample_data_logs*'); expect(status.logIndicesExist).to.be(true); expect(status.metricIndicesExist).to.be(true); });