[8.18] [Fleet] Never delete @custom component templates (#214232) (#214289)

# Backport

This will backport the following commits from `main` to `8.18`:
- [[Fleet] Never delete @custom component templates
(#214232)](https://github.com/elastic/kibana/pull/214232)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Nicolas
Chaulet","email":"nicolas.chaulet@elastic.co"},"sourceCommit":{"committedDate":"2025-03-12T19:58:40Z","message":"[Fleet]
Never delete @custom component templates
(#214232)","sha":"fc64501577284038eef59bb8fc37ea4d80b49827","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Fleet","v9.0.0","backport:prev-minor","backport:version","v9.1.0","backport:8.18","v8.18.1"],"title":"[Fleet]
Never delete @custom component
templates","number":214232,"url":"https://github.com/elastic/kibana/pull/214232","mergeCommit":{"message":"[Fleet]
Never delete @custom component templates
(#214232)","sha":"fc64501577284038eef59bb8fc37ea4d80b49827"}},"sourceBranch":"main","suggestedTargetBranches":["8.18"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/214279","number":214279,"state":"MERGED","mergeCommit":{"sha":"ffc575724f73009d5d564b7c896ab162e7880c4e","message":"[9.0]
[Fleet] Never delete @custom component templates (#214232)
(#214279)\n\n# Backport\n\nThis will backport the following commits from
`main` to `9.0`:\n- [[Fleet] Never delete @custom component
templates\n(#214232)](https://github.com/elastic/kibana/pull/214232)\n\n\n\n###
Questions ?\nPlease refer to the [Backport
tool\ndocumentation](https://github.com/sorenlouv/backport)\n\n\n\nCo-authored-by:
Nicolas Chaulet
<nicolas.chaulet@elastic.co>"}},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/214232","number":214232,"mergeCommit":{"message":"[Fleet]
Never delete @custom component templates
(#214232)","sha":"fc64501577284038eef59bb8fc37ea4d80b49827"}},{"branch":"8.18","label":"v8.18.1","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

---------

Co-authored-by: Nicolas Chaulet <nicolas.chaulet@elastic.co>
This commit is contained in:
Kibana Machine 2025-03-14 03:57:01 +11:00 committed by GitHub
parent 66223fbf1f
commit e1b9411764
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 44 additions and 3 deletions

View file

@ -11,6 +11,7 @@ import type {
} from '@elastic/elasticsearch/lib/api/types';
import type { ElasticsearchClient, Logger } from '@kbn/core/server';
import { USER_SETTINGS_TEMPLATE_SUFFIX } from '../../../../../common/constants';
import type { InstallablePackage, RegistryDataStream } from '../../../../types';
import { getRegistryDataStreamAssetBaseName } from '../../../../../common/services';
const LEGACY_TEMPLATE_SUFFIXES = ['@mappings', '@settings'];
@ -108,6 +109,9 @@ export const _filterComponentTemplatesInUse = ({
const usedByLookup = _getIndexTemplatesToUsedByMap(indexTemplates);
return componentTemplateNames.filter((componentTemplateName) => {
if (componentTemplateName.endsWith(USER_SETTINGS_TEMPLATE_SUFFIX)) {
return false;
}
const indexTemplatesUsingComponentTemplate = usedByLookup.get(componentTemplateName);
if (indexTemplatesUsingComponentTemplate?.length) {

View file

@ -4,13 +4,14 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { elasticsearchServiceMock } from '@kbn/core/server/mocks';
import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../../common';
import { ElasticsearchAssetType, PACKAGES_SAVED_OBJECT_TYPE } from '../../../../common';
import { packagePolicyService } from '../..';
import { auditLoggingService } from '../../audit_logging';
import { removeInstallation } from './remove';
import { deleteESAssets, removeInstallation } from './remove';
jest.mock('../..', () => {
return {
@ -111,3 +112,38 @@ describe('removeInstallation', () => {
});
});
});
describe('deleteESAssets', () => {
it('should not delete @custom components template', async () => {
const esClient = elasticsearchServiceMock.createInternalClient();
await deleteESAssets(
[
{
id: 'logs@custom',
type: ElasticsearchAssetType.componentTemplate,
},
],
esClient
);
expect(esClient.cluster.deleteComponentTemplate).not.toBeCalled();
});
it('should delete @package components template', async () => {
const esClient = elasticsearchServiceMock.createInternalClient();
await deleteESAssets(
[
{
id: 'logs-nginx.access@package',
type: ElasticsearchAssetType.componentTemplate,
},
],
esClient
);
expect(esClient.cluster.deleteComponentTemplate).toBeCalledWith(
{ name: 'logs-nginx.access@package' },
expect.anything()
);
});
});

View file

@ -24,6 +24,7 @@ import {
PACKAGE_POLICY_SAVED_OBJECT_TYPE,
PACKAGES_SAVED_OBJECT_TYPE,
SO_SEARCH_LIMIT,
USER_SETTINGS_TEMPLATE_SUFFIX,
} from '../../../constants';
import { ElasticsearchAssetType } from '../../../types';
import type {
@ -368,7 +369,7 @@ async function deleteIndexTemplate(esClient: ElasticsearchClient, name: string):
async function deleteComponentTemplate(esClient: ElasticsearchClient, name: string): Promise<void> {
// '*' shouldn't ever appear here, but it still would delete all templates
if (name && name !== '*') {
if (name && name !== '*' && !name.endsWith(USER_SETTINGS_TEMPLATE_SUFFIX)) {
try {
await esClient.cluster.deleteComponentTemplate({ name }, { ignore: [404] });
} catch (error) {