Skip to content

Commit a4bf5e4

Browse files
committed
Add data stream field in logistics step
1 parent 913cfeb commit a4bf5e4

File tree

5 files changed

+140
-59
lines changed

5 files changed

+140
-59
lines changed

x-pack/plugins/index_management/common/lib/template_serialization.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,22 @@ import {
1313
const hasEntries = (data: object = {}) => Object.entries(data).length > 0;
1414

1515
export function serializeTemplate(templateDeserialized: TemplateDeserialized): TemplateSerialized {
16-
const { version, priority, indexPatterns, template, composedOf, _meta } = templateDeserialized;
16+
const {
17+
version,
18+
priority,
19+
indexPatterns,
20+
template,
21+
composedOf,
22+
dataStream,
23+
_meta,
24+
} = templateDeserialized;
1725

1826
return {
1927
version,
2028
priority,
2129
template,
2230
index_patterns: indexPatterns,
31+
data_stream: dataStream,
2332
composed_of: composedOf,
2433
_meta,
2534
};

x-pack/plugins/index_management/common/types/templates.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@ export interface TemplateDeserialized {
3838
aliases?: Aliases;
3939
mappings?: Mappings;
4040
};
41-
composedOf?: string[]; // Used on composable index template
41+
composedOf?: string[]; // Composable template only
4242
version?: number;
43-
priority?: number;
44-
order?: number; // Used on legacy index template
43+
priority?: number; // Composable template only
44+
order?: number; // Legacy template only
4545
ilmPolicy?: {
4646
name: string;
4747
};
48-
_meta?: { [key: string]: any };
49-
dataStream?: { timestamp_field: string };
48+
_meta?: { [key: string]: any }; // Composable template only
49+
dataStream?: { timestamp_field: string }; // Composable template only
5050
_kbnMeta: {
5151
isManaged: boolean;
5252
isCloudManaged: boolean;

x-pack/plugins/index_management/public/application/components/template_form/steps/step_logistics.tsx

Lines changed: 97 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,14 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66
import React, { useEffect } from 'react';
7-
import { EuiFlexGroup, EuiFlexItem, EuiTitle, EuiButtonEmpty, EuiSpacer } from '@elastic/eui';
7+
import {
8+
EuiFlexGroup,
9+
EuiFlexItem,
10+
EuiTitle,
11+
EuiButtonEmpty,
12+
EuiSpacer,
13+
EuiLink,
14+
} from '@elastic/eui';
815
import { FormattedMessage } from '@kbn/i18n/react';
916
import { i18n } from '@kbn/i18n';
1017

@@ -25,56 +32,82 @@ import { schemas, nameConfig, nameConfigWithoutValidations } from '../template_f
2532
const UseField = getUseField({ component: Field });
2633
const FormRow = getFormRow({ titleTag: 'h3' });
2734

28-
const fieldsMeta = {
29-
name: {
30-
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.nameTitle', {
31-
defaultMessage: 'Name',
32-
}),
33-
description: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.nameDescription', {
34-
defaultMessage: 'A unique identifier for this template.',
35-
}),
36-
testSubject: 'nameField',
37-
},
38-
indexPatterns: {
39-
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.indexPatternsTitle', {
40-
defaultMessage: 'Index patterns',
41-
}),
42-
description: i18n.translate(
43-
'xpack.idxMgmt.templateForm.stepLogistics.indexPatternsDescription',
44-
{
45-
defaultMessage: 'The index patterns to apply to the template.',
46-
}
47-
),
48-
testSubject: 'indexPatternsField',
49-
},
50-
order: {
51-
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.orderTitle', {
52-
defaultMessage: 'Merge order',
53-
}),
54-
description: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.orderDescription', {
55-
defaultMessage: 'The merge order when multiple templates match an index.',
56-
}),
57-
testSubject: 'orderField',
58-
},
59-
priority: {
60-
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.priorityTitle', {
61-
defaultMessage: 'Priority',
62-
}),
63-
description: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.priorityDescription', {
64-
defaultMessage: 'Only the highest priority template will be applied.',
65-
}),
66-
testSubject: 'priorityField',
67-
},
68-
version: {
69-
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.versionTitle', {
70-
defaultMessage: 'Version',
71-
}),
72-
description: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.versionDescription', {
73-
defaultMessage: 'A number that identifies the template to external management systems.',
74-
}),
75-
testSubject: 'versionField',
76-
},
77-
};
35+
function getFieldsMeta(esDocsBase: string) {
36+
return {
37+
name: {
38+
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.nameTitle', {
39+
defaultMessage: 'Name',
40+
}),
41+
description: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.nameDescription', {
42+
defaultMessage: 'A unique identifier for this template.',
43+
}),
44+
testSubject: 'nameField',
45+
},
46+
indexPatterns: {
47+
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.indexPatternsTitle', {
48+
defaultMessage: 'Index patterns',
49+
}),
50+
description: i18n.translate(
51+
'xpack.idxMgmt.templateForm.stepLogistics.indexPatternsDescription',
52+
{
53+
defaultMessage: 'The index patterns to apply to the template.',
54+
}
55+
),
56+
testSubject: 'indexPatternsField',
57+
},
58+
dataStream: {
59+
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.dataStreamTitle', {
60+
defaultMessage: 'Data stream',
61+
}),
62+
description: (
63+
<FormattedMessage
64+
id="xpack.idxMgmt.templateForm.stepLogistics.dataStreamDescription"
65+
defaultMessage="Wheter indices that match the index patterns should automatically create a data stream. {docsLink}"
66+
values={{
67+
docsLink: (
68+
<>
69+
<br />
70+
<EuiLink href={`${esDocsBase}/data-streams.html`} target="_blank">
71+
{i18n.translate('xpack.idxMgmt.mappingsEditor.dynamicMappingDocumentionLink', {
72+
defaultMessage: 'Learn more about data streams.',
73+
})}
74+
</EuiLink>
75+
</>
76+
),
77+
}}
78+
/>
79+
),
80+
testSubject: 'dataStreamField',
81+
},
82+
order: {
83+
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.orderTitle', {
84+
defaultMessage: 'Merge order',
85+
}),
86+
description: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.orderDescription', {
87+
defaultMessage: 'The merge order when multiple templates match an index.',
88+
}),
89+
testSubject: 'orderField',
90+
},
91+
priority: {
92+
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.priorityTitle', {
93+
defaultMessage: 'Priority',
94+
}),
95+
description: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.priorityDescription', {
96+
defaultMessage: 'Only the highest priority template will be applied.',
97+
}),
98+
testSubject: 'priorityField',
99+
},
100+
version: {
101+
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.versionTitle', {
102+
defaultMessage: 'Version',
103+
}),
104+
description: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.versionDescription', {
105+
defaultMessage: 'A number that identifies the template to external management systems.',
106+
}),
107+
testSubject: 'versionField',
108+
},
109+
};
110+
}
78111

79112
interface LogisticsForm {
80113
[key: string]: any;
@@ -144,7 +177,9 @@ export const StepLogistics: React.FunctionComponent<Props> = React.memo(
144177
return subscription.unsubscribe;
145178
}, [onChange]); // eslint-disable-line react-hooks/exhaustive-deps
146179

147-
const { name, indexPatterns, order, priority, version } = fieldsMeta;
180+
const { name, indexPatterns, dataStream, order, priority, version } = getFieldsMeta(
181+
documentationService.getEsDocsBase()
182+
);
148183

149184
return (
150185
<>
@@ -207,6 +242,16 @@ export const StepLogistics: React.FunctionComponent<Props> = React.memo(
207242
/>
208243
</FormRow>
209244

245+
{/* Create data stream */}
246+
{isLegacy !== true && (
247+
<FormRow title={dataStream.title} description={dataStream.description}>
248+
<UseField
249+
path="dataStream"
250+
componentProps={{ 'data-test-subj': dataStream.testSubject }}
251+
/>
252+
</FormRow>
253+
)}
254+
210255
{/* Order */}
211256
{isLegacy && (
212257
<FormRow title={order.title} description={order.description}>

x-pack/plugins/index_management/public/application/components/template_form/template_form_schemas.tsx

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,32 @@ export const schemas: Record<string, FormSchema> = {
128128
},
129129
],
130130
},
131+
dataStream: {
132+
type: FIELD_TYPES.TOGGLE,
133+
label: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.datastreamLabel', {
134+
defaultMessage: 'Create data stream',
135+
}),
136+
defaultValue: false,
137+
serializer: (value) => {
138+
if (value === true) {
139+
return {
140+
timestamp_field: '@timestamp',
141+
};
142+
}
143+
},
144+
deserializer: (value) => {
145+
if (typeof value === 'boolean') {
146+
return value;
147+
}
148+
149+
/**
150+
* For now, it is enough to have a "data_stream" declared on the index template
151+
* to assume that the template creates a data stream. In the future, this condition
152+
* might change
153+
*/
154+
return value !== undefined;
155+
},
156+
},
131157
order: {
132158
type: FIELD_TYPES.NUMBER,
133159
label: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.fieldOrderLabel', {
@@ -193,7 +219,7 @@ export const schemas: Record<string, FormSchema> = {
193219
label: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.addMetadataLabel', {
194220
defaultMessage: 'Add metadata',
195221
}),
196-
} as FieldConfig,
222+
},
197223
},
198224
},
199225
};

x-pack/plugins/index_management/server/routes/api/templates/validate_schemas.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const templateSchema = schema.object({
2020
})
2121
),
2222
composedOf: schema.maybe(schema.arrayOf(schema.string())),
23+
dataStream: schema.maybe(schema.object({}, { unknowns: 'allow' })),
2324
_meta: schema.maybe(schema.object({}, { unknowns: 'allow' })),
2425
ilmPolicy: schema.maybe(
2526
schema.object({

0 commit comments

Comments
 (0)