From e8e53e36e580b7473da275259d88aa6e9f3fcf31 Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Fri, 20 Aug 2021 12:52:34 -0400 Subject: [PATCH] [RAC] Get o11y alerts in alerts table (#109346) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * get back index names in o11y * testing and integration * fix types * Avoid using the rule data client for field list * Remove left-over index argument * no needs of alert consumer anymore Co-authored-by: Felix Stürmer --- .../public/components/case_view/index.tsx | 5 +- .../components/timeline_context/index.tsx | 8 +--- .../public/pages/alerts/alerts_search_bar.tsx | 19 ++++++-- .../pages/alerts/alerts_table_t_grid.tsx | 18 ++----- .../public/pages/alerts/index.tsx | 47 +++++++++++++++---- x-pack/plugins/observability/server/plugin.ts | 14 +----- .../server/routes/register_routes.ts | 8 ++-- .../observability/server/routes/rules.ts | 25 ++++++++-- .../observability/server/routes/types.ts | 4 +- .../server/alert_data_client/alerts_client.ts | 4 +- .../rule_data_plugin_service.mock.ts | 1 + .../rule_data_plugin_service.ts | 12 +++++ .../cases/components/case_view/index.tsx | 7 +-- .../side_panel/event_details/index.tsx | 6 --- .../timelines/components/side_panel/index.tsx | 4 -- .../timelines/containers/details/index.tsx | 8 +--- .../common/search_strategy/timeline/index.ts | 2 - .../components/t_grid/standalone/index.tsx | 4 -- .../server/search_strategy/timeline/index.ts | 41 ++-------------- .../applications/timelines_test/index.tsx | 7 --- 20 files changed, 109 insertions(+), 135 deletions(-) diff --git a/x-pack/plugins/cases/public/components/case_view/index.tsx b/x-pack/plugins/cases/public/components/case_view/index.tsx index b333d908fa77..a44c2cb22010 100644 --- a/x-pack/plugins/cases/public/components/case_view/index.tsx +++ b/x-pack/plugins/cases/public/components/case_view/index.tsx @@ -105,7 +105,6 @@ export const CaseComponent = React.memo( const [initLoadingData, setInitLoadingData] = useState(true); const init = useRef(true); const timelineUi = useTimelineContext()?.ui; - const alertConsumers = useTimelineContext()?.alertConsumers; const { caseUserActions, @@ -487,9 +486,7 @@ export const CaseComponent = React.memo( - {timelineUi?.renderTimelineDetailsPanel - ? timelineUi.renderTimelineDetailsPanel({ alertConsumers }) - : null} + {timelineUi?.renderTimelineDetailsPanel ? timelineUi.renderTimelineDetailsPanel() : null} ); } diff --git a/x-pack/plugins/cases/public/components/timeline_context/index.tsx b/x-pack/plugins/cases/public/components/timeline_context/index.tsx index 76952e638e19..727e4b64628d 100644 --- a/x-pack/plugins/cases/public/components/timeline_context/index.tsx +++ b/x-pack/plugins/cases/public/components/timeline_context/index.tsx @@ -7,7 +7,6 @@ import React, { useState } from 'react'; import { EuiMarkdownEditorUiPlugin, EuiMarkdownAstNodePosition } from '@elastic/eui'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { Plugin } from 'unified'; /** * @description - manage the plugins, hooks, and ui components needed to enable timeline functionality within the cases plugin @@ -29,7 +28,6 @@ interface TimelineProcessingPluginRendererProps { } export interface CasesTimelineIntegration { - alertConsumers?: AlertConsumers[]; editor_plugins: { parsingPlugin: Plugin; processingPluginRenderer: React.FC< @@ -45,11 +43,7 @@ export interface CasesTimelineIntegration { }; ui?: { renderInvestigateInTimelineActionComponent?: (alertIds: string[]) => JSX.Element; - renderTimelineDetailsPanel?: ({ - alertConsumers, - }: { - alertConsumers?: AlertConsumers[]; - }) => JSX.Element; + renderTimelineDetailsPanel?: () => JSX.Element; }; } diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_search_bar.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_search_bar.tsx index f32088e2646b..01bb01857eaf 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts_search_bar.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts_search_bar.tsx @@ -5,19 +5,20 @@ * 2.0. */ +import { IndexPatternBase } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import React, { useMemo, useState } from 'react'; -import { IIndexPattern, SearchBar, TimeHistory } from '../../../../../../src/plugins/data/public'; +import { SearchBar, TimeHistory } from '../../../../../../src/plugins/data/public'; import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; export function AlertsSearchBar({ - dynamicIndexPattern, + dynamicIndexPatterns, rangeFrom, rangeTo, onQueryChange, query, }: { - dynamicIndexPattern: IIndexPattern[]; + dynamicIndexPatterns: IndexPatternBase[]; rangeFrom?: string; rangeTo?: string; query?: string; @@ -31,9 +32,19 @@ export function AlertsSearchBar({ }, []); const [queryLanguage, setQueryLanguage] = useState<'lucene' | 'kuery'>('kuery'); + const compatibleIndexPatterns = useMemo( + () => + dynamicIndexPatterns.map((dynamicIndexPattern) => ({ + title: dynamicIndexPattern.title ?? '', + id: dynamicIndexPattern.id ?? '', + fields: dynamicIndexPattern.fields, + })), + [dynamicIndexPatterns] + ); + return ( 75', })} diff --git a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx index 174650fc57c6..298dec27a31d 100644 --- a/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/alerts_table_t_grid.tsx @@ -11,7 +11,6 @@ * This way plugins can do targeted imports to reduce the final code bundle */ import { - AlertConsumers as AlertConsumersTyped, ALERT_DURATION as ALERT_DURATION_TYPED, ALERT_REASON as ALERT_REASON_TYPED, ALERT_RULE_CONSUMER, @@ -62,14 +61,13 @@ import { LazyAlertsFlyout } from '../..'; import { parseAlert } from './parse_alert'; import { CoreStart } from '../../../../../../src/core/public'; -const AlertConsumers: typeof AlertConsumersTyped = AlertConsumersNonTyped; const ALERT_DURATION: typeof ALERT_DURATION_TYPED = ALERT_DURATION_NON_TYPED; const ALERT_REASON: typeof ALERT_REASON_TYPED = ALERT_REASON_NON_TYPED; const ALERT_STATUS: typeof ALERT_STATUS_TYPED = ALERT_STATUS_NON_TYPED; const ALERT_WORKFLOW_STATUS: typeof ALERT_WORKFLOW_STATUS_TYPED = ALERT_WORKFLOW_STATUS_NON_TYPED; interface AlertsTableTGridProps { - indexName: string; + indexNames: string[]; rangeFrom: string; rangeTo: string; kuery: string; @@ -147,13 +145,6 @@ const NO_ROW_RENDER: RowRenderer[] = []; const trailingControlColumns: never[] = []; -const OBSERVABILITY_ALERT_CONSUMERS = [ - AlertConsumers.APM, - AlertConsumers.LOGS, - AlertConsumers.INFRASTRUCTURE, - AlertConsumers.UPTIME, -]; - function ObservabilityActions({ data, eventId, @@ -290,7 +281,7 @@ function ObservabilityActions({ } export function AlertsTableTGrid(props: AlertsTableTGridProps) { - const { indexName, rangeFrom, rangeTo, kuery, workflowStatus, setRefetch, addToQuery } = props; + const { indexNames, rangeFrom, rangeTo, kuery, workflowStatus, setRefetch, addToQuery } = props; const { timelines } = useKibana<{ timelines: TimelinesUIStart }>().services; const [flyoutAlert, setFlyoutAlert] = useState(undefined); @@ -328,7 +319,6 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) { const type: TGridType = 'standalone'; const sortDirection: SortDirection = 'desc'; return { - alertConsumers: OBSERVABILITY_ALERT_CONSUMERS, appId: observabilityFeatureId, casePermissions, type, @@ -337,7 +327,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) { defaultCellActions: getDefaultCellActions({ addToQuery }), end: rangeTo, filters: [], - indexNames: [indexName], + indexNames, itemsPerPage: 10, itemsPerPageOptions: [10, 25, 50], loadingText: i18n.translate('xpack.observability.alertsTable.loadingTextLabel', { @@ -372,7 +362,7 @@ export function AlertsTableTGrid(props: AlertsTableTGridProps) { }; }, [ casePermissions, - indexName, + indexNames, kuery, leadingControlColumns, rangeFrom, diff --git a/x-pack/plugins/observability/public/pages/alerts/index.tsx b/x-pack/plugins/observability/public/pages/alerts/index.tsx index 0d6b4ab9b4cf..751307196fa1 100644 --- a/x-pack/plugins/observability/public/pages/alerts/index.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/index.tsx @@ -7,8 +7,10 @@ import { EuiButtonEmpty, EuiCallOut, EuiFlexGroup, EuiFlexItem, EuiLink } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import React, { useCallback, useMemo, useRef } from 'react'; +import React, { useCallback, useRef } from 'react'; import { useHistory } from 'react-router-dom'; +import useAsync from 'react-use/lib/useAsync'; +import { IndexPatternBase } from '@kbn/es-query'; import { ParsedTechnicalFields } from '../../../../rule_registry/common/parse_technical_fields'; import type { AlertWorkflowStatus } from '../../../common/typings'; import { ExperimentalBadge } from '../../components/shared/experimental_badge'; @@ -35,7 +37,7 @@ interface AlertsPageProps { } export function AlertsPage({ routeParams }: AlertsPageProps) { - const { core, ObservabilityPageTemplate } = usePluginContext(); + const { core, plugins, ObservabilityPageTemplate } = usePluginContext(); const { prepend } = core.http.basePath; const history = useHistory(); const refetch = useRef<() => void>(); @@ -60,17 +62,41 @@ export function AlertsPage({ routeParams }: AlertsPageProps) { // observability. For now link to the settings page. const manageRulesHref = prepend('/app/management/insightsAndAlerting/triggersActions/alerts'); - const { data: dynamicIndexPatternResp } = useFetcher(({ signal }) => { + const { data: indexNames = NO_INDEX_NAMES } = useFetcher(({ signal }) => { return callObservabilityApi({ signal, endpoint: 'GET /api/observability/rules/alerts/dynamic_index_pattern', + params: { + query: { + namespace: 'default', + registrationContexts: [ + 'observability.apm', + 'observability.logs', + 'observability.infrastructure', + 'observability.metrics', + 'observability.uptime', + ], + }, + }, }); }, []); - const dynamicIndexPattern = useMemo( - () => (dynamicIndexPatternResp ? [dynamicIndexPatternResp] : []), - [dynamicIndexPatternResp] - ); + const dynamicIndexPatternsAsyncState = useAsync(async (): Promise => { + if (indexNames.length === 0) { + return []; + } + + return [ + { + id: 'dynamic-observability-alerts-table-index-pattern', + title: indexNames.join(','), + fields: await plugins.data.indexPatterns.getFieldsForWildcard({ + pattern: indexNames.join(','), + allowNoIndex: true, + }), + }, + ]; + }, [indexNames]); const setWorkflowStatusFilter = useCallback( (value: AlertWorkflowStatus) => { @@ -165,7 +191,7 @@ export function AlertsPage({ routeParams }: AlertsPageProps) { 0 ? dynamicIndexPattern[0].title : ''} + indexNames={indexNames} rangeFrom={rangeFrom} rangeTo={rangeTo} kuery={kuery} @@ -196,3 +222,6 @@ export function AlertsPage({ routeParams }: AlertsPageProps) { ); } + +const NO_INDEX_NAMES: string[] = []; +const NO_INDEX_PATTERNS: IndexPatternBase[] = []; diff --git a/x-pack/plugins/observability/server/plugin.ts b/x-pack/plugins/observability/server/plugin.ts index f65311711373..cb4f85a44d12 100644 --- a/x-pack/plugins/observability/server/plugin.ts +++ b/x-pack/plugins/observability/server/plugin.ts @@ -18,7 +18,7 @@ import { ScopedAnnotationsClientFactory, AnnotationsAPI, } from './lib/annotations/bootstrap_annotations'; -import { Dataset, RuleRegistryPluginSetupContract } from '../../rule_registry/server'; +import { RuleRegistryPluginSetupContract } from '../../rule_registry/server'; import { PluginSetupContract as FeaturesSetup } from '../../features/server'; import { uiSettings } from './ui_settings'; import { registerRoutes } from './routes/register_routes'; @@ -101,16 +101,6 @@ export class ObservabilityPlugin implements Plugin { const start = () => core.getStartServices().then(([coreStart]) => coreStart); const { ruleDataService } = plugins.ruleRegistry; - const ruleDataClient = ruleDataService.initializeIndex({ - feature: 'observability', - registrationContext: 'observability', - dataset: Dataset.alerts, - componentTemplateRefs: [], - componentTemplates: [], - indexTemplate: { - version: 0, - }, - }); registerRoutes({ core: { @@ -119,7 +109,7 @@ export class ObservabilityPlugin implements Plugin { }, logger: this.initContext.logger.get(), repository: getGlobalObservabilityServerRouteRepository(), - ruleDataClient, + ruleDataService, }); return { diff --git a/x-pack/plugins/observability/server/routes/register_routes.ts b/x-pack/plugins/observability/server/routes/register_routes.ts index 43b47f26dcdd..660c38edb8e9 100644 --- a/x-pack/plugins/observability/server/routes/register_routes.ts +++ b/x-pack/plugins/observability/server/routes/register_routes.ts @@ -13,7 +13,7 @@ import { import { CoreSetup, CoreStart, Logger, RouteRegistrar } from 'kibana/server'; import Boom from '@hapi/boom'; import { RequestAbortedError } from '@elastic/elasticsearch/lib/errors'; -import { IRuleDataClient } from '../../../rule_registry/server'; +import { RuleDataPluginService } from '../../../rule_registry/server'; import { ObservabilityRequestHandlerContext } from '../types'; import { AbstractObservabilityServerRouteRepository } from './types'; @@ -21,7 +21,7 @@ export function registerRoutes({ repository, core, logger, - ruleDataClient, + ruleDataService, }: { core: { setup: CoreSetup; @@ -29,7 +29,7 @@ export function registerRoutes({ }; repository: AbstractObservabilityServerRouteRepository; logger: Logger; - ruleDataClient: IRuleDataClient; + ruleDataService: RuleDataPluginService; }) { const routes = repository.getRoutes(); @@ -62,7 +62,7 @@ export function registerRoutes({ core, logger, params: decodedParams, - ruleDataClient, + ruleDataService, })) as any; return response.ok({ body: data }); diff --git a/x-pack/plugins/observability/server/routes/rules.ts b/x-pack/plugins/observability/server/routes/rules.ts index 6ca4dc58147f..a9039e4a6621 100644 --- a/x-pack/plugins/observability/server/routes/rules.ts +++ b/x-pack/plugins/observability/server/routes/rules.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { observabilityFeatureId } from '../../common'; +import * as t from 'io-ts'; import { createObservabilityServerRoute } from './create_observability_server_route'; import { createObservabilityServerRouteRepository } from './create_observability_server_route_repository'; @@ -14,10 +14,27 @@ const alertsDynamicIndexPatternRoute = createObservabilityServerRoute({ options: { tags: [], }, - handler: async ({ ruleDataClient }) => { - const reader = ruleDataClient.getReader({ namespace: observabilityFeatureId }); + params: t.type({ + query: t.type({ + registrationContexts: t.array(t.string), + namespace: t.string, + }), + }), + handler: async ({ ruleDataService, params }) => { + const { namespace, registrationContexts } = params.query; + const indexNames = registrationContexts.flatMap((registrationContext) => { + const indexName = ruleDataService + .getRegisteredIndexInfo(registrationContext) + ?.getPrimaryAlias(namespace); - return reader.getDynamicIndexPattern(); + if (indexName != null) { + return [indexName]; + } else { + return []; + } + }); + + return indexNames; }, }); diff --git a/x-pack/plugins/observability/server/routes/types.ts b/x-pack/plugins/observability/server/routes/types.ts index 15a3274087d0..5075b21fdf1f 100644 --- a/x-pack/plugins/observability/server/routes/types.ts +++ b/x-pack/plugins/observability/server/routes/types.ts @@ -12,7 +12,7 @@ import type { ServerRouteRepository, } from '@kbn/server-route-repository'; import { CoreSetup, CoreStart, KibanaRequest, Logger } from 'kibana/server'; -import { IRuleDataClient } from '../../../rule_registry/server'; +import { RuleDataPluginService } from '../../../rule_registry/server'; import { ObservabilityServerRouteRepository } from './get_global_observability_server_route_repository'; import { ObservabilityRequestHandlerContext } from '../types'; @@ -24,7 +24,7 @@ export interface ObservabilityRouteHandlerResources { start: () => Promise; setup: CoreSetup; }; - ruleDataClient: IRuleDataClient; + ruleDataService: RuleDataPluginService; request: KibanaRequest; context: ObservabilityRequestHandlerContext; logger: Logger; diff --git a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts index d2a8b914d10b..090978949e2f 100644 --- a/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts +++ b/x-pack/plugins/rule_registry/server/alert_data_client/alerts_client.ts @@ -650,6 +650,8 @@ export class AlertsClient { public async getAuthorizedAlertsIndices(featureIds: string[]): Promise { try { + // ATTENTION FUTURE DEVELOPER when you are a super user the augmentedRuleTypes.authorizedRuleTypes will + // return all of the features that you can access and does not care about your featureIds const augmentedRuleTypes = await this.authorization.getAugmentedRuleTypesWithAuthorization( featureIds, [ReadOperations.Find, ReadOperations.Get, WriteOperations.Update], @@ -665,7 +667,7 @@ export class AlertsClient { } const toReturn = Array.from(authorizedFeatures).flatMap((feature) => { - if (isValidFeatureId(feature)) { + if (featureIds.includes(feature) && isValidFeatureId(feature)) { if (feature === 'siem') { return `${mapConsumerToIndexName[feature]}-${this.spaceId}`; } else { diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.mock.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.mock.ts index 467d6816d044..f95ed8c6994b 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.mock.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.mock.ts @@ -12,6 +12,7 @@ type Schema = PublicMethodsOf; const createRuleDataPluginService = () => { const mocked: jest.Mocked = { + getRegisteredIndexInfo: jest.fn(), getResourcePrefix: jest.fn(), getResourceName: jest.fn(), isWriteEnabled: jest.fn(), diff --git a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts index b95effd4801b..734518e86d17 100644 --- a/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts +++ b/x-pack/plugins/rule_registry/server/rule_data_plugin_service/rule_data_plugin_service.ts @@ -29,6 +29,7 @@ export class RuleDataPluginService { private readonly resourceInstaller: ResourceInstaller; private installCommonResources: Promise>; private isInitialized: boolean; + private registeredIndices: Map = new Map(); constructor(private readonly options: ConstructorOptions) { this.resourceInstaller = new ResourceInstaller({ @@ -105,6 +106,8 @@ export class RuleDataPluginService { indexOptions, }); + this.registeredIndices.set(indexOptions.registrationContext, indexInfo); + const waitUntilClusterClientAvailable = async (): Promise => { try { const clusterClient = await this.options.getClusterClient(); @@ -148,4 +151,13 @@ export class RuleDataPluginService { waitUntilReadyForWriting, }); } + + /** + * Looks up the index information associated with the given `registrationContext`. + * @param registrationContext + * @returns the IndexInfo or undefined + */ + public getRegisteredIndexInfo(registrationContext: string): IndexInfo | undefined { + return this.registeredIndices.get(registrationContext); + } } diff --git a/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx index c255702e8de8..3ec616127f24 100644 --- a/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx @@ -7,7 +7,6 @@ import React, { useCallback, useRef, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { getCaseDetailsUrl, getCaseDetailsUrlWithCommentId, @@ -53,14 +52,11 @@ export interface CaseProps extends Props { updateCase: (newCase: Case) => void; } -const SECURITY_SOLUTION_ALERT_CONSUMERS: AlertConsumers[] = [AlertConsumers.SIEM]; - -const TimelineDetailsPanel = ({ alertConsumers }: { alertConsumers?: AlertConsumers[] }) => { +const TimelineDetailsPanel = () => { const { browserFields, docValueFields } = useSourcererScope(SourcererScopeName.detections); return ( = ({ - alertConsumers = SECURITY_SOLUTION_ALERT_CONSUMERS, // Default to Security Solution so only other applications have to pass this in browserFields, docValueFields, entityType = 'events', // Default to events so only alerts have to pass entityType in @@ -82,7 +77,6 @@ const EventDetailsPanelComponent: React.FC = ({ timelineId, }) => { const [loading, detailsData] = useTimelineEventsDetails({ - alertConsumers, docValueFields, entityType, indexName: expandedEvent.indexName ?? '', diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx index e264c7ec9fa0..97d9e4b492d6 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/index.tsx @@ -8,7 +8,6 @@ import React, { useCallback, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { EuiFlyout, EuiFlyoutProps } from '@elastic/eui'; -import { AlertConsumers } from '@kbn/rule-data-utils'; import { timelineActions, timelineSelectors } from '../../store/timeline'; import { timelineDefaults } from '../../store/timeline/defaults'; @@ -21,7 +20,6 @@ import { NetworkDetailsPanel } from './network_details'; import { EntityType } from '../../../../../timelines/common'; interface DetailsPanelProps { - alertConsumers?: AlertConsumers[]; browserFields: BrowserFields; docValueFields: DocValueFields[]; entityType?: EntityType; @@ -38,7 +36,6 @@ interface DetailsPanelProps { */ export const DetailsPanel = React.memo( ({ - alertConsumers, browserFields, docValueFields, entityType, @@ -77,7 +74,6 @@ export const DetailsPanel = React.memo( panelSize = 'm'; visiblePanel = ( { const myRequest = { ...(prevRequest ?? {}), - alertConsumers, docValueFields, entityType, indexName, @@ -124,7 +118,7 @@ export const useTimelineEventsDetails = ({ } return prevRequest; }); - }, [alertConsumers, docValueFields, entityType, eventId, indexName]); + }, [docValueFields, entityType, eventId, indexName]); useEffect(() => { timelineDetailsSearch(timelineDetailsRequest); diff --git a/x-pack/plugins/timelines/common/search_strategy/timeline/index.ts b/x-pack/plugins/timelines/common/search_strategy/timeline/index.ts index 269fc6598bea..c173e347fbdb 100644 --- a/x-pack/plugins/timelines/common/search_strategy/timeline/index.ts +++ b/x-pack/plugins/timelines/common/search_strategy/timeline/index.ts @@ -4,7 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { AlertConsumers } from '@kbn/rule-data-utils'; import { IEsSearchRequest } from '../../../../../../src/plugins/data/common'; import { ESQuery } from '../../typed_json'; @@ -44,7 +43,6 @@ export interface TimelineRequestBasicOptions extends IEsSearchRequest { docValueFields?: DocValueFields[]; factoryQueryType?: TimelineFactoryQueryTypes; entityType?: EntityType; - alertConsumers?: AlertConsumers[]; } export interface TimelineRequestSortField extends SortField { diff --git a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx index 19c5bd84a551..4f78b090a2f9 100644 --- a/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx +++ b/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx @@ -4,7 +4,6 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { AlertConsumers } from '@kbn/rule-data-utils'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { isEmpty } from 'lodash/fp'; import React, { useEffect, useMemo, useState } from 'react'; @@ -80,7 +79,6 @@ const ScrollableFlexItem = styled(EuiFlexItem)` `; export interface TGridStandaloneProps { - alertConsumers: AlertConsumers[]; appId: string; casePermissions: { crud: boolean; @@ -117,7 +115,6 @@ export interface TGridStandaloneProps { const TGridStandaloneComponent: React.FC = ({ afterCaseSelection, - alertConsumers, appId, casePermissions, columns, @@ -210,7 +207,6 @@ const TGridStandaloneComponent: React.FC = ({ loading, { events, updatedAt, loadPage, pageInfo, refetch, totalCount = 0, inspect }, ] = useTimelineEvents({ - alertConsumers, docValueFields: [], entityType, excludeEcsData: true, diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts index bd70d989d97d..b2e073d3ecf5 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts @@ -5,26 +5,10 @@ * 2.0. */ -import { - AlertConsumers as CONSUMERS, - ALERT_RULE_CONSUMER, - ALERT_RULE_TYPE_ID, - SPACE_IDS, -} from '@kbn/rule-data-utils'; +import { ALERT_RULE_CONSUMER, ALERT_RULE_TYPE_ID, SPACE_IDS } from '@kbn/rule-data-utils'; import { map, mergeMap, catchError } from 'rxjs/operators'; import { from } from 'rxjs'; -import type { - AlertConsumers, - mapConsumerToIndexName as mapConsumerToIndexNameTyped, - isValidFeatureId as isValidFeatureIdTyped, -} from '@kbn/rule-data-utils'; -import { - mapConsumerToIndexName as mapConsumerToIndexNameNonTyped, - isValidFeatureId as isValidFeatureIdNonTyped, - // @ts-expect-error -} from '@kbn/rule-data-utils/target_node/alerts_as_data_rbac'; - import { AlertingAuthorizationEntity, AlertingAuthorizationFilterType, @@ -49,9 +33,6 @@ import { ISearchOptions, } from '../../../../../../src/plugins/data/common'; -const mapConsumerToIndexName: typeof mapConsumerToIndexNameTyped = mapConsumerToIndexNameNonTyped; -const isValidFeatureId: typeof isValidFeatureIdTyped = isValidFeatureIdNonTyped; - export const timelineSearchStrategyProvider = ( data: PluginStart, alerting: AlertingPluginStartContract @@ -63,7 +44,6 @@ export const timelineSearchStrategyProvider = { const factoryQueryType = request.factoryQueryType; const entityType = request.entityType; - const alertConsumers = request.alertConsumers; if (factoryQueryType == null) { throw new Error('factoryQueryType is required'); @@ -71,13 +51,7 @@ export const timelineSearchStrategyProvider = = timelineFactory[factoryQueryType]; - if (alertConsumers != null && entityType != null && entityType === EntityType.ALERTS) { - const allFeatureIdsValid = alertConsumers.every((id) => isValidFeatureId(id)); - - if (!allFeatureIdsValid) { - throw new Error('An invalid alerts consumer feature id was provided'); - } - + if (entityType != null && entityType === EntityType.ALERTS) { return timelineAlertsSearchStrategy({ es: esAsInternal, request, @@ -85,7 +59,6 @@ export const timelineSearchStrategyProvider = ({ deps, queryFactory, alerting, - alertConsumers, }: { es: ISearchStrategy; request: TimelineStrategyRequestType; @@ -139,17 +111,10 @@ const timelineAlertsSearchStrategy = ({ deps: SearchStrategyDependencies; alerting: AlertingPluginStartContract; queryFactory: TimelineFactory; - alertConsumers: AlertConsumers[]; }) => { // Based on what solution alerts you want to see, figures out what corresponding // index to query (ex: siem --> .alerts-security.alerts) - const indices = alertConsumers.flatMap((consumer) => { - if (consumer === CONSUMERS.SIEM) { - return request.defaultIndex ?? request.indexType; - } - - return `${mapConsumerToIndexName[consumer]}`; - }); + const indices = request.defaultIndex ?? request.indexType; const requestWithAlertsIndices = { ...request, defaultIndex: indices, indexName: indices }; // Note: Alerts RBAC are built off of the alerting's authorization class, which diff --git a/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx b/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx index 61322261d04d..3059ff0629a2 100644 --- a/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx +++ b/x-pack/test/plugin_functional/plugins/timelines_test/public/applications/timelines_test/index.tsx @@ -5,9 +5,6 @@ * 2.0. */ -import type { AlertConsumers as AlertConsumersTyped } from '@kbn/rule-data-utils'; -// @ts-expect-error -import { AlertConsumers as AlertConsumersNonTyped } from '@kbn/rule-data-utils/target_node/alerts_as_data_rbac'; import { Router } from 'react-router-dom'; import React, { useCallback, useRef } from 'react'; import ReactDOM from 'react-dom'; @@ -17,8 +14,6 @@ import { KibanaContextProvider } from '../../../../../../../../src/plugins/kiban import { TimelinesUIStart } from '../../../../../../../plugins/timelines/public'; import { DataPublicPluginStart } from '../../../../../../../../src/plugins/data/public'; -const AlertConsumers: typeof AlertConsumersTyped = AlertConsumersNonTyped; - type CoreStartTimelines = CoreStart & { data: DataPublicPluginStart }; /** @@ -42,7 +37,6 @@ export function renderApp( ReactDOM.unmountComponentAtNode(parameters.element); }; } -const ALERT_RULE_CONSUMER = [AlertConsumers.SIEM]; const AppRoot = React.memo( ({ @@ -67,7 +61,6 @@ const AppRoot = React.memo( {(timelinesPluginSetup && timelinesPluginSetup.getTGrid && timelinesPluginSetup.getTGrid<'standalone'>({ - alertConsumers: ALERT_RULE_CONSUMER, appId: 'securitySolution', type: 'standalone', casePermissions: {