Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Index templates] Keep configuration of data stream when editing #87666

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ describe('<TemplateEdit />', () => {
const templateToEdit = fixtures.getTemplate({
name: 'index_template_without_mappings',
indexPatterns: ['indexPattern1'],
dataStream: {
hidden: true,
anyUnknownKey: 'should_be_kept',
},
});

beforeAll(() => {
Expand All @@ -85,7 +89,7 @@ describe('<TemplateEdit />', () => {
testBed.component.update();
});

it('allows you to add mappings', async () => {
test('allows you to add mappings', async () => {
const { actions, find } = testBed;
// Logistics
await actions.completeStepOne();
Expand All @@ -98,6 +102,47 @@ describe('<TemplateEdit />', () => {

expect(find('fieldsListItem').length).toBe(1);
});

test('should keep data stream configuration', async () => {
const { actions } = testBed;
// Logistics
await actions.completeStepOne({
name: 'test',
indexPatterns: ['myPattern*'],
version: 1,
});
// Component templates
await actions.completeStepTwo();
// Index settings
await actions.completeStepThree();
// Mappings
await actions.completeStepFour();
// Aliases
await actions.completeStepFive();

await act(async () => {
actions.clickNextButton();
});

const latestRequest = server.requests[server.requests.length - 1];

const expected = {
name: 'test',
indexPatterns: ['myPattern*'],
dataStream: {
hidden: true,
anyUnknownKey: 'should_be_kept',
},
version: 1,
_kbnMeta: {
type: 'default',
isLegacy: false,
hasDatastream: true,
},
};

expect(JSON.parse(JSON.parse(latestRequest.requestBody).body)).toEqual(expected);
});
});

describe('with mappings', () => {
Expand Down
6 changes: 5 additions & 1 deletion x-pack/plugins/index_management/common/types/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ export interface TemplateDeserialized {
name: string;
};
_meta?: { [key: string]: any }; // Composable template only
dataStream?: {}; // Composable template only
// Composable template only
dataStream?: {
hidden?: boolean;
[key: string]: any;
};
_kbnMeta: {
type: TemplateType;
hasDatastream: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function getFieldsMeta(esDocsBase: string) {
),
testSubject: 'indexPatternsField',
},
dataStream: {
createDataStream: {
title: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.dataStreamTitle', {
defaultMessage: 'Data stream',
}),
Expand Down Expand Up @@ -119,6 +119,7 @@ interface LogisticsForm {

interface LogisticsFormInternal extends LogisticsForm {
addMeta: boolean;
doCreateDataStream: boolean;
}

interface Props {
Expand All @@ -132,12 +133,16 @@ function formDeserializer(formData: LogisticsForm): LogisticsFormInternal {
return {
...formData,
addMeta: Boolean(formData._meta && Object.keys(formData._meta).length),
doCreateDataStream: Boolean(formData.dataStream),
};
}

function formSerializer(formData: LogisticsFormInternal): LogisticsForm {
const { addMeta, ...rest } = formData;
return rest;
function getformSerializer(initialTemplateData: LogisticsForm = {}) {
return (formData: LogisticsFormInternal): LogisticsForm => {
const { addMeta, doCreateDataStream, ...rest } = formData;
const dataStream = doCreateDataStream ? initialTemplateData.dataStream ?? {} : undefined;
return { ...rest, dataStream };
};
}

export const StepLogistics: React.FunctionComponent<Props> = React.memo(
Expand All @@ -146,7 +151,7 @@ export const StepLogistics: React.FunctionComponent<Props> = React.memo(
schema: schemas.logistics,
defaultValue,
options: { stripEmptyFields: false },
serializer: formSerializer,
serializer: getformSerializer(defaultValue),
deserializer: formDeserializer,
});
const {
Expand Down Expand Up @@ -178,7 +183,7 @@ export const StepLogistics: React.FunctionComponent<Props> = React.memo(
});
}, [onChange, isFormValid, validate, getFormData]);

const { name, indexPatterns, dataStream, order, priority, version } = getFieldsMeta(
const { name, indexPatterns, createDataStream, order, priority, version } = getFieldsMeta(
documentationService.getEsDocsBase()
);

Expand Down Expand Up @@ -245,10 +250,10 @@ export const StepLogistics: React.FunctionComponent<Props> = React.memo(

{/* Create data stream */}
{isLegacy !== true && (
<FormRow title={dataStream.title} description={dataStream.description}>
<FormRow title={createDataStream.title} description={createDataStream.description}>
<UseField
path="dataStream"
componentProps={{ 'data-test-subj': dataStream.testSubject }}
path="doCreateDataStream"
componentProps={{ 'data-test-subj': createDataStream.testSubject }}
/>
</FormRow>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,31 +129,12 @@ export const schemas: Record<string, FormSchema> = {
},
],
},
dataStream: {
doCreateDataStream: {
type: FIELD_TYPES.TOGGLE,
label: i18n.translate('xpack.idxMgmt.templateForm.stepLogistics.datastreamLabel', {
defaultMessage: 'Create data stream',
}),
defaultValue: false,
serializer: (value) => {
if (value === true) {
// For now, ES expects an empty object when defining a data stream
// https://github.com/elastic/elasticsearch/pull/59317
return {};
}
},
deserializer: (value) => {
if (typeof value === 'boolean') {
return value;
}

/**
* For now, it is enough to have a "data_stream" declared on the index template
* to assume that the template creates a data stream. In the future, this condition
* might change
*/
return value !== undefined;
},
},
order: {
type: FIELD_TYPES.NUMBER,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@ export const templateSchema = schema.object({
})
),
composedOf: schema.maybe(schema.arrayOf(schema.string())),
dataStream: schema.maybe(schema.object({}, { unknowns: 'allow' })),
dataStream: schema.maybe(
schema.object(
{
hidden: schema.maybe(schema.boolean()),
},
{ unknowns: 'allow' }
)
),
_meta: schema.maybe(schema.object({}, { unknowns: 'allow' })),
ilmPolicy: schema.maybe(
schema.object({
Expand Down
4 changes: 3 additions & 1 deletion x-pack/plugins/index_management/test/fixtures/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export const getTemplate = ({
order = getRandomNumber(),
indexPatterns = [],
template: { settings, aliases, mappings } = {},
dataStream,
hasDatastream = false,
isLegacy = false,
type = 'default',
Expand All @@ -73,12 +74,13 @@ export const getTemplate = ({
mappings,
settings,
},
dataStream,
hasSettings: objHasProperties(settings),
hasMappings: objHasProperties(mappings),
hasAliases: objHasProperties(aliases),
_kbnMeta: {
type,
hasDatastream,
hasDatastream: dataStream !== undefined ? true : hasDatastream,
isLegacy,
},
};
Expand Down