[RAM][O11Y] Integrate Conditional Actions with several Observability rule types (#159522)

## Summary

Closes #159520 

<img width="573" alt="Screenshot 2023-06-12 at 3 12 27 PM"
src="ec16b8d7-25a5-435c-bf29-7392747b8c0f">


### Checklist

- [ ] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Patryk Kopyciński <contact@patrykkopycinski.com>
This commit is contained in:
Zacqary Adam Xeper 2023-06-27 11:36:49 -05:00 committed by GitHub
parent 3bd43abd69
commit faadf347ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 111 additions and 11 deletions

View file

@ -72,6 +72,7 @@ type AuthorizedConsumers = Record<string, HasPrivileges>;
export interface RegistryAlertTypeWithAuth extends RegistryRuleType { export interface RegistryAlertTypeWithAuth extends RegistryRuleType {
authorizedConsumers: AuthorizedConsumers; authorizedConsumers: AuthorizedConsumers;
hasGetSummarizedAlerts?: boolean; hasGetSummarizedAlerts?: boolean;
hasFieldsForAAD?: boolean;
} }
type IsAuthorizedAtProducerLevel = boolean; type IsAuthorizedAtProducerLevel = boolean;

View file

@ -88,6 +88,7 @@ describe('ruleTypesRoute', () => {
producer: 'test', producer: 'test',
enabled_in_license: true, enabled_in_license: true,
has_get_summarized_alerts: true, has_get_summarized_alerts: true,
has_fields_for_a_a_d: false,
}, },
]; ];
rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(listTypes)); rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(listTypes));
@ -113,6 +114,7 @@ describe('ruleTypesRoute', () => {
"default_schedule_interval": "10m", "default_schedule_interval": "10m",
"does_set_recovery_context": false, "does_set_recovery_context": false,
"enabled_in_license": true, "enabled_in_license": true,
"has_fields_for_a_a_d": false,
"has_get_summarized_alerts": true, "has_get_summarized_alerts": true,
"id": "1", "id": "1",
"is_exportable": true, "is_exportable": true,

View file

@ -26,6 +26,7 @@ const rewriteBodyRes: RewriteResponseCase<RegistryAlertTypeWithAuth[]> = (result
defaultScheduleInterval, defaultScheduleInterval,
doesSetRecoveryContext, doesSetRecoveryContext,
hasGetSummarizedAlerts, hasGetSummarizedAlerts,
hasFieldsForAAD,
...rest ...rest
}) => ({ }) => ({
...rest, ...rest,
@ -41,6 +42,7 @@ const rewriteBodyRes: RewriteResponseCase<RegistryAlertTypeWithAuth[]> = (result
default_schedule_interval: defaultScheduleInterval, default_schedule_interval: defaultScheduleInterval,
does_set_recovery_context: doesSetRecoveryContext, does_set_recovery_context: doesSetRecoveryContext,
has_get_summarized_alerts: !!hasGetSummarizedAlerts, has_get_summarized_alerts: !!hasGetSummarizedAlerts,
has_fields_for_a_a_d: !!hasFieldsForAAD,
}) })
); );
}; };

View file

@ -704,6 +704,7 @@ describe('Create Lifecycle', () => {
"defaultScheduleInterval": undefined, "defaultScheduleInterval": undefined,
"doesSetRecoveryContext": false, "doesSetRecoveryContext": false,
"enabledInLicense": false, "enabledInLicense": false,
"hasFieldsForAAD": false,
"hasGetSummarizedAlerts": false, "hasGetSummarizedAlerts": false,
"id": "test", "id": "test",
"isExportable": true, "isExportable": true,

View file

@ -61,6 +61,7 @@ export interface RegistryRuleType
| 'ruleTaskTimeout' | 'ruleTaskTimeout'
| 'defaultScheduleInterval' | 'defaultScheduleInterval'
| 'doesSetRecoveryContext' | 'doesSetRecoveryContext'
| 'fieldsForAAD'
> { > {
id: string; id: string;
enabledInLicense: boolean; enabledInLicense: boolean;
@ -372,6 +373,7 @@ export class RuleTypeRegistry {
doesSetRecoveryContext, doesSetRecoveryContext,
alerts, alerts,
getSummarizedAlerts, getSummarizedAlerts,
fieldsForAAD,
}, },
]: [string, UntypedNormalizedRuleType]) => ({ ]: [string, UntypedNormalizedRuleType]) => ({
id, id,
@ -392,6 +394,7 @@ export class RuleTypeRegistry {
minimumLicenseRequired minimumLicenseRequired
).isValid, ).isValid,
hasGetSummarizedAlerts: !!getSummarizedAlerts, hasGetSummarizedAlerts: !!getSummarizedAlerts,
hasFieldsForAAD: Boolean(fieldsForAAD),
...(alerts ? { alerts } : {}), ...(alerts ? { alerts } : {}),
}) })
) )

View file

@ -49,6 +49,7 @@ import {
WARNING_ACTIONS, WARNING_ACTIONS,
} from './inventory_metric_threshold_executor'; } from './inventory_metric_threshold_executor';
import { MetricsRulesTypeAlertDefinition } from '../register_rule_types'; import { MetricsRulesTypeAlertDefinition } from '../register_rule_types';
import { O11Y_AAD_FIELDS } from '../../../../common/constants';
const condition = schema.object({ const condition = schema.object({
threshold: schema.arrayOf(schema.number()), threshold: schema.arrayOf(schema.number()),
@ -146,5 +147,6 @@ export async function registerMetricInventoryThresholdRuleType(
}, },
getSummarizedAlerts: libs.metricsRules.createGetSummarizedAlerts(), getSummarizedAlerts: libs.metricsRules.createGetSummarizedAlerts(),
alerts: MetricsRulesTypeAlertDefinition, alerts: MetricsRulesTypeAlertDefinition,
fieldsForAAD: O11Y_AAD_FIELDS,
}); });
} }

View file

@ -7,6 +7,7 @@
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { PluginSetupContract } from '@kbn/alerting-plugin/server'; import { PluginSetupContract } from '@kbn/alerting-plugin/server';
import { O11Y_AAD_FIELDS } from '../../../../common/constants';
import { createLogThresholdExecutor, FIRED_ACTIONS } from './log_threshold_executor'; import { createLogThresholdExecutor, FIRED_ACTIONS } from './log_threshold_executor';
import { extractReferences, injectReferences } from './log_threshold_references_manager'; import { extractReferences, injectReferences } from './log_threshold_references_manager';
import { import {
@ -165,5 +166,6 @@ export async function registerLogThresholdRuleType(
injectReferences, injectReferences,
}, },
alerts: LogsRulesTypeAlertDefinition, alerts: LogsRulesTypeAlertDefinition,
fieldsForAAD: O11Y_AAD_FIELDS,
}); });
} }

View file

@ -14,6 +14,7 @@ import {
AlertInstanceContext as AlertContext, AlertInstanceContext as AlertContext,
} from '@kbn/alerting-plugin/server'; } from '@kbn/alerting-plugin/server';
import { RecoveredActionGroupId } from '@kbn/alerting-plugin/common'; import { RecoveredActionGroupId } from '@kbn/alerting-plugin/common';
import { O11Y_AAD_FIELDS } from '../../../../common/constants';
import { import {
createMetricAnomalyExecutor, createMetricAnomalyExecutor,
FIRED_ACTIONS, FIRED_ACTIONS,
@ -67,6 +68,7 @@ export const registerMetricAnomalyRuleType = (
minimumLicenseRequired: 'basic', minimumLicenseRequired: 'basic',
isExportable: true, isExportable: true,
executor: createMetricAnomalyExecutor(libs, ml), executor: createMetricAnomalyExecutor(libs, ml),
fieldsForAAD: O11Y_AAD_FIELDS,
actionVariables: { actionVariables: {
context: [ context: [
{ name: 'alertState', description: alertStateActionVariableDescription }, { name: 'alertState', description: alertStateActionVariableDescription },

View file

@ -252,6 +252,7 @@ describe('alert_form', () => {
} }
actionTypeRegistry={actionTypeRegistry} actionTypeRegistry={actionTypeRegistry}
featureId="alerting" featureId="alerting"
producerId="alerting"
/> />
</KibanaReactContext.Provider> </KibanaReactContext.Provider>
</I18nProvider> </I18nProvider>

View file

@ -23,6 +23,7 @@ import type {
} from '@kbn/alerting-plugin/common'; } from '@kbn/alerting-plugin/common';
import { SecurityConnectorFeatureId } from '@kbn/actions-plugin/common'; import { SecurityConnectorFeatureId } from '@kbn/actions-plugin/common';
import { FormattedMessage } from '@kbn/i18n-react'; import { FormattedMessage } from '@kbn/i18n-react';
import { AlertConsumers } from '@kbn/rule-data-utils';
import { NOTIFICATION_DEFAULT_FREQUENCY } from '../../../../../common/constants'; import { NOTIFICATION_DEFAULT_FREQUENCY } from '../../../../../common/constants';
import type { FieldHook } from '../../../../shared_imports'; import type { FieldHook } from '../../../../shared_imports';
import { useFormContext } from '../../../../shared_imports'; import { useFormContext } from '../../../../shared_imports';
@ -243,13 +244,13 @@ export const RuleActionsField: React.FC<Props> = ({
setActionFrequencyProperty: setActionFrequency, setActionFrequencyProperty: setActionFrequency,
setActionAlertsFilterProperty, setActionAlertsFilterProperty,
featureId: SecurityConnectorFeatureId, featureId: SecurityConnectorFeatureId,
producerId: AlertConsumers.SIEM,
defaultActionMessage: FORM_FOR_EACH_ALERT_BODY_MESSAGE, defaultActionMessage: FORM_FOR_EACH_ALERT_BODY_MESSAGE,
defaultSummaryMessage: FORM_SUMMARY_BODY_MESSAGE, defaultSummaryMessage: FORM_SUMMARY_BODY_MESSAGE,
hideActionHeader: true, hideActionHeader: true,
hasSummary: true, hasSummary: true,
notifyWhenSelectOptions: NOTIFY_WHEN_OPTIONS, notifyWhenSelectOptions: NOTIFY_WHEN_OPTIONS,
defaultRuleFrequency: NOTIFICATION_DEFAULT_FREQUENCY, defaultRuleFrequency: NOTIFICATION_DEFAULT_FREQUENCY,
showActionAlertsFilter: true,
}), }),
[ [
actions, actions,

View file

@ -100,6 +100,7 @@ const baseProps = {
recoveryActionGroup: 'recovered', recoveryActionGroup: 'recovered',
actionTypeRegistry, actionTypeRegistry,
minimumThrottleInterval: [1, 'm'] as [number | undefined, string], minimumThrottleInterval: [1, 'm'] as [number | undefined, string],
producerId: 'infratstructure',
setActions: jest.fn(), setActions: jest.fn(),
setActionIdByIndex: jest.fn(), setActionIdByIndex: jest.fn(),
setActionParamsProperty: jest.fn(), setActionParamsProperty: jest.fn(),

View file

@ -0,0 +1,28 @@
/*
* 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.
*/
import { DataViewField } from '@kbn/data-views-plugin/common';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { BASE_RAC_ALERTS_API_PATH } from '@kbn/rule-registry-plugin/common';
import useAsync from 'react-use/lib/useAsync';
import type { AsyncState } from 'react-use/lib/useAsync';
import { TriggersAndActionsUiServices } from '../..';
export function useRuleAADFields(ruleTypeId?: string): AsyncState<DataViewField[]> {
const { http } = useKibana<TriggersAndActionsUiServices>().services;
const aadFields = useAsync(async () => {
if (!ruleTypeId) return [];
const fields = await http.get<DataViewField[]>(`${BASE_RAC_ALERTS_API_PATH}/aad_fields`, {
query: { ruleTypeId },
});
return fields;
});
return aadFields;
}

View file

@ -25,6 +25,7 @@ const rewriteBodyReq: RewriteRequestCase<RuleType> = ({
does_set_recovery_context: doesSetRecoveryContext, does_set_recovery_context: doesSetRecoveryContext,
default_schedule_interval: defaultScheduleInterval, default_schedule_interval: defaultScheduleInterval,
has_get_summarized_alerts: hasGetSummarizedAlerts, has_get_summarized_alerts: hasGetSummarizedAlerts,
has_fields_for_a_a_d: hasFieldsForAAD,
...rest ...rest
}: AsApiContract<RuleType>) => ({ }: AsApiContract<RuleType>) => ({
enabledInLicense, enabledInLicense,
@ -38,6 +39,7 @@ const rewriteBodyReq: RewriteRequestCase<RuleType> = ({
doesSetRecoveryContext, doesSetRecoveryContext,
defaultScheduleInterval, defaultScheduleInterval,
hasGetSummarizedAlerts, hasGetSummarizedAlerts,
hasFieldsForAAD,
...rest, ...rest,
}); });

View file

@ -6,6 +6,7 @@
*/ */
import React, { useState, useCallback, useMemo, useEffect } from 'react'; import React, { useState, useCallback, useMemo, useEffect } from 'react';
import { ValidFeatureId } from '@kbn/rule-data-utils';
import { Filter } from '@kbn/es-query'; import { Filter } from '@kbn/es-query';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { EuiSwitch, EuiSpacer } from '@elastic/eui'; import { EuiSwitch, EuiSpacer } from '@elastic/eui';
@ -16,11 +17,17 @@ import { AlertsSearchBar } from '../alerts_search_bar';
interface ActionAlertsFilterQueryProps { interface ActionAlertsFilterQueryProps {
state?: AlertsFilter['query']; state?: AlertsFilter['query'];
onChange: (update?: AlertsFilter['query']) => void; onChange: (update?: AlertsFilter['query']) => void;
appName: string;
featureIds: ValidFeatureId[];
ruleTypeId?: string;
} }
export const ActionAlertsFilterQuery: React.FC<ActionAlertsFilterQueryProps> = ({ export const ActionAlertsFilterQuery: React.FC<ActionAlertsFilterQueryProps> = ({
state, state,
onChange, onChange,
appName,
featureIds,
ruleTypeId,
}) => { }) => {
const [query, setQuery] = useState(state ?? { kql: '', filters: [] }); const [query, setQuery] = useState(state ?? { kql: '', filters: [] });
@ -61,7 +68,7 @@ export const ActionAlertsFilterQuery: React.FC<ActionAlertsFilterQueryProps> = (
label={i18n.translate( label={i18n.translate(
'xpack.triggersActionsUI.sections.actionTypeForm.ActionAlertsFilterQueryToggleLabel', 'xpack.triggersActionsUI.sections.actionTypeForm.ActionAlertsFilterQueryToggleLabel',
{ {
defaultMessage: 'if alert matches a query', defaultMessage: 'If alert matches a query',
} }
)} )}
checked={queryEnabled} checked={queryEnabled}
@ -72,9 +79,10 @@ export const ActionAlertsFilterQuery: React.FC<ActionAlertsFilterQueryProps> = (
<> <>
<EuiSpacer size="s" /> <EuiSpacer size="s" />
<AlertsSearchBar <AlertsSearchBar
appName="siem" appName={appName}
featureIds={featureIds}
ruleTypeId={ruleTypeId}
disableQueryLanguageSwitcher={true} disableQueryLanguageSwitcher={true}
featureIds={['siem']}
query={query.kql} query={query.kql}
filters={query.filters ?? []} filters={query.filters ?? []}
onQueryChange={onQueryChange} onQueryChange={onQueryChange}

View file

@ -146,7 +146,7 @@ export const ActionAlertsFilterTimeframe: React.FC<ActionAlertsFilterTimeframePr
label={i18n.translate( label={i18n.translate(
'xpack.triggersActionsUI.sections.actionTypeForm.ActionAlertsFilterTimeframeToggleLabel', 'xpack.triggersActionsUI.sections.actionTypeForm.ActionAlertsFilterTimeframeToggleLabel',
{ {
defaultMessage: 'if alert is generated during timeframe', defaultMessage: 'If alert is generated during timeframe',
} }
)} )}
checked={timeframeEnabled} checked={timeframeEnabled}

View file

@ -314,6 +314,7 @@ describe('action_form', () => {
context: [{ name: 'contextVar', description: 'context var1' }], context: [{ name: 'contextVar', description: 'context var1' }],
}} }}
featureId="alerting" featureId="alerting"
producerId="alerting"
defaultActionGroupId={'default'} defaultActionGroupId={'default'}
isActionGroupDisabledForActionType={(actionGroupId: string, actionTypeId: string) => { isActionGroupDisabledForActionType={(actionGroupId: string, actionTypeId: string) => {
const recoveryActionGroupId = customRecoveredActionGroup const recoveryActionGroupId = customRecoveredActionGroup

View file

@ -69,6 +69,7 @@ export interface ActionAccordionFormProps {
index: number index: number
) => void; ) => void;
featureId: string; featureId: string;
producerId: string;
messageVariables?: ActionVariables; messageVariables?: ActionVariables;
summaryMessageVariables?: ActionVariables; summaryMessageVariables?: ActionVariables;
setHasActionsDisabled?: (value: boolean) => void; setHasActionsDisabled?: (value: boolean) => void;
@ -83,7 +84,8 @@ export interface ActionAccordionFormProps {
minimumThrottleInterval?: [number | undefined, string]; minimumThrottleInterval?: [number | undefined, string];
notifyWhenSelectOptions?: NotifyWhenSelectOptions[]; notifyWhenSelectOptions?: NotifyWhenSelectOptions[];
defaultRuleFrequency?: RuleActionFrequency; defaultRuleFrequency?: RuleActionFrequency;
showActionAlertsFilter?: boolean; ruleTypeId?: string;
hasFieldsForAAD?: boolean;
} }
interface ActiveActionConnectorState { interface ActiveActionConnectorState {
@ -117,7 +119,9 @@ export const ActionForm = ({
minimumThrottleInterval, minimumThrottleInterval,
notifyWhenSelectOptions, notifyWhenSelectOptions,
defaultRuleFrequency = DEFAULT_FREQUENCY, defaultRuleFrequency = DEFAULT_FREQUENCY,
showActionAlertsFilter, ruleTypeId,
producerId,
hasFieldsForAAD,
}: ActionAccordionFormProps) => { }: ActionAccordionFormProps) => {
const { const {
http, http,
@ -491,7 +495,10 @@ export const ActionForm = ({
minimumThrottleInterval={minimumThrottleInterval} minimumThrottleInterval={minimumThrottleInterval}
notifyWhenSelectOptions={notifyWhenSelectOptions} notifyWhenSelectOptions={notifyWhenSelectOptions}
defaultNotifyWhenValue={defaultRuleFrequency.notifyWhen} defaultNotifyWhenValue={defaultRuleFrequency.notifyWhen}
showActionAlertsFilter={showActionAlertsFilter} featureId={featureId}
producerId={producerId}
ruleTypeId={ruleTypeId}
hasFieldsForAAD={hasFieldsForAAD}
/> />
); );
})} })}

View file

@ -634,6 +634,8 @@ function getActionTypeForm({
summaryMessageVariables={summaryMessageVariables} summaryMessageVariables={summaryMessageVariables}
notifyWhenSelectOptions={notifyWhenSelectOptions} notifyWhenSelectOptions={notifyWhenSelectOptions}
defaultNotifyWhenValue={defaultNotifyWhenValue} defaultNotifyWhenValue={defaultNotifyWhenValue}
producerId="infrastructure"
featureId="infrastructure"
/> />
); );
} }

View file

@ -8,6 +8,7 @@
import React, { Suspense, useEffect, useState, useCallback, useMemo } from 'react'; import React, { Suspense, useEffect, useState, useCallback, useMemo } from 'react';
import { i18n } from '@kbn/i18n'; import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react'; import { FormattedMessage } from '@kbn/i18n-react';
import { ValidFeatureId, AlertConsumers } from '@kbn/rule-data-utils';
import { import {
EuiFlexGroup, EuiFlexGroup,
EuiFlexItem, EuiFlexItem,
@ -87,7 +88,10 @@ export type ActionTypeFormProps = {
minimumThrottleInterval?: [number | undefined, string]; minimumThrottleInterval?: [number | undefined, string];
notifyWhenSelectOptions?: NotifyWhenSelectOptions[]; notifyWhenSelectOptions?: NotifyWhenSelectOptions[];
defaultNotifyWhenValue?: RuleNotifyWhenType; defaultNotifyWhenValue?: RuleNotifyWhenType;
showActionAlertsFilter?: boolean; featureId: string;
producerId: string;
ruleTypeId?: string;
hasFieldsForAAD?: boolean;
} & Pick< } & Pick<
ActionAccordionFormProps, ActionAccordionFormProps,
| 'defaultActionGroupId' | 'defaultActionGroupId'
@ -134,7 +138,10 @@ export const ActionTypeForm = ({
minimumThrottleInterval, minimumThrottleInterval,
notifyWhenSelectOptions, notifyWhenSelectOptions,
defaultNotifyWhenValue, defaultNotifyWhenValue,
showActionAlertsFilter, producerId,
featureId,
ruleTypeId,
hasFieldsForAAD,
}: ActionTypeFormProps) => { }: ActionTypeFormProps) => {
const { const {
application: { capabilities }, application: { capabilities },
@ -333,6 +340,8 @@ export const ActionTypeForm = ({
setActionGroupIdByIndex && setActionGroupIdByIndex &&
!actionItem.frequency?.summary; !actionItem.frequency?.summary;
const showActionAlertsFilter = hasFieldsForAAD || producerId === AlertConsumers.SIEM;
const accordionContent = checkEnabledResult.isEnabled ? ( const accordionContent = checkEnabledResult.isEnabled ? (
<> <>
<EuiSplitPanel.Inner <EuiSplitPanel.Inner
@ -418,6 +427,9 @@ export const ActionTypeForm = ({
<ActionAlertsFilterQuery <ActionAlertsFilterQuery
state={actionItem.alertsFilter?.query} state={actionItem.alertsFilter?.query}
onChange={(query) => setActionAlertsFilterProperty('query', query, index)} onChange={(query) => setActionAlertsFilterProperty('query', query, index)}
featureIds={[producerId as ValidFeatureId]}
appName={featureId!}
ruleTypeId={ruleTypeId}
/> />
<EuiSpacer size="s" /> <EuiSpacer size="s" />
<ActionAlertsFilterTimeframe <ActionAlertsFilterTimeframe

View file

@ -13,12 +13,14 @@ import { SEARCH_BAR_PLACEHOLDER } from './translations';
import { AlertsSearchBarProps, QueryLanguageType } from './types'; import { AlertsSearchBarProps, QueryLanguageType } from './types';
import { useAlertDataView } from '../../hooks/use_alert_data_view'; import { useAlertDataView } from '../../hooks/use_alert_data_view';
import { TriggersAndActionsUiServices } from '../../..'; import { TriggersAndActionsUiServices } from '../../..';
import { useRuleAADFields } from '../../hooks/use_rule_aad_fields';
// TODO Share buildEsQuery to be used between AlertsSearchBar and AlertsStateTable component https://github.com/elastic/kibana/issues/144615 // TODO Share buildEsQuery to be used between AlertsSearchBar and AlertsStateTable component https://github.com/elastic/kibana/issues/144615
export function AlertsSearchBar({ export function AlertsSearchBar({
appName, appName,
disableQueryLanguageSwitcher = false, disableQueryLanguageSwitcher = false,
featureIds, featureIds,
ruleTypeId,
query, query,
filters, filters,
onQueryChange, onQueryChange,
@ -40,6 +42,14 @@ export function AlertsSearchBar({
const [queryLanguage, setQueryLanguage] = useState<QueryLanguageType>('kuery'); const [queryLanguage, setQueryLanguage] = useState<QueryLanguageType>('kuery');
const { value: dataView, loading, error } = useAlertDataView(featureIds); const { value: dataView, loading, error } = useAlertDataView(featureIds);
const {
value: aadFields,
loading: fieldsLoading,
error: fieldsError,
} = useRuleAADFields(ruleTypeId);
const indexPatterns =
ruleTypeId && aadFields?.length ? [{ title: ruleTypeId, fields: aadFields }] : [dataView!];
const onSearchQuerySubmit = useCallback( const onSearchQuerySubmit = useCallback(
({ dateRange, query: nextQuery }: { dateRange: TimeRange; query?: Query }) => { ({ dateRange, query: nextQuery }: { dateRange: TimeRange; query?: Query }) => {
@ -72,7 +82,10 @@ export function AlertsSearchBar({
<SearchBar <SearchBar
appName={appName} appName={appName}
disableQueryLanguageSwitcher={disableQueryLanguageSwitcher} disableQueryLanguageSwitcher={disableQueryLanguageSwitcher}
indexPatterns={loading || error ? NO_INDEX_PATTERNS : [dataView!]} // @ts-expect-error - DataView fields prop and SearchBar indexPatterns props are overly broad
indexPatterns={
loading || error || fieldsLoading || fieldsError ? NO_INDEX_PATTERNS : indexPatterns
}
placeholder={placeholder} placeholder={placeholder}
query={{ query: query ?? '', language: queryLanguage }} query={{ query: query ?? '', language: queryLanguage }}
filters={filters} filters={filters}

View file

@ -23,6 +23,7 @@ export interface AlertsSearchBarProps {
showSubmitButton?: boolean; showSubmitButton?: boolean;
placeholder?: string; placeholder?: string;
submitOnBlur?: boolean; submitOnBlur?: boolean;
ruleTypeId?: string;
onQueryChange?: (query: { onQueryChange?: (query: {
dateRange: { from: string; to: string; mode?: 'absolute' | 'relative' }; dateRange: { from: string; to: string; mode?: 'absolute' | 'relative' };
query?: string; query?: string;

View file

@ -661,6 +661,9 @@ export const RuleForm = ({
defaultActionGroupId={defaultActionGroupId} defaultActionGroupId={defaultActionGroupId}
hasSummary={selectedRuleType.hasGetSummarizedAlerts} hasSummary={selectedRuleType.hasGetSummarizedAlerts}
featureId={connectorFeatureId} featureId={connectorFeatureId}
producerId={selectedRuleType.producer}
hasFieldsForAAD={selectedRuleType.hasFieldsForAAD}
ruleTypeId={rule.ruleTypeId}
isActionGroupDisabledForActionType={(actionGroupId: string, actionTypeId: string) => isActionGroupDisabledForActionType={(actionGroupId: string, actionTypeId: string) =>
isActionGroupDisabledForActionType(selectedRuleType, actionGroupId, actionTypeId) isActionGroupDisabledForActionType(selectedRuleType, actionGroupId, actionTypeId)
} }

View file

@ -337,6 +337,7 @@ export interface RuleType<
actionVariables: ActionVariables; actionVariables: ActionVariables;
authorizedConsumers: Record<string, { read: boolean; all: boolean }>; authorizedConsumers: Record<string, { read: boolean; all: boolean }>;
enabledInLicense: boolean; enabledInLicense: boolean;
hasFieldsForAAD?: boolean;
hasGetSummarizedAlerts?: boolean; hasGetSummarizedAlerts?: boolean;
} }

View file

@ -37,6 +37,7 @@ export default function listRuleTypes({ getService }: FtrProviderContext) {
name: 'Recovered', name: 'Recovered',
}, },
enabled_in_license: true, enabled_in_license: true,
has_fields_for_a_a_d: false,
has_get_summarized_alerts: false, has_get_summarized_alerts: false,
rule_task_timeout: '5m', rule_task_timeout: '5m',
}; };
@ -63,6 +64,7 @@ export default function listRuleTypes({ getService }: FtrProviderContext) {
minimum_license_required: 'basic', minimum_license_required: 'basic',
is_exportable: true, is_exportable: true,
enabled_in_license: true, enabled_in_license: true,
has_fields_for_a_a_d: false,
has_get_summarized_alerts: false, has_get_summarized_alerts: false,
rule_task_timeout: '5m', rule_task_timeout: '5m',
}; };

View file

@ -45,6 +45,7 @@ export default function listRuleTypes({ getService }: FtrProviderContext) {
minimum_license_required: 'basic', minimum_license_required: 'basic',
is_exportable: true, is_exportable: true,
enabled_in_license: true, enabled_in_license: true,
has_fields_for_a_a_d: false,
has_get_summarized_alerts: false, has_get_summarized_alerts: false,
rule_task_timeout: '5m', rule_task_timeout: '5m',
}); });
@ -133,6 +134,7 @@ export default function listRuleTypes({ getService }: FtrProviderContext) {
minimumLicenseRequired: 'basic', minimumLicenseRequired: 'basic',
isExportable: true, isExportable: true,
enabledInLicense: true, enabledInLicense: true,
hasFieldsForAAD: false,
hasGetSummarizedAlerts: false, hasGetSummarizedAlerts: false,
ruleTaskTimeout: '5m', ruleTaskTimeout: '5m',
}); });