mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[Index Templates] Fix edit form when there are missing component templates (#187766)
Fixes https://github.com/elastic/kibana/issues/186600 ## Summary This PR fixes the following issues in the Index template edit form: For an index template that is composed of a nonexistent component template and has a `ignore_missing_component_templates` property: 1. when we edit the index template and pass through the "Component template" steps, the nonexistent component template is removed. 2. when we edit the index template and go directly to the "Review" step, the `ignore_missing_templates` field is removed from the request. Therefore, when we try to save the template, it fails with an error as it contains a missing component template and doesn't have a `ignore_missing_templates` property. **How to test:** 1. Start Es and Kibana 2. Create a test index template composed of a nonexistent component template: ``` PUT _index_template/test { "index_patterns": [ "test-*" ], "composed_of": [ "mytesttemplate" ], "ignore_missing_component_templates": [ "mytesttemplate" ] } ``` 3. Go to Index Management -> Index Templates and start editing the created template. 4. Go directly to the Review step and verify that the request includes both the `composed_of` and the `ignore_missing_component_templates` fields as they were initially. Verify that saving the form doesn't result in an error. 5. Start editing the template again and this time go to the Component Template step. Verify that the non-existent step is displayed in the list. Go to the "Review" step and verify that the request contains the correct `composed_of` and `ignore_missing_component_templates` fields. 6. You can also try the above steps with some of the auto-created index templates that are composed of non-existent component templates (e.g. `logs`, `logs-apm.app@template`, `logs-apm.error@template` - they all are composed of `*@custom` component templates which don't exist).
This commit is contained in:
parent
ee7c047653
commit
462ac5c2a4
4 changed files with 121 additions and 3 deletions
|
@ -12,7 +12,13 @@ import * as fixtures from '../../../test/fixtures';
|
|||
import { API_BASE_PATH } from '../../../common/constants';
|
||||
import { setupEnvironment, kibanaVersion } from '../helpers';
|
||||
|
||||
import { TEMPLATE_NAME, SETTINGS, ALIASES, MAPPINGS as DEFAULT_MAPPING } from './constants';
|
||||
import {
|
||||
TEMPLATE_NAME,
|
||||
SETTINGS,
|
||||
ALIASES,
|
||||
MAPPINGS as DEFAULT_MAPPING,
|
||||
INDEX_PATTERNS,
|
||||
} from './constants';
|
||||
import { setup } from './template_edit.helpers';
|
||||
import { TemplateFormTestBed } from './template_form.helpers';
|
||||
|
||||
|
@ -26,6 +32,22 @@ const MAPPING = {
|
|||
},
|
||||
},
|
||||
};
|
||||
const NONEXISTENT_COMPONENT_TEMPLATE = {
|
||||
name: 'component_template@custom',
|
||||
hasMappings: false,
|
||||
hasAliases: false,
|
||||
hasSettings: false,
|
||||
usedBy: [],
|
||||
};
|
||||
|
||||
const EXISTING_COMPONENT_TEMPLATE = {
|
||||
name: 'test_component_template',
|
||||
hasMappings: true,
|
||||
hasAliases: false,
|
||||
hasSettings: false,
|
||||
usedBy: [],
|
||||
isManaged: false,
|
||||
};
|
||||
|
||||
jest.mock('@kbn/code-editor', () => {
|
||||
const original = jest.requireActual('@kbn/code-editor');
|
||||
|
@ -70,6 +92,7 @@ describe('<TemplateEdit />', () => {
|
|||
beforeAll(() => {
|
||||
jest.useFakeTimers({ legacyFakeTimers: true });
|
||||
httpRequestsMockHelpers.setLoadComponentTemplatesResponse([]);
|
||||
httpRequestsMockHelpers.setLoadComponentTemplatesResponse([EXISTING_COMPONENT_TEMPLATE]);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
|
@ -296,6 +319,84 @@ describe('<TemplateEdit />', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when composed of a nonexistent component template', () => {
|
||||
const templateToEdit = fixtures.getTemplate({
|
||||
name: TEMPLATE_NAME,
|
||||
indexPatterns: INDEX_PATTERNS,
|
||||
composedOf: [NONEXISTENT_COMPONENT_TEMPLATE.name],
|
||||
ignoreMissingComponentTemplates: [NONEXISTENT_COMPONENT_TEMPLATE.name],
|
||||
});
|
||||
|
||||
beforeAll(() => {
|
||||
httpRequestsMockHelpers.setLoadTemplateResponse('my_template', templateToEdit);
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await act(async () => {
|
||||
testBed = await setup(httpSetup);
|
||||
});
|
||||
testBed.component.update();
|
||||
});
|
||||
|
||||
it('the nonexistent component template should be selected in the Component templates selector', async () => {
|
||||
const { actions, exists } = testBed;
|
||||
|
||||
// Complete step 1: Logistics
|
||||
await actions.completeStepOne();
|
||||
jest.advanceTimersByTime(0); // advance timers to allow the form to validate
|
||||
|
||||
// Should be at the Component templates step
|
||||
expect(exists('stepComponents')).toBe(true);
|
||||
|
||||
const {
|
||||
actions: {
|
||||
componentTemplates: { getComponentTemplatesSelected },
|
||||
},
|
||||
} = testBed;
|
||||
|
||||
expect(exists('componentTemplatesSelection.emptyPrompt')).toBe(false);
|
||||
expect(getComponentTemplatesSelected()).toEqual([NONEXISTENT_COMPONENT_TEMPLATE.name]);
|
||||
});
|
||||
|
||||
it('the composedOf and ignoreMissingComponentTemplates fields should be included in the final payload', async () => {
|
||||
const { component, actions, find } = testBed;
|
||||
|
||||
// Complete step 1: Logistics
|
||||
await actions.completeStepOne();
|
||||
// Complete step 2: Component templates
|
||||
await actions.completeStepTwo();
|
||||
// Complete step 3: Index settings
|
||||
await actions.completeStepThree();
|
||||
// Complete step 4: Mappings
|
||||
await actions.completeStepFour();
|
||||
// Complete step 5: Aliases
|
||||
await actions.completeStepFive();
|
||||
|
||||
expect(find('stepTitle').text()).toEqual(`Review details for '${TEMPLATE_NAME}'`);
|
||||
|
||||
await act(async () => {
|
||||
actions.clickNextButton();
|
||||
});
|
||||
component.update();
|
||||
|
||||
expect(httpSetup.put).toHaveBeenLastCalledWith(
|
||||
`${API_BASE_PATH}/index_templates/${TEMPLATE_NAME}`,
|
||||
expect.objectContaining({
|
||||
body: JSON.stringify({
|
||||
name: TEMPLATE_NAME,
|
||||
indexPatterns: INDEX_PATTERNS,
|
||||
version: templateToEdit.version,
|
||||
allowAutoCreate: templateToEdit.allowAutoCreate,
|
||||
_kbnMeta: templateToEdit._kbnMeta,
|
||||
composedOf: [NONEXISTENT_COMPONENT_TEMPLATE.name],
|
||||
template: {},
|
||||
ignoreMissingComponentTemplates: [NONEXISTENT_COMPONENT_TEMPLATE.name],
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
if (kibanaVersion.major < 8) {
|
||||
describe('legacy index templates', () => {
|
||||
const legacyTemplateToEdit = fixtures.getTemplate({
|
||||
|
|
|
@ -87,8 +87,20 @@ export const ComponentTemplatesSelector = ({
|
|||
.map((name) => components.find((comp) => comp.name === name))
|
||||
.filter(Boolean) as ComponentTemplateListItem[];
|
||||
|
||||
setComponentsSelected(nextComponentsSelected);
|
||||
onChange(nextComponentsSelected.map(({ name }) => name));
|
||||
// Add the non-existing templates from the "defaultValue" prop
|
||||
const missingDefaultComponents: ComponentTemplateListItem[] = defaultValue
|
||||
.filter((name) => !components.find((comp) => comp.name === name))
|
||||
.map((name) => ({
|
||||
name,
|
||||
usedBy: [],
|
||||
hasMappings: false,
|
||||
hasAliases: false,
|
||||
hasSettings: false,
|
||||
isManaged: false,
|
||||
}));
|
||||
|
||||
setComponentsSelected([...nextComponentsSelected, ...missingDefaultComponents]);
|
||||
onChange([...nextComponentsSelected, ...missingDefaultComponents].map(({ name }) => name));
|
||||
isInitialized.current = true;
|
||||
} else {
|
||||
onChange(componentsSelected.map(({ name }) => name));
|
||||
|
|
|
@ -218,6 +218,7 @@ export const TemplateForm = ({
|
|||
? serializeAsESLifecycle(wizardData.logistics.lifecycle)
|
||||
: undefined,
|
||||
},
|
||||
ignoreMissingComponentTemplates: initialTemplate.ignoreMissingComponentTemplates,
|
||||
};
|
||||
|
||||
return cleanupTemplateObject(outputTemplate as TemplateDeserialized);
|
||||
|
|
|
@ -67,6 +67,8 @@ export const getTemplate = ({
|
|||
indexPatterns = [],
|
||||
template: { settings, aliases, mappings } = {},
|
||||
dataStream,
|
||||
composedOf,
|
||||
ignoreMissingComponentTemplates,
|
||||
hasDatastream = false,
|
||||
isLegacy = false,
|
||||
type = 'default',
|
||||
|
@ -98,6 +100,8 @@ export const getTemplate = ({
|
|||
hasDatastream: dataStream !== undefined ? true : hasDatastream,
|
||||
isLegacy,
|
||||
},
|
||||
composedOf,
|
||||
ignoreMissingComponentTemplates,
|
||||
};
|
||||
|
||||
return indexTemplate;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue