diff --git a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts index b8efe43c7075b6..5dab1ddc29dfb3 100644 --- a/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts +++ b/x-pack/plugins/alerting/server/authorization/alerting_authorization.ts @@ -72,6 +72,7 @@ type AuthorizedConsumers = Record; export interface RegistryAlertTypeWithAuth extends RegistryRuleType { authorizedConsumers: AuthorizedConsumers; hasGetSummarizedAlerts?: boolean; + hasFieldsForAAD?: boolean; } type IsAuthorizedAtProducerLevel = boolean; diff --git a/x-pack/plugins/alerting/server/routes/rule_types.test.ts b/x-pack/plugins/alerting/server/routes/rule_types.test.ts index d9edac9df94b78..3b8b7ad16a399b 100644 --- a/x-pack/plugins/alerting/server/routes/rule_types.test.ts +++ b/x-pack/plugins/alerting/server/routes/rule_types.test.ts @@ -88,6 +88,7 @@ describe('ruleTypesRoute', () => { producer: 'test', enabled_in_license: true, has_get_summarized_alerts: true, + has_fields_for_a_a_d: false, }, ]; rulesClient.listRuleTypes.mockResolvedValueOnce(new Set(listTypes)); @@ -113,6 +114,7 @@ describe('ruleTypesRoute', () => { "default_schedule_interval": "10m", "does_set_recovery_context": false, "enabled_in_license": true, + "has_fields_for_a_a_d": false, "has_get_summarized_alerts": true, "id": "1", "is_exportable": true, diff --git a/x-pack/plugins/alerting/server/routes/rule_types.ts b/x-pack/plugins/alerting/server/routes/rule_types.ts index 61c0ead8c955be..89670c793ec020 100644 --- a/x-pack/plugins/alerting/server/routes/rule_types.ts +++ b/x-pack/plugins/alerting/server/routes/rule_types.ts @@ -26,6 +26,7 @@ const rewriteBodyRes: RewriteResponseCase = (result defaultScheduleInterval, doesSetRecoveryContext, hasGetSummarizedAlerts, + hasFieldsForAAD, ...rest }) => ({ ...rest, @@ -41,6 +42,7 @@ const rewriteBodyRes: RewriteResponseCase = (result default_schedule_interval: defaultScheduleInterval, does_set_recovery_context: doesSetRecoveryContext, has_get_summarized_alerts: !!hasGetSummarizedAlerts, + has_fields_for_a_a_d: !!hasFieldsForAAD, }) ); }; diff --git a/x-pack/plugins/alerting/server/rule_type_registry.test.ts b/x-pack/plugins/alerting/server/rule_type_registry.test.ts index 272232767ae98b..ef39d7c261af22 100644 --- a/x-pack/plugins/alerting/server/rule_type_registry.test.ts +++ b/x-pack/plugins/alerting/server/rule_type_registry.test.ts @@ -704,6 +704,7 @@ describe('Create Lifecycle', () => { "defaultScheduleInterval": undefined, "doesSetRecoveryContext": false, "enabledInLicense": false, + "hasFieldsForAAD": false, "hasGetSummarizedAlerts": false, "id": "test", "isExportable": true, diff --git a/x-pack/plugins/alerting/server/rule_type_registry.ts b/x-pack/plugins/alerting/server/rule_type_registry.ts index abf0223a50c086..c74aafe6e3cc34 100644 --- a/x-pack/plugins/alerting/server/rule_type_registry.ts +++ b/x-pack/plugins/alerting/server/rule_type_registry.ts @@ -61,6 +61,7 @@ export interface RegistryRuleType | 'ruleTaskTimeout' | 'defaultScheduleInterval' | 'doesSetRecoveryContext' + | 'fieldsForAAD' > { id: string; enabledInLicense: boolean; @@ -372,6 +373,7 @@ export class RuleTypeRegistry { doesSetRecoveryContext, alerts, getSummarizedAlerts, + fieldsForAAD, }, ]: [string, UntypedNormalizedRuleType]) => ({ id, @@ -392,6 +394,7 @@ export class RuleTypeRegistry { minimumLicenseRequired ).isValid, hasGetSummarizedAlerts: !!getSummarizedAlerts, + hasFieldsForAAD: Boolean(fieldsForAAD), ...(alerts ? { alerts } : {}), }) ) diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts index 86ac1f97f32031..509960ba50cc6c 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/register_inventory_metric_threshold_rule_type.ts @@ -49,6 +49,7 @@ import { WARNING_ACTIONS, } from './inventory_metric_threshold_executor'; import { MetricsRulesTypeAlertDefinition } from '../register_rule_types'; +import { O11Y_AAD_FIELDS } from '../../../../common/constants'; const condition = schema.object({ threshold: schema.arrayOf(schema.number()), @@ -146,5 +147,6 @@ export async function registerMetricInventoryThresholdRuleType( }, getSummarizedAlerts: libs.metricsRules.createGetSummarizedAlerts(), alerts: MetricsRulesTypeAlertDefinition, + fieldsForAAD: O11Y_AAD_FIELDS, }); } diff --git a/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts b/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts index ccbf33bb6e84fe..929f491c3dea91 100644 --- a/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/log_threshold/register_log_threshold_rule_type.ts @@ -7,6 +7,7 @@ import { i18n } from '@kbn/i18n'; import { PluginSetupContract } from '@kbn/alerting-plugin/server'; +import { O11Y_AAD_FIELDS } from '../../../../common/constants'; import { createLogThresholdExecutor, FIRED_ACTIONS } from './log_threshold_executor'; import { extractReferences, injectReferences } from './log_threshold_references_manager'; import { @@ -165,5 +166,6 @@ export async function registerLogThresholdRuleType( injectReferences, }, alerts: LogsRulesTypeAlertDefinition, + fieldsForAAD: O11Y_AAD_FIELDS, }); } diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_anomaly/register_metric_anomaly_rule_type.ts b/x-pack/plugins/infra/server/lib/alerting/metric_anomaly/register_metric_anomaly_rule_type.ts index b27ae6889fd284..37b1ce55a98dc1 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_anomaly/register_metric_anomaly_rule_type.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_anomaly/register_metric_anomaly_rule_type.ts @@ -14,6 +14,7 @@ import { AlertInstanceContext as AlertContext, } from '@kbn/alerting-plugin/server'; import { RecoveredActionGroupId } from '@kbn/alerting-plugin/common'; +import { O11Y_AAD_FIELDS } from '../../../../common/constants'; import { createMetricAnomalyExecutor, FIRED_ACTIONS, @@ -67,6 +68,7 @@ export const registerMetricAnomalyRuleType = ( minimumLicenseRequired: 'basic', isExportable: true, executor: createMetricAnomalyExecutor(libs, ml), + fieldsForAAD: O11Y_AAD_FIELDS, actionVariables: { context: [ { name: 'alertState', description: alertStateActionVariableDescription }, diff --git a/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx b/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx index 82baf344dfff7f..0113391558854d 100644 --- a/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx +++ b/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx @@ -252,6 +252,7 @@ describe('alert_form', () => { } actionTypeRegistry={actionTypeRegistry} featureId="alerting" + producerId="alerting" /> diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx index 61130979e9cfae..a524ad3929ea8a 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_field/index.tsx @@ -23,6 +23,7 @@ import type { } from '@kbn/alerting-plugin/common'; import { SecurityConnectorFeatureId } from '@kbn/actions-plugin/common'; import { FormattedMessage } from '@kbn/i18n-react'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { NOTIFICATION_DEFAULT_FREQUENCY } from '../../../../../common/constants'; import type { FieldHook } from '../../../../shared_imports'; import { useFormContext } from '../../../../shared_imports'; @@ -243,13 +244,13 @@ export const RuleActionsField: React.FC = ({ setActionFrequencyProperty: setActionFrequency, setActionAlertsFilterProperty, featureId: SecurityConnectorFeatureId, + producerId: AlertConsumers.SIEM, defaultActionMessage: FORM_FOR_EACH_ALERT_BODY_MESSAGE, defaultSummaryMessage: FORM_SUMMARY_BODY_MESSAGE, hideActionHeader: true, hasSummary: true, notifyWhenSelectOptions: NOTIFY_WHEN_OPTIONS, defaultRuleFrequency: NOTIFICATION_DEFAULT_FREQUENCY, - showActionAlertsFilter: true, }), [ actions, diff --git a/x-pack/plugins/stack_connectors/public/connector_types/slack/action_form.test.tsx b/x-pack/plugins/stack_connectors/public/connector_types/slack/action_form.test.tsx index cfa9014e5bb4cf..e3ac518ffa8ba1 100644 --- a/x-pack/plugins/stack_connectors/public/connector_types/slack/action_form.test.tsx +++ b/x-pack/plugins/stack_connectors/public/connector_types/slack/action_form.test.tsx @@ -100,6 +100,7 @@ const baseProps = { recoveryActionGroup: 'recovered', actionTypeRegistry, minimumThrottleInterval: [1, 'm'] as [number | undefined, string], + producerId: 'infratstructure', setActions: jest.fn(), setActionIdByIndex: jest.fn(), setActionParamsProperty: jest.fn(), diff --git a/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_rule_aad_fields.ts b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_rule_aad_fields.ts new file mode 100644 index 00000000000000..7fa2e3f0dfd04a --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/hooks/use_rule_aad_fields.ts @@ -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 { + const { http } = useKibana().services; + + const aadFields = useAsync(async () => { + if (!ruleTypeId) return []; + const fields = await http.get(`${BASE_RAC_ALERTS_API_PATH}/aad_fields`, { + query: { ruleTypeId }, + }); + + return fields; + }); + + return aadFields; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rule_types.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rule_types.ts index 05b36c8c36b832..ecded2a72e0e3e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rule_types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/rule_types.ts @@ -25,6 +25,7 @@ const rewriteBodyReq: RewriteRequestCase = ({ does_set_recovery_context: doesSetRecoveryContext, default_schedule_interval: defaultScheduleInterval, has_get_summarized_alerts: hasGetSummarizedAlerts, + has_fields_for_a_a_d: hasFieldsForAAD, ...rest }: AsApiContract) => ({ enabledInLicense, @@ -38,6 +39,7 @@ const rewriteBodyReq: RewriteRequestCase = ({ doesSetRecoveryContext, defaultScheduleInterval, hasGetSummarizedAlerts, + hasFieldsForAAD, ...rest, }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_alerts_filter_query.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_alerts_filter_query.tsx index d315ce65362b84..bbaf737101910e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_alerts_filter_query.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_alerts_filter_query.tsx @@ -6,6 +6,7 @@ */ import React, { useState, useCallback, useMemo, useEffect } from 'react'; +import { ValidFeatureId } from '@kbn/rule-data-utils'; import { Filter } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { EuiSwitch, EuiSpacer } from '@elastic/eui'; @@ -16,11 +17,17 @@ import { AlertsSearchBar } from '../alerts_search_bar'; interface ActionAlertsFilterQueryProps { state?: AlertsFilter['query']; onChange: (update?: AlertsFilter['query']) => void; + appName: string; + featureIds: ValidFeatureId[]; + ruleTypeId?: string; } export const ActionAlertsFilterQuery: React.FC = ({ state, onChange, + appName, + featureIds, + ruleTypeId, }) => { const [query, setQuery] = useState(state ?? { kql: '', filters: [] }); @@ -61,7 +68,7 @@ export const ActionAlertsFilterQuery: React.FC = ( label={i18n.translate( 'xpack.triggersActionsUI.sections.actionTypeForm.ActionAlertsFilterQueryToggleLabel', { - defaultMessage: 'if alert matches a query', + defaultMessage: 'If alert matches a query', } )} checked={queryEnabled} @@ -72,9 +79,10 @@ export const ActionAlertsFilterQuery: React.FC = ( <> { context: [{ name: 'contextVar', description: 'context var1' }], }} featureId="alerting" + producerId="alerting" defaultActionGroupId={'default'} isActionGroupDisabledForActionType={(actionGroupId: string, actionTypeId: string) => { const recoveryActionGroupId = customRecoveredActionGroup diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index bf2a144921d9c4..b7ff043d9727a9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -69,6 +69,7 @@ export interface ActionAccordionFormProps { index: number ) => void; featureId: string; + producerId: string; messageVariables?: ActionVariables; summaryMessageVariables?: ActionVariables; setHasActionsDisabled?: (value: boolean) => void; @@ -83,7 +84,8 @@ export interface ActionAccordionFormProps { minimumThrottleInterval?: [number | undefined, string]; notifyWhenSelectOptions?: NotifyWhenSelectOptions[]; defaultRuleFrequency?: RuleActionFrequency; - showActionAlertsFilter?: boolean; + ruleTypeId?: string; + hasFieldsForAAD?: boolean; } interface ActiveActionConnectorState { @@ -117,7 +119,9 @@ export const ActionForm = ({ minimumThrottleInterval, notifyWhenSelectOptions, defaultRuleFrequency = DEFAULT_FREQUENCY, - showActionAlertsFilter, + ruleTypeId, + producerId, + hasFieldsForAAD, }: ActionAccordionFormProps) => { const { http, @@ -491,7 +495,10 @@ export const ActionForm = ({ minimumThrottleInterval={minimumThrottleInterval} notifyWhenSelectOptions={notifyWhenSelectOptions} defaultNotifyWhenValue={defaultRuleFrequency.notifyWhen} - showActionAlertsFilter={showActionAlertsFilter} + featureId={featureId} + producerId={producerId} + ruleTypeId={ruleTypeId} + hasFieldsForAAD={hasFieldsForAAD} /> ); })} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx index a8a95b21d408df..171636d060c9eb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.test.tsx @@ -634,6 +634,8 @@ function getActionTypeForm({ summaryMessageVariables={summaryMessageVariables} notifyWhenSelectOptions={notifyWhenSelectOptions} defaultNotifyWhenValue={defaultNotifyWhenValue} + producerId="infrastructure" + featureId="infrastructure" /> ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx index d669242d0606de..d7fbb7f20169e8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_form.tsx @@ -8,6 +8,7 @@ import React, { Suspense, useEffect, useState, useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; +import { ValidFeatureId, AlertConsumers } from '@kbn/rule-data-utils'; import { EuiFlexGroup, EuiFlexItem, @@ -87,7 +88,10 @@ export type ActionTypeFormProps = { minimumThrottleInterval?: [number | undefined, string]; notifyWhenSelectOptions?: NotifyWhenSelectOptions[]; defaultNotifyWhenValue?: RuleNotifyWhenType; - showActionAlertsFilter?: boolean; + featureId: string; + producerId: string; + ruleTypeId?: string; + hasFieldsForAAD?: boolean; } & Pick< ActionAccordionFormProps, | 'defaultActionGroupId' @@ -134,7 +138,10 @@ export const ActionTypeForm = ({ minimumThrottleInterval, notifyWhenSelectOptions, defaultNotifyWhenValue, - showActionAlertsFilter, + producerId, + featureId, + ruleTypeId, + hasFieldsForAAD, }: ActionTypeFormProps) => { const { application: { capabilities }, @@ -333,6 +340,8 @@ export const ActionTypeForm = ({ setActionGroupIdByIndex && !actionItem.frequency?.summary; + const showActionAlertsFilter = hasFieldsForAAD || producerId === AlertConsumers.SIEM; + const accordionContent = checkEnabledResult.isEnabled ? ( <> setActionAlertsFilterProperty('query', query, index)} + featureIds={[producerId as ValidFeatureId]} + appName={featureId!} + ruleTypeId={ruleTypeId} /> ('kuery'); 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( ({ dateRange, query: nextQuery }: { dateRange: TimeRange; query?: Query }) => { @@ -72,7 +82,10 @@ export function AlertsSearchBar({ isActionGroupDisabledForActionType(selectedRuleType, actionGroupId, actionTypeId) } diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index d4ee51c2cadef4..923f3847df0781 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -337,6 +337,7 @@ export interface RuleType< actionVariables: ActionVariables; authorizedConsumers: Record; enabledInLicense: boolean; + hasFieldsForAAD?: boolean; hasGetSummarizedAlerts?: boolean; } diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/rule_types.ts b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/rule_types.ts index 301a161887923c..3418ee1f53689e 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/rule_types.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/group1/tests/alerting/rule_types.ts @@ -37,6 +37,7 @@ export default function listRuleTypes({ getService }: FtrProviderContext) { name: 'Recovered', }, enabled_in_license: true, + has_fields_for_a_a_d: false, has_get_summarized_alerts: false, rule_task_timeout: '5m', }; @@ -63,6 +64,7 @@ export default function listRuleTypes({ getService }: FtrProviderContext) { minimum_license_required: 'basic', is_exportable: true, enabled_in_license: true, + has_fields_for_a_a_d: false, has_get_summarized_alerts: false, rule_task_timeout: '5m', }; diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/rule_types.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/rule_types.ts index fbce0d38fcae30..fd7a5dd6d81b08 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/rule_types.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/alerting/group1/rule_types.ts @@ -45,6 +45,7 @@ export default function listRuleTypes({ getService }: FtrProviderContext) { minimum_license_required: 'basic', is_exportable: true, enabled_in_license: true, + has_fields_for_a_a_d: false, has_get_summarized_alerts: false, rule_task_timeout: '5m', }); @@ -133,6 +134,7 @@ export default function listRuleTypes({ getService }: FtrProviderContext) { minimumLicenseRequired: 'basic', isExportable: true, enabledInLicense: true, + hasFieldsForAAD: false, hasGetSummarizedAlerts: false, ruleTaskTimeout: '5m', });