"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useFetchPrevalence = exports.USER_NAME_AGG_KEY = exports.USERS_AGG_KEY = exports.HOST_NAME_AGG_KEY = exports.HOSTS_AGG_KEY = exports.FIELD_NAMES_AGG_KEY = exports.EVENT_KIND_AGG_KEY = void 0; var _esQuery = require("@kbn/es-query"); var _reactQuery = require("@tanstack/react-query"); var _fetch_data = require("../utils/fetch_data"); var _kibana = require("../../../common/lib/kibana"); var _use_timeline_data_filters = require("../../../timelines/containers/use_timeline_data_filters"); var _helpers = require("../../../helpers"); var _model = require("../../../common/store/sourcerer/model"); /* * 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 QUERY_KEY = 'useFetchFieldValuePairWithAggregation'; const FIELD_NAMES_AGG_KEY = 'fieldNames'; exports.FIELD_NAMES_AGG_KEY = FIELD_NAMES_AGG_KEY; const EVENT_KIND_AGG_KEY = 'eventKind'; exports.EVENT_KIND_AGG_KEY = EVENT_KIND_AGG_KEY; const HOST_NAME_AGG_KEY = 'hostName'; exports.HOST_NAME_AGG_KEY = HOST_NAME_AGG_KEY; const USER_NAME_AGG_KEY = 'userName'; exports.USER_NAME_AGG_KEY = USER_NAME_AGG_KEY; const HOSTS_AGG_KEY = 'hosts'; exports.HOSTS_AGG_KEY = HOSTS_AGG_KEY; const USERS_AGG_KEY = 'users'; exports.USERS_AGG_KEY = USERS_AGG_KEY; /** * Hook to fetch prevalence data for both the PrevalenceDetails and PrevalenceOverview components. * Here's how we fetch the data: * - the query filter is just limiting to the from/to datetime range * - we do 3 top level aggregations: * - one for each field/value pairs * - one for all the unique hosts in the environment * - one for all the unique users in the environment * For each field/value pair aggregated, we do 3 sub aggregations: * - one to retrieve the unique hosts which have the field/value pair * - one to retrieve the unique users which have the field/value pair * - one to retrieve how many documents are of the different type of event.kind * All of these values are then used to calculate the alert count, document count, host and user prevalence values. */ const useFetchPrevalence = ({ highlightedFieldsFilters, interval: { from, to } }) => { const { services: { data: { search: searchService } } } = (0, _kibana.useKibana)(); // retrieves detections and non-detections indices (for example, the alert security index from the current space and 'logs-*' indices) const { selectedPatterns } = (0, _use_timeline_data_filters.useTimelineDataFilters)((0, _helpers.isActiveTimeline)(_model.SourcererScopeName.default)); const searchRequest = buildSearchRequest(highlightedFieldsFilters, from, to, selectedPatterns); const { data, isLoading, isError } = (0, _reactQuery.useQuery)([QUERY_KEY, highlightedFieldsFilters, from, to], () => (0, _fetch_data.createFetchData)(searchService, searchRequest)); return { loading: isLoading, error: isError, data }; }; /** * Build the search request for the field/values pair, for a date range from/to. * The request contains aggregation by aggregationField. */ exports.useFetchPrevalence = useFetchPrevalence; const buildSearchRequest = (highlightedFieldsFilters, from, to, selectedPatterns) => { const query = (0, _esQuery.buildEsQuery)(undefined, [], [{ query: { bool: { filter: [{ range: { '@timestamp': { gte: from, lte: to } } }] } }, meta: {} }]); return buildAggregationSearchRequest(query, highlightedFieldsFilters, selectedPatterns); }; const buildAggregationSearchRequest = (query, highlightedFieldsFilters, selectedPatterns) => ({ params: { index: selectedPatterns, body: { query, aggs: { // with this aggregation, we can in a single call retrieve all the values for each field/value pairs [FIELD_NAMES_AGG_KEY]: { filters: { filters: highlightedFieldsFilters }, aggs: { // this sub aggregation allows us to retrieve all the hosts which have the field/value pair [HOST_NAME_AGG_KEY]: { cardinality: { field: 'host.name' } }, // this sub aggregation allows us to retrieve all the users which have the field/value pair [USER_NAME_AGG_KEY]: { cardinality: { field: 'user.name' } }, // we use this sub aggregation to differentiate between alerts (event.kind === 'signal') and documents (event.kind !== 'signal') [EVENT_KIND_AGG_KEY]: { terms: { field: 'event.kind', size: 10 // there should be only 8 different value for the event.kind field } } } }, // retrieve all the unique hosts in the environment [HOSTS_AGG_KEY]: { cardinality: { field: 'host.name' } }, // retrieve all the unique users in the environment [USERS_AGG_KEY]: { cardinality: { field: 'user.name' } } }, size: 0 } } });