"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.REINDEX_TEMP_SUFFIX = exports.MigrationType = void 0; exports.addExcludedTypesToBoolQuery = addExcludedTypesToBoolQuery; exports.addMustClausesToBoolQuery = addMustClausesToBoolQuery; exports.addMustNotClausesToBoolQuery = addMustNotClausesToBoolQuery; exports.aliasVersion = aliasVersion; exports.buildRemoveAliasActions = buildRemoveAliasActions; exports.createBulkIndexOperationTuple = exports.createBulkDeleteOperationBody = void 0; exports.getAliases = getAliases; exports.getIndexTypes = void 0; exports.getMigrationType = getMigrationType; exports.getTempIndexName = void 0; exports.hasLaterVersionAlias = hasLaterVersionAlias; exports.increaseBatchSize = void 0; exports.indexBelongsToLaterVersion = indexBelongsToLaterVersion; exports.indexVersion = indexVersion; exports.mergeMigrationMappingPropertyHashes = mergeMigrationMappingPropertyHashes; exports.throwBadControlState = throwBadControlState; exports.throwBadResponse = throwBadResponse; exports.versionMigrationCompleted = versionMigrationCompleted; var _semver = require("semver"); var Either = _interopRequireWildcard(require("fp-ts/lib/Either")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * 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 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ /** @internal */ const REINDEX_TEMP_SUFFIX = '_reindex_temp'; /** @internal */ exports.REINDEX_TEMP_SUFFIX = REINDEX_TEMP_SUFFIX; function throwBadControlState(controlState) { throw new Error('Unexpected control state: ' + controlState); } /** * A helper function/type for ensuring that all response types are handled. */ function throwBadResponse(state, res) { throw new Error(`${state.controlState} received unexpected action response: ` + JSON.stringify(res)); } /** * Merge the _meta.migrationMappingPropertyHashes mappings of an index with * the given target mappings. * * @remarks When another instance already completed a migration, the existing * target index might contain documents and mappings created by a plugin that * is disabled in the current Kibana instance performing this migration. * Mapping updates are commutative (deeply merged) by Elasticsearch, except * for the `_meta` key. By merging the `_meta.migrationMappingPropertyHashes` * mappings from the existing target index index into the targetMappings we * ensure that any `migrationPropertyHashes` for disabled plugins aren't lost. * * Right now we don't use these `migrationPropertyHashes` but it could be used * in the future to detect if mappings were changed. If mappings weren't * changed we don't need to reindex but can clone the index to save disk space. * * @param targetMappings * @param indexMappings */ function mergeMigrationMappingPropertyHashes(targetMappings, indexMappings) { var _indexMappings$_meta, _targetMappings$_meta; return { ...targetMappings, _meta: { ...targetMappings._meta, migrationMappingPropertyHashes: { ...((_indexMappings$_meta = indexMappings._meta) === null || _indexMappings$_meta === void 0 ? void 0 : _indexMappings$_meta.migrationMappingPropertyHashes), ...((_targetMappings$_meta = targetMappings._meta) === null || _targetMappings$_meta === void 0 ? void 0 : _targetMappings$_meta.migrationMappingPropertyHashes) } } }; } /** * If `.kibana` and the version specific aliases both exists and * are pointing to the same index. This version's migration has already * been completed. */ function versionMigrationCompleted(currentAlias, versionAlias, aliases) { return aliases[currentAlias] != null && aliases[currentAlias] === aliases[versionAlias]; } function indexBelongsToLaterVersion(kibanaVersion, indexName) { const version = (0, _semver.valid)(indexVersion(indexName)); return version != null ? (0, _semver.gt)(version, kibanaVersion) : false; } function hasLaterVersionAlias(kibanaVersion, aliases) { const mostRecentAlias = Object.keys(aliases !== null && aliases !== void 0 ? aliases : {}).filter(aliasVersion).sort().pop(); const mostRecentAliasVersion = (0, _semver.valid)(aliasVersion(mostRecentAlias)); return mostRecentAliasVersion != null && (0, _semver.gt)(mostRecentAliasVersion, kibanaVersion) ? mostRecentAlias : undefined; } /** * Add new must_not clauses to the given query * in order to filter out the specified types * @param boolQuery the bool query to be enriched * @param types the types to be filtered out * @returns a new query container with the enriched query */ function addExcludedTypesToBoolQuery(types, boolQuery) { return addMustNotClausesToBoolQuery(types.map(type => ({ term: { type } })), boolQuery); } /** * Add the given clauses to the 'must' of the given query * @param filterClauses the clauses to be added to a 'must' * @param boolQuery the bool query to be enriched * @returns a new query container with the enriched query */ function addMustClausesToBoolQuery(filterClauses, boolQuery) { let must = []; if (boolQuery !== null && boolQuery !== void 0 && boolQuery.must) { must = must.concat(boolQuery.must); } must.push(...filterClauses); return { bool: { ...boolQuery, must } }; } /** * Add the given clauses to the 'must_not' of the given query * @param filterClauses the clauses to be added to a 'must_not' * @param boolQuery the bool query to be enriched * @returns a new query container with the enriched query */ function addMustNotClausesToBoolQuery(filterClauses, boolQuery) { let mustNot = []; if (boolQuery !== null && boolQuery !== void 0 && boolQuery.must_not) { mustNot = mustNot.concat(boolQuery.must_not); } mustNot.push(...filterClauses); return { bool: { ...boolQuery, must_not: mustNot } }; } /** * Extracts the version number from a >= 7.11 index * @param indexName A >= v7.11 index name */ function indexVersion(indexName) { return ((indexName === null || indexName === void 0 ? void 0 : indexName.match(/.+_(\d+\.\d+\.\d+)_\d+/)) || [])[1]; } /** * Extracts the version number from a >= 7.11 index alias * @param indexName A >= v7.11 index alias */ function aliasVersion(alias) { return ((alias === null || alias === void 0 ? void 0 : alias.match(/.+_(\d+\.\d+\.\d+)/)) || [])[1]; } /** @internal */ /** * Creates a record of alias -> index name pairs */ function getAliases(indices) { const aliases = {}; for (const index of Object.getOwnPropertyNames(indices)) { for (const alias of Object.getOwnPropertyNames(indices[index].aliases || {})) { const secondIndexThisAliasPointsTo = aliases[alias]; if (secondIndexThisAliasPointsTo != null) { return Either.left({ type: 'multiple_indices_per_alias', alias, indices: [secondIndexThisAliasPointsTo, index] }); } aliases[alias] = index; } } return Either.right(aliases); } /** * Build a list of alias actions to remove the provided aliases from the given index. */ function buildRemoveAliasActions(index, aliases, exclude) { return aliases.flatMap(alias => { if (exclude.includes(alias)) { return []; } return [{ remove: { index, alias, must_exist: true } }]; }); } /** * Given a document, creates a valid body to index the document using the Bulk API. */ const createBulkIndexOperationTuple = (doc, typeIndexMap = {}) => { return [{ index: { _id: doc._id, ...(typeIndexMap[doc._source.type] && { _index: typeIndexMap[doc._source.type] }), // use optimistic concurrency control to ensure that outdated // documents are only overwritten once with the latest version ...(typeof doc._seq_no !== 'undefined' && { if_seq_no: doc._seq_no }), ...(typeof doc._primary_term !== 'undefined' && { if_primary_term: doc._primary_term }) } }, doc._source]; }; /** * Given a document id, creates a valid body to delete the document using the Bulk API. */ exports.createBulkIndexOperationTuple = createBulkIndexOperationTuple; const createBulkDeleteOperationBody = _id => ({ delete: { _id } }); /** @internal */ exports.createBulkDeleteOperationBody = createBulkDeleteOperationBody; let MigrationType; exports.MigrationType = MigrationType; (function (MigrationType) { MigrationType["Compatible"] = "compatible"; MigrationType["Incompatible"] = "incompatible"; MigrationType["Unnecessary"] = "unnecessary"; MigrationType["Invalid"] = "invalid"; })(MigrationType || (exports.MigrationType = MigrationType = {})); function getMigrationType({ isMappingsCompatible, isVersionMigrationCompleted }) { if (isMappingsCompatible && isVersionMigrationCompleted) { return MigrationType.Unnecessary; } if (isMappingsCompatible && !isVersionMigrationCompleted) { return MigrationType.Compatible; } if (!isMappingsCompatible && !isVersionMigrationCompleted) { return MigrationType.Incompatible; } return MigrationType.Invalid; } /** * Generate a temporary index name, to reindex documents into it * @param index The name of the SO index * @param kibanaVersion The current kibana version * @returns A temporary index name to reindex documents */ const getTempIndexName = (indexPrefix, kibanaVersion) => `${indexPrefix}_${kibanaVersion}${REINDEX_TEMP_SUFFIX}`; /** Increase batchSize by 20% until a maximum of maxBatchSize */ exports.getTempIndexName = getTempIndexName; const increaseBatchSize = stateP => { const increasedBatchSize = Math.floor(stateP.batchSize * 1.2); return increasedBatchSize > stateP.maxBatchSize ? stateP.maxBatchSize : increasedBatchSize; }; exports.increaseBatchSize = increaseBatchSize; const getIndexTypes = state => { return state.indexTypesMap[state.indexPrefix]; }; exports.getIndexTypes = getIndexTypes;