mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
# Backport This will backport the following commits from `8.18` to `main`: - [[SecuritySolution] Fix risk engine component template renaming (#212853)](https://github.com/elastic/kibana/pull/212853) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Pablo Machado","email":"pablo.nevesmachado@elastic.co"},"sourceCommit":{"committedDate":"2025-03-05T09:50:31Z","message":"[SecuritySolution] Fix risk engine component template renaming (#212853)\n\n## Summary\n\nThe previous implementation tried to rename the index template during\n`init` and did not consider multiple spaces. to fix it, I have:\n* Delete the previous code from `init`\n* Created a new migration that created the new component templates and\nupdated the index templates\n* Deleted the old component template after all spaces migration ran\n* Add support for multiple spaces\n* I also renamed a function inside `init` to make the code more clear\n* Added error handling code that concatenates error messages and logs\nall of them at the end\n\n\n### How to test it:\n\n**Scenario 1**\n\n* The usual way to desk test this PR would be\n* Create a cluster with 8.17\n* Enable the risk Engine in 8.17\n* Create a new space in 8.17\n* Upgrade the cluster to 8.18 (this branch)\n* Enable the risk engine in the second space.\n\n**Scenario 2**\n* Create a cluster with 8.17\n* Enable the risk engine\n* Create a space\n* Enable another risk engine\n* Create another space\n* Upgrade the cluster to 8.18 (this branch)\n* Check if the migration ran in the logs\n* Check if all risk engines are installed and the index templates and\nindex components are there.\n* Install a new risk engine in the space where it isn't installed.\n* Restart Kibana and make sure the migrations didn't run a second time\n\n### Checklist\n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n### Identify risks\n\n[ ] This PR needs to be tested for upgrades between different versions\nand a diverse number of spaces and risk engines installed\n\n---------\n\nCo-authored-by: abhishekbhatia1710 <abhishek.bhatia@elastic.co>","sha":"b7908a4c6f91c79459f7b509bfd444ad169d6770","branchLabelMapping":{"^v8.16.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:skip","v9.0.0","Team: SecuritySolution","Feature:Entity Analytics","Team:Entity Analytics","backport:version","v8.18.0","v9.1.0","v8.19.0"],"title":"[SecuritySolution] Fix risk engine component template renaming","number":212853,"url":"https://github.com/elastic/kibana/pull/212853","mergeCommit":{"message":"[SecuritySolution] Fix risk engine component template renaming (#212853)\n\n## Summary\n\nThe previous implementation tried to rename the index template during\n`init` and did not consider multiple spaces. to fix it, I have:\n* Delete the previous code from `init`\n* Created a new migration that created the new component templates and\nupdated the index templates\n* Deleted the old component template after all spaces migration ran\n* Add support for multiple spaces\n* I also renamed a function inside `init` to make the code more clear\n* Added error handling code that concatenates error messages and logs\nall of them at the end\n\n\n### How to test it:\n\n**Scenario 1**\n\n* The usual way to desk test this PR would be\n* Create a cluster with 8.17\n* Enable the risk Engine in 8.17\n* Create a new space in 8.17\n* Upgrade the cluster to 8.18 (this branch)\n* Enable the risk engine in the second space.\n\n**Scenario 2**\n* Create a cluster with 8.17\n* Enable the risk engine\n* Create a space\n* Enable another risk engine\n* Create another space\n* Upgrade the cluster to 8.18 (this branch)\n* Check if the migration ran in the logs\n* Check if all risk engines are installed and the index templates and\nindex components are there.\n* Install a new risk engine in the space where it isn't installed.\n* Restart Kibana and make sure the migrations didn't run a second time\n\n### Checklist\n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n### Identify risks\n\n[ ] This PR needs to be tested for upgrades between different versions\nand a diverse number of spaces and risk engines installed\n\n---------\n\nCo-authored-by: abhishekbhatia1710 <abhishek.bhatia@elastic.co>","sha":"b7908a4c6f91c79459f7b509bfd444ad169d6770"}},"sourceBranch":"8.18","suggestedTargetBranches":["9.0","main","8.x"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/212853","number":212853,"mergeCommit":{"message":"[SecuritySolution] Fix risk engine component template renaming (#212853)\n\n## Summary\n\nThe previous implementation tried to rename the index template during\n`init` and did not consider multiple spaces. to fix it, I have:\n* Delete the previous code from `init`\n* Created a new migration that created the new component templates and\nupdated the index templates\n* Deleted the old component template after all spaces migration ran\n* Add support for multiple spaces\n* I also renamed a function inside `init` to make the code more clear\n* Added error handling code that concatenates error messages and logs\nall of them at the end\n\n\n### How to test it:\n\n**Scenario 1**\n\n* The usual way to desk test this PR would be\n* Create a cluster with 8.17\n* Enable the risk Engine in 8.17\n* Create a new space in 8.17\n* Upgrade the cluster to 8.18 (this branch)\n* Enable the risk engine in the second space.\n\n**Scenario 2**\n* Create a cluster with 8.17\n* Enable the risk engine\n* Create a space\n* Enable another risk engine\n* Create another space\n* Upgrade the cluster to 8.18 (this branch)\n* Check if the migration ran in the logs\n* Check if all risk engines are installed and the index templates and\nindex components are there.\n* Install a new risk engine in the space where it isn't installed.\n* Restart Kibana and make sure the migrations didn't run a second time\n\n### Checklist\n\nReviewers should verify this PR satisfies this list as well.\n\n- [x] [Unit or functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere updated or added to match the most common scenarios\n- [x] The PR description includes the appropriate Release Notes section,\nand the correct `release_note:*` label is applied per the\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\n\n### Identify risks\n\n[ ] This PR needs to be tested for upgrades between different versions\nand a diverse number of spaces and risk engines installed\n\n---------\n\nCo-authored-by: abhishekbhatia1710 <abhishek.bhatia@elastic.co>","sha":"b7908a4c6f91c79459f7b509bfd444ad169d6770"}},{"branch":"9.1","label":"v9.1.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.19","label":"v8.19.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT-->
This commit is contained in:
parent
48926e5173
commit
98c18a395e
5 changed files with 368 additions and 69 deletions
|
@ -13,6 +13,7 @@ import { assetCrticalityCopyTimestampToEventIngested } from './asset_criticality
|
|||
import { riskScoreCopyTimestampToEventIngested } from './risk_score_copy_timestamp_to_event_ingested';
|
||||
import { updateAssetCriticalityMappings } from '../asset_criticality/migrations/update_asset_criticality_mappings';
|
||||
import { updateRiskScoreMappings } from '../risk_engine/migrations/update_risk_score_mappings';
|
||||
import { renameRiskScoreComponentTemplate } from '../risk_engine/migrations/rename_risk_score_component_templates';
|
||||
|
||||
export interface EntityAnalyticsMigrationsParams {
|
||||
taskManager?: TaskManagerSetupContract;
|
||||
|
@ -43,6 +44,7 @@ export const scheduleEntityAnalyticsMigration = async (params: EntityAnalyticsMi
|
|||
|
||||
await updateAssetCriticalityMappings({ ...params, logger: scopedLogger });
|
||||
await scheduleAssetCriticalityEcsCompliancyMigration({ ...params, logger: scopedLogger });
|
||||
await renameRiskScoreComponentTemplate({ ...params, logger: scopedLogger });
|
||||
await updateRiskScoreMappings({ ...params, logger: scopedLogger });
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import { renameRiskScoreComponentTemplate } from './rename_risk_score_component_templates';
|
||||
import {
|
||||
loggingSystemMock,
|
||||
savedObjectsClientMock as mockSavedObjectsClient,
|
||||
elasticsearchServiceMock,
|
||||
} from '@kbn/core/server/mocks';
|
||||
import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks';
|
||||
|
||||
const mockCreateComponentTemplate = jest.fn();
|
||||
const mockCreateIndexTemplate = jest.fn();
|
||||
|
||||
jest.mock('../../risk_score/risk_score_data_client', () => ({
|
||||
RiskScoreDataClient: jest.fn().mockImplementation(() => ({
|
||||
createOrUpdateRiskScoreComponentTemplate: () => mockCreateComponentTemplate(),
|
||||
createOrUpdateRiskScoreIndexTemplate: () => mockCreateIndexTemplate(),
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('../../risk_score/tasks/helpers', () => ({
|
||||
buildScopedInternalSavedObjectsClientUnsafe: () => mockSavedObjectsClient.create(),
|
||||
}));
|
||||
|
||||
const buildSavedObjectResponse = (namespaces = ['default']) => ({
|
||||
page: 1,
|
||||
per_page: 20,
|
||||
total: namespaces.length,
|
||||
saved_objects: namespaces.map((namespace) => ({
|
||||
namespaces: [namespace],
|
||||
attributes: {},
|
||||
id: 'id',
|
||||
type: 'type',
|
||||
references: [],
|
||||
score: 1,
|
||||
})),
|
||||
});
|
||||
|
||||
describe('renameRiskScoreComponentTemplate', () => {
|
||||
const mockGetStartServices = jest.fn();
|
||||
const mockAuditLogger = auditLoggerMock.create();
|
||||
const mockLogger = loggingSystemMock.createLogger();
|
||||
const mockEsClient = elasticsearchServiceMock.createClusterClient().asInternalUser;
|
||||
const mockSoClient = mockSavedObjectsClient.create();
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
mockCreateComponentTemplate.mockReset();
|
||||
mockCreateIndexTemplate.mockReset();
|
||||
mockGetStartServices.mockResolvedValue([
|
||||
{
|
||||
savedObjects: {
|
||||
createInternalRepository: jest.fn().mockReturnValue(mockSoClient),
|
||||
},
|
||||
elasticsearch: {
|
||||
client: {
|
||||
asInternalUser: mockEsClient,
|
||||
},
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not proceed if old component template does not exist', async () => {
|
||||
mockEsClient.cluster.existsComponentTemplate.mockResolvedValue(false);
|
||||
|
||||
await renameRiskScoreComponentTemplate({
|
||||
auditLogger: mockAuditLogger,
|
||||
logger: mockLogger,
|
||||
getStartServices: mockGetStartServices,
|
||||
kibanaVersion: '8.0.0',
|
||||
});
|
||||
|
||||
expect(mockEsClient.cluster.existsComponentTemplate).toHaveBeenCalledWith({
|
||||
name: '.risk-score-mappings',
|
||||
});
|
||||
expect(mockEsClient.cluster.deleteComponentTemplate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should proceed with migration if old component template exists', async () => {
|
||||
mockEsClient.cluster.existsComponentTemplate.mockResolvedValue(true);
|
||||
mockSoClient.find.mockResolvedValue(buildSavedObjectResponse(['default']));
|
||||
|
||||
await renameRiskScoreComponentTemplate({
|
||||
auditLogger: mockAuditLogger,
|
||||
logger: mockLogger,
|
||||
getStartServices: mockGetStartServices,
|
||||
kibanaVersion: '8.0.0',
|
||||
});
|
||||
|
||||
expect(mockEsClient.cluster.existsComponentTemplate).toHaveBeenCalledWith({
|
||||
name: '.risk-score-mappings',
|
||||
});
|
||||
expect(mockEsClient.cluster.deleteComponentTemplate).toHaveBeenCalledWith(
|
||||
{ name: '.risk-score-mappings' },
|
||||
{ ignore: [404] }
|
||||
);
|
||||
});
|
||||
|
||||
it('should log an error if a saved object has no namespace', async () => {
|
||||
const savedObj = buildSavedObjectResponse([]);
|
||||
mockEsClient.cluster.existsComponentTemplate.mockResolvedValue(true);
|
||||
mockSoClient.find.mockResolvedValue({
|
||||
...savedObj,
|
||||
saved_objects: [
|
||||
{
|
||||
...savedObj.saved_objects[0],
|
||||
namespaces: [],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await renameRiskScoreComponentTemplate({
|
||||
auditLogger: mockAuditLogger,
|
||||
logger: mockLogger,
|
||||
getStartServices: mockGetStartServices,
|
||||
kibanaVersion: '8.0.0',
|
||||
});
|
||||
|
||||
expect(mockLogger.error).toHaveBeenCalledWith(
|
||||
'Unexpected saved object. Risk Score saved objects must have a namespace'
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw an error if any promise is rejected', async () => {
|
||||
mockEsClient.cluster.existsComponentTemplate.mockResolvedValue(true);
|
||||
mockSoClient.find.mockResolvedValue(buildSavedObjectResponse(['default']));
|
||||
mockCreateComponentTemplate.mockRejectedValue(new Error('Test error'));
|
||||
|
||||
await expect(
|
||||
renameRiskScoreComponentTemplate({
|
||||
auditLogger: mockAuditLogger,
|
||||
logger: mockLogger,
|
||||
getStartServices: mockGetStartServices,
|
||||
kibanaVersion: '8.0.0',
|
||||
})
|
||||
).rejects.toThrow('Risk Score component template migration failed with errors: \nTest error');
|
||||
expect(mockEsClient.cluster.deleteComponentTemplate).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should throw an error with concatenated error messages when more than one error happens', async () => {
|
||||
mockEsClient.cluster.existsComponentTemplate.mockResolvedValue(true);
|
||||
mockSoClient.find.mockResolvedValue(buildSavedObjectResponse(['space-1', 'space-2']));
|
||||
|
||||
mockCreateComponentTemplate
|
||||
.mockRejectedValueOnce(new Error('Test error 1'))
|
||||
.mockRejectedValueOnce(new Error('Test error 2'));
|
||||
|
||||
await expect(
|
||||
renameRiskScoreComponentTemplate({
|
||||
auditLogger: mockAuditLogger,
|
||||
logger: mockLogger,
|
||||
getStartServices: mockGetStartServices,
|
||||
kibanaVersion: '8.0.0',
|
||||
})
|
||||
).rejects.toThrow(
|
||||
'Risk Score component template migration failed with errors: \nTest error 1\nTest error 2'
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle errors when creating/updating index template', async () => {
|
||||
mockEsClient.cluster.existsComponentTemplate.mockResolvedValue(true);
|
||||
mockSoClient.find.mockResolvedValue(buildSavedObjectResponse(['default']));
|
||||
|
||||
mockCreateIndexTemplate.mockRejectedValue(new Error('Index template error'));
|
||||
|
||||
await expect(
|
||||
renameRiskScoreComponentTemplate({
|
||||
auditLogger: mockAuditLogger,
|
||||
logger: mockLogger,
|
||||
getStartServices: mockGetStartServices,
|
||||
kibanaVersion: '8.0.0',
|
||||
})
|
||||
).rejects.toThrow(
|
||||
'Risk Score component template migration failed with errors: \nIndex template error'
|
||||
);
|
||||
});
|
||||
|
||||
it('should log info when migration starts for a namespace', async () => {
|
||||
mockEsClient.cluster.existsComponentTemplate.mockResolvedValue(true);
|
||||
mockSoClient.find.mockResolvedValue(buildSavedObjectResponse(['default']));
|
||||
|
||||
await renameRiskScoreComponentTemplate({
|
||||
auditLogger: mockAuditLogger,
|
||||
logger: mockLogger,
|
||||
getStartServices: mockGetStartServices,
|
||||
kibanaVersion: '8.0.0',
|
||||
});
|
||||
|
||||
expect(mockLogger.info).toHaveBeenCalledWith(
|
||||
'Starting Risk Score component template migration on namespace default'
|
||||
);
|
||||
});
|
||||
|
||||
it('should log debug when migration completes for a namespace', async () => {
|
||||
mockEsClient.cluster.existsComponentTemplate.mockResolvedValue(true);
|
||||
mockSoClient.find.mockResolvedValue(buildSavedObjectResponse(['default']));
|
||||
|
||||
await renameRiskScoreComponentTemplate({
|
||||
auditLogger: mockAuditLogger,
|
||||
logger: mockLogger,
|
||||
getStartServices: mockGetStartServices,
|
||||
kibanaVersion: '8.0.0',
|
||||
});
|
||||
|
||||
expect(mockLogger.debug).toHaveBeenCalledWith(
|
||||
'Risk score component template migration ran on namespace default'
|
||||
);
|
||||
});
|
||||
|
||||
it('should delete the old component template if all migrations succeed', async () => {
|
||||
mockEsClient.cluster.existsComponentTemplate.mockResolvedValue(true);
|
||||
mockSoClient.find.mockResolvedValue(buildSavedObjectResponse(['default']));
|
||||
|
||||
await renameRiskScoreComponentTemplate({
|
||||
auditLogger: mockAuditLogger,
|
||||
logger: mockLogger,
|
||||
getStartServices: mockGetStartServices,
|
||||
kibanaVersion: '8.0.0',
|
||||
});
|
||||
|
||||
expect(mockEsClient.cluster.deleteComponentTemplate).toHaveBeenCalledWith(
|
||||
{ name: '.risk-score-mappings' },
|
||||
{ ignore: [404] }
|
||||
);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import type { EntityAnalyticsMigrationsParams } from '../../migrations';
|
||||
import { RiskScoreDataClient } from '../../risk_score/risk_score_data_client';
|
||||
import type { RiskEngineConfiguration } from '../../types';
|
||||
import { riskEngineConfigurationTypeName } from '../saved_object';
|
||||
import { buildScopedInternalSavedObjectsClientUnsafe } from '../../risk_score/tasks/helpers';
|
||||
import { mappingComponentName } from '../../risk_score/configurations';
|
||||
|
||||
export const MAX_PER_PAGE = 10_000;
|
||||
|
||||
/**
|
||||
* This migration renames the Risk Score component templates to include the namespace in the name. Before 8.18 all spaces used the `.risk-score-mappings` component template, we now use `.risk-score-mappings-<spacename>`.
|
||||
*
|
||||
* The migration creates the new component template and updates the index template for each space, then finally deletes the old component template.
|
||||
*/
|
||||
export const renameRiskScoreComponentTemplate = async ({
|
||||
auditLogger,
|
||||
logger,
|
||||
getStartServices,
|
||||
kibanaVersion,
|
||||
}: EntityAnalyticsMigrationsParams) => {
|
||||
const [coreStart] = await getStartServices();
|
||||
const soClientKibanaUser = coreStart.savedObjects.createInternalRepository();
|
||||
const esClient = coreStart.elasticsearch.client.asInternalUser;
|
||||
|
||||
// Check if the legacy component templates (without the namespace in the name) exists
|
||||
const oldComponentTemplateExists = await esClient.cluster.existsComponentTemplate({
|
||||
name: mappingComponentName,
|
||||
});
|
||||
|
||||
if (!oldComponentTemplateExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all installed Risk Engine Configurations
|
||||
const savedObjectsResponse = await soClientKibanaUser.find<RiskEngineConfiguration>({
|
||||
type: riskEngineConfigurationTypeName,
|
||||
perPage: MAX_PER_PAGE,
|
||||
namespaces: ['*'],
|
||||
});
|
||||
|
||||
const settledPromises = await Promise.allSettled(
|
||||
savedObjectsResponse.saved_objects.map(async (savedObject) => {
|
||||
const namespace = savedObject.namespaces?.[0]; // We need to create one component template per space
|
||||
|
||||
if (!namespace) {
|
||||
logger.error('Unexpected saved object. Risk Score saved objects must have a namespace');
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info(`Starting Risk Score component template migration on namespace ${namespace}`);
|
||||
|
||||
const soClient = buildScopedInternalSavedObjectsClientUnsafe({ coreStart, namespace });
|
||||
|
||||
const riskScoreDataClient = new RiskScoreDataClient({
|
||||
logger,
|
||||
kibanaVersion,
|
||||
esClient,
|
||||
namespace,
|
||||
soClient,
|
||||
auditLogger,
|
||||
});
|
||||
|
||||
await riskScoreDataClient.createOrUpdateRiskScoreComponentTemplate();
|
||||
await riskScoreDataClient.createOrUpdateRiskScoreIndexTemplate();
|
||||
|
||||
logger.debug(`Risk score component template migration ran on namespace ${namespace}`);
|
||||
})
|
||||
);
|
||||
|
||||
const rejectedPromises = settledPromises.filter(
|
||||
(promise) => promise.status === 'rejected'
|
||||
) as PromiseRejectedResult[];
|
||||
|
||||
// Migration successfully ran on all spaces
|
||||
if (rejectedPromises.length === 0) {
|
||||
// Delete the legacy component template without the namespace in the name
|
||||
await esClient.cluster.deleteComponentTemplate(
|
||||
{
|
||||
name: mappingComponentName,
|
||||
},
|
||||
{ ignore: [404] }
|
||||
);
|
||||
} else {
|
||||
const errorMessages = rejectedPromises.map((promise) => promise.reason?.message).join('\n');
|
||||
throw new Error(
|
||||
`Risk Score component template migration failed with errors: \n${errorMessages}`
|
||||
);
|
||||
}
|
||||
};
|
|
@ -68,7 +68,7 @@ export const updateRiskScoreMappings = async ({
|
|||
});
|
||||
|
||||
await riskScoreDataClient.createOrUpdateRiskScoreLatestIndex();
|
||||
await riskScoreDataClient.createOrUpdateRiskScoreIndexTemplate();
|
||||
await riskScoreDataClient.createOrUpdateRiskScoreComponentTemplate();
|
||||
await riskScoreDataClient.updateRiskScoreTimeSeriesIndexMappings();
|
||||
await riskEngineDataClient.updateConfiguration({
|
||||
_meta: {
|
||||
|
|
|
@ -111,7 +111,7 @@ export class RiskScoreDataClient {
|
|||
});
|
||||
};
|
||||
|
||||
public createOrUpdateRiskScoreIndexTemplate = async () =>
|
||||
public createOrUpdateRiskScoreComponentTemplate = async () =>
|
||||
createOrUpdateComponentTemplate({
|
||||
logger: this.options.logger,
|
||||
esClient: this.options.esClient,
|
||||
|
@ -128,6 +128,40 @@ export class RiskScoreDataClient {
|
|||
totalFieldsLimit,
|
||||
});
|
||||
|
||||
public createOrUpdateRiskScoreIndexTemplate = async () => {
|
||||
const indexPatterns = getIndexPatternDataStream(this.options.namespace);
|
||||
const indexMetadata: Metadata = {
|
||||
kibana: {
|
||||
version: this.options.kibanaVersion,
|
||||
},
|
||||
managed: true,
|
||||
namespace: this.options.namespace,
|
||||
};
|
||||
|
||||
return createOrUpdateIndexTemplate({
|
||||
logger: this.options.logger,
|
||||
esClient: this.options.esClient,
|
||||
template: {
|
||||
name: indexPatterns.template,
|
||||
data_stream: { hidden: true },
|
||||
index_patterns: [indexPatterns.alias],
|
||||
composed_of: [nameSpaceAwareMappingsComponentName(this.options.namespace)],
|
||||
template: {
|
||||
lifecycle: {},
|
||||
settings: {
|
||||
'index.mapping.total_fields.limit': totalFieldsLimit,
|
||||
'index.default_pipeline': getIngestPipelineName(this.options.namespace),
|
||||
},
|
||||
mappings: {
|
||||
dynamic: false,
|
||||
_meta: indexMetadata,
|
||||
},
|
||||
},
|
||||
_meta: indexMetadata,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
public updateRiskScoreTimeSeriesIndexMappings = async () =>
|
||||
updateUnderlyingMapping({
|
||||
esClient: this.options.esClient,
|
||||
|
@ -142,59 +176,11 @@ export class RiskScoreDataClient {
|
|||
try {
|
||||
await createEventIngestedFromTimestamp(esClient, namespace);
|
||||
|
||||
const indexPatterns = getIndexPatternDataStream(namespace);
|
||||
await this.createOrUpdateRiskScoreComponentTemplate();
|
||||
|
||||
const indexMetadata: Metadata = {
|
||||
kibana: {
|
||||
version: this.options.kibanaVersion,
|
||||
},
|
||||
managed: true,
|
||||
namespace,
|
||||
};
|
||||
|
||||
// Check if there are any existing component templates with the namespace in the name
|
||||
const oldComponentTemplateExists = await esClient.cluster.existsComponentTemplate({
|
||||
name: mappingComponentName,
|
||||
});
|
||||
if (oldComponentTemplateExists) {
|
||||
await this.updateComponentTemplateNameWithNamespace(namespace);
|
||||
}
|
||||
|
||||
// Update the new component template with the required data
|
||||
await this.createOrUpdateRiskScoreIndexTemplate();
|
||||
|
||||
// Reference the new component template in the index template
|
||||
await createOrUpdateIndexTemplate({
|
||||
logger: this.options.logger,
|
||||
esClient,
|
||||
template: {
|
||||
name: indexPatterns.template,
|
||||
data_stream: { hidden: true },
|
||||
index_patterns: [indexPatterns.alias],
|
||||
composed_of: [nameSpaceAwareMappingsComponentName(namespace)],
|
||||
template: {
|
||||
lifecycle: {},
|
||||
settings: {
|
||||
'index.mapping.total_fields.limit': totalFieldsLimit,
|
||||
'index.default_pipeline': getIngestPipelineName(namespace),
|
||||
},
|
||||
mappings: {
|
||||
dynamic: false,
|
||||
_meta: indexMetadata,
|
||||
},
|
||||
},
|
||||
_meta: indexMetadata,
|
||||
},
|
||||
});
|
||||
|
||||
// Delete the component template without the namespace in the name
|
||||
await esClient.cluster.deleteComponentTemplate(
|
||||
{
|
||||
name: mappingComponentName,
|
||||
},
|
||||
{ ignore: [404] }
|
||||
);
|
||||
|
||||
const indexPatterns = getIndexPatternDataStream(namespace);
|
||||
await createDataStream({
|
||||
logger: this.options.logger,
|
||||
esClient,
|
||||
|
@ -331,23 +317,6 @@ export class RiskScoreDataClient {
|
|||
);
|
||||
}
|
||||
|
||||
private async updateComponentTemplateNameWithNamespace(namespace: string): Promise<void> {
|
||||
const esClient = this.options.esClient;
|
||||
const oldComponentTemplateResponse = await esClient.cluster.getComponentTemplate(
|
||||
{
|
||||
name: mappingComponentName,
|
||||
},
|
||||
{ ignore: [404] }
|
||||
);
|
||||
const oldComponentTemplate = oldComponentTemplateResponse?.component_templates[0];
|
||||
const newComponentTemplateName = nameSpaceAwareMappingsComponentName(namespace);
|
||||
await esClient.cluster.putComponentTemplate({
|
||||
name: newComponentTemplateName,
|
||||
// @ts-expect-error elasticsearch@9.0.0 https://github.com/elastic/elasticsearch-js/issues/2584
|
||||
body: oldComponentTemplate.component_template,
|
||||
});
|
||||
}
|
||||
|
||||
public copyTimestampToEventIngestedForRiskScore = (abortSignal?: AbortSignal) => {
|
||||
return this.options.esClient.updateByQuery(
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue