"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.addRuleExceptions = void 0; exports.bulkExportRules = bulkExportRules; exports.patchRule = exports.installFleetPackage = exports.importRules = exports.getPrebuiltRulesStatus = exports.getPrePackagedRulesStatus = exports.findRuleExceptionReferences = exports.fetchRulesSnoozeSettings = exports.fetchRules = exports.fetchRuleManagementFilters = exports.fetchRuleById = exports.fetchCoverageOverview = exports.fetchConnectors = exports.fetchConnectorTypes = exports.exportRules = exports.createRule = exports.bulkInstallFleetPackages = void 0; exports.performBulkAction = performBulkAction; exports.updateRule = exports.reviewRuleUpgrade = exports.reviewRuleInstall = exports.previewRule = exports.performUpgradeSpecificRules = exports.performUpgradeAllRules = exports.performInstallSpecificRules = exports.performInstallAllRules = void 0; var _common = require("@kbn/alerting-plugin/common"); var _common2 = require("@kbn/actions-plugin/common"); var _common3 = require("@kbn/fleet-plugin/common"); var _rule_filtering = require("../../../../common/detection_engine/rule_management/rule_filtering"); var _rule_management = require("../../../../common/api/detection_engine/rule_management"); var _constants = require("../../../../common/constants"); var _prebuilt_rules = require("../../../../common/api/detection_engine/prebuilt_rules"); var _rule_exceptions = require("../../../../common/api/detection_engine/rule_exceptions"); var _bulk_actions_route = require("../../../../common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route"); var _kibana = require("../../../common/lib/kibana"); var i18n = _interopRequireWildcard(require("../../../detections/pages/detection_engine/rules/translations")); 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; you may not use this file except in compliance with the Elastic License * 2.0. */ /** * Create provided Rule * * @param rule RuleCreateProps to add * @param signal to cancel request * * @throws An error if response is not OK */ const createRule = async ({ rule, signal }) => _kibana.KibanaServices.get().http.fetch(_constants.DETECTION_ENGINE_RULES_URL, { method: 'POST', body: JSON.stringify(rule), signal }); /** * Update provided Rule using PUT * * @param rule RuleUpdateProps to be updated * @param signal to cancel request * * @returns Promise An updated rule * * In fact this function should return Promise but it'd require massive refactoring. * It should be addressed as a part of OpenAPI schema adoption. * * @throws An error if response is not OK */ exports.createRule = createRule; const updateRule = async ({ rule, signal }) => _kibana.KibanaServices.get().http.fetch(_constants.DETECTION_ENGINE_RULES_URL, { method: 'PUT', body: JSON.stringify(rule), signal }); /** * Patch provided rule * NOTE: The rule edit flow does NOT use patch as it relies on the * functionality of PUT to delete field values when not provided, if * just expecting changes, use this `patchRule` * * @param ruleProperties to patch * @param signal to cancel request * * @throws An error if response is not OK */ exports.updateRule = updateRule; const patchRule = async ({ ruleProperties, signal }) => _kibana.KibanaServices.get().http.fetch(_constants.DETECTION_ENGINE_RULES_URL, { method: 'PATCH', body: JSON.stringify(ruleProperties), signal }); /** * Preview provided Rule * * @param rule RuleCreateProps to add * @param signal to cancel request * * @throws An error if response is not OK */ exports.patchRule = patchRule; const previewRule = async ({ rule, signal }) => _kibana.KibanaServices.get().http.fetch(_constants.DETECTION_ENGINE_RULES_PREVIEW, { method: 'POST', body: JSON.stringify(rule), signal }); /** * Fetches all rules from the Detection Engine API * * @param filterOptions desired filters (e.g. filter/sortField/sortOrder) * @param pagination desired pagination options (e.g. page/perPage) * @param signal to cancel request * * @throws An error if response is not OK */ exports.previewRule = previewRule; const fetchRules = async ({ filterOptions = { filter: '', showCustomRules: false, showElasticRules: false, tags: [] }, sortingOptions = { field: 'enabled', order: 'desc' }, pagination = { page: 1, perPage: 20 }, signal }) => { const kql = (0, _rule_filtering.convertRulesFilterToKQL)(filterOptions); const query = { page: pagination.page, per_page: pagination.perPage, sort_field: sortingOptions.field, sort_order: sortingOptions.order, ...(kql !== '' ? { filter: kql } : {}) }; return _kibana.KibanaServices.get().http.fetch(_constants.DETECTION_ENGINE_RULES_URL_FIND, { method: 'GET', query, signal }); }; /** * Fetch a Rule by providing a Rule ID * * @param id Rule ID's (not rule_id) * @param signal to cancel request * * @returns Promise * * In fact this function should return Promise but it'd require massive refactoring. * It should be addressed as a part of OpenAPI schema adoption. * * @throws An error if response is not OK */ exports.fetchRules = fetchRules; const fetchRuleById = async ({ id, signal }) => _kibana.KibanaServices.get().http.fetch(_constants.DETECTION_ENGINE_RULES_URL, { method: 'GET', query: { id }, signal }); /** * Fetch rule snooze settings for each provided ruleId * * @param ids Rule IDs (not rule_id) * @param signal to cancel request * * @returns An error if response is not OK */ exports.fetchRuleById = fetchRuleById; const fetchRulesSnoozeSettings = async ({ ids, signal }) => { var _response$data; const response = await _kibana.KibanaServices.get().http.fetch(_common.INTERNAL_ALERTING_API_FIND_RULES_PATH, { method: 'GET', query: { filter: ids.map(x => `alert.id:"alert:${x}"`).join(' or '), fields: JSON.stringify(['muteAll', 'activeSnoozes', 'isSnoozedUntil', 'snoozeSchedule']), per_page: ids.length }, signal }); return (_response$data = response.data) === null || _response$data === void 0 ? void 0 : _response$data.reduce((result, { id, ...snoozeSettings }) => { var _snoozeSettings$mute_, _snoozeSettings$activ; result[id] = { muteAll: (_snoozeSettings$mute_ = snoozeSettings.mute_all) !== null && _snoozeSettings$mute_ !== void 0 ? _snoozeSettings$mute_ : false, activeSnoozes: (_snoozeSettings$activ = snoozeSettings.active_snoozes) !== null && _snoozeSettings$activ !== void 0 ? _snoozeSettings$activ : [], isSnoozedUntil: snoozeSettings.is_snoozed_until ? new Date(snoozeSettings.is_snoozed_until) : undefined, snoozeSchedule: snoozeSettings.snooze_schedule }; return result; }, {}); }; exports.fetchRulesSnoozeSettings = fetchRulesSnoozeSettings; const fetchConnectors = signal => _kibana.KibanaServices.get().http.fetch(`${_common2.BASE_ACTION_API_PATH}/connectors`, { method: 'GET', signal }); exports.fetchConnectors = fetchConnectors; const fetchCoverageOverview = async ({ filter, signal }) => _kibana.KibanaServices.get().http.fetch(_rule_management.RULE_MANAGEMENT_COVERAGE_OVERVIEW_URL, { method: 'POST', body: JSON.stringify({ filter }), signal }); exports.fetchCoverageOverview = fetchCoverageOverview; const fetchConnectorTypes = signal => _kibana.KibanaServices.get().http.fetch(`${_common2.BASE_ACTION_API_PATH}/connector_types`, { method: 'GET', signal, query: { feature_id: 'siem' } }); exports.fetchConnectorTypes = fetchConnectorTypes; /** * Perform bulk action with rules selected by a filter query * * @param bulkAction bulk action which contains type, query or ids and edit fields * @param dryRun enables dry run mode for bulk actions * * @throws An error if response is not OK */ async function performBulkAction({ bulkAction, dryRun = false }) { const params = { action: bulkAction.type, query: bulkAction.query, ids: bulkAction.ids, edit: bulkAction.type === _bulk_actions_route.BulkActionType.edit ? bulkAction.editPayload : undefined, duplicate: bulkAction.type === _bulk_actions_route.BulkActionType.duplicate ? bulkAction.duplicatePayload : undefined }; return _kibana.KibanaServices.get().http.fetch(_constants.DETECTION_ENGINE_RULES_BULK_ACTION, { method: 'POST', body: JSON.stringify(params), query: { dry_run: dryRun } }); } /** * Bulk export rules selected by a filter query * * @param queryOrIds filter query to select rules to perform bulk action with or rule ids to select rules to perform bulk action with * * @throws An error if response is not OK */ async function bulkExportRules(queryOrIds) { const params = { action: _bulk_actions_route.BulkActionType.export, query: queryOrIds.query, ids: queryOrIds.ids }; return _kibana.KibanaServices.get().http.fetch(_constants.DETECTION_ENGINE_RULES_BULK_ACTION, { method: 'POST', body: JSON.stringify(params) }); } /** * Imports rules in the same format as exported via the _export API * * @param fileToImport File to upload containing rules to import * @param overwrite whether or not to overwrite rules with the same ruleId * @param signal AbortSignal for cancelling request * * @throws An error if response is not OK */ const importRules = async ({ fileToImport, overwrite = false, overwriteExceptions = false, overwriteActionConnectors = false, signal }) => { const formData = new FormData(); formData.append('file', fileToImport); return _kibana.KibanaServices.get().http.fetch(`${_constants.DETECTION_ENGINE_RULES_URL}/_import`, { method: 'POST', headers: { 'Content-Type': undefined }, query: { overwrite, overwrite_exceptions: overwriteExceptions, overwrite_action_connectors: overwriteActionConnectors }, body: formData, signal }); }; /** * Export rules from the server as a file download * * @param excludeExportDetails whether or not to exclude additional details at bottom of exported file (defaults to false) * @param filename of exported rules. Be sure to include `.ndjson` extension! (defaults to localized `rules_export.ndjson`) * @param ruleIds array of rule_id's (not id!) to export (empty array exports _all_ rules) * @param signal AbortSignal for cancelling request * * @throws An error if response is not OK */ exports.importRules = importRules; const exportRules = async ({ excludeExportDetails = false, filename = `${i18n.EXPORT_FILENAME}.ndjson`, ids = [], signal }) => { const body = ids.length > 0 ? JSON.stringify({ objects: ids.map(rule => ({ rule_id: rule })) }) : undefined; return _kibana.KibanaServices.get().http.fetch(`${_constants.DETECTION_ENGINE_RULES_URL}/_export`, { method: 'POST', body, query: { exclude_export_details: excludeExportDetails, file_name: filename }, signal }); }; /** * Fetch rule filters related information like installed rules count, tags and etc * * @param signal to cancel request * * @throws An error if response is not OK */ exports.exportRules = exportRules; const fetchRuleManagementFilters = async ({ signal }) => _kibana.KibanaServices.get().http.fetch(_rule_management.RULE_MANAGEMENT_FILTERS_URL, { method: 'GET', signal }); /** * Get pre packaged rules Status * * @param signal AbortSignal for cancelling request * * @throws An error if response is not OK */ exports.fetchRuleManagementFilters = fetchRuleManagementFilters; const getPrePackagedRulesStatus = async ({ signal }) => _kibana.KibanaServices.get().http.fetch(_prebuilt_rules.PREBUILT_RULES_STATUS_URL, { method: 'GET', signal }); /** * Fetch info on what exceptions lists are referenced by what rules * * @param lists exception list information needed for making request * @param signal to cancel request * * @throws An error if response is not OK */ exports.getPrePackagedRulesStatus = getPrePackagedRulesStatus; const findRuleExceptionReferences = async ({ lists, signal }) => { const idsUndefined = lists.some(({ id }) => id === undefined); const query = idsUndefined ? { namespace_types: lists.map(({ namespaceType }) => namespaceType).join(',') } : { ids: lists.map(({ id }) => id).join(','), list_ids: lists.map(({ listId }) => listId).join(','), namespace_types: lists.map(({ namespaceType }) => namespaceType).join(',') }; return _kibana.KibanaServices.get().http.fetch(_rule_exceptions.DETECTION_ENGINE_RULES_EXCEPTIONS_REFERENCE_URL, { method: 'GET', query, signal }); }; /** * Add exception items to default rule exception list * * @param ruleId `id` of rule to add items to * @param items CreateRuleExceptionListItemSchema[] * @param signal to cancel request * * @throws An error if response is not OK */ exports.findRuleExceptionReferences = findRuleExceptionReferences; const addRuleExceptions = async ({ ruleId, items, signal }) => _kibana.KibanaServices.get().http.fetch(`${_constants.DETECTION_ENGINE_RULES_URL}/${ruleId}/exceptions`, { method: 'POST', body: JSON.stringify({ items }), signal }); exports.addRuleExceptions = addRuleExceptions; /** * Install a Fleet package from the registry * * @param packageName Name of the package to install * @param packageVersion Version of the package to install * @param prerelease Whether to install a prerelease version of the package * @param force Whether to force install the package. If false, the package will only be installed if it is not already installed * * @returns The response from the Fleet API */ const installFleetPackage = ({ packageName, packageVersion, prerelease = false, force = true }) => { return _kibana.KibanaServices.get().http.post(_common3.epmRouteService.getInstallPath(packageName, packageVersion), { query: { prerelease }, body: JSON.stringify({ force }) }); }; exports.installFleetPackage = installFleetPackage; /** * Install multiple Fleet packages from the registry * * @param packages Array of package names to install * @param prerelease Whether to install prerelease versions of the packages * * @returns The response from the Fleet API */ const bulkInstallFleetPackages = ({ packages, prerelease = false }) => { return _kibana.KibanaServices.get().http.post(_common3.epmRouteService.getBulkInstallPath(), { query: { prerelease }, body: JSON.stringify({ packages }) }); }; /** * NEW PREBUILT RULES ROUTES START HERE! 👋 * USE THESE ONES! THEY'RE THE NICE ONES, PROMISE! */ /** * Get prebuilt rules status * * @param signal AbortSignal for cancelling request * * @throws An error if response is not OK */ exports.bulkInstallFleetPackages = bulkInstallFleetPackages; const getPrebuiltRulesStatus = async ({ signal }) => _kibana.KibanaServices.get().http.fetch(_prebuilt_rules.GET_PREBUILT_RULES_STATUS_URL, { method: 'GET', signal }); /** * Review prebuilt rules upgrade * * @param signal AbortSignal for cancelling request * * @throws An error if response is not OK */ exports.getPrebuiltRulesStatus = getPrebuiltRulesStatus; const reviewRuleUpgrade = async ({ signal }) => _kibana.KibanaServices.get().http.fetch(_prebuilt_rules.REVIEW_RULE_UPGRADE_URL, { method: 'POST', signal }); /** * Review prebuilt rules install (new rules) * * @param signal AbortSignal for cancelling request * * @throws An error if response is not OK */ exports.reviewRuleUpgrade = reviewRuleUpgrade; const reviewRuleInstall = async ({ signal }) => _kibana.KibanaServices.get().http.fetch(_prebuilt_rules.REVIEW_RULE_INSTALLATION_URL, { method: 'POST', signal }); exports.reviewRuleInstall = reviewRuleInstall; const performInstallAllRules = async () => _kibana.KibanaServices.get().http.fetch(_prebuilt_rules.PERFORM_RULE_INSTALLATION_URL, { method: 'POST', body: JSON.stringify({ mode: 'ALL_RULES' }) }); exports.performInstallAllRules = performInstallAllRules; const performInstallSpecificRules = async rules => _kibana.KibanaServices.get().http.fetch(_prebuilt_rules.PERFORM_RULE_INSTALLATION_URL, { method: 'POST', body: JSON.stringify({ mode: 'SPECIFIC_RULES', rules }) }); exports.performInstallSpecificRules = performInstallSpecificRules; const performUpgradeAllRules = async () => _kibana.KibanaServices.get().http.fetch(_prebuilt_rules.PERFORM_RULE_UPGRADE_URL, { method: 'POST', body: JSON.stringify({ mode: 'ALL_RULES', pick_version: 'TARGET' }) }); exports.performUpgradeAllRules = performUpgradeAllRules; const performUpgradeSpecificRules = async rules => _kibana.KibanaServices.get().http.fetch(_prebuilt_rules.PERFORM_RULE_UPGRADE_URL, { method: 'POST', body: JSON.stringify({ mode: 'SPECIFIC_RULES', rules, pick_version: 'TARGET' // Setting fixed 'TARGET' temporarily for Milestone 2 }) }); exports.performUpgradeSpecificRules = performUpgradeSpecificRules;