[UII] Make constant keyword backfill optional (#192921)

## Summary

Follow up to #188145. In some edge cases
(https://github.com/elastic/sdh-beats/issues/5156), users could override
the index template used by integration data streams. It is possible to
create an index template without mappings, this causes
`fillConstantKeywordValues` to receive an undefined object when
upgrading the integration, and the upgrade then fails.

This PR makes the backfill operation here more fail-safe.
This commit is contained in:
Jen Huang 2024-09-13 19:34:46 -07:00 committed by GitHub
parent cabaf7a077
commit b5abc4ec7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 114 additions and 4 deletions

View file

@ -1867,6 +1867,110 @@ describe('EPM template', () => {
},
});
});
it('should fill constant keywords from previous mappings', async () => {
const esClient = elasticsearchServiceMock.createElasticsearchClient();
esClient.indices.getDataStream.mockResponse({
data_streams: [{ name: 'test-constant.keyword-default' }],
} as any);
esClient.indices.get.mockResponse({
'test-constant.keyword-default': {
mappings: {
properties: {
some_keyword_field: {
type: 'constant_keyword',
},
},
},
},
} as any);
esClient.indices.simulateTemplate.mockResponse({
template: {
settings: { index: {} },
mappings: {
properties: {
some_keyword_field: {
type: 'constant_keyword',
value: 'some_value',
},
},
},
},
} as any);
const logger = loggerMock.create();
await updateCurrentWriteIndices(esClient, logger, [
{
templateName: 'test',
indexTemplate: {
index_patterns: ['test-constant.keyword-*'],
template: {
template: {
settings: { index: {} },
mappings: { properties: {} },
},
},
} as any,
},
]);
const putMappingsCalls = esClient.indices.putMapping.mock.calls;
expect(putMappingsCalls).toHaveLength(1);
expect(putMappingsCalls[0][0]).toEqual({
index: 'test-constant.keyword-default',
body: {
properties: {
some_keyword_field: {
type: 'constant_keyword',
value: 'some_value',
},
},
},
write_index_only: true,
});
});
it('should not error when previous mappings are not found', async () => {
const esClient = elasticsearchServiceMock.createElasticsearchClient();
esClient.indices.getDataStream.mockResponse({
data_streams: [{ name: 'test-constant.keyword-default' }],
} as any);
esClient.indices.get.mockResponse({
'test-constant.keyword-default': {
mappings: {
properties: {
some_keyword_field: {
type: 'constant_keyword',
},
},
},
},
} as any);
esClient.indices.simulateTemplate.mockResponse({
template: {},
} as any);
const logger = loggerMock.create();
await updateCurrentWriteIndices(esClient, logger, [
{
templateName: 'test',
indexTemplate: {
index_patterns: ['test-constant.keyword-*'],
template: {
template: {
settings: { index: {} },
mappings: { properties: {} },
},
},
} as any,
},
]);
const putMappingsCalls = esClient.indices.putMapping.mock.calls;
expect(putMappingsCalls).toHaveLength(1);
expect(putMappingsCalls[0][0]).toEqual({
index: 'test-constant.keyword-default',
body: {},
write_index_only: true,
});
});
it('should rollover on expected error', async () => {
const esClient = elasticsearchServiceMock.createElasticsearchClient();
esClient.indices.getDataStream.mockResponse({

View file

@ -1027,10 +1027,16 @@ const updateExistingDataStream = async ({
);
settings = simulateResult.template.settings;
mappings = fillConstantKeywordValues(
currentBackingIndexConfig?.mappings || {},
simulateResult.template.mappings
);
try {
mappings = fillConstantKeywordValues(
currentBackingIndexConfig?.mappings || {},
simulateResult.template.mappings || {}
);
} catch (err) {
logger.error(`Error filling constant keyword values: ${err}`);
mappings = simulateResult.template.mappings;
}
lifecycle = simulateResult.template.lifecycle;