"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.tryToEnableTasks = exports.bulkEnableRules = void 0; var _pMap = _interopRequireDefault(require("p-map")); var _esQuery = require("@kbn/es-query"); var _apmUtils = require("@kbn/apm-utils"); var _server = require("@kbn/task-manager-plugin/server"); 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 getShouldScheduleTask = async (context, scheduledTaskId) => { if (!scheduledTaskId) return true; try { // make sure scheduledTaskId exist return await (0, _apmUtils.withSpan)({ name: 'getShouldScheduleTask', type: 'rules' }, async () => { const task = await context.taskManager.get(scheduledTaskId); // Check whether task status is unrecognized. If so, we want to delete // this task and create a fresh one if (task.status === _server.TaskStatus.Unrecognized) { await context.taskManager.removeIfExists(scheduledTaskId); return true; } return false; }); } catch (err) { return true; } }; const bulkEnableRules = 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: 'ENABLE' }); const kueryNodeFilterWithAuth = authorizationFilter && kueryNodeFilter ? _esQuery.nodeBuilder.and([kueryNodeFilter, authorizationFilter]) : kueryNodeFilter; const { total } = await (0, _lib2.checkAuthorizationAndGetTotal)(context, { filter: kueryNodeFilterWithAuth, action: 'ENABLE' }); const { errors, rules, accListSpecificForBulkOperation } = await (0, _common.retryIfBulkOperationConflicts)({ action: 'ENABLE', logger: context.logger, bulkOperation: filterKueryNode => bulkEnableRulesWithOCC(context, { filter: filterKueryNode }), filter: kueryNodeFilterWithAuth }); const [taskIdsToEnable] = accListSpecificForBulkOperation; const taskIdsFailedToBeEnabled = await tryToEnableTasks({ taskIdsToEnable, 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, taskIdsFailedToBeEnabled }; }; exports.bulkEnableRules = bulkEnableRules; const bulkEnableRulesWithOCC = async (context, { filter }) => { const additionalFilter = _esQuery.nodeBuilder.is('alert.attributes.enabled', 'false'); const rulesFinder = await (0, _apmUtils.withSpan)({ name: 'encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser', type: 'rules' }, async () => await context.encryptedSavedObjectsClient.createPointInTimeFinderDecryptedAsInternalUser({ filter: filter ? _esQuery.nodeBuilder.and([filter, additionalFilter]) : additionalFilter, type: 'alert', perPage: 100, ...(context.namespace ? { namespaces: [context.namespace] } : undefined) })); const rulesToEnable = []; 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; if (rule.attributes.actions.length) { try { await context.actionsAuthorization.ensureAuthorized({ operation: 'execute' }); } catch (error) { throw Error(`Rule not authorized for bulk enable - ${error.message}`); } } 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, ...(!rule.attributes.apiKey && (await (0, _lib2.createNewAPIKeySet)(context, { id: rule.attributes.alertTypeId, ruleName: rule.attributes.name, username, shouldUpdateApiKey: true }))), ...(migratedActions.hasLegacyActions ? { actions: migratedActions.resultedActions, throttle: undefined, notifyWhen: undefined } : {}), enabled: true, updatedBy: username, updatedAt: new Date().toISOString(), executionStatus: { status: 'pending', lastDuration: 0, lastExecutionDate: new Date().toISOString(), error: null, warning: null } }); const shouldScheduleTask = await getShouldScheduleTask(context, rule.attributes.scheduledTaskId); let scheduledTaskId; if (shouldScheduleTask) { const scheduledTask = await (0, _lib2.scheduleTask)(context, { id: rule.id, consumer: rule.attributes.consumer, ruleTypeId: rule.attributes.alertTypeId, schedule: rule.attributes.schedule, throwOnConflict: false }); scheduledTaskId = scheduledTask.id; } rulesToEnable.push({ ...rule, attributes: { ...updatedAttributes, ...(scheduledTaskId ? { scheduledTaskId } : undefined) }, ...(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.ENABLE, 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.ENABLE, error })); } }); } await rulesFinder.close(); }); const result = await (0, _apmUtils.withSpan)({ name: 'unsecuredSavedObjectsClient.bulkCreate', type: 'rules' }, () => context.unsecuredSavedObjectsClient.bulkCreate(rulesToEnable, { overwrite: true })); const rules = []; const taskIdsToEnable = []; result.saved_objects.forEach(rule => { if (rule.error === undefined) { if (rule.attributes.scheduledTaskId) { taskIdsToEnable.push(rule.attributes.scheduledTaskId); } rules.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, accListSpecificForBulkOperation: [taskIdsToEnable] }; }; const tryToEnableTasks = async ({ taskIdsToEnable, logger, taskManager }) => { const taskIdsFailedToBeEnabled = []; if (taskIdsToEnable.length > 0) { try { var _resultFromEnablingTa; const resultFromEnablingTasks = await (0, _apmUtils.withSpan)({ name: 'taskManager.bulkEnable', type: 'rules' }, async () => taskManager.bulkEnable(taskIdsToEnable)); resultFromEnablingTasks === null || resultFromEnablingTasks === void 0 ? void 0 : (_resultFromEnablingTa = resultFromEnablingTasks.errors) === null || _resultFromEnablingTa === void 0 ? void 0 : _resultFromEnablingTa.forEach(error => { taskIdsFailedToBeEnabled.push(error.id); }); if (resultFromEnablingTasks.tasks.length) { logger.debug(`Successfully enabled schedules for underlying tasks: ${resultFromEnablingTasks.tasks.map(task => task.id).join(', ')}`); } if (resultFromEnablingTasks.errors.length) { logger.error(`Failure to enable schedules for underlying tasks: ${resultFromEnablingTasks.errors.map(error => error.id).join(', ')}`); } } catch (error) { taskIdsFailedToBeEnabled.push(...taskIdsToEnable); logger.error(`Failure to enable schedules for underlying tasks: ${taskIdsToEnable.join(', ')}. TaskManager bulkEnable failed with Error: ${error.message}`); } } return taskIdsFailedToBeEnabled; }; exports.tryToEnableTasks = tryToEnableTasks;