diff --git a/src/platform/packages/shared/kbn-alerting-types/rule_settings.ts b/src/platform/packages/shared/kbn-alerting-types/rule_settings.ts index 86823668b7f7f..7bc7dbc273090 100644 --- a/src/platform/packages/shared/kbn-alerting-types/rule_settings.ts +++ b/src/platform/packages/shared/kbn-alerting-types/rule_settings.ts @@ -21,6 +21,7 @@ export interface RulesSettingsFlappingProperties { } export interface RuleSpecificFlappingProperties { + enabled?: boolean; lookBackWindow: number; statusChangeThreshold: number; } diff --git a/src/platform/packages/shared/kbn-alerts-ui-shared/src/rule_settings/rule_settings_flapping_form.tsx b/src/platform/packages/shared/kbn-alerts-ui-shared/src/rule_settings/rule_settings_flapping_form.tsx index 8b24b21ac4669..0c1dae5f69423 100644 --- a/src/platform/packages/shared/kbn-alerts-ui-shared/src/rule_settings/rule_settings_flapping_form.tsx +++ b/src/platform/packages/shared/kbn-alerts-ui-shared/src/rule_settings/rule_settings_flapping_form.tsx @@ -7,26 +7,21 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import React, { useCallback, useMemo, useRef, useState } from 'react'; +import React, { useCallback, useMemo, useRef } from 'react'; import { EuiBadge, - EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, - EuiLink, - EuiPopover, EuiSpacer, EuiSplitPanel, EuiSwitch, EuiText, - EuiOutsideClickDetector, useEuiTheme, useIsWithinMinBreakpoint, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { RuleSpecificFlappingProperties, RulesSettingsFlapping } from '@kbn/alerting-types'; -import { FormattedMessage } from '@kbn/i18n-react'; import { RuleSettingsFlappingMessage } from './rule_settings_flapping_message'; import { RuleSettingsFlappingInputs } from './rule_settings_flapping_inputs'; @@ -42,6 +37,14 @@ const flappingOffLabel = i18n.translate('alertsUIShared.ruleSettingsFlappingForm defaultMessage: 'OFF', }); +const enabledOnLabel = i18n.translate('alertsUIShared.ruleSettingsFlappingForm.enabledOnLabel', { + defaultMessage: 'On', +}); + +const enabledOffLabel = i18n.translate('alertsUIShared.ruleSettingsFlappingForm.enabledOffLabel', { + defaultMessage: 'Off', +}); + const flappingOverrideLabel = i18n.translate( 'alertsUIShared.ruleSettingsFlappingForm.overrideLabel', { @@ -49,27 +52,6 @@ const flappingOverrideLabel = i18n.translate( } ); -const flappingOffContentRules = i18n.translate( - 'alertsUIShared.ruleSettingsFlappingForm.flappingOffContentRules', - { - defaultMessage: 'Rules', - } -); - -const flappingOffContentSettings = i18n.translate( - 'alertsUIShared.ruleSettingsFlappingForm.flappingOffContentSettings', - { - defaultMessage: 'Settings', - } -); - -const flappingExternalLinkLabel = i18n.translate( - 'alertsUIShared.ruleSettingsFlappingForm.flappingExternalLinkLabel', - { - defaultMessage: "What's this?", - } -); - const flappingOverrideConfiguration = i18n.translate( 'alertsUIShared.ruleSettingsFlappingForm.flappingOverrideConfiguration', { @@ -95,8 +77,6 @@ export const RuleSettingsFlappingForm = (props: RuleSettingsFlappingFormProps) = const { flappingSettings, spaceFlappingSettings, canWriteFlappingSettingsUI, onFlappingChange } = props; - const [isPopoverOpen, setIsPopoverOpen] = useState(false); - const cachedFlappingSettings = useRef(); const isDesktop = useIsWithinMinBreakpoint('xl'); @@ -113,6 +93,7 @@ export const RuleSettingsFlappingForm = (props: RuleSettingsFlappingFormProps) = } const initialFlappingSettings = cachedFlappingSettings.current || spaceFlappingSettings; onFlappingChange({ + enabled: initialFlappingSettings.enabled, lookBackWindow: initialFlappingSettings.lookBackWindow, statusChangeThreshold: initialFlappingSettings.statusChangeThreshold, }); @@ -153,63 +134,24 @@ export const RuleSettingsFlappingForm = (props: RuleSettingsFlappingFormProps) = [flappingSettings, internalOnFlappingChange] ); - const flappingOffTooltip = useMemo(() => { - if (!spaceFlappingSettings) { - return null; - } - const { enabled } = spaceFlappingSettings; - if (enabled) { - return null; - } - - if (canWriteFlappingSettingsUI) { - return ( - setIsPopoverOpen(false)}> - setIsPopoverOpen(!isPopoverOpen)} - /> - } - > - - {flappingOffContentRules}, - settings: {flappingOffContentSettings}, - }} - /> - - - - ); - } - // TODO: Add the external doc link here! - return ( - - {flappingExternalLinkLabel} - - ); - }, [canWriteFlappingSettingsUI, isPopoverOpen, spaceFlappingSettings]); + const onEnabledChange = useCallback( + (value: boolean) => { + if (!flappingSettings) { + return; + } + internalOnFlappingChange({ + ...flappingSettings, + enabled: value, + }); + }, + [flappingSettings, internalOnFlappingChange] + ); const flappingFormHeader = useMemo(() => { if (!spaceFlappingSettings) { return null; } - const { enabled } = spaceFlappingSettings; + const enabled = !flappingSettings ? spaceFlappingSettings.enabled : flappingSettings.enabled; return ( @@ -232,17 +174,14 @@ export const RuleSettingsFlappingForm = (props: RuleSettingsFlappingFormProps) = )} - {enabled && ( - - )} - {flappingOffTooltip} + {flappingSettings && enabled && ( @@ -258,7 +197,6 @@ export const RuleSettingsFlappingForm = (props: RuleSettingsFlappingFormProps) = euiTheme, spaceFlappingSettings, flappingSettings, - flappingOffTooltip, canWriteFlappingSettingsUI, onFlappingToggle, ]); @@ -267,9 +205,6 @@ export const RuleSettingsFlappingForm = (props: RuleSettingsFlappingFormProps) = if (!flappingSettings) { return null; } - if (!spaceFlappingSettings?.enabled) { - return null; - } return ( { + if (!flappingSettings) { + return null; + } + + return ( + + onEnabledChange(e.target.checked)} + /> + + ); + }, [flappingSettings, canWriteFlappingSettingsUI, onEnabledChange]); + const flappingFormMessage = useMemo(() => { if (!spaceFlappingSettings || !spaceFlappingSettings.enabled) { return null; @@ -315,6 +266,7 @@ export const RuleSettingsFlappingForm = (props: RuleSettingsFlappingFormProps) = {flappingFormHeader} + {flappingFormSwitch} {flappingFormBody} diff --git a/src/platform/packages/shared/response-ops/rule_form/src/common/apis/create_rule/transform_create_rule_body.test.ts b/src/platform/packages/shared/response-ops/rule_form/src/common/apis/create_rule/transform_create_rule_body.test.ts index fb10af8dd1795..4fe0456970816 100644 --- a/src/platform/packages/shared/response-ops/rule_form/src/common/apis/create_rule/transform_create_rule_body.test.ts +++ b/src/platform/packages/shared/response-ops/rule_form/src/common/apis/create_rule/transform_create_rule_body.test.ts @@ -57,6 +57,7 @@ const ruleToCreate: CreateRuleBody = { active: 10, }, flapping: { + enabled: true, lookBackWindow: 10, statusChangeThreshold: 10, }, @@ -103,6 +104,7 @@ describe('transformCreateRuleBody', () => { ], alert_delay: { active: 10 }, flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, diff --git a/src/platform/packages/shared/response-ops/rule_form/src/common/apis/create_rule/transform_create_rule_body.ts b/src/platform/packages/shared/response-ops/rule_form/src/common/apis/create_rule/transform_create_rule_body.ts index 715b3529dd3b1..ae59d1fd6c011 100644 --- a/src/platform/packages/shared/response-ops/rule_form/src/common/apis/create_rule/transform_create_rule_body.ts +++ b/src/platform/packages/shared/response-ops/rule_form/src/common/apis/create_rule/transform_create_rule_body.ts @@ -17,6 +17,7 @@ const transformCreateRuleFlapping = (flapping: Rule['flapping']) => { } return { + enabled: flapping.enabled, look_back_window: flapping.lookBackWindow, status_change_threshold: flapping.statusChangeThreshold, }; diff --git a/src/platform/packages/shared/response-ops/rule_form/src/common/apis/update_rule/transform_update_rule_body.test.ts b/src/platform/packages/shared/response-ops/rule_form/src/common/apis/update_rule/transform_update_rule_body.test.ts index afb8fb8cd2a8f..a001b359117e3 100644 --- a/src/platform/packages/shared/response-ops/rule_form/src/common/apis/update_rule/transform_update_rule_body.test.ts +++ b/src/platform/packages/shared/response-ops/rule_form/src/common/apis/update_rule/transform_update_rule_body.test.ts @@ -54,6 +54,7 @@ const ruleToUpdate: UpdateRuleBody = { active: 10, }, flapping: { + enabled: true, lookBackWindow: 10, statusChangeThreshold: 10, }, @@ -104,6 +105,7 @@ describe('transformUpdateRuleBody', () => { tags: [], throttle: null, flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, diff --git a/src/platform/packages/shared/response-ops/rule_form/src/common/apis/update_rule/transform_update_rule_body.ts b/src/platform/packages/shared/response-ops/rule_form/src/common/apis/update_rule/transform_update_rule_body.ts index 040f753c4710c..8c8639b6226b2 100644 --- a/src/platform/packages/shared/response-ops/rule_form/src/common/apis/update_rule/transform_update_rule_body.ts +++ b/src/platform/packages/shared/response-ops/rule_form/src/common/apis/update_rule/transform_update_rule_body.ts @@ -17,6 +17,7 @@ const transformUpdateRuleFlapping = (flapping: Rule['flapping']) => { } return { + enabled: flapping.enabled, look_back_window: flapping.lookBackWindow, status_change_threshold: flapping.statusChangeThreshold, }; diff --git a/src/platform/packages/shared/response-ops/rule_form/src/common/transformations/transform_rule.ts b/src/platform/packages/shared/response-ops/rule_form/src/common/transformations/transform_rule.ts index b8e5453a4fef1..20a2ae1557938 100644 --- a/src/platform/packages/shared/response-ops/rule_form/src/common/transformations/transform_rule.ts +++ b/src/platform/packages/shared/response-ops/rule_form/src/common/transformations/transform_rule.ts @@ -40,6 +40,7 @@ const transformFlapping = (flapping: AsApiContract) => { } return { + enabled: flapping.enabled, lookBackWindow: flapping.look_back_window, statusChangeThreshold: flapping.status_change_threshold, }; diff --git a/x-pack/platform/plugins/private/translations/translations/de-DE.json b/x-pack/platform/plugins/private/translations/translations/de-DE.json index de444ab3434e0..e2c216d549a3c 100644 --- a/x-pack/platform/plugins/private/translations/translations/de-DE.json +++ b/x-pack/platform/plugins/private/translations/translations/de-DE.json @@ -181,11 +181,7 @@ "alertsUIShared.maintenanceWindowCallout.fetchErrorDescription": "Regelbenachrichtigungen werden gestoppt, während Wartungsfenster aktiv sind.", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActiveDescription": "Regelbenachrichtigungen werden gestoppt, während Wartungsfenster aktiv sind.", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActiveNoCategories": "Ein oder mehrere Wartungsfenster sind aktiv", - "alertsUIShared.ruleSettingsFlappingForm.flappingExternalLinkLabel": "Was ist das?", "alertsUIShared.ruleSettingsFlappingForm.flappingLabel": "Flapping-Erkennung", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffContentRules": "Regeln", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffContentSettings": "Einstellungen", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffPopoverContent": "Gehen Sie zu {rules} > {settings}, um die Flapping-Erkennung für alle Regeln in einem Bereich zu aktivieren. Sie können anschließend das Rückblickfenster und die Schwellenwerte in jeder Regel anpassen.", "alertsUIShared.ruleSettingsFlappingForm.flappingOverrideConfiguration": "Konfiguration anpassen", "alertsUIShared.ruleSettingsFlappingForm.offLabel": "OFF", "alertsUIShared.ruleSettingsFlappingForm.onLabel": "ON", diff --git a/x-pack/platform/plugins/private/translations/translations/fr-FR.json b/x-pack/platform/plugins/private/translations/translations/fr-FR.json index 8fad2e096adb1..7903aaf1fd135 100644 --- a/x-pack/platform/plugins/private/translations/translations/fr-FR.json +++ b/x-pack/platform/plugins/private/translations/translations/fr-FR.json @@ -181,11 +181,7 @@ "alertsUIShared.maintenanceWindowCallout.fetchErrorDescription": "Les notifications de règle sont arrêtées lorsque les fenêtres de maintenance sont en cours d'exécution.", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActiveDescription": "Les notifications de règle sont arrêtées lorsque les fenêtres de maintenance sont en cours d'exécution.", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActiveNoCategories": "Une ou plusieurs fenêtres de maintenance sont en cours d'exécution", - "alertsUIShared.ruleSettingsFlappingForm.flappingExternalLinkLabel": "Qu'est-ce que c'est ?", "alertsUIShared.ruleSettingsFlappingForm.flappingLabel": "Détection des éléments instables", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffContentRules": "Règles", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffContentSettings": "Paramètres", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffPopoverContent": "Accédez à {rules} > {settings} pour activer la détection d'instabilité pour l'ensemble des règles d'un espace. Vous pouvez ensuite personnaliser la période d'analyse et les valeurs seuils de chaque règle.", "alertsUIShared.ruleSettingsFlappingForm.flappingOverrideConfiguration": "Personnaliser la configuration", "alertsUIShared.ruleSettingsFlappingForm.offLabel": "DÉSACTIVÉ", "alertsUIShared.ruleSettingsFlappingForm.onLabel": "ACTIVÉ", diff --git a/x-pack/platform/plugins/private/translations/translations/ja-JP.json b/x-pack/platform/plugins/private/translations/translations/ja-JP.json index 6bcc9f662ff1a..d2278aaa344ad 100644 --- a/x-pack/platform/plugins/private/translations/translations/ja-JP.json +++ b/x-pack/platform/plugins/private/translations/translations/ja-JP.json @@ -181,11 +181,7 @@ "alertsUIShared.maintenanceWindowCallout.fetchErrorDescription": "保守時間枠の実行中は、ルール通知が停止されます。", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActiveDescription": "保守時間枠の実行中は、ルール通知が停止されます。", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActiveNoCategories": "1つ以上の保守時間枠が実行中です。", - "alertsUIShared.ruleSettingsFlappingForm.flappingExternalLinkLabel": "概要", "alertsUIShared.ruleSettingsFlappingForm.flappingLabel": "フラップ検出", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffContentRules": "ルール", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffContentSettings": "設定", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffPopoverContent": "スペース内のすべてのルールでフラッピング検出を有効にするには、{rules} > {settings}に移動します。その後、各ルールで履歴表示期間としきい値をカスタマイズできます。", "alertsUIShared.ruleSettingsFlappingForm.flappingOverrideConfiguration": "構成をカスタマイズ", "alertsUIShared.ruleSettingsFlappingForm.offLabel": "オフ", "alertsUIShared.ruleSettingsFlappingForm.onLabel": "オン", diff --git a/x-pack/platform/plugins/private/translations/translations/zh-CN.json b/x-pack/platform/plugins/private/translations/translations/zh-CN.json index 4e5a62c6b209e..e0aefdc65f9c8 100644 --- a/x-pack/platform/plugins/private/translations/translations/zh-CN.json +++ b/x-pack/platform/plugins/private/translations/translations/zh-CN.json @@ -181,11 +181,7 @@ "alertsUIShared.maintenanceWindowCallout.fetchErrorDescription": "维护窗口正在运行时会停止规则通知。", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActiveDescription": "维护窗口正在运行时会停止规则通知。", "alertsUIShared.maintenanceWindowCallout.maintenanceWindowActiveNoCategories": "一个或多个维护窗口正在运行", - "alertsUIShared.ruleSettingsFlappingForm.flappingExternalLinkLabel": "这是什么?", "alertsUIShared.ruleSettingsFlappingForm.flappingLabel": "摆动检测", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffContentRules": "规则", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffContentSettings": "设置", - "alertsUIShared.ruleSettingsFlappingForm.flappingOffPopoverContent": "请前往 {rules} > {settings} 为工作区中的所有规则打开摆动检测。随后,您可以自定义每个规则中的回顾窗口和阈值。", "alertsUIShared.ruleSettingsFlappingForm.flappingOverrideConfiguration": "定制配置", "alertsUIShared.ruleSettingsFlappingForm.offLabel": "关闭", "alertsUIShared.ruleSettingsFlappingForm.onLabel": "开启", diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts index ec9534daf1326..f118ecb5ec132 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.test.ts @@ -3285,6 +3285,7 @@ describe('create()', () => { test('should create rule with flapping', async () => { const flapping = { + enabled: true, lookBackWindow: 10, statusChangeThreshold: 10, }; @@ -3321,7 +3322,7 @@ describe('create()', () => { ], }); - const result = await rulesClient.create({ data, isFlappingEnabled: true }); + const result = await rulesClient.create({ data }); expect(unsecuredSavedObjectsClient.create).toHaveBeenCalledWith( RULE_SAVED_OBJECT_TYPE, expect.objectContaining({ @@ -3342,22 +3343,6 @@ describe('create()', () => { expect(result.flapping).toEqual(flapping); }); - test('throws error when creating a rule with flapping if global flapping is disabled', async () => { - const flapping = { - lookBackWindow: 10, - statusChangeThreshold: 10, - }; - - const data = getMockData({ - name: 'my rule name', - flapping, - }); - - await expect(rulesClient.create({ data })).rejects.toThrowErrorMatchingInlineSnapshot( - `"Error creating rule: can not create rule with flapping if global flapping is disabled"` - ); - }); - test('throws error when creating with an interval less than the minimum configured one when enforce = true', async () => { rulesClient = new RulesClient({ ...rulesClientParams, @@ -3956,7 +3941,7 @@ describe('create()', () => { ], }); await expect(rulesClient.create({ data })).rejects.toThrowErrorMatchingInlineSnapshot( - `"Failed to validate actions due to the following error: Action's alertsFilter must have either \\"query\\" or \\"timeframe\\" : 154"` + `"Failed to validate actions due to the following error: Action's alertsFilter must have either \\"query\\" or \\"timeframe\\" : 153"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); @@ -4013,7 +3998,7 @@ describe('create()', () => { ], }); await expect(rulesClient.create({ data })).rejects.toThrowErrorMatchingInlineSnapshot( - `"Failed to validate actions due to the following error: This ruleType (Test) can't have an action with Alerts Filter. Actions: [155]"` + `"Failed to validate actions due to the following error: This ruleType (Test) can't have an action with Alerts Filter. Actions: [154]"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); @@ -4085,7 +4070,7 @@ describe('create()', () => { group: 'default', actionTypeId: 'test', params: { foo: true }, - uuid: '156', + uuid: '155', }, ], alertTypeId: '123', @@ -4319,13 +4304,13 @@ describe('create()', () => { params: { foo: true, }, - uuid: '158', + uuid: '157', }, { actionRef: 'system_action:system_action-id', actionTypeId: '.test', params: { foo: 'test' }, - uuid: '159', + uuid: '158', }, ], alertTypeId: '123', @@ -4403,13 +4388,13 @@ describe('create()', () => { params: { foo: true, }, - uuid: '160', + uuid: '159', }, { actionRef: 'system_action:system_action-id', actionTypeId: '.test', params: { foo: 'test' }, - uuid: '161', + uuid: '160', }, ]); }); diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts index 673a346f9b987..f71763df70c96 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/create/create_rule.ts @@ -49,7 +49,6 @@ export interface CreateRuleParams { data: CreateRuleData; options?: CreateRuleOptions; allowMissingConnectorSecrets?: boolean; - isFlappingEnabled?: boolean; } export async function createRule( @@ -57,12 +56,7 @@ export async function createRule( createParams: CreateRuleParams // TODO (http-versioning): This should be of type Rule, change this when all rule types are fixed ): Promise> { - const { - data: initialData, - options, - allowMissingConnectorSecrets, - isFlappingEnabled = false, - } = createParams; + const { data: initialData, options, allowMissingConnectorSecrets } = createParams; const actionsClient = await context.getActionsClient(); @@ -184,12 +178,6 @@ export async function createRule( ); } - if (initialData.flapping !== undefined && !isFlappingEnabled) { - throw Boom.badRequest( - 'Error creating rule: can not create rule with flapping if global flapping is disabled' - ); - } - const allActions = [...data.actions, ...(data.systemActions ?? [])]; const artifacts = data.artifacts ?? {}; // Extract saved object references for this rule diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts index 1488c813b193d..7c5c2c78d18d2 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.test.ts @@ -1798,6 +1798,7 @@ describe('update()', () => { it('should update rule flapping', async () => { const flapping = { + enabled: true, lookBackWindow: 10, statusChangeThreshold: 10, }; @@ -1841,7 +1842,6 @@ describe('update()', () => { systemActions: [], flapping, }, - isFlappingEnabled: true, }); expect(unsecuredSavedObjectsClient.create).toHaveBeenNthCalledWith( @@ -1861,35 +1861,6 @@ describe('update()', () => { expect(result.flapping).toEqual(flapping); }); - it('should throw error when updating a rule with flapping if global flapping is disabled', async () => { - const flapping = { - lookBackWindow: 10, - statusChangeThreshold: 10, - }; - - await expect( - rulesClient.update({ - id: '1', - data: { - schedule: { interval: '1m' }, - name: 'abc', - tags: ['foo'], - params: { - bar: true, - }, - throttle: null, - notifyWhen: 'onActiveAlert', - actions: [], - systemActions: [], - flapping, - }, - isFlappingEnabled: false, - }) - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Error updating rule: can not update rule flapping if global flapping is disabled"` - ); - }); - it('swallows error when invalidate API key throws', async () => { unsecuredSavedObjectsClient.create.mockResolvedValueOnce({ id: '1', diff --git a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts index e42683cd73fa9..7b8c6d28fbcc2 100644 --- a/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts +++ b/x-pack/platform/plugins/shared/alerting/server/application/rule/methods/update/update_rule.ts @@ -41,36 +41,6 @@ import { updateRuleDataSchema } from './schemas'; import { transformRuleAttributesToRuleDomain, transformRuleDomainToRule } from '../../transforms'; import { ruleDomainSchema } from '../../schemas'; -const validateCanUpdateFlapping = ( - isFlappingEnabled: boolean, - originalFlapping: RawRule['flapping'], - updateFlapping: UpdateRuleParams['data']['flapping'] -) => { - // If flapping is enabled, allow rule flapping to be updated and do nothing - if (isFlappingEnabled) { - return; - } - - // If updated flapping is undefined then don't do anything, it's not being updated - if (updateFlapping === undefined) { - return; - } - - // If both versions are falsy, allow it even if its changing between undefined and null - if (!originalFlapping && !updateFlapping) { - return; - } - - // If both values are equal, allow it because it's essentially not changing anything - if (isEqual(originalFlapping, updateFlapping)) { - return; - } - - throw Boom.badRequest( - `Error updating rule: can not update rule flapping if global flapping is disabled` - ); -}; - type ShouldIncrementRevision = (params?: RuleParams) => boolean; export interface UpdateRuleParams { @@ -78,7 +48,6 @@ export interface UpdateRuleParams { data: UpdateRuleData; allowMissingConnectorSecrets?: boolean; shouldIncrementRevision?: ShouldIncrementRevision; - isFlappingEnabled?: boolean; } export async function updateRule( @@ -101,7 +70,6 @@ async function updateWithOCC( data: initialData, allowMissingConnectorSecrets, id, - isFlappingEnabled = false, shouldIncrementRevision = () => true, } = updateParams; @@ -146,18 +114,8 @@ async function updateWithOCC( systemActions: genSystemActions, }; - const { - alertTypeId, - consumer, - enabled, - schedule, - name, - apiKey, - apiKeyCreatedByUser, - flapping: originalFlapping, - } = originalRuleSavedObject.attributes; - - validateCanUpdateFlapping(isFlappingEnabled, originalFlapping, initialData.flapping); + const { alertTypeId, consumer, enabled, schedule, name, apiKey, apiKeyCreatedByUser } = + originalRuleSavedObject.attributes; let validationPayload: ValidateScheduleLimitResult = null; if (enabled && schedule.interval !== data.schedule.interval) { diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/create_rule_route.test.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/create_rule_route.test.ts index af9068c83ba24..e88942c2eb882 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/create_rule_route.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/create_rule_route.test.ts @@ -267,7 +267,6 @@ describe('createRuleRoute', () => { ], "throttle": "30s", }, - "isFlappingEnabled": true, "options": Object { "id": undefined, }, @@ -387,7 +386,6 @@ describe('createRuleRoute', () => { ], "throttle": "30s", }, - "isFlappingEnabled": true, "options": Object { "id": "custom-id", }, @@ -508,7 +506,6 @@ describe('createRuleRoute', () => { ], "throttle": "30s", }, - "isFlappingEnabled": true, "options": Object { "id": "custom-id", }, @@ -629,7 +626,6 @@ describe('createRuleRoute', () => { ], "throttle": "30s", }, - "isFlappingEnabled": true, "options": Object { "id": "custom-id", }, @@ -809,7 +805,6 @@ describe('createRuleRoute', () => { ], "throttle": "30s", }, - "isFlappingEnabled": true, "options": Object { "id": undefined, }, diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/create_rule_route.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/create_rule_route.ts index 5dc4a145198a3..e805113e6dc72 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/create_rule_route.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/create_rule_route.ts @@ -71,7 +71,6 @@ export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOpt const alertingContext = await context.alerting; const rulesClient = await alertingContext.getRulesClient(); const actionsClient = (await context.actions).getActionsClient(); - const rulesSettingsClient = (await context.alerting).getRulesSettingsClient(true); const ruleTypes = alertingContext.listTypes(); // Assert versioned inputs @@ -105,8 +104,6 @@ export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOpt actionsClient.isSystemAction(action.id) ); - const flappingSettings = await rulesSettingsClient.flapping().get(); - // TODO (http-versioning): Remove this cast, this enables us to move forward // without fixing all of other solution types const createdRule: Rule = (await rulesClient.create({ @@ -115,7 +112,6 @@ export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOpt actions, systemActions, }), - isFlappingEnabled: flappingSettings.enabled, options: { id: params?.id }, })) as Rule; diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts index dc0c707c6b8ad..c279c679d5e3b 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/create/transforms/transform_create_body/v1.ts @@ -73,6 +73,7 @@ const transformCreateBodyFlapping = ( return flapping; } return { + enabled: flapping.enabled, lookBackWindow: flapping.look_back_window, statusChangeThreshold: flapping.status_change_threshold, }; diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.test.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.test.ts index 7dd15a4c913ec..4577ade5435a2 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.test.ts @@ -22,6 +22,7 @@ describe('transformUpdateBody', () => { notify_when: 'onActionGroupChange' as 'onActionGroupChange', alert_delay: { active: 5 }, flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 5, }, @@ -69,6 +70,7 @@ describe('transformUpdateBody', () => { notifyWhen: 'onActionGroupChange', alertDelay: { active: 5 }, flapping: { + enabled: true, lookBackWindow: 10, statusChangeThreshold: 5, }, @@ -129,6 +131,7 @@ describe('transformUpdateBody', () => { }, }, "flapping": Object { + "enabled": true, "lookBackWindow": 10, "statusChangeThreshold": 5, }, diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.ts index 00b15ebf4db9a..e10ec766c1bb0 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/transforms/transform_update_body/v1.ts @@ -77,6 +77,7 @@ const transformUpdateBodyFlapping = ( return flapping; } return { + enabled: flapping.enabled, lookBackWindow: flapping.look_back_window, statusChangeThreshold: flapping.status_change_threshold, }; diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/update_rule_route.test.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/update_rule_route.test.ts index 026df99a76edf..faf54a0a2bdbb 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/update_rule_route.test.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/update_rule_route.test.ts @@ -218,7 +218,6 @@ describe('updateRuleRoute', () => { "throttle": "10m", }, "id": "1", - "isFlappingEnabled": true, }, ] `); diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/update_rule_route.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/update_rule_route.ts index 5eee31e1367a8..65291f625cfab 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/update_rule_route.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/apis/update/update_rule_route.ts @@ -75,7 +75,6 @@ export const updateRuleRoute = ( const alertingContext = await context.alerting; const rulesClient = await alertingContext.getRulesClient(); const actionsClient = (await context.actions).getActionsClient(); - const rulesSettingsClient = (await context.alerting).getRulesSettingsClient(true); const ruleTypes = alertingContext.listTypes(); // Assert versioned inputs @@ -105,8 +104,6 @@ export const updateRuleRoute = ( actionsClient.isSystemAction(action.id) ); - const flappingSettings = await rulesSettingsClient.flapping().get(); - // TODO (http-versioning): Remove this cast, this enables us to move forward // without fixing all of other solution types const updatedRule: Rule = (await rulesClient.update({ @@ -116,7 +113,6 @@ export const updateRuleRoute = ( actions, systemActions, }), - isFlappingEnabled: flappingSettings.enabled, })) as Rule; // Assert versioned response type diff --git a/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts b/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts index de3e99fe092fc..89379999bc34d 100644 --- a/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts +++ b/x-pack/platform/plugins/shared/alerting/server/routes/rule/transforms/transform_rule_to_rule_response/v1.ts @@ -94,6 +94,7 @@ export const transformFlapping = (flapping: Rule['flapping']) => { } return { + enabled: flapping.enabled, look_back_window: flapping.lookBackWindow, status_change_threshold: flapping.statusChangeThreshold, }; diff --git a/x-pack/platform/plugins/shared/alerting/server/task_runner/task_runner.ts b/x-pack/platform/plugins/shared/alerting/server/task_runner/task_runner.ts index 100ff6d6bc0c0..0f526c3487e3d 100644 --- a/x-pack/platform/plugins/shared/alerting/server/task_runner/task_runner.ts +++ b/x-pack/platform/plugins/shared/alerting/server/task_runner/task_runner.ts @@ -297,14 +297,12 @@ export class TaskRunner< const ruleFlappingSettings = rule.flapping ? { - enabled: true, + enabled: true, // default to true if flapping.enabled is undefined ...rule.flapping, } : null; - const flappingSettings = spaceFlappingSettings.enabled - ? ruleFlappingSettings || spaceFlappingSettings - : spaceFlappingSettings; + const flappingSettings = ruleFlappingSettings || spaceFlappingSettings; const ruleTypeRunnerContext = { alertingEventLogger: this.alertingEventLogger, diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/rule_api/common_transformations.ts b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/rule_api/common_transformations.ts index 51225699c9518..5f639016f509e 100644 --- a/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/rule_api/common_transformations.ts +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/public/application/lib/rule_api/common_transformations.ts @@ -62,6 +62,7 @@ const transformFlapping = (flapping: AsApiContract) => { return flapping; } return { + enabled: flapping.enabled, lookBackWindow: flapping.look_back_window, statusChangeThreshold: flapping.status_change_threshold, }; diff --git a/x-pack/platform/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update.ts b/x-pack/platform/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update.ts index 51cf2133e296b..f1d28d63adf6e 100644 --- a/x-pack/platform/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update.ts +++ b/x-pack/platform/test/alerting_api_integration/security_and_spaces/group2/tests/alerting/update.ts @@ -87,6 +87,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { throttle: '1m', notify_when: 'onThrottleInterval', flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -156,6 +157,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { execution_status: response.body.execution_status, revision: 1, flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -207,6 +209,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { throttle: '1m', notify_when: 'onThrottleInterval', flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -268,6 +271,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { execution_status: response.body.execution_status, revision: 1, flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -319,6 +323,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { throttle: '1m', notify_when: 'onThrottleInterval', flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -380,6 +385,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { execution_status: response.body.execution_status, revision: 1, flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -431,6 +437,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { throttle: '1m', notify_when: 'onThrottleInterval', flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -484,6 +491,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { execution_status: response.body.execution_status, revision: 1, flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -544,6 +552,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { throttle: '1m', notify_when: 'onThrottleInterval', flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -597,6 +606,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { execution_status: response.body.execution_status, revision: 1, flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -643,6 +653,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { throttle: '1m', notify_when: 'onActiveAlert', flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, diff --git a/x-pack/platform/test/alerting_api_integration/security_and_spaces/group5/tests/alerting/create.ts b/x-pack/platform/test/alerting_api_integration/security_and_spaces/group5/tests/alerting/create.ts index 2939a429e21b7..9d5bde8b0b5dd 100644 --- a/x-pack/platform/test/alerting_api_integration/security_and_spaces/group5/tests/alerting/create.ts +++ b/x-pack/platform/test/alerting_api_integration/security_and_spaces/group5/tests/alerting/create.ts @@ -71,6 +71,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { }, ], flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, @@ -135,6 +136,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { execution_status: response.body.execution_status, revision: 0, flapping: { + enabled: true, look_back_window: 10, status_change_threshold: 10, }, diff --git a/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts b/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts index 7cf0b3ef2231f..416b9c14dcf1f 100644 --- a/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts +++ b/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group1/create.ts @@ -682,6 +682,7 @@ export default function createAlertTests({ getService }: FtrProviderContext) { .send( getTestRuleData({ flapping: { + enabled: false, look_back_window: 5, status_change_threshold: 5, }, @@ -692,12 +693,13 @@ export default function createAlertTests({ getService }: FtrProviderContext) { objectRemover.add(Spaces.space1.id, response.body.id, 'rule', 'alerting'); expect(response.body.flapping).to.eql({ + enabled: false, look_back_window: 5, status_change_threshold: 5, }); }); - it('should throw if flapping is created when global flapping is off', async () => { + it('should not throw if flapping is created when global flapping is off', async () => { await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/settings/_flapping`) .set('kbn-xsrf', 'foo') @@ -713,16 +715,21 @@ export default function createAlertTests({ getService }: FtrProviderContext) { .send( getTestRuleData({ flapping: { + enabled: true, look_back_window: 5, status_change_threshold: 5, }, }) ); - expect(response.statusCode).eql(400); - expect(response.body.message).eql( - 'Error creating rule: can not create rule with flapping if global flapping is disabled' - ); + expect(response.status).to.eql(200); + objectRemover.add(Spaces.space1.id, response.body.id, 'rule', 'alerting'); + + expect(response.body.flapping).to.eql({ + enabled: true, + look_back_window: 5, + status_change_threshold: 5, + }); }); it('should throw if flapping is invalid', async () => { diff --git a/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group2/update.ts b/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group2/update.ts index 29219812f5bd3..55ce372c45eaf 100644 --- a/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group2/update.ts +++ b/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group2/update.ts @@ -260,12 +260,14 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { throttle: '1m', notify_when: 'onThrottleInterval', flapping: { + enabled: false, look_back_window: 5, status_change_threshold: 5, }, }); expect(updatedRule.flapping).eql({ + enabled: false, look_back_window: 5, status_change_threshold: 5, }); @@ -310,7 +312,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { expect(updatedRule.flapping).eql(null); }); - it('should throw if flapping is updated when global flapping is off', async () => { + it('should not throw if flapping is updated when global flapping is off', async () => { const response = await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) .set('kbn-xsrf', 'foo') @@ -327,7 +329,7 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { status_change_threshold: 5, }); - await supertest + const { body: updatedRule } = await supertest .put(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule/${response.body.id}`) .set('kbn-xsrf', 'foo') .send({ @@ -341,72 +343,17 @@ export default function createUpdateTests({ getService }: FtrProviderContext) { throttle: '1m', notify_when: 'onThrottleInterval', flapping: { + enabled: true, look_back_window: 5, status_change_threshold: 5, }, - }) - .expect(400); - }); - - it('should allow rule to be updated when global flapping is off if not updating flapping', async () => { - const response = await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule`) - .set('kbn-xsrf', 'foo') - .send( - getTestRuleData({ - flapping: { - look_back_window: 5, - status_change_threshold: 5, - }, - }) - ); - - objectRemover.add(Spaces.space1.id, response.body.id, 'rule', 'alerting'); - - await supertest - .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/settings/_flapping`) - .set('kbn-xsrf', 'foo') - .send({ - enabled: false, - look_back_window: 5, - status_change_threshold: 5, }); - await supertest - .put(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule/${response.body.id}`) - .set('kbn-xsrf', 'foo') - .send({ - name: 'updated name 1', - tags: ['foo'], - params: { - foo: true, - }, - schedule: { interval: '12s' }, - actions: [], - throttle: '1m', - notify_when: 'onThrottleInterval', - }) - .expect(200); - - await supertest - .put(`${getUrlPrefix(Spaces.space1.id)}/api/alerting/rule/${response.body.id}`) - .set('kbn-xsrf', 'foo') - .send({ - name: 'updated name 2', - tags: ['foo'], - params: { - foo: true, - }, - schedule: { interval: '12s' }, - actions: [], - throttle: '1m', - notify_when: 'onThrottleInterval', - flapping: { - look_back_window: 5, - status_change_threshold: 5, - }, - }) - .expect(200); + expect(updatedRule.flapping).eql({ + enabled: true, + look_back_window: 5, + status_change_threshold: 5, + }); }); it('should throw if flapping is invalid', async () => { diff --git a/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts b/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts index dff419ec0165e..6de1b01499b93 100644 --- a/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts +++ b/x-pack/platform/test/alerting_api_integration/spaces_only/tests/alerting/group4/alerts_as_data/alerts_as_data_flapping.ts @@ -740,7 +740,7 @@ export default function createAlertsAsDataFlappingTest({ getService }: FtrProvid expect(runWhichItFlapped).eql(6); }); - it('should ignore rule flapping if the space flapping is disabled', async () => { + it('should not ignore rule flapping if the space flapping is disabled', async () => { await supertest .post(`${getUrlPrefix(Spaces.space1.id)}/internal/alerting/rules/settings/_flapping`) .set('kbn-xsrf', 'foo') @@ -823,8 +823,7 @@ export default function createAlertsAsDataFlappingTest({ getService }: FtrProvid } } - // Never flapped, since globl flapping is off - expect(runWhichItFlapped).eql(0); + expect(runWhichItFlapped).eql(6); }); it('should drop tracked alerts early after hitting the alert limit', async () => {