"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.createRule = createRule; var _semver = _interopRequireDefault(require("semver")); var _boom = _interopRequireDefault(require("@hapi/boom")); var _server = require("@kbn/core/server"); var _apmUtils = require("@kbn/apm-utils"); var _parse_duration = require("../../../../../common/parse_duration"); var _authorization = require("../../../../authorization"); var _lib = require("../../../../lib"); var _rule_execution_status = require("../../../../lib/rule_execution_status"); var _lib2 = require("../../../../rules_client/lib"); var _common = require("../../../../rules_client/common"); var _audit_events = require("../../../../rules_client/common/audit_events"); var _transforms = require("../../transforms"); var _schemas = require("../../schemas"); var _schemas2 = require("./schemas"); /* * 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. */ async function createRule(context, createParams) { var _data$notifyWhen, _data$throttle, _data$throttle2; const { data: initialData, options, allowMissingConnectorSecrets } = createParams; const data = { ...initialData, actions: (0, _lib2.addGeneratedActionValues)(initialData.actions) }; const id = (options === null || options === void 0 ? void 0 : options.id) || _server.SavedObjectsUtils.generateId(); try { _schemas2.createRuleDataSchema.validate(data); } catch (error) { throw _boom.default.badRequest(`Error validating create data - ${error.message}`); } try { await (0, _apmUtils.withSpan)({ name: 'authorization.ensureAuthorized', type: 'rules' }, () => context.authorization.ensureAuthorized({ ruleTypeId: data.alertTypeId, consumer: data.consumer, operation: _authorization.WriteOperations.Create, entity: _authorization.AlertingAuthorizationEntity.Rule })); } catch (error) { var _context$auditLogger; (_context$auditLogger = context.auditLogger) === null || _context$auditLogger === void 0 ? void 0 : _context$auditLogger.log((0, _audit_events.ruleAuditEvent)({ action: _audit_events.RuleAuditAction.CREATE, savedObject: { type: 'alert', id }, error })); throw error; } context.ruleTypeRegistry.ensureRuleTypeEnabled(data.alertTypeId); // Throws an error if alert type isn't registered const ruleType = context.ruleTypeRegistry.get(data.alertTypeId); const validatedAlertTypeParams = (0, _lib.validateRuleTypeParams)(data.params, ruleType.validate.params); const username = await context.getUserName(); let createdAPIKey = null; let isAuthTypeApiKey = false; try { isAuthTypeApiKey = context.isAuthenticationTypeAPIKey(); const name = (0, _common.generateAPIKeyName)(ruleType.id, data.name); createdAPIKey = data.enabled ? isAuthTypeApiKey ? context.getAuthenticationAPIKey(`${name}-user-created`) : await (0, _apmUtils.withSpan)({ name: 'createAPIKey', type: 'rules' }, () => context.createAPIKey(name)) : null; } catch (error) { throw _boom.default.badRequest(`Error creating rule: could not create API key - ${error.message}`); } await (0, _apmUtils.withSpan)({ name: 'validateActions', type: 'rules' }, () => (0, _lib2.validateActions)(context, ruleType, data, allowMissingConnectorSecrets)); // Throw error if schedule interval is less than the minimum and we are enforcing it const intervalInMs = (0, _parse_duration.parseDuration)(data.schedule.interval); if (intervalInMs < context.minimumScheduleIntervalInMs && context.minimumScheduleInterval.enforce) { throw _boom.default.badRequest(`Error creating rule: the interval is less than the allowed minimum interval of ${context.minimumScheduleInterval.value}`); } // Extract saved object references for this rule const { references, params: updatedParams, actions } = await (0, _apmUtils.withSpan)({ name: 'extractReferences', type: 'rules' }, () => (0, _lib2.extractReferences)(context, ruleType, data.actions, validatedAlertTypeParams)); const createTime = Date.now(); const lastRunTimestamp = new Date(); const legacyId = _semver.default.lt(context.kibanaVersion, '8.0.0') ? id : null; const notifyWhen = (0, _lib.getRuleNotifyWhenType)((_data$notifyWhen = data.notifyWhen) !== null && _data$notifyWhen !== void 0 ? _data$notifyWhen : null, (_data$throttle = data.throttle) !== null && _data$throttle !== void 0 ? _data$throttle : null); const throttle = (_data$throttle2 = data.throttle) !== null && _data$throttle2 !== void 0 ? _data$throttle2 : null; // Convert domain rule object to ES rule attributes const ruleAttributes = (0, _transforms.transformRuleDomainToRuleAttributes)({ ...data, // TODO (http-versioning) create a rule domain version of this function // Right now this works because the 2 types can interop but it's not ideal ...(0, _common.apiKeyAsRuleDomainProperties)(createdAPIKey, username, isAuthTypeApiKey), id, createdBy: username, updatedBy: username, createdAt: new Date(createTime), updatedAt: new Date(createTime), snoozeSchedule: [], muteAll: false, mutedInstanceIds: [], notifyWhen, throttle, executionStatus: (0, _rule_execution_status.getRuleExecutionStatusPending)(lastRunTimestamp.toISOString()), monitoring: (0, _lib.getDefaultMonitoringRuleDomainProperties)(lastRunTimestamp.toISOString()), revision: 0, running: false }, { legacyId, actionsWithRefs: actions, paramsWithRefs: updatedParams }); const createdRuleSavedObject = await (0, _apmUtils.withSpan)({ name: 'createRuleSavedObject', type: 'rules' }, () => (0, _lib2.createRuleSavedObject)(context, { intervalInMs, rawRule: ruleAttributes, references, ruleId: id, options, returnRuleAttributes: true })); // Convert ES RuleAttributes back to domain rule object const ruleDomain = (0, _transforms.transformRuleAttributesToRuleDomain)(createdRuleSavedObject.attributes, { id: createdRuleSavedObject.id, logger: context.logger, ruleType: context.ruleTypeRegistry.get(createdRuleSavedObject.attributes.alertTypeId), references }); // Try to validate created rule, but don't throw. try { _schemas.ruleDomainSchema.validate(ruleDomain); } catch (e) { context.logger.warn(`Error validating created rule domain object for id: ${id}, ${e}`); } // Convert domain rule to rule (Remove certain properties) const rule = (0, _transforms.transformRuleDomainToRule)(ruleDomain, { isPublic: true }); // TODO (http-versioning): Remove this cast, this enables us to move forward // without fixing all of other solution types return rule; }