Skip to content

Commit

Permalink
[Index Management] Add index mode field in index template form (elast…
Browse files Browse the repository at this point in the history
…ic#199521)

Closes elastic#198620

## Summary

This PR adds a field for index mode setting in the Logistics step in
Index Template form.



https://github.com/user-attachments/assets/ee38bdec-66ff-468d-a55e-abf5354c3da2


**How to test:**
1. Go to Index Management -> Index Templates and start creating an index
template
2. Verify that the index mode is only enabled if the data stream toggle
is on.
3. Verify that typing the `logs-*-*` index pattern sets the index mode
to "LogsDB":

<img width="1401" alt="Screenshot 2024-11-13 at 13 00 10"
src="https://github.com/user-attachments/assets/d1825d08-5039-4c43-80a8-653233e0b677">



4. Go to the Settings step and verify that the index mode callout is
displayed correctly.
5. Go to Review step and verify that Index mode is displayed correctly
in both the summary and the preview request.
6. Save the template and verify that the template details tab correctly
displays the index mode.

<img width="1565" alt="Screenshot 2024-11-13 at 17 22 54"
src="https://github.com/user-attachments/assets/2055501b-32c9-463c-b61d-541b9687b459">

<img width="1565" alt="Screenshot 2024-11-13 at 17 22 31"
src="https://github.com/user-attachments/assets/21c9cf9e-5858-4403-9106-57ed8ccf3639">





### Checklist

Delete any items that are not applicable to this PR.

- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
  • Loading branch information
ElenaStoeva authored and CAWilson94 committed Nov 18, 2024
1 parent 76e7565 commit 0d0d0a9
Show file tree
Hide file tree
Showing 26 changed files with 403 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ jest.mock('@elastic/eui', () => {
}}
/>
),
EuiSuperSelect: (props: any) => (
<input
data-test-subj={props['data-test-subj'] || 'mockSuperSelect'}
value={props.valueOfSelected}
onChange={(e) => {
props.onChange(e.target.value);
}}
/>
),
};
});

Expand Down Expand Up @@ -301,6 +310,15 @@ describe('<TemplateCreate />', () => {
expect(find('stepTitle').text()).toEqual('Index settings (optional)');
});

it('should display a warning callout displaying the selected index mode', async () => {
const { exists, find } = testBed;

expect(exists('indexModeCallout')).toBe(true);
expect(find('indexModeCallout').text()).toContain(
'The index.mode setting has been set to Standard within template Logistics.'
);
});

it('should not allow invalid json', async () => {
const { form, actions } = testBed;

Expand Down Expand Up @@ -426,6 +444,53 @@ describe('<TemplateCreate />', () => {
});
});

describe('logistics (step 1)', () => {
beforeEach(async () => {
await act(async () => {
testBed = await setup(httpSetup);
});
testBed.component.update();
});

it('setting index pattern to logs-*-* should set the index mode to logsdb', async () => {
const { component, actions } = testBed;
// Logistics
await actions.completeStepOne({ name: 'my_logs_template', indexPatterns: ['logs-*-*'] });
// Component templates
await actions.completeStepTwo();
// Index settings
await actions.completeStepThree('{}');
// Mappings
await actions.completeStepFour();
// Aliases
await actions.completeStepFive();

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

expect(httpSetup.post).toHaveBeenLastCalledWith(
`${API_BASE_PATH}/index_templates`,
expect.objectContaining({
body: JSON.stringify({
name: 'my_logs_template',
indexPatterns: ['logs-*-*'],
allowAutoCreate: 'NO_OVERWRITE',
indexMode: 'logsdb',
dataStream: {},
_kbnMeta: {
type: 'default',
hasDatastream: false,
isLegacy: false,
},
template: {},
}),
})
);
});
});

describe('review (step 6)', () => {
beforeEach(async () => {
await act(async () => {
Expand Down Expand Up @@ -529,6 +594,7 @@ describe('<TemplateCreate />', () => {
name: TEMPLATE_NAME,
indexPatterns: DEFAULT_INDEX_PATTERNS,
allowAutoCreate: 'TRUE',
indexMode: 'time_series',
});
// Component templates
await actions.completeStepTwo('test_component_template_1');
Expand Down Expand Up @@ -557,6 +623,7 @@ describe('<TemplateCreate />', () => {
name: TEMPLATE_NAME,
indexPatterns: DEFAULT_INDEX_PATTERNS,
allowAutoCreate: 'TRUE',
indexMode: 'time_series',
dataStream: {},
_kbnMeta: {
type: 'default',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ describe('<TemplateEdit />', () => {
indexPatterns: ['myPattern*'],
version: 1,
allowAutoCreate: 'NO_OVERWRITE',
indexMode: 'standard',
dataStream: {
hidden: true,
anyUnknownKey: 'should_be_kept',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export const formSetup = async (initTestBed: SetupFunc<TestSubjects>) => {
enableDataStream,
lifecycle,
allowAutoCreate,
indexMode,
}: Partial<TemplateDeserialized> & { enableDataStream?: boolean } = {}) => {
const { component, form, find } = testBed;

Expand Down Expand Up @@ -204,6 +205,10 @@ export const formSetup = async (initTestBed: SetupFunc<TestSubjects>) => {
radioOption.simulate('change', { target: { checked: true } });
component.update();
}

if (indexMode) {
form.setSelectValue('indexModeField', indexMode);
}
});
component.update();

Expand Down Expand Up @@ -356,6 +361,7 @@ export type TestSubjects =
| 'mappingsEditorFieldEdit'
| 'mockCodeEditor'
| 'mockComboBox'
| 'mockSuperSelect'
| 'nameField'
| 'nameField.input'
| 'nameParameterInput'
Expand All @@ -364,6 +370,8 @@ export type TestSubjects =
| 'orderField.input'
| 'priorityField.input'
| 'dataStreamField.input'
| 'indexModeField'
| 'indexModeCallout'
| 'dataRetentionToggle.input'
| 'allowAutoCreateField.input'
| 'pageTitle'
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/index_management/common/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { i18n } from '@kbn/i18n';
export { BASE_PATH } from './base_path';
export { API_BASE_PATH, INTERNAL_API_BASE_PATH } from './api_base_path';
export { INVALID_INDEX_PATTERN_CHARS, INVALID_TEMPLATE_NAME_CHARS } from './invalid_characters';
export * from './index_modes';
export * from './index_statuses';

// Since each index can have a max length or 255 characters and the max length of
Expand Down
10 changes: 10 additions & 0 deletions x-pack/plugins/index_management/common/constants/index_modes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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.
*/

export const STANDARD_INDEX_MODE = 'standard';
export const LOGSDB_INDEX_MODE = 'logsdb';
export const TIME_SERIES_MODE = 'time_series';
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
*/

import { deserializeTemplate, serializeTemplate } from './template_serialization';
import { TemplateDeserialized, TemplateSerialized } from '../types';
import { TemplateDeserialized, TemplateSerialized, IndexMode } from '../types';
import { STANDARD_INDEX_MODE, LOGSDB_INDEX_MODE, TIME_SERIES_MODE } from '../constants';

const defaultSerializedTemplate: TemplateSerialized = {
template: {},
Expand All @@ -17,6 +18,7 @@ const defaultSerializedTemplate: TemplateSerialized = {
const defaultDeserializedTemplate: TemplateDeserialized = {
name: 'my_template',
indexPatterns: ['test'],
indexMode: STANDARD_INDEX_MODE,
_kbnMeta: {
type: 'default',
hasDatastream: true,
Expand All @@ -26,12 +28,13 @@ const defaultDeserializedTemplate: TemplateDeserialized = {

const allowAutoCreateRadioOptions = ['NO_OVERWRITE', 'TRUE', 'FALSE'];
const allowAutoCreateSerializedValues = [undefined, true, false];
const indexModeValues = [STANDARD_INDEX_MODE, LOGSDB_INDEX_MODE, TIME_SERIES_MODE, undefined];

describe('Template serialization', () => {
describe('serialization of allow_auto_create parameter', () => {
describe('deserializeTemplate()', () => {
allowAutoCreateSerializedValues.forEach((value, index) => {
test(`correctly deserializes ${value} value`, () => {
test(`correctly deserializes ${value} allow_auto_create value`, () => {
expect(
deserializeTemplate({
...defaultSerializedTemplate,
Expand All @@ -41,11 +44,29 @@ describe('Template serialization', () => {
).toHaveProperty('allowAutoCreate', allowAutoCreateRadioOptions[index]);
});
});

indexModeValues.forEach((value) => {
test(`correctly deserializes ${value} index mode settings value`, () => {
expect(
deserializeTemplate({
...defaultSerializedTemplate,
name: 'my_template',
template: {
settings: {
index: {
mode: value,
},
},
},
})
).toHaveProperty('indexMode', value ?? STANDARD_INDEX_MODE);
});
});
});

describe('serializeTemplate()', () => {
allowAutoCreateRadioOptions.forEach((option, index) => {
test(`correctly serializes ${option} radio option`, () => {
test(`correctly serializes ${option} allowAutoCreate radio option`, () => {
expect(
serializeTemplate({
...defaultDeserializedTemplate,
Expand All @@ -54,6 +75,18 @@ describe('Template serialization', () => {
).toHaveProperty('allow_auto_create', allowAutoCreateSerializedValues[index]);
});
});

// Only use the first three values (omit undefined)
indexModeValues.slice(0, 3).forEach((value) => {
test(`correctly serializes ${value} indexMode option`, () => {
expect(
serializeTemplate({
...defaultDeserializedTemplate,
indexMode: value as IndexMode,
})
).toHaveProperty('template.settings.index.mode', value);
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ import {
TemplateSerialized,
TemplateListItem,
TemplateType,
IndexMode,
} from '../types';
import { deserializeESLifecycle } from './data_stream_utils';
import { allowAutoCreateRadioValues, allowAutoCreateRadioIds } from '../constants';
import {
allowAutoCreateRadioValues,
allowAutoCreateRadioIds,
STANDARD_INDEX_MODE,
LOGSDB_INDEX_MODE,
} from '../constants';

const hasEntries = (data: object = {}) => Object.entries(data).length > 0;

Expand All @@ -26,6 +32,7 @@ export function serializeTemplate(templateDeserialized: TemplateDeserialized): T
composedOf,
ignoreMissingComponentTemplates,
dataStream,
indexMode,
_meta,
allowAutoCreate,
deprecated,
Expand All @@ -34,7 +41,16 @@ export function serializeTemplate(templateDeserialized: TemplateDeserialized): T
return {
version,
priority,
template,
template: {
...template,
settings: {
...template?.settings,
index: {
...template?.settings?.index,
mode: indexMode,
},
},
},
index_patterns: indexPatterns,
data_stream: dataStream,
composed_of: composedOf,
Expand Down Expand Up @@ -75,13 +91,19 @@ export function deserializeTemplate(

const ilmPolicyName = settings?.index?.lifecycle?.name;

const indexMode = (settings?.index?.mode ??
(indexPatterns.some((pattern) => pattern === 'logs-*-*')
? LOGSDB_INDEX_MODE
: STANDARD_INDEX_MODE)) as IndexMode;

const deserializedTemplate: TemplateDeserialized = {
name,
version,
priority,
...(template.lifecycle ? { lifecycle: deserializeESLifecycle(template.lifecycle) } : {}),
indexPatterns: indexPatterns.sort(),
template,
indexMode,
ilmPolicy: ilmPolicyName ? { name: ilmPolicyName } : undefined,
composedOf: composedOf ?? [],
ignoreMissingComponentTemplates: ignoreMissingComponentTemplates ?? [],
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/index_management/common/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type {
DataStream,
DataStreamIndex,
DataRetention,
IndexMode,
} from './data_streams';

export * from './component_templates';
Expand Down
3 changes: 2 additions & 1 deletion x-pack/plugins/index_management/common/types/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import { DataRetention, DataStream } from './data_streams';
import { DataRetention, DataStream, IndexMode } from './data_streams';
import { IndexSettings } from './indices';
import { Aliases } from './aliases';
import { Mappings } from './mappings';
Expand Down Expand Up @@ -51,6 +51,7 @@ export interface TemplateDeserialized {
priority?: number; // Composable template only
allowAutoCreate: string;
order?: number; // Legacy template only
indexMode: IndexMode;
ilmPolicy?: {
name: string;
};
Expand Down
Loading

0 comments on commit 0d0d0a9

Please sign in to comment.