"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.bulkDisableRules = void 0; var _esQuery = require("@kbn/es-query"); var _apmUtils = require("@kbn/apm-utils"); var _pMap = _interopRequireDefault(require("p-map")); var _lib = require("../../lib"); var _audit_events = require("../common/audit_events"); var _common = require("../common"); var _lib2 = require("../lib"); /* * 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. */ const bulkDisableRules = async (context, options) => { const { ids, filter } = (0, _common.getAndValidateCommonBulkOptions)(options); const kueryNodeFilter = ids ? (0, _lib.convertRuleIdsToKueryNode)(ids) : (0, _common.buildKueryNodeFilter)(filter); const authorizationFilter = await (0, _lib2.getAuthorizationFilter)(context, { action: 'DISABLE' }); const kueryNodeFilterWithAuth = authorizationFilter && kueryNodeFilter ? _esQuery.nodeBuilder.and([kueryNodeFilter, authorizationFilter]) : kueryNodeFilter; const { total } = await (0, _lib2.checkAuthorizationAndGetTotal)(context, { filter: kueryNodeFilterWithAuth, action: 'DISABLE' }); const { errors, rules, accListSpecificForBulkOperation } = await (0, _apmUtils.withSpan)({ name: 'retryIfBulkOperationConflicts', type: 'rules' }, () => (0, _common.retryIfBulkOperationConflicts)({ action: 'DISABLE', logger: context.logger, bulkOperation: filterKueryNode => bulkDisableRulesWithOCC(context, { filter: filterKueryNode }), filter: kueryNodeFilterWithAuth })); const [taskIdsToDisable, taskIdsToDelete] = accListSpecificForBulkOperation; await Promise.allSettled([tryToDisableTasks({ taskIdsToDisable, logger: context.logger, taskManager: context.taskManager }), (0, _common.tryToRemoveTasks)({ taskIdsToDelete, logger: context.logger, taskManager: context.taskManager })]); const updatedRules = rules.map(({ id, attributes, references }) => { return (0, _lib2.getAlertFromRaw)(context, id, attributes.alertTypeId, attributes, references, false); }); return { errors, rules: updatedRules, total }; }; exports.bulkDisableRules = bulkDisableRules; const bulkDisableRulesWithOCC = async (context, { filter }) => { const additionalFilter = _esQuery.nodeBuilder.is('alert.attributes.enabled', 'true'); const rulesFinder = await (0, _apmUtils.withSpan)({ name: 'encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser', type: 'rules' }, () => context.encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser({ filter: filter ? _esQuery.nodeBuilder.and([filter, additionalFilter]) : additionalFilter, type: 'alert', perPage: 100, ...(context.namespace ? { namespaces: [context.namespace] } : undefined) })); const rulesToDisable = []; const errors = []; const ruleNameToRuleIdMapping = {}; const username = await context.getUserName(); await (0, _apmUtils.withSpan)({ name: 'Get rules, collect them and their attributes', type: 'rules' }, async () => { for await (const response of rulesFinder.find()) { await (0, _pMap.default)(response.saved_objects, async rule => { try { var _context$auditLogger; await (0, _lib2.recoverRuleAlerts)(context, rule.id, rule.attributes); if (rule.attributes.name) { ruleNameToRuleIdMapping[rule.id] = rule.attributes.name; } const migratedActions = await (0, _lib2.migrateLegacyActions)(context, { ruleId: rule.id, actions: rule.attributes.actions, references: rule.references, attributes: rule.attributes }); const updatedAttributes = (0, _lib2.updateMeta)(context, { ...rule.attributes, ...(migratedActions.hasLegacyActions ? { actions: migratedActions.resultedActions, throttle: undefined, notifyWhen: undefined } : {}), enabled: false, scheduledTaskId: rule.attributes.scheduledTaskId === rule.id ? rule.attributes.scheduledTaskId : null, updatedBy: username, updatedAt: new Date().toISOString() }); rulesToDisable.push({ ...rule, attributes: { ...updatedAttributes }, ...(migratedActions.hasLegacyActions ? { references: migratedActions.resultedReferences } : {}) }); (_context$auditLogger = context.auditLogger) === null || _context$auditLogger === void 0 ? void 0 : _context$auditLogger.log((0, _audit_events.ruleAuditEvent)({ action: _audit_events.RuleAuditAction.DISABLE, outcome: 'unknown', savedObject: { type: 'alert', id: rule.id } })); } catch (error) { var _rule$attributes, _context$auditLogger2; errors.push({ message: error.message, rule: { id: rule.id, name: (_rule$attributes = rule.attributes) === null || _rule$attributes === void 0 ? void 0 : _rule$attributes.name } }); (_context$auditLogger2 = context.auditLogger) === null || _context$auditLogger2 === void 0 ? void 0 : _context$auditLogger2.log((0, _audit_events.ruleAuditEvent)({ action: _audit_events.RuleAuditAction.DISABLE, error })); } }); } await rulesFinder.close(); }); const result = await (0, _apmUtils.withSpan)({ name: 'unsecuredSavedObjectsClient.bulkCreate', type: 'rules' }, () => context.unsecuredSavedObjectsClient.bulkCreate(rulesToDisable, { overwrite: true })); const taskIdsToDisable = []; const taskIdsToDelete = []; const disabledRules = []; result.saved_objects.forEach(rule => { if (rule.error === undefined) { if (rule.attributes.scheduledTaskId) { if (rule.attributes.scheduledTaskId !== rule.id) { taskIdsToDelete.push(rule.attributes.scheduledTaskId); } else { taskIdsToDisable.push(rule.attributes.scheduledTaskId); } } disabledRules.push(rule); } else { var _rule$error$message, _ruleNameToRuleIdMapp; errors.push({ message: (_rule$error$message = rule.error.message) !== null && _rule$error$message !== void 0 ? _rule$error$message : 'n/a', status: rule.error.statusCode, rule: { id: rule.id, name: (_ruleNameToRuleIdMapp = ruleNameToRuleIdMapping[rule.id]) !== null && _ruleNameToRuleIdMapp !== void 0 ? _ruleNameToRuleIdMapp : 'n/a' } }); } }); return { errors, rules: disabledRules, accListSpecificForBulkOperation: [taskIdsToDisable, taskIdsToDelete] }; }; const tryToDisableTasks = async ({ taskIdsToDisable, logger, taskManager }) => { return await (0, _apmUtils.withSpan)({ name: 'taskManager.bulkDisable', type: 'rules' }, async () => { if (taskIdsToDisable.length > 0) { try { const resultFromDisablingTasks = await taskManager.bulkDisable(taskIdsToDisable); if (resultFromDisablingTasks.tasks.length) { logger.debug(`Successfully disabled schedules for underlying tasks: ${resultFromDisablingTasks.tasks.map(task => task.id).join(', ')}`); } if (resultFromDisablingTasks.errors.length) { logger.error(`Failure to disable schedules for underlying tasks: ${resultFromDisablingTasks.errors.map(error => error.id).join(', ')}`); } } catch (error) { logger.error(`Failure to disable schedules for underlying tasks: ${taskIdsToDisable.join(', ')}. TaskManager bulkDisable failed with Error: ${error.message}`); } } }); };