"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.initializeCspIndices = void 0; var _elasticsearch = require("@elastic/elasticsearch"); var _constants = require("../../common/constants"); var _create_processor = require("./create_processor"); var _benchmark_score_mapping = require("./benchmark_score_mapping"); var _ingest_pipelines = require("./ingest_pipelines"); var _latest_indices = require("./latest_indices"); /* * 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. */ // TODO: Add integration tests const initializeCspIndices = async (esClient, logger) => { await Promise.allSettled([(0, _create_processor.createPipelineIfNotExists)(esClient, _ingest_pipelines.scorePipelineIngestConfig, logger), (0, _create_processor.createPipelineIfNotExists)(esClient, _ingest_pipelines.latestFindingsPipelineIngestConfig, logger)]); const [createFindingsLatestIndexPromise, createVulnerabilitiesLatestIndexPromise, createBenchmarkScoreIndexPromise] = await Promise.allSettled([createLatestIndex(esClient, logger, _latest_indices.latestIndexConfigs.findings), createLatestIndex(esClient, logger, _latest_indices.latestIndexConfigs.vulnerabilities), createBenchmarkScoreIndex(esClient, logger)]); if (createFindingsLatestIndexPromise.status === 'rejected') { logger.error(createFindingsLatestIndexPromise.reason); } if (createVulnerabilitiesLatestIndexPromise.status === 'rejected') { logger.error(createVulnerabilitiesLatestIndexPromise.reason); } if (createBenchmarkScoreIndexPromise.status === 'rejected') { logger.error(createBenchmarkScoreIndexPromise.reason); } }; exports.initializeCspIndices = initializeCspIndices; const createBenchmarkScoreIndex = async (esClient, logger) => { try { // Deletes old assets from previous versions as part of upgrade process const INDEX_TEMPLATE_V830 = 'cloud_security_posture.scores'; await deleteIndexTemplateSafe(esClient, logger, INDEX_TEMPLATE_V830); // We always want to keep the index template updated await esClient.indices.putIndexTemplate({ name: _constants.BENCHMARK_SCORE_INDEX_TEMPLATE_NAME, index_patterns: _constants.BENCHMARK_SCORE_INDEX_PATTERN, template: { mappings: _benchmark_score_mapping.benchmarkScoreMapping, settings: { default_pipeline: _ingest_pipelines.scorePipelineIngestConfig.id, // TODO: once we will convert the score index to datastream we will no longer override the ilm to be empty lifecycle: { name: '' } } }, _meta: { package: { name: _constants.CLOUD_SECURITY_POSTURE_PACKAGE_NAME }, managed_by: 'cloud_security_posture', managed: true }, priority: 500 }); const result = await createIndexSafe(esClient, logger, _constants.BENCHMARK_SCORE_INDEX_DEFAULT_NS); if (result === 'already-exists') { await updateIndexSafe(esClient, logger, _constants.BENCHMARK_SCORE_INDEX_DEFAULT_NS, _benchmark_score_mapping.benchmarkScoreMapping); } } catch (e) { logger.error(e); throw Error(`Failed to upsert index template [Template: ${_constants.BENCHMARK_SCORE_INDEX_TEMPLATE_NAME}]`); } }; const createLatestIndex = async (esClient, logger, indexConfig) => { const { indexName, indexPattern, indexTemplateName, indexDefaultName } = indexConfig; try { // We want that our latest findings index template would be identical to the findings index template const indexTemplateResponse = await esClient.indices.getIndexTemplate({ name: indexName }); // eslint-disable-next-line @typescript-eslint/naming-convention const { template, composed_of, _meta } = indexTemplateResponse.index_templates[0].index_template; const indexTemplateParams = { template, composedOf: composed_of, _meta, indexTemplateName, indexPattern }; // We always want to keep the index template updated await updateIndexTemplate(esClient, logger, indexTemplateParams); const result = await createIndexSafe(esClient, logger, indexDefaultName); if (result === 'already-exists') { // Make sure mappings are up-to-date const simulateResponse = await esClient.indices.simulateTemplate({ name: indexTemplateName }); await updateIndexSafe(esClient, logger, indexDefaultName, simulateResponse.template.mappings); } } catch (e) { logger.error(e); throw Error(`Failed to upsert index template [Template: ${indexTemplateName}]`); } }; const deleteIndexTemplateSafe = async (esClient, logger, name) => { try { const resp = await esClient.indices.getIndexTemplate({ name }); if (resp.index_templates) { await esClient.indices.deleteIndexTemplate({ name }); logger.info(`Deleted index template successfully [Name: ${name}]`); } } catch (e) { if (e instanceof _elasticsearch.errors.ResponseError && e.statusCode === 404) { logger.trace(`Index template no longer exists [Name: ${name}]`); } else { logger.error(`Failed to delete index template [Name: ${name}]`); logger.error(e); } } }; const createIndexSafe = async (esClient, logger, index) => { try { const isLatestIndexExists = await esClient.indices.exists({ index }); if (!isLatestIndexExists) { await esClient.indices.create({ index }); logger.info(`Created index successfully [Name: ${index}]`); return 'success'; } else { logger.trace(`Index already exists [Name: ${index}]`); return 'already-exists'; } } catch (e) { logger.error(`Failed to create index [Name: ${index}]`); logger.error(e); return 'fail'; } }; const updateIndexTemplate = async (esClient, logger, indexTemplateParams) => { const { indexTemplateName, indexPattern, template, composedOf, _meta } = indexTemplateParams; try { await esClient.indices.putIndexTemplate({ name: indexTemplateName, index_patterns: indexPattern, priority: 500, template: { mappings: template === null || template === void 0 ? void 0 : template.mappings, settings: { ...(template === null || template === void 0 ? void 0 : template.settings), default_pipeline: _ingest_pipelines.latestFindingsPipelineIngestConfig.id, lifecycle: { name: '' } }, aliases: template === null || template === void 0 ? void 0 : template.aliases }, _meta, composed_of: composedOf }); logger.info(`Updated index template successfully [Name: ${indexTemplateName}]`); } catch (e) { logger.error(`Failed to update index template [Name: ${indexTemplateName}]`); logger.error(e); } }; const updateIndexSafe = async (esClient, logger, index, mappings) => { // for now, remove from object so as not to update stream or data stream properties of the index until type and name // are added in https://github.com/elastic/kibana/issues/66551. namespace value we will continue // to skip updating and assume the value in the index mapping is correct if (mappings && mappings.properties) { delete mappings.properties.stream; delete mappings.properties.data_stream; } try { await esClient.indices.putMapping({ index, properties: mappings.properties }); logger.info(`Updated index successfully [Name: ${index}]`); } catch (e) { logger.error(`Failed to update index [Name: ${index}]`); logger.error(e); } };