diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts index bd119a77378af..608d2ce5390da 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.helpers.ts @@ -298,6 +298,7 @@ export const createDataStreamPayload = (dataStream: Partial): DataSt enabled: true, data_retention: '7d', }, + indexMode: 'standard', ...dataStream, }); diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts index a4ea7b9296e28..1d7ee65790cfd 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/data_streams_tab.test.ts @@ -205,8 +205,8 @@ describe('Data Streams tab', () => { const { tableCellsValues } = table.getMetaData('dataStreamTable'); expect(tableCellsValues).toEqual([ - ['', 'dataStream1', 'green', '1', '7 days', 'Delete'], - ['', 'dataStream2', 'green', '1', '5 days ', 'Delete'], + ['', 'dataStream1', 'green', '1', 'Standard', '7 days', 'Delete'], + ['', 'dataStream2', 'green', '1', 'Standard', '5 days ', 'Delete'], ]); }); @@ -254,6 +254,7 @@ describe('Data Streams tab', () => { 'December 31st, 1969 7:00:00 PM', '5b', '1', + 'Standard', '7 days', 'Delete', ], @@ -264,6 +265,7 @@ describe('Data Streams tab', () => { 'December 31st, 1969 7:00:00 PM', '1kb', '1', + 'Standard', '5 days ', 'Delete', ], @@ -289,6 +291,7 @@ describe('Data Streams tab', () => { 'December 31st, 1969 7:00:00 PM', '5b', '1', + 'Standard', '7 days', 'Delete', ], @@ -299,6 +302,7 @@ describe('Data Streams tab', () => { 'December 31st, 1969 7:00:00 PM', '1kb', '1', + 'Standard', '5 days ', 'Delete', ], @@ -346,8 +350,8 @@ describe('Data Streams tab', () => { const { tableCellsValues } = table.getMetaData('dataStreamTable'); expect(tableCellsValues).toEqual([ - ['', 'dataStream1', 'green', '156kb', '10000', '1', '7 days', 'Delete'], - ['', 'dataStream2', 'green', '156kb', '10000', '1', '5 days ', 'Delete'], + ['', 'dataStream1', 'green', '156kb', '10000', '1', 'Standard', '7 days', 'Delete'], + ['', 'dataStream2', 'green', '156kb', '10000', '1', 'Standard', '5 days ', 'Delete'], ]); }); @@ -378,6 +382,7 @@ describe('Data Streams tab', () => { 'December 31st, 1969 7:00:00 PM', '5b', '1', + 'Standard', '7 days', 'Delete', ], @@ -388,6 +393,7 @@ describe('Data Streams tab', () => { 'December 31st, 1969 7:00:00 PM', '1kb', '1', + 'Standard', '5 days ', 'Delete', ], @@ -509,8 +515,8 @@ describe('Data Streams tab', () => { const { tableCellsValues } = table.getMetaData('dataStreamTable'); expect(tableCellsValues).toEqual([ - ['', 'dataStream1', 'green', '1', 'Disabled', 'Delete'], - ['', 'dataStream2', 'green', '1', '', 'Delete'], + ['', 'dataStream1', 'green', '1', 'Standard', 'Disabled', 'Delete'], + ['', 'dataStream2', 'green', '1', 'Standard', '', 'Delete'], ]); await actions.clickNameAt(0); @@ -892,8 +898,16 @@ describe('Data Streams tab', () => { const { tableCellsValues } = table.getMetaData('dataStreamTable'); expect(tableCellsValues).toEqual([ - ['', `managed-data-stream${nonBreakingSpace}Managed`, 'green', '1', '7 days', 'Delete'], - ['', 'non-managed-data-stream', 'green', '1', '7 days', 'Delete'], + [ + '', + `managed-data-stream${nonBreakingSpace}Managed`, + 'green', + '1', + 'Standard', + '7 days', + 'Delete', + ], + ['', 'non-managed-data-stream', 'green', '1', 'Standard', '7 days', 'Delete'], ]); }); @@ -902,15 +916,23 @@ describe('Data Streams tab', () => { let { tableCellsValues } = table.getMetaData('dataStreamTable'); expect(tableCellsValues).toEqual([ - ['', `managed-data-stream${nonBreakingSpace}Managed`, 'green', '1', '7 days', 'Delete'], - ['', 'non-managed-data-stream', 'green', '1', '7 days', 'Delete'], + [ + '', + `managed-data-stream${nonBreakingSpace}Managed`, + 'green', + '1', + 'Standard', + '7 days', + 'Delete', + ], + ['', 'non-managed-data-stream', 'green', '1', 'Standard', '7 days', 'Delete'], ]); actions.toggleViewFilterAt(0); ({ tableCellsValues } = table.getMetaData('dataStreamTable')); expect(tableCellsValues).toEqual([ - ['', 'non-managed-data-stream', 'green', '1', '7 days', 'Delete'], + ['', 'non-managed-data-stream', 'green', '1', 'Standard', '7 days', 'Delete'], ]); }); }); @@ -942,7 +964,15 @@ describe('Data Streams tab', () => { const { tableCellsValues } = table.getMetaData('dataStreamTable'); expect(tableCellsValues).toEqual([ - ['', `hidden-data-stream${nonBreakingSpace}Hidden`, 'green', '1', '7 days', 'Delete'], + [ + '', + `hidden-data-stream${nonBreakingSpace}Hidden`, + 'green', + '1', + 'Standard', + '7 days', + 'Delete', + ], ]); }); }); @@ -989,10 +1019,10 @@ describe('Data Streams tab', () => { const { tableCellsValues } = table.getMetaData('dataStreamTable'); expect(tableCellsValues).toEqual([ - ['', 'dataStreamNoDelete', 'green', '1', '7 days', ''], - ['', 'dataStreamNoEditRetention', 'green', '1', '7 days', 'Delete'], - ['', 'dataStreamNoPermissions', 'green', '1', '7 days', ''], - ['', 'dataStreamWithDelete', 'green', '1', '7 days', 'Delete'], + ['', 'dataStreamNoDelete', 'green', '1', 'Standard', '7 days', ''], + ['', 'dataStreamNoEditRetention', 'green', '1', 'Standard', '7 days', 'Delete'], + ['', 'dataStreamNoPermissions', 'green', '1', 'Standard', '7 days', ''], + ['', 'dataStreamWithDelete', 'green', '1', 'Standard', '7 days', 'Delete'], ]); }); diff --git a/x-pack/plugins/index_management/common/lib/template_serialization.ts b/x-pack/plugins/index_management/common/lib/template_serialization.ts index f8b4ed47a22f7..0ed52e3f04ba0 100644 --- a/x-pack/plugins/index_management/common/lib/template_serialization.ts +++ b/x-pack/plugins/index_management/common/lib/template_serialization.ts @@ -73,6 +73,8 @@ export function deserializeTemplate( type = 'managed'; } + const ilmPolicyName = settings?.index?.lifecycle?.name; + const deserializedTemplate: TemplateDeserialized = { name, version, @@ -80,7 +82,7 @@ export function deserializeTemplate( ...(template.lifecycle ? { lifecycle: deserializeESLifecycle(template.lifecycle) } : {}), indexPatterns: indexPatterns.sort(), template, - ilmPolicy: settings?.index?.lifecycle, + ilmPolicy: ilmPolicyName ? { name: ilmPolicyName } : undefined, composedOf: composedOf ?? [], ignoreMissingComponentTemplates: ignoreMissingComponentTemplates ?? [], dataStream, diff --git a/x-pack/plugins/index_management/common/types/data_streams.ts b/x-pack/plugins/index_management/common/types/data_streams.ts index 78c671969f579..993d32f32bee1 100644 --- a/x-pack/plugins/index_management/common/types/data_streams.ts +++ b/x-pack/plugins/index_management/common/types/data_streams.ts @@ -33,6 +33,8 @@ export type DataStreamIndexFromEs = IndicesDataStreamIndex; export type Health = 'green' | 'yellow' | 'red'; +export type IndexMode = 'standard' | 'logsdb' | 'time_series'; + export interface EnhancedDataStreamFromEs extends IndicesDataStream { global_max_retention?: string; store_size?: IndicesDataStreamsStatsDataStreamsStatsItem['store_size']; @@ -45,6 +47,7 @@ export interface EnhancedDataStreamFromEs extends IndicesDataStream { delete_index: boolean; manage_data_stream_lifecycle: boolean; }; + index_mode?: string | null; } export interface DataStream { @@ -71,6 +74,7 @@ export interface DataStream { retention_determined_by?: string; globalMaxRetention?: string; }; + indexMode: IndexMode; } export interface DataStreamIndex { diff --git a/x-pack/plugins/index_management/common/types/indices.ts b/x-pack/plugins/index_management/common/types/indices.ts index 612aaf3bd6c9b..804a1bce1e299 100644 --- a/x-pack/plugins/index_management/common/types/indices.ts +++ b/x-pack/plugins/index_management/common/types/indices.ts @@ -5,29 +5,9 @@ * 2.0. */ -export type { Index } from '@kbn/index-management-shared-types'; +import { IndicesIndexSettingsKeys } from '@elastic/elasticsearch/lib/api/types'; -export interface IndexModule { - number_of_shards: number | string; - codec: string; - routing_partition_size: number; - refresh_interval: string; - load_fixed_bitset_filters_eagerly: boolean; - shard: { - check_on_startup: boolean | 'checksum'; - }; - number_of_replicas: number; - auto_expand_replicas: false | string; - lifecycle: LifecycleModule; - routing: { - allocation: { - enable: 'all' | 'primaries' | 'new_primaries' | 'none'; - }; - rebalance: { - enable: 'all' | 'primaries' | 'replicas' | 'none'; - }; - }; -} +export type { Index } from '@kbn/index-management-shared-types'; interface AnalysisModule { analyzer: { @@ -41,15 +21,8 @@ interface AnalysisModule { }; } -interface LifecycleModule { - name: string; - rollover_alias?: string; - parse_origination_date?: boolean; - origination_date?: number; -} - export interface IndexSettings { - index?: Partial; + index?: IndicesIndexSettingsKeys; analysis?: AnalysisModule; [key: string]: any; } diff --git a/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx index 24544db04498b..9cb5c481b6b50 100644 --- a/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx +++ b/x-pack/plugins/index_management/public/application/components/template_form/steps/step_review.tsx @@ -22,6 +22,7 @@ import { EuiCodeBlock, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { getIndexModeLabel } from '../../../lib/index_mode_labels'; import { allowAutoCreateRadioIds } from '../../../../../common/constants'; import { serializers } from '../../../../shared_imports'; @@ -268,6 +269,19 @@ export const StepReview: React.FunctionComponent = React.memo( {getDescriptionText(serializedSettings)} + {/* Index mode */} + + + + + {getIndexModeLabel( + serializedSettings?.['index.mode'] ?? serializedSettings?.index?.mode + )} + + {/* Mappings */} { + switch (mode) { + case 'standard': + case null: + case undefined: + return i18n.translate('xpack.idxMgmt.indexModeLabels.standardModeLabel', { + defaultMessage: 'Standard', + }); + case 'logsdb': + return i18n.translate('xpack.idxMgmt.indexModeLabels.logsdbModeLabel', { + defaultMessage: 'LogsDB', + }); + case 'time_series': + return i18n.translate('xpack.idxMgmt.indexModeLabels.tsdbModeLabel', { + defaultMessage: 'Time series', + }); + default: + return mode; + } +}; diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx index 974ba6f082042..5b3bf0920c3b7 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_detail_panel/data_stream_detail_panel.tsx @@ -34,6 +34,7 @@ import { EuiSpacer, } from '@elastic/eui'; +import { getIndexModeLabel } from '../../../../lib/index_mode_labels'; import { DiscoverLink } from '../../../../lib/discover_link'; import { getLifecycleValue } from '../../../../lib/data_streams'; import { SectionLoading, reactRouterNavigate } from '../../../../../shared_imports'; @@ -166,6 +167,7 @@ export const DataStreamDetailPanel: React.FunctionComponent = ({ meteringStorageSize, meteringDocsCount, lifecycle, + indexMode, } = dataStream; const getManagementDetails = () => { @@ -345,6 +347,17 @@ export const DataStreamDetailPanel: React.FunctionComponent = ({ ), dataTestSubj: 'indexTemplateDetail', }, + { + name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.indexModeTitle', { + defaultMessage: 'Index mode', + }), + toolTip: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.indexModeToolTip', { + defaultMessage: + "The index mode applied to the data stream's backing indices, as defined in its associated index template.", + }), + content: getIndexModeLabel(indexMode), + dataTestSubj: 'indexModeDetail', + }, { name: i18n.translate('xpack.idxMgmt.dataStreamDetailPanel.dataRetentionTitle', { defaultMessage: 'Effective data retention', diff --git a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx index 927907757fe7b..e91fd644f795c 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/data_stream_list/data_stream_table/data_stream_table.tsx @@ -36,6 +36,7 @@ import { humanizeTimeStamp } from '../humanize_time_stamp'; import { DataStreamsBadges } from '../data_stream_badges'; import { ConditionalWrap } from '../data_stream_detail_panel'; import { isDataStreamFullyManagedByILM } from '../../../../lib/data_streams'; +import { getIndexModeLabel } from '../../../../lib/index_mode_labels'; import { FilterListButton, Filters } from '../../components'; import { type DataStreamFilterName } from '../data_stream_list'; @@ -184,6 +185,16 @@ export const DataStreamTable: React.FunctionComponent = ({ ), }); + columns.push({ + field: 'indexMode', + name: i18n.translate('xpack.idxMgmt.dataStreamList.table.indexModeColumnTitle', { + defaultMessage: 'Index mode', + }), + truncateText: true, + sortable: true, + render: (indexMode: DataStream['indexMode']) => getIndexModeLabel(indexMode), + }); + columns.push({ field: 'lifecycle', name: ( diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table_pagination.tsx b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table_pagination.tsx index b9dd98e21a426..a0988aec797f6 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table_pagination.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_table/index_table_pagination.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { EuiTablePagination } from '@elastic/eui'; import { useEuiTablePersist } from '@kbn/shared-ux-table-persist'; -import { IndexModule } from '../../../../../../common'; +import { Index } from '../../../../../../common'; interface IndexTablePaginationProps { pager: any; @@ -27,7 +27,7 @@ export const IndexTablePagination = ({ readURLParams, setURLParam, }: IndexTablePaginationProps) => { - const { pageSize, onTableChange } = useEuiTablePersist({ + const { pageSize, onTableChange } = useEuiTablePersist({ tableId: 'indices', initialPageSize: pager.itemsPerPage, pageSizeOptions: PAGE_SIZE_OPTIONS, diff --git a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx index 513377714ffe0..ff06a08014f61 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx +++ b/x-pack/plugins/index_management/public/application/sections/home/template_list/template_details/tabs/tab_summary.tsx @@ -28,6 +28,7 @@ import { TemplateDeserialized } from '../../../../../../../common'; import { ILM_PAGES_POLICY_EDIT } from '../../../../../constants'; import { useIlmLocator } from '../../../../../services/use_ilm_locator'; import { allowAutoCreateRadioIds } from '../../../../../../../common/constants'; +import { getIndexModeLabel } from '../../../../../lib/index_mode_labels'; interface Props { templateDetails: TemplateDeserialized; @@ -57,6 +58,7 @@ export const TabSummary: React.FunctionComponent = ({ templateDetails }) _meta, _kbnMeta: { isLegacy, hasDatastream }, allowAutoCreate, + template, } = templateDetails; const numIndexPatterns = indexPatterns.length; @@ -221,6 +223,17 @@ export const TabSummary: React.FunctionComponent = ({ templateDetails }) )} + {/* Index mode */} + + + + + {getIndexModeLabel(template?.settings?.index?.mode)} + + {/* Allow auto create */} {isLegacy !== true && allowAutoCreate !== allowAutoCreateRadioIds.NO_OVERWRITE_RADIO_OPTION && ( diff --git a/x-pack/plugins/index_management/server/lib/data_stream_serialization.ts b/x-pack/plugins/index_management/server/lib/data_stream_serialization.ts index 2e493ca02aa79..31c0baa6c6b8c 100644 --- a/x-pack/plugins/index_management/server/lib/data_stream_serialization.ts +++ b/x-pack/plugins/index_management/server/lib/data_stream_serialization.ts @@ -6,6 +6,7 @@ */ import { ByteSizeValue } from '@kbn/config-schema'; +import { IndexMode } from '../../common/types/data_streams'; import type { DataStream, EnhancedDataStreamFromEs, Health } from '../../common'; export function deserializeDataStream(dataStreamFromEs: EnhancedDataStreamFromEs): DataStream { @@ -28,6 +29,7 @@ export function deserializeDataStream(dataStreamFromEs: EnhancedDataStreamFromEs lifecycle, global_max_retention: globalMaxRetention, next_generation_managed_by: nextGenerationManagedBy, + index_mode: indexMode, } = dataStreamFromEs; const meteringStorageSize = meteringStorageSizeBytes !== undefined @@ -73,6 +75,7 @@ export function deserializeDataStream(dataStreamFromEs: EnhancedDataStreamFromEs globalMaxRetention, }, nextGenerationManagedBy, + indexMode: (indexMode ?? 'standard') as IndexMode, }; } diff --git a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts index 8b62c2b3a25cb..cd47b8cc9e0bb 100644 --- a/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts +++ b/x-pack/plugins/index_management/server/routes/api/data_streams/register_get_route.ts @@ -11,6 +11,7 @@ import { IScopedClusterClient } from '@kbn/core/server'; import { IndicesDataStream, IndicesDataStreamsStatsDataStreamsStatsItem, + IndicesGetIndexTemplateIndexTemplateItem, SecurityHasPrivilegesResponse, } from '@elastic/elasticsearch/lib/api/types'; import type { MeteringStats } from '../../../lib/types'; @@ -31,12 +32,14 @@ const enhanceDataStreams = ({ meteringStats, dataStreamsPrivileges, globalMaxRetention, + indexTemplates, }: { dataStreams: IndicesDataStream[]; dataStreamsStats?: IndicesDataStreamsStatsDataStreamsStatsItem[]; meteringStats?: MeteringStats[]; dataStreamsPrivileges?: SecurityHasPrivilegesResponse; globalMaxRetention?: string; + indexTemplates?: IndicesGetIndexTemplateIndexTemplateItem[]; }): EnhancedDataStreamFromEs[] => { return dataStreams.map((dataStream) => { const enhancedDataStream: EnhancedDataStreamFromEs = { @@ -71,6 +74,16 @@ const enhanceDataStreams = ({ } } + if (indexTemplates) { + const indexTemplate = indexTemplates.find( + (template) => template.name === dataStream.template + ); + if (indexTemplate) { + enhancedDataStream.index_mode = + indexTemplate.index_template?.template?.settings?.index?.mode; + } + } + return enhancedDataStream; }); }; @@ -152,11 +165,15 @@ export function registerGetAllRoute({ router, lib: { handleEsError }, config }: ); } + const { index_templates: indexTemplates } = + await client.asCurrentUser.indices.getIndexTemplate(); + const enhancedDataStreams = enhanceDataStreams({ dataStreams, dataStreamsStats, meteringStats, dataStreamsPrivileges, + indexTemplates, }); return response.ok({ body: deserializeDataStreamList(enhancedDataStreams) }); @@ -199,17 +216,30 @@ export function registerGetOneRoute({ router, lib: { handleEsError }, config }: if (dataStreams[0]) { let dataStreamsPrivileges; + let indexTemplates; if (config.isSecurityEnabled()) { dataStreamsPrivileges = await getDataStreamsPrivileges(client, [dataStreams[0].name]); } + if (dataStreams[0].template) { + const { index_templates: templates } = + await client.asCurrentUser.indices.getIndexTemplate({ + name: dataStreams[0].template, + }); + + if (templates) { + indexTemplates = templates; + } + } + const enhancedDataStreams = enhanceDataStreams({ dataStreams, dataStreamsStats, meteringStats, dataStreamsPrivileges, globalMaxRetention, + indexTemplates, }); const body = deserializeDataStream(enhancedDataStreams[0]); return response.ok({ body }); diff --git a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/hooks/use_get_data_stream_statuses.ts b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/hooks/use_get_data_stream_statuses.ts index f3b3136200bd7..00d301e9eb706 100644 --- a/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/hooks/use_get_data_stream_statuses.ts +++ b/x-pack/plugins/observability_solution/synthetics/public/apps/synthetics/components/settings/hooks/use_get_data_stream_statuses.ts @@ -94,6 +94,7 @@ function toMissingDataStream({ privileges: { delete_index: true, manage_data_stream_lifecycle: true }, hidden: false, nextGenerationManagedBy: 'Data stream lifecycle', + indexMode: 'standard', }; } diff --git a/x-pack/test/api_integration/apis/management/index_management/data_streams.ts b/x-pack/test/api_integration/apis/management/index_management/data_streams.ts index 791e23149aff1..2976d4eac03b4 100644 --- a/x-pack/test/api_integration/apis/management/index_management/data_streams.ts +++ b/x-pack/test/api_integration/apis/management/index_management/data_streams.ts @@ -73,6 +73,7 @@ export default function ({ getService }: FtrProviderContext) { health: 'yellow', indexTemplateName: testDataStreamName, hidden: false, + indexMode: 'standard', }); }); @@ -120,6 +121,7 @@ export default function ({ getService }: FtrProviderContext) { lifecycle: { enabled: true, }, + indexMode: 'standard', }); }); @@ -158,8 +160,25 @@ export default function ({ getService }: FtrProviderContext) { lifecycle: { enabled: true, }, + indexMode: 'standard', }); }); + + it('correctly returns index mode property', async () => { + const logsdbDataStreamName = 'logsdb-test-data-stream'; + const indexMode = 'logsdb'; + + await createDataStream(logsdbDataStreamName, indexMode); + + const { body: dataStream } = await supertest + .get(`${API_BASE_PATH}/data_streams/${logsdbDataStreamName}`) + .set('kbn-xsrf', 'xxx') + .expect(200); + + expect(dataStream.indexMode).to.eql(indexMode); + + await deleteDataStream(logsdbDataStreamName); + }); }); describe('Update', () => { diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/datastreams.helpers.ts b/x-pack/test/api_integration/apis/management/index_management/lib/datastreams.helpers.ts index 65e2d733dd696..944c679c3205f 100644 --- a/x-pack/test/api_integration/apis/management/index_management/lib/datastreams.helpers.ts +++ b/x-pack/test/api_integration/apis/management/index_management/lib/datastreams.helpers.ts @@ -11,7 +11,7 @@ import { FtrProviderContext } from '../../../../ftr_provider_context'; export function datastreamsHelpers(getService: FtrProviderContext['getService']) { const es = getService('es'); - const createDataStream = async (name: string) => { + const createDataStream = async (name: string, indexMode?: string) => { // A data stream requires an index template before it can be created. await es.indices.putIndexTemplate({ name, @@ -26,6 +26,11 @@ export function datastreamsHelpers(getService: FtrProviderContext['getService']) }, }, }, + settings: { + index: { + mode: indexMode, + }, + }, lifecycle: { // @ts-expect-error @elastic/elasticsearch enabled prop is not typed yet enabled: true, diff --git a/x-pack/test/functional/apps/index_management/data_streams_tab/data_streams_tab.ts b/x-pack/test/functional/apps/index_management/data_streams_tab/data_streams_tab.ts index d680778adc523..97ceeefbee9bd 100644 --- a/x-pack/test/functional/apps/index_management/data_streams_tab/data_streams_tab.ts +++ b/x-pack/test/functional/apps/index_management/data_streams_tab/data_streams_tab.ts @@ -88,6 +88,47 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.click('closeDetailsButton'); }); + describe('shows the correct index mode in the details flyout', function () { + it('standard index mode', async () => { + // Open details flyout of existing data stream - it has standard index mode + await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME); + // Check that index mode detail exists and its label is "Standard" + expect(await testSubjects.exists('indexModeDetail')).to.be(true); + expect(await testSubjects.getVisibleText('indexModeDetail')).to.be('Standard'); + // Close flyout + await testSubjects.click('closeDetailsButton'); + }); + + it('logsdb index mode', async () => { + // Create an index template with a logsdb index mode + await es.indices.putIndexTemplate({ + name: `logsdb_index_template`, + index_patterns: ['test-logsdb'], + data_stream: {}, + template: { + settings: { mode: 'logsdb' }, + }, + }); + // Create a data stream matching the index pattern of the index template above + await es.indices.createDataStream({ + name: 'test-logsdb', + }); + await browser.refresh(); + // Open details flyout of data stream + await pageObjects.indexManagement.clickDataStreamNameLink('test-logsdb'); + // Check that index mode detail exists and its label is "LogsDB" + expect(await testSubjects.exists('indexModeDetail')).to.be(true); + expect(await testSubjects.getVisibleText('indexModeDetail')).to.be('LogsDB'); + // Close flyout + await testSubjects.click('closeDetailsButton'); + // Delete data stream and index template + await es.indices.deleteDataStream({ name: 'test-logsdb' }); + await es.indices.deleteIndexTemplate({ + name: `logsdb_index_template`, + }); + }); + }); + it('allows to update data retention', async () => { // Open details flyout await pageObjects.indexManagement.clickDataStreamNameLink(TEST_DS_NAME); diff --git a/x-pack/test/functional/apps/index_management/index_template_wizard.ts b/x-pack/test/functional/apps/index_management/index_template_wizard.ts index 5b49286f6182b..cf6f1bf6a44a1 100644 --- a/x-pack/test/functional/apps/index_management/index_template_wizard.ts +++ b/x-pack/test/functional/apps/index_management/index_template_wizard.ts @@ -98,6 +98,10 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const summaryTabContent = await testSubjects.exists('summaryTabContent'); expect(summaryTabContent).to.be(true); + // Verify that index mode is set to "Standard" + expect(await testSubjects.exists('indexModeTitle')).to.be(true); + expect(await testSubjects.getVisibleText('indexModeValue')).to.be('Standard'); + // Click Create template await pageObjects.indexManagement.clickNextButton(); }); diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/datastream.ts b/x-pack/test/reporting_api_integration/reporting_and_security/datastream.ts index f116110db78f1..0f2bbeb314dfa 100644 --- a/x-pack/test/reporting_api_integration/reporting_and_security/datastream.ts +++ b/x-pack/test/reporting_api_integration/reporting_and_security/datastream.ts @@ -61,6 +61,7 @@ export default function ({ getService }: FtrProviderContext) { nextGenerationManagedBy: 'Index Lifecycle Management', storageSize: expect.any(String), storageSizeBytes: expect.any(Number), + indexMode: 'standard', }); }); }); diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts index de3a92587d6b9..12151f1b169db 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/datastreams.ts @@ -80,6 +80,7 @@ export default function ({ getService }: FtrProviderContext) { health: 'green', indexTemplateName: testDataStreamName, hidden: false, + indexMode: 'standard', }); }); @@ -121,6 +122,7 @@ export default function ({ getService }: FtrProviderContext) { meteringDocsCount: 0, meteringStorageSize: '0b', meteringStorageSizeBytes: 0, + indexMode: 'standard', }); }); });