From 52d34335184f1e072057b7418189fc1e6975bbdf Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 27 Oct 2022 11:15:12 -0500 Subject: [PATCH 01/85] Add frequency props to actions and validate them on edit/create --- x-pack/plugins/alerting/common/rule.ts | 9 +++- .../server/rules_client/rules_client.ts | 48 ++++++++++++++++--- x-pack/plugins/alerting/server/types.ts | 9 +++- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/alerting/common/rule.ts b/x-pack/plugins/alerting/common/rule.ts index c6c598cf8aebc..964fbb24fcb0f 100644 --- a/x-pack/plugins/alerting/common/rule.ts +++ b/x-pack/plugins/alerting/common/rule.ts @@ -72,6 +72,11 @@ export interface RuleAction { id: string; actionTypeId: string; params: RuleActionParams; + frequency?: { + summary: boolean; + notifyWhen: RuleNotifyWhenType; + throttle: string | null; + }; } export interface RuleAggregations { @@ -107,9 +112,9 @@ export interface Rule { updatedAt: Date; apiKey: string | null; apiKeyOwner: string | null; - throttle: string | null; + throttle?: string | null; muteAll: boolean; - notifyWhen: RuleNotifyWhenType | null; + notifyWhen?: RuleNotifyWhenType | null; mutedInstanceIds: string[]; executionStatus: RuleExecutionStatus; monitoring?: RuleMonitoring; diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 777cf340b53e7..f39f7f95b4001 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -568,7 +568,8 @@ export class RulesClient { throw Boom.badRequest(`Error creating rule: could not create API key - ${error.message}`); } - await this.validateActions(ruleType, data.actions); + const usesGlobalFreqParams = Boolean(data.notifyWhen && data.throttle); + await this.validateActions(ruleType, data.actions, usesGlobalFreqParams); // Throw error if schedule interval is less than the minimum and we are enforcing it const intervalInMs = parseDuration(data.schedule.interval); @@ -587,7 +588,7 @@ export class RulesClient { const createTime = Date.now(); const legacyId = Semver.lt(this.kibanaVersion, '8.0.0') ? id : null; - const notifyWhen = getRuleNotifyWhenType(data.notifyWhen, data.throttle); + const notifyWhen = getRuleNotifyWhenType(data.notifyWhen ?? null, data.throttle ?? null); const rawRule: RawRule = { ...data, @@ -1628,7 +1629,8 @@ export class RulesClient { // Validate const validatedAlertTypeParams = validateRuleTypeParams(data.params, ruleType.validate?.params); - await this.validateActions(ruleType, data.actions); + const usesGlobalFreqParams = Boolean(data.notifyWhen && data.throttle); + await this.validateActions(ruleType, data.actions, usesGlobalFreqParams); // Throw error if schedule interval is less than the minimum and we are enforcing it const intervalInMs = parseDuration(data.schedule.interval); @@ -2149,7 +2151,10 @@ export class RulesClient { for (const operation of operations) { switch (operation.field) { case 'actions': - await this.validateActions(ruleType, operation.value); + const usesGlobalFreqParams = Boolean( + attributes.notifyWhen && attributes.throttle + ); + await this.validateActions(ruleType, operation.value, usesGlobalFreqParams); ruleActions = applyBulkEditOperation(operation, ruleActions); break; case 'snoozeSchedule': @@ -2259,7 +2264,7 @@ export class RulesClient { // get notifyWhen const notifyWhen = getRuleNotifyWhenType( - attributes.notifyWhen, + attributes.notifyWhen ?? null, attributes.throttle ?? null ); @@ -3421,7 +3426,8 @@ export class RulesClient { private async validateActions( alertType: UntypedNormalizedRuleType, - actions: NormalizedAlertAction[] + actions: NormalizedAlertAction[], + usesGlobalFreqParams: boolean ): Promise { if (actions.length === 0) { return; @@ -3465,6 +3471,36 @@ export class RulesClient { }) ); } + + // check for actions using frequency params if the rule has global frequency params defined + if (usesGlobalFreqParams) { + const actionsWithFrequency = actions.filter((action) => Boolean(action.frequency)); + if (actionsWithFrequency.length) { + throw Boom.badRequest( + i18n.translate('xpack.alerting.rulesClient.validateActions.mixAndMatchFreqParams', { + defaultMessage: + 'Cannot mix and match per-action frequency params when notify_when and throttle are globally defined: {groups}', + values: { + groups: actionsWithFrequency.join(', '), + }, + }) + ); + } + } else { + const actionsWithoutFrequency = actions.filter( + (action) => !action.frequency || !action.frequency.notifyWhen || !action.frequency.throttle + ); + if (actionsWithoutFrequency.length) { + throw Boom.badRequest( + i18n.translate('xpack.alerting.rulesClient.validateActions.notAllActionsWithFreq', { + defaultMessage: 'Actions missing frequency parameters: {groups}', + values: { + groups: actionsWithoutFrequency.join(', '), + }, + }) + ); + } + } } private async extractReferences< diff --git a/x-pack/plugins/alerting/server/types.ts b/x-pack/plugins/alerting/server/types.ts index 9326f30dd7828..dea20abeacaa5 100644 --- a/x-pack/plugins/alerting/server/types.ts +++ b/x-pack/plugins/alerting/server/types.ts @@ -184,6 +184,11 @@ export interface RawRuleAction extends SavedObjectAttributes { actionRef: string; actionTypeId: string; params: RuleActionParams; + frequency?: { + summary: boolean; + notifyWhen: RuleNotifyWhenType; + throttle: string | null; + }; } export interface RuleMeta extends SavedObjectAttributes { @@ -243,8 +248,8 @@ export interface RawRule extends SavedObjectAttributes { updatedAt: string; apiKey: string | null; apiKeyOwner: string | null; - throttle: string | null; - notifyWhen: RuleNotifyWhenType | null; + throttle?: string | null; + notifyWhen?: RuleNotifyWhenType | null; muteAll: boolean; mutedInstanceIds: string[]; meta?: RuleMeta; From d077ea17d4dc289ef1bb496f1ebba4a5657c5123 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 27 Oct 2022 11:33:36 -0500 Subject: [PATCH 02/85] Nullify undefined throttle --- x-pack/plugins/alerting/server/rules_client/rules_client.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index f39f7f95b4001..6085dd0959752 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -589,6 +589,7 @@ export class RulesClient { const createTime = Date.now(); const legacyId = Semver.lt(this.kibanaVersion, '8.0.0') ? id : null; const notifyWhen = getRuleNotifyWhenType(data.notifyWhen ?? null, data.throttle ?? null); + const throttle = data.throttle ?? null; const rawRule: RawRule = { ...data, @@ -604,6 +605,7 @@ export class RulesClient { muteAll: false, mutedInstanceIds: [], notifyWhen, + throttle, executionStatus: getRuleExecutionStatusPending(new Date().toISOString()), monitoring: getDefaultRuleMonitoring(), }; From 378d4e80ec554c46742102ce3ddb9013f824cd8e Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 27 Oct 2022 15:07:16 -0500 Subject: [PATCH 03/85] Update schema to allow for frequency param on actions --- .../alerting/common/rule_notify_when_type.ts | 2 +- .../alerting/server/routes/create_rule.ts | 13 +++----- .../alerting/server/routes/legacy/create.ts | 14 ++------- .../alerting/server/routes/legacy/update.ts | 13 ++------ .../server/routes/lib/actions_schema.ts | 29 +++++++++++++++++ .../alerting/server/routes/lib/index.ts | 2 ++ .../server/routes/lib/rewrite_actions.ts | 31 +++++++++++++++++++ .../server/routes/lib/rewrite_request_case.ts | 2 +- .../server/routes/lib/rewrite_rule.ts | 10 +++++- .../alerting/server/routes/update_rule.ts | 12 +++---- .../server/rules_client/rules_client.ts | 4 +-- 11 files changed, 89 insertions(+), 43 deletions(-) create mode 100644 x-pack/plugins/alerting/server/routes/lib/actions_schema.ts create mode 100644 x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts diff --git a/x-pack/plugins/alerting/common/rule_notify_when_type.ts b/x-pack/plugins/alerting/common/rule_notify_when_type.ts index 700c87acdbdbb..4be2e35f2d392 100644 --- a/x-pack/plugins/alerting/common/rule_notify_when_type.ts +++ b/x-pack/plugins/alerting/common/rule_notify_when_type.ts @@ -5,7 +5,7 @@ * 2.0. */ -const RuleNotifyWhenTypeValues = [ +export const RuleNotifyWhenTypeValues = [ 'onActionGroupChange', 'onActiveAlert', 'onThrottleInterval', diff --git a/x-pack/plugins/alerting/server/routes/create_rule.ts b/x-pack/plugins/alerting/server/routes/create_rule.ts index 442162ae21cbb..739f0952b0841 100644 --- a/x-pack/plugins/alerting/server/routes/create_rule.ts +++ b/x-pack/plugins/alerting/server/routes/create_rule.ts @@ -11,9 +11,11 @@ import { CreateOptions } from '../rules_client'; import { RewriteRequestCase, RewriteResponseCase, + rewriteActions, handleDisabledApiKeysError, verifyAccessAndContext, countUsageOfPredefinedIds, + actionsSchema, } from './lib'; import { SanitizedRule, @@ -35,14 +37,7 @@ export const bodySchema = schema.object({ schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), }), - actions: schema.arrayOf( - schema.object({ - group: schema.string(), - id: schema.string(), - params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - }), - { defaultValue: [] } - ), + actions: actionsSchema, notify_when: schema.string({ validate: validateNotifyWhenType }), }); @@ -55,6 +50,7 @@ const rewriteBodyReq: RewriteRequestCase['data']> alertTypeId, notifyWhen, }); + const rewriteBodyRes: RewriteResponseCase> = ({ actions, alertTypeId, @@ -127,6 +123,7 @@ export const createRuleRoute = ({ router, licenseState, usageCounter }: RouteOpt await rulesClient.create({ data: rewriteBodyReq({ ...rule, + actions: rewriteActions(rule.actions), notify_when: rule.notify_when as RuleNotifyWhenType, }), options: { id: params?.id }, diff --git a/x-pack/plugins/alerting/server/routes/legacy/create.ts b/x-pack/plugins/alerting/server/routes/legacy/create.ts index e7583033ae4ba..331cc4734f4f1 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/create.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/create.ts @@ -18,7 +18,7 @@ import { } from '../../types'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { RouteOptions } from '..'; -import { countUsageOfPredefinedIds } from '../lib'; +import { countUsageOfPredefinedIds, actionsSchema, rewriteActions } from '../lib'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; export const bodySchema = schema.object({ @@ -32,15 +32,7 @@ export const bodySchema = schema.object({ schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), }), - actions: schema.arrayOf( - schema.object({ - group: schema.string(), - id: schema.string(), - actionTypeId: schema.maybe(schema.string()), - params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - }), - { defaultValue: [] } - ), + actions: actionsSchema, notifyWhen: schema.nullable(schema.string({ validate: validateNotifyWhenType })), }); @@ -79,7 +71,7 @@ export const createAlertRoute = ({ router, licenseState, usageCounter }: RouteOp try { const alertRes: SanitizedRule = await rulesClient.create({ - data: { ...alert, notifyWhen }, + data: { ...alert, notifyWhen, actions: rewriteActions(alert.actions) }, options: { id: params?.id }, }); return res.ok({ diff --git a/x-pack/plugins/alerting/server/routes/legacy/update.ts b/x-pack/plugins/alerting/server/routes/legacy/update.ts index 07bde524076c1..065c69e4d5d68 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update.ts @@ -14,6 +14,7 @@ import { validateDurationSchema } from '../../lib'; import { handleDisabledApiKeysError } from '../lib/error_handler'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; +import { actionsSchema, rewriteActions } from '../lib'; import { RuleNotifyWhenType, LEGACY_BASE_ALERT_API_PATH, @@ -32,15 +33,7 @@ const bodySchema = schema.object({ }), throttle: schema.nullable(schema.string({ validate: validateDurationSchema })), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - actions: schema.arrayOf( - schema.object({ - group: schema.string(), - id: schema.string(), - params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - actionTypeId: schema.maybe(schema.string()), - }), - { defaultValue: [] } - ), + actions: actionsSchema, notifyWhen: schema.nullable(schema.string({ validate: validateNotifyWhenType })), }); @@ -72,7 +65,7 @@ export const updateAlertRoute = ( id, data: { name, - actions, + actions: rewriteActions(actions), params, schedule, tags, diff --git a/x-pack/plugins/alerting/server/routes/lib/actions_schema.ts b/x-pack/plugins/alerting/server/routes/lib/actions_schema.ts new file mode 100644 index 0000000000000..d89873a48c2ea --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/lib/actions_schema.ts @@ -0,0 +1,29 @@ +/* + * 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 { schema } from '@kbn/config-schema'; +import { validateDurationSchema } from '../../lib'; + +export const actionsSchema = schema.arrayOf( + schema.object({ + group: schema.string(), + id: schema.string(), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + frequency: schema.maybe( + schema.object({ + summary: schema.boolean(), + notify_when: schema.oneOf([ + schema.literal('onActionGroupChange'), + schema.literal('onActiveAlert'), + schema.literal('onThrottleInterval'), + ]), + throttle: schema.nullable(schema.string({ validate: validateDurationSchema })), + }) + ), + }), + { defaultValue: [] } +); diff --git a/x-pack/plugins/alerting/server/routes/lib/index.ts b/x-pack/plugins/alerting/server/routes/lib/index.ts index e772f091bb059..7075315b6edb7 100644 --- a/x-pack/plugins/alerting/server/routes/lib/index.ts +++ b/x-pack/plugins/alerting/server/routes/lib/index.ts @@ -19,3 +19,5 @@ export type { export { verifyAccessAndContext } from './verify_access_and_context'; export { countUsageOfPredefinedIds } from './count_usage_of_predefined_ids'; export { rewriteRule } from './rewrite_rule'; +export { rewriteActions } from './rewrite_actions'; +export { actionsSchema } from './actions_schema'; diff --git a/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts b/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts new file mode 100644 index 0000000000000..60e24cfdb8d1f --- /dev/null +++ b/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts @@ -0,0 +1,31 @@ +/* + * 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 { CamelToSnake, RewriteRequestCase } from './rewrite_request_case'; +import { RuleAction } from '../../types'; + +type ReqRuleAction = Omit & { + frequency?: { + [K in keyof NonNullable as CamelToSnake]: NonNullable< + RuleAction['frequency'] + >[K]; + }; +}; +export const rewriteActions: (actions: ReqRuleAction[]) => Omit[] = ( + actions +) => { + const rewriteFrequency: RewriteRequestCase> = ({ + notify_when: notifyWhen, + ...rest + }) => ({ ...rest, notifyWhen }); + return actions.map( + (action) => + ({ + ...action, + ...(action.frequency ? { frequency: rewriteFrequency(action.frequency) } : {}), + } as RuleAction) + ); +}; diff --git a/x-pack/plugins/alerting/server/routes/lib/rewrite_request_case.ts b/x-pack/plugins/alerting/server/routes/lib/rewrite_request_case.ts index 2874f9567231b..52f1a7907c737 100644 --- a/x-pack/plugins/alerting/server/routes/lib/rewrite_request_case.ts +++ b/x-pack/plugins/alerting/server/routes/lib/rewrite_request_case.ts @@ -71,7 +71,7 @@ export type RewriteResponseCase = ( * * For more details see this PR comment: https://github.com/microsoft/TypeScript/pull/40336#issuecomment-686723087 */ -type CamelToSnake = string extends T +export type CamelToSnake = string extends T ? string : T extends `${infer C0}${infer C1}${infer R}` ? `${C0 extends Uppercase ? '_' : ''}${Lowercase}${C1 extends Uppercase diff --git a/x-pack/plugins/alerting/server/routes/lib/rewrite_rule.ts b/x-pack/plugins/alerting/server/routes/lib/rewrite_rule.ts index 4b3ab65e3e8e4..28e54727a5810 100644 --- a/x-pack/plugins/alerting/server/routes/lib/rewrite_rule.ts +++ b/x-pack/plugins/alerting/server/routes/lib/rewrite_rule.ts @@ -45,10 +45,18 @@ export const rewriteRule = ({ last_execution_date: executionStatus.lastExecutionDate, last_duration: executionStatus.lastDuration, }, - actions: actions.map(({ group, id, actionTypeId, params }) => ({ + actions: actions.map(({ group, id, actionTypeId, params, frequency }) => ({ group, id, params, connector_type_id: actionTypeId, + ...(frequency + ? { + frequency: { + ...frequency, + notify_when: frequency.notifyWhen, + }, + } + : {}), })), }); diff --git a/x-pack/plugins/alerting/server/routes/update_rule.ts b/x-pack/plugins/alerting/server/routes/update_rule.ts index 1faddd66c8f0e..93ef40407dd45 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule.ts @@ -15,6 +15,8 @@ import { RewriteResponseCase, RewriteRequestCase, handleDisabledApiKeysError, + rewriteActions, + actionsSchema, } from './lib'; import { RuleTypeParams, @@ -36,14 +38,7 @@ const bodySchema = schema.object({ }), throttle: schema.nullable(schema.string({ validate: validateDurationSchema })), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - actions: schema.arrayOf( - schema.object({ - group: schema.string(), - id: schema.string(), - params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - }), - { defaultValue: [] } - ), + actions: actionsSchema, notify_when: schema.string({ validate: validateNotifyWhenType }), }); @@ -132,6 +127,7 @@ export const updateRuleRoute = ( id, data: { ...rule, + actions: rewriteActions(rule.actions), notify_when: rule.notify_when as RuleNotifyWhenType, }, }) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 6085dd0959752..6485572397b17 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -3489,9 +3489,7 @@ export class RulesClient { ); } } else { - const actionsWithoutFrequency = actions.filter( - (action) => !action.frequency || !action.frequency.notifyWhen || !action.frequency.throttle - ); + const actionsWithoutFrequency = actions.filter((action) => !action.frequency); if (actionsWithoutFrequency.length) { throw Boom.badRequest( i18n.translate('xpack.alerting.rulesClient.validateActions.notAllActionsWithFreq', { From 11cd1d3840086740fd49eea136848a9bc804e546 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Thu, 27 Oct 2022 20:20:01 +0000 Subject: [PATCH 04/85] [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' --- .../plugins/alerting/server/routes/lib/rewrite_actions.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts b/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts index 60e24cfdb8d1f..669cb2c3cfe51 100644 --- a/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts +++ b/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts @@ -14,9 +14,9 @@ type ReqRuleAction = Omit & { >[K]; }; }; -export const rewriteActions: (actions: ReqRuleAction[]) => Omit[] = ( - actions -) => { +export const rewriteActions: ( + actions: ReqRuleAction[] +) => Array> = (actions) => { const rewriteFrequency: RewriteRequestCase> = ({ notify_when: notifyWhen, ...rest From 48890230f539a6c76820741ecb2e6662a9283fbd Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Fri, 28 Oct 2022 16:54:37 -0500 Subject: [PATCH 05/85] Commit missing file --- .../server/lib/validate_rule_frequency.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 x-pack/plugins/alerting/server/lib/validate_rule_frequency.ts diff --git a/x-pack/plugins/alerting/server/lib/validate_rule_frequency.ts b/x-pack/plugins/alerting/server/lib/validate_rule_frequency.ts new file mode 100644 index 0000000000000..b791b05499263 --- /dev/null +++ b/x-pack/plugins/alerting/server/lib/validate_rule_frequency.ts @@ -0,0 +1,24 @@ +/* + * 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 Boom from '@hapi/boom'; +import { RuleTypeParams, RuleTypeParamsValidator } from '../types'; + +export function validateRuleTypeParams( + params: Record, + validator?: RuleTypeParamsValidator +): Params { + if (!validator) { + return params as Params; + } + + try { + return validator.validate(params); + } catch (err) { + throw Boom.badRequest(`params invalid: ${err.message}`); + } +} From 4349c7362fdf92eab017563d33d3015310af5ad5 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Fri, 28 Oct 2022 16:57:51 -0500 Subject: [PATCH 06/85] Fix types --- tsconfig.base.json | 700 ------------------ .../plugins/alerting/common/alert_summary.ts | 2 +- .../lib/alert_summary_from_event_log.ts | 2 +- .../server/task_runner/task_runner.ts | 4 +- 4 files changed, 4 insertions(+), 704 deletions(-) diff --git a/tsconfig.base.json b/tsconfig.base.json index 55b307ddc81f7..97efbcf215827 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -6,702 +6,6 @@ "@kbn/core": ["src/core"], "@kbn/core/*": ["src/core/*"], // START AUTOMATED PACKAGE LISTING - "@kbn/analytics-client": ["packages/analytics/client"], - "@kbn/analytics-client/*": ["packages/analytics/client/*"], - "@kbn/analytics-shippers-elastic-v3-browser": ["packages/analytics/shippers/elastic_v3/browser"], - "@kbn/analytics-shippers-elastic-v3-browser/*": ["packages/analytics/shippers/elastic_v3/browser/*"], - "@kbn/analytics-shippers-elastic-v3-common": ["packages/analytics/shippers/elastic_v3/common"], - "@kbn/analytics-shippers-elastic-v3-common/*": ["packages/analytics/shippers/elastic_v3/common/*"], - "@kbn/analytics-shippers-elastic-v3-server": ["packages/analytics/shippers/elastic_v3/server"], - "@kbn/analytics-shippers-elastic-v3-server/*": ["packages/analytics/shippers/elastic_v3/server/*"], - "@kbn/analytics-shippers-fullstory": ["packages/analytics/shippers/fullstory"], - "@kbn/analytics-shippers-fullstory/*": ["packages/analytics/shippers/fullstory/*"], - "@kbn/analytics-shippers-gainsight": ["packages/analytics/shippers/gainsight"], - "@kbn/analytics-shippers-gainsight/*": ["packages/analytics/shippers/gainsight/*"], - "@kbn/content-management-table-list": ["packages/content-management/table_list"], - "@kbn/content-management-table-list/*": ["packages/content-management/table_list/*"], - "@kbn/core-analytics-browser": ["packages/core/analytics/core-analytics-browser"], - "@kbn/core-analytics-browser/*": ["packages/core/analytics/core-analytics-browser/*"], - "@kbn/core-analytics-browser-internal": ["packages/core/analytics/core-analytics-browser-internal"], - "@kbn/core-analytics-browser-internal/*": ["packages/core/analytics/core-analytics-browser-internal/*"], - "@kbn/core-analytics-browser-mocks": ["packages/core/analytics/core-analytics-browser-mocks"], - "@kbn/core-analytics-browser-mocks/*": ["packages/core/analytics/core-analytics-browser-mocks/*"], - "@kbn/core-analytics-server": ["packages/core/analytics/core-analytics-server"], - "@kbn/core-analytics-server/*": ["packages/core/analytics/core-analytics-server/*"], - "@kbn/core-analytics-server-internal": ["packages/core/analytics/core-analytics-server-internal"], - "@kbn/core-analytics-server-internal/*": ["packages/core/analytics/core-analytics-server-internal/*"], - "@kbn/core-analytics-server-mocks": ["packages/core/analytics/core-analytics-server-mocks"], - "@kbn/core-analytics-server-mocks/*": ["packages/core/analytics/core-analytics-server-mocks/*"], - "@kbn/core-application-browser": ["packages/core/application/core-application-browser"], - "@kbn/core-application-browser/*": ["packages/core/application/core-application-browser/*"], - "@kbn/core-application-browser-internal": ["packages/core/application/core-application-browser-internal"], - "@kbn/core-application-browser-internal/*": ["packages/core/application/core-application-browser-internal/*"], - "@kbn/core-application-browser-mocks": ["packages/core/application/core-application-browser-mocks"], - "@kbn/core-application-browser-mocks/*": ["packages/core/application/core-application-browser-mocks/*"], - "@kbn/core-application-common": ["packages/core/application/core-application-common"], - "@kbn/core-application-common/*": ["packages/core/application/core-application-common/*"], - "@kbn/core-apps-browser-internal": ["packages/core/apps/core-apps-browser-internal"], - "@kbn/core-apps-browser-internal/*": ["packages/core/apps/core-apps-browser-internal/*"], - "@kbn/core-apps-browser-mocks": ["packages/core/apps/core-apps-browser-mocks"], - "@kbn/core-apps-browser-mocks/*": ["packages/core/apps/core-apps-browser-mocks/*"], - "@kbn/core-base-browser-internal": ["packages/core/base/core-base-browser-internal"], - "@kbn/core-base-browser-internal/*": ["packages/core/base/core-base-browser-internal/*"], - "@kbn/core-base-browser-mocks": ["packages/core/base/core-base-browser-mocks"], - "@kbn/core-base-browser-mocks/*": ["packages/core/base/core-base-browser-mocks/*"], - "@kbn/core-base-common": ["packages/core/base/core-base-common"], - "@kbn/core-base-common/*": ["packages/core/base/core-base-common/*"], - "@kbn/core-base-common-internal": ["packages/core/base/core-base-common-internal"], - "@kbn/core-base-common-internal/*": ["packages/core/base/core-base-common-internal/*"], - "@kbn/core-base-server-internal": ["packages/core/base/core-base-server-internal"], - "@kbn/core-base-server-internal/*": ["packages/core/base/core-base-server-internal/*"], - "@kbn/core-base-server-mocks": ["packages/core/base/core-base-server-mocks"], - "@kbn/core-base-server-mocks/*": ["packages/core/base/core-base-server-mocks/*"], - "@kbn/core-capabilities-browser-internal": ["packages/core/capabilities/core-capabilities-browser-internal"], - "@kbn/core-capabilities-browser-internal/*": ["packages/core/capabilities/core-capabilities-browser-internal/*"], - "@kbn/core-capabilities-browser-mocks": ["packages/core/capabilities/core-capabilities-browser-mocks"], - "@kbn/core-capabilities-browser-mocks/*": ["packages/core/capabilities/core-capabilities-browser-mocks/*"], - "@kbn/core-capabilities-common": ["packages/core/capabilities/core-capabilities-common"], - "@kbn/core-capabilities-common/*": ["packages/core/capabilities/core-capabilities-common/*"], - "@kbn/core-capabilities-server": ["packages/core/capabilities/core-capabilities-server"], - "@kbn/core-capabilities-server/*": ["packages/core/capabilities/core-capabilities-server/*"], - "@kbn/core-capabilities-server-internal": ["packages/core/capabilities/core-capabilities-server-internal"], - "@kbn/core-capabilities-server-internal/*": ["packages/core/capabilities/core-capabilities-server-internal/*"], - "@kbn/core-capabilities-server-mocks": ["packages/core/capabilities/core-capabilities-server-mocks"], - "@kbn/core-capabilities-server-mocks/*": ["packages/core/capabilities/core-capabilities-server-mocks/*"], - "@kbn/core-chrome-browser": ["packages/core/chrome/core-chrome-browser"], - "@kbn/core-chrome-browser/*": ["packages/core/chrome/core-chrome-browser/*"], - "@kbn/core-chrome-browser-internal": ["packages/core/chrome/core-chrome-browser-internal"], - "@kbn/core-chrome-browser-internal/*": ["packages/core/chrome/core-chrome-browser-internal/*"], - "@kbn/core-chrome-browser-mocks": ["packages/core/chrome/core-chrome-browser-mocks"], - "@kbn/core-chrome-browser-mocks/*": ["packages/core/chrome/core-chrome-browser-mocks/*"], - "@kbn/core-config-server-internal": ["packages/core/config/core-config-server-internal"], - "@kbn/core-config-server-internal/*": ["packages/core/config/core-config-server-internal/*"], - "@kbn/core-deprecations-browser": ["packages/core/deprecations/core-deprecations-browser"], - "@kbn/core-deprecations-browser/*": ["packages/core/deprecations/core-deprecations-browser/*"], - "@kbn/core-deprecations-browser-internal": ["packages/core/deprecations/core-deprecations-browser-internal"], - "@kbn/core-deprecations-browser-internal/*": ["packages/core/deprecations/core-deprecations-browser-internal/*"], - "@kbn/core-deprecations-browser-mocks": ["packages/core/deprecations/core-deprecations-browser-mocks"], - "@kbn/core-deprecations-browser-mocks/*": ["packages/core/deprecations/core-deprecations-browser-mocks/*"], - "@kbn/core-deprecations-common": ["packages/core/deprecations/core-deprecations-common"], - "@kbn/core-deprecations-common/*": ["packages/core/deprecations/core-deprecations-common/*"], - "@kbn/core-deprecations-server": ["packages/core/deprecations/core-deprecations-server"], - "@kbn/core-deprecations-server/*": ["packages/core/deprecations/core-deprecations-server/*"], - "@kbn/core-deprecations-server-internal": ["packages/core/deprecations/core-deprecations-server-internal"], - "@kbn/core-deprecations-server-internal/*": ["packages/core/deprecations/core-deprecations-server-internal/*"], - "@kbn/core-deprecations-server-mocks": ["packages/core/deprecations/core-deprecations-server-mocks"], - "@kbn/core-deprecations-server-mocks/*": ["packages/core/deprecations/core-deprecations-server-mocks/*"], - "@kbn/core-doc-links-browser": ["packages/core/doc-links/core-doc-links-browser"], - "@kbn/core-doc-links-browser/*": ["packages/core/doc-links/core-doc-links-browser/*"], - "@kbn/core-doc-links-browser-internal": ["packages/core/doc-links/core-doc-links-browser-internal"], - "@kbn/core-doc-links-browser-internal/*": ["packages/core/doc-links/core-doc-links-browser-internal/*"], - "@kbn/core-doc-links-browser-mocks": ["packages/core/doc-links/core-doc-links-browser-mocks"], - "@kbn/core-doc-links-browser-mocks/*": ["packages/core/doc-links/core-doc-links-browser-mocks/*"], - "@kbn/core-doc-links-server": ["packages/core/doc-links/core-doc-links-server"], - "@kbn/core-doc-links-server/*": ["packages/core/doc-links/core-doc-links-server/*"], - "@kbn/core-doc-links-server-internal": ["packages/core/doc-links/core-doc-links-server-internal"], - "@kbn/core-doc-links-server-internal/*": ["packages/core/doc-links/core-doc-links-server-internal/*"], - "@kbn/core-doc-links-server-mocks": ["packages/core/doc-links/core-doc-links-server-mocks"], - "@kbn/core-doc-links-server-mocks/*": ["packages/core/doc-links/core-doc-links-server-mocks/*"], - "@kbn/core-elasticsearch-client-server-internal": ["packages/core/elasticsearch/core-elasticsearch-client-server-internal"], - "@kbn/core-elasticsearch-client-server-internal/*": ["packages/core/elasticsearch/core-elasticsearch-client-server-internal/*"], - "@kbn/core-elasticsearch-client-server-mocks": ["packages/core/elasticsearch/core-elasticsearch-client-server-mocks"], - "@kbn/core-elasticsearch-client-server-mocks/*": ["packages/core/elasticsearch/core-elasticsearch-client-server-mocks/*"], - "@kbn/core-elasticsearch-server": ["packages/core/elasticsearch/core-elasticsearch-server"], - "@kbn/core-elasticsearch-server/*": ["packages/core/elasticsearch/core-elasticsearch-server/*"], - "@kbn/core-elasticsearch-server-internal": ["packages/core/elasticsearch/core-elasticsearch-server-internal"], - "@kbn/core-elasticsearch-server-internal/*": ["packages/core/elasticsearch/core-elasticsearch-server-internal/*"], - "@kbn/core-elasticsearch-server-mocks": ["packages/core/elasticsearch/core-elasticsearch-server-mocks"], - "@kbn/core-elasticsearch-server-mocks/*": ["packages/core/elasticsearch/core-elasticsearch-server-mocks/*"], - "@kbn/core-environment-server-internal": ["packages/core/environment/core-environment-server-internal"], - "@kbn/core-environment-server-internal/*": ["packages/core/environment/core-environment-server-internal/*"], - "@kbn/core-environment-server-mocks": ["packages/core/environment/core-environment-server-mocks"], - "@kbn/core-environment-server-mocks/*": ["packages/core/environment/core-environment-server-mocks/*"], - "@kbn/core-execution-context-browser": ["packages/core/execution-context/core-execution-context-browser"], - "@kbn/core-execution-context-browser/*": ["packages/core/execution-context/core-execution-context-browser/*"], - "@kbn/core-execution-context-browser-internal": ["packages/core/execution-context/core-execution-context-browser-internal"], - "@kbn/core-execution-context-browser-internal/*": ["packages/core/execution-context/core-execution-context-browser-internal/*"], - "@kbn/core-execution-context-browser-mocks": ["packages/core/execution-context/core-execution-context-browser-mocks"], - "@kbn/core-execution-context-browser-mocks/*": ["packages/core/execution-context/core-execution-context-browser-mocks/*"], - "@kbn/core-execution-context-common": ["packages/core/execution-context/core-execution-context-common"], - "@kbn/core-execution-context-common/*": ["packages/core/execution-context/core-execution-context-common/*"], - "@kbn/core-execution-context-server": ["packages/core/execution-context/core-execution-context-server"], - "@kbn/core-execution-context-server/*": ["packages/core/execution-context/core-execution-context-server/*"], - "@kbn/core-execution-context-server-internal": ["packages/core/execution-context/core-execution-context-server-internal"], - "@kbn/core-execution-context-server-internal/*": ["packages/core/execution-context/core-execution-context-server-internal/*"], - "@kbn/core-execution-context-server-mocks": ["packages/core/execution-context/core-execution-context-server-mocks"], - "@kbn/core-execution-context-server-mocks/*": ["packages/core/execution-context/core-execution-context-server-mocks/*"], - "@kbn/core-fatal-errors-browser": ["packages/core/fatal-errors/core-fatal-errors-browser"], - "@kbn/core-fatal-errors-browser/*": ["packages/core/fatal-errors/core-fatal-errors-browser/*"], - "@kbn/core-fatal-errors-browser-internal": ["packages/core/fatal-errors/core-fatal-errors-browser-internal"], - "@kbn/core-fatal-errors-browser-internal/*": ["packages/core/fatal-errors/core-fatal-errors-browser-internal/*"], - "@kbn/core-fatal-errors-browser-mocks": ["packages/core/fatal-errors/core-fatal-errors-browser-mocks"], - "@kbn/core-fatal-errors-browser-mocks/*": ["packages/core/fatal-errors/core-fatal-errors-browser-mocks/*"], - "@kbn/core-http-browser": ["packages/core/http/core-http-browser"], - "@kbn/core-http-browser/*": ["packages/core/http/core-http-browser/*"], - "@kbn/core-http-browser-internal": ["packages/core/http/core-http-browser-internal"], - "@kbn/core-http-browser-internal/*": ["packages/core/http/core-http-browser-internal/*"], - "@kbn/core-http-browser-mocks": ["packages/core/http/core-http-browser-mocks"], - "@kbn/core-http-browser-mocks/*": ["packages/core/http/core-http-browser-mocks/*"], - "@kbn/core-http-common": ["packages/core/http/core-http-common"], - "@kbn/core-http-common/*": ["packages/core/http/core-http-common/*"], - "@kbn/core-http-context-server-internal": ["packages/core/http/core-http-context-server-internal"], - "@kbn/core-http-context-server-internal/*": ["packages/core/http/core-http-context-server-internal/*"], - "@kbn/core-http-context-server-mocks": ["packages/core/http/core-http-context-server-mocks"], - "@kbn/core-http-context-server-mocks/*": ["packages/core/http/core-http-context-server-mocks/*"], - "@kbn/core-http-request-handler-context-server": ["packages/core/http/core-http-request-handler-context-server"], - "@kbn/core-http-request-handler-context-server/*": ["packages/core/http/core-http-request-handler-context-server/*"], - "@kbn/core-http-request-handler-context-server-internal": ["packages/core/http/core-http-request-handler-context-server-internal"], - "@kbn/core-http-request-handler-context-server-internal/*": ["packages/core/http/core-http-request-handler-context-server-internal/*"], - "@kbn/core-http-resources-server": ["packages/core/http/core-http-resources-server"], - "@kbn/core-http-resources-server/*": ["packages/core/http/core-http-resources-server/*"], - "@kbn/core-http-resources-server-internal": ["packages/core/http/core-http-resources-server-internal"], - "@kbn/core-http-resources-server-internal/*": ["packages/core/http/core-http-resources-server-internal/*"], - "@kbn/core-http-resources-server-mocks": ["packages/core/http/core-http-resources-server-mocks"], - "@kbn/core-http-resources-server-mocks/*": ["packages/core/http/core-http-resources-server-mocks/*"], - "@kbn/core-http-router-server-internal": ["packages/core/http/core-http-router-server-internal"], - "@kbn/core-http-router-server-internal/*": ["packages/core/http/core-http-router-server-internal/*"], - "@kbn/core-http-router-server-mocks": ["packages/core/http/core-http-router-server-mocks"], - "@kbn/core-http-router-server-mocks/*": ["packages/core/http/core-http-router-server-mocks/*"], - "@kbn/core-http-server": ["packages/core/http/core-http-server"], - "@kbn/core-http-server/*": ["packages/core/http/core-http-server/*"], - "@kbn/core-http-server-internal": ["packages/core/http/core-http-server-internal"], - "@kbn/core-http-server-internal/*": ["packages/core/http/core-http-server-internal/*"], - "@kbn/core-http-server-mocks": ["packages/core/http/core-http-server-mocks"], - "@kbn/core-http-server-mocks/*": ["packages/core/http/core-http-server-mocks/*"], - "@kbn/core-i18n-browser": ["packages/core/i18n/core-i18n-browser"], - "@kbn/core-i18n-browser/*": ["packages/core/i18n/core-i18n-browser/*"], - "@kbn/core-i18n-browser-internal": ["packages/core/i18n/core-i18n-browser-internal"], - "@kbn/core-i18n-browser-internal/*": ["packages/core/i18n/core-i18n-browser-internal/*"], - "@kbn/core-i18n-browser-mocks": ["packages/core/i18n/core-i18n-browser-mocks"], - "@kbn/core-i18n-browser-mocks/*": ["packages/core/i18n/core-i18n-browser-mocks/*"], - "@kbn/core-i18n-server": ["packages/core/i18n/core-i18n-server"], - "@kbn/core-i18n-server/*": ["packages/core/i18n/core-i18n-server/*"], - "@kbn/core-i18n-server-internal": ["packages/core/i18n/core-i18n-server-internal"], - "@kbn/core-i18n-server-internal/*": ["packages/core/i18n/core-i18n-server-internal/*"], - "@kbn/core-i18n-server-mocks": ["packages/core/i18n/core-i18n-server-mocks"], - "@kbn/core-i18n-server-mocks/*": ["packages/core/i18n/core-i18n-server-mocks/*"], - "@kbn/core-injected-metadata-browser": ["packages/core/injected-metadata/core-injected-metadata-browser"], - "@kbn/core-injected-metadata-browser/*": ["packages/core/injected-metadata/core-injected-metadata-browser/*"], - "@kbn/core-injected-metadata-browser-internal": ["packages/core/injected-metadata/core-injected-metadata-browser-internal"], - "@kbn/core-injected-metadata-browser-internal/*": ["packages/core/injected-metadata/core-injected-metadata-browser-internal/*"], - "@kbn/core-injected-metadata-browser-mocks": ["packages/core/injected-metadata/core-injected-metadata-browser-mocks"], - "@kbn/core-injected-metadata-browser-mocks/*": ["packages/core/injected-metadata/core-injected-metadata-browser-mocks/*"], - "@kbn/core-injected-metadata-common-internal": ["packages/core/injected-metadata/core-injected-metadata-common-internal"], - "@kbn/core-injected-metadata-common-internal/*": ["packages/core/injected-metadata/core-injected-metadata-common-internal/*"], - "@kbn/core-integrations-browser-internal": ["packages/core/integrations/core-integrations-browser-internal"], - "@kbn/core-integrations-browser-internal/*": ["packages/core/integrations/core-integrations-browser-internal/*"], - "@kbn/core-integrations-browser-mocks": ["packages/core/integrations/core-integrations-browser-mocks"], - "@kbn/core-integrations-browser-mocks/*": ["packages/core/integrations/core-integrations-browser-mocks/*"], - "@kbn/core-lifecycle-browser": ["packages/core/lifecycle/core-lifecycle-browser"], - "@kbn/core-lifecycle-browser/*": ["packages/core/lifecycle/core-lifecycle-browser/*"], - "@kbn/core-lifecycle-browser-internal": ["packages/core/lifecycle/core-lifecycle-browser-internal"], - "@kbn/core-lifecycle-browser-internal/*": ["packages/core/lifecycle/core-lifecycle-browser-internal/*"], - "@kbn/core-lifecycle-browser-mocks": ["packages/core/lifecycle/core-lifecycle-browser-mocks"], - "@kbn/core-lifecycle-browser-mocks/*": ["packages/core/lifecycle/core-lifecycle-browser-mocks/*"], - "@kbn/core-lifecycle-server": ["packages/core/lifecycle/core-lifecycle-server"], - "@kbn/core-lifecycle-server/*": ["packages/core/lifecycle/core-lifecycle-server/*"], - "@kbn/core-lifecycle-server-internal": ["packages/core/lifecycle/core-lifecycle-server-internal"], - "@kbn/core-lifecycle-server-internal/*": ["packages/core/lifecycle/core-lifecycle-server-internal/*"], - "@kbn/core-lifecycle-server-mocks": ["packages/core/lifecycle/core-lifecycle-server-mocks"], - "@kbn/core-lifecycle-server-mocks/*": ["packages/core/lifecycle/core-lifecycle-server-mocks/*"], - "@kbn/core-logging-server": ["packages/core/logging/core-logging-server"], - "@kbn/core-logging-server/*": ["packages/core/logging/core-logging-server/*"], - "@kbn/core-logging-server-internal": ["packages/core/logging/core-logging-server-internal"], - "@kbn/core-logging-server-internal/*": ["packages/core/logging/core-logging-server-internal/*"], - "@kbn/core-logging-server-mocks": ["packages/core/logging/core-logging-server-mocks"], - "@kbn/core-logging-server-mocks/*": ["packages/core/logging/core-logging-server-mocks/*"], - "@kbn/core-metrics-collectors-server-internal": ["packages/core/metrics/core-metrics-collectors-server-internal"], - "@kbn/core-metrics-collectors-server-internal/*": ["packages/core/metrics/core-metrics-collectors-server-internal/*"], - "@kbn/core-metrics-collectors-server-mocks": ["packages/core/metrics/core-metrics-collectors-server-mocks"], - "@kbn/core-metrics-collectors-server-mocks/*": ["packages/core/metrics/core-metrics-collectors-server-mocks/*"], - "@kbn/core-metrics-server": ["packages/core/metrics/core-metrics-server"], - "@kbn/core-metrics-server/*": ["packages/core/metrics/core-metrics-server/*"], - "@kbn/core-metrics-server-internal": ["packages/core/metrics/core-metrics-server-internal"], - "@kbn/core-metrics-server-internal/*": ["packages/core/metrics/core-metrics-server-internal/*"], - "@kbn/core-metrics-server-mocks": ["packages/core/metrics/core-metrics-server-mocks"], - "@kbn/core-metrics-server-mocks/*": ["packages/core/metrics/core-metrics-server-mocks/*"], - "@kbn/core-mount-utils-browser": ["packages/core/mount-utils/core-mount-utils-browser"], - "@kbn/core-mount-utils-browser/*": ["packages/core/mount-utils/core-mount-utils-browser/*"], - "@kbn/core-mount-utils-browser-internal": ["packages/core/mount-utils/core-mount-utils-browser-internal"], - "@kbn/core-mount-utils-browser-internal/*": ["packages/core/mount-utils/core-mount-utils-browser-internal/*"], - "@kbn/core-node-server": ["packages/core/node/core-node-server"], - "@kbn/core-node-server/*": ["packages/core/node/core-node-server/*"], - "@kbn/core-node-server-internal": ["packages/core/node/core-node-server-internal"], - "@kbn/core-node-server-internal/*": ["packages/core/node/core-node-server-internal/*"], - "@kbn/core-node-server-mocks": ["packages/core/node/core-node-server-mocks"], - "@kbn/core-node-server-mocks/*": ["packages/core/node/core-node-server-mocks/*"], - "@kbn/core-notifications-browser": ["packages/core/notifications/core-notifications-browser"], - "@kbn/core-notifications-browser/*": ["packages/core/notifications/core-notifications-browser/*"], - "@kbn/core-notifications-browser-internal": ["packages/core/notifications/core-notifications-browser-internal"], - "@kbn/core-notifications-browser-internal/*": ["packages/core/notifications/core-notifications-browser-internal/*"], - "@kbn/core-notifications-browser-mocks": ["packages/core/notifications/core-notifications-browser-mocks"], - "@kbn/core-notifications-browser-mocks/*": ["packages/core/notifications/core-notifications-browser-mocks/*"], - "@kbn/core-overlays-browser": ["packages/core/overlays/core-overlays-browser"], - "@kbn/core-overlays-browser/*": ["packages/core/overlays/core-overlays-browser/*"], - "@kbn/core-overlays-browser-internal": ["packages/core/overlays/core-overlays-browser-internal"], - "@kbn/core-overlays-browser-internal/*": ["packages/core/overlays/core-overlays-browser-internal/*"], - "@kbn/core-overlays-browser-mocks": ["packages/core/overlays/core-overlays-browser-mocks"], - "@kbn/core-overlays-browser-mocks/*": ["packages/core/overlays/core-overlays-browser-mocks/*"], - "@kbn/core-plugins-base-server-internal": ["packages/core/plugins/core-plugins-base-server-internal"], - "@kbn/core-plugins-base-server-internal/*": ["packages/core/plugins/core-plugins-base-server-internal/*"], - "@kbn/core-plugins-browser": ["packages/core/plugins/core-plugins-browser"], - "@kbn/core-plugins-browser/*": ["packages/core/plugins/core-plugins-browser/*"], - "@kbn/core-plugins-browser-internal": ["packages/core/plugins/core-plugins-browser-internal"], - "@kbn/core-plugins-browser-internal/*": ["packages/core/plugins/core-plugins-browser-internal/*"], - "@kbn/core-plugins-browser-mocks": ["packages/core/plugins/core-plugins-browser-mocks"], - "@kbn/core-plugins-browser-mocks/*": ["packages/core/plugins/core-plugins-browser-mocks/*"], - "@kbn/core-plugins-server": ["packages/core/plugins/core-plugins-server"], - "@kbn/core-plugins-server/*": ["packages/core/plugins/core-plugins-server/*"], - "@kbn/core-plugins-server-internal": ["packages/core/plugins/core-plugins-server-internal"], - "@kbn/core-plugins-server-internal/*": ["packages/core/plugins/core-plugins-server-internal/*"], - "@kbn/core-plugins-server-mocks": ["packages/core/plugins/core-plugins-server-mocks"], - "@kbn/core-plugins-server-mocks/*": ["packages/core/plugins/core-plugins-server-mocks/*"], - "@kbn/core-preboot-server": ["packages/core/preboot/core-preboot-server"], - "@kbn/core-preboot-server/*": ["packages/core/preboot/core-preboot-server/*"], - "@kbn/core-preboot-server-internal": ["packages/core/preboot/core-preboot-server-internal"], - "@kbn/core-preboot-server-internal/*": ["packages/core/preboot/core-preboot-server-internal/*"], - "@kbn/core-preboot-server-mocks": ["packages/core/preboot/core-preboot-server-mocks"], - "@kbn/core-preboot-server-mocks/*": ["packages/core/preboot/core-preboot-server-mocks/*"], - "@kbn/core-rendering-browser-internal": ["packages/core/rendering/core-rendering-browser-internal"], - "@kbn/core-rendering-browser-internal/*": ["packages/core/rendering/core-rendering-browser-internal/*"], - "@kbn/core-rendering-browser-mocks": ["packages/core/rendering/core-rendering-browser-mocks"], - "@kbn/core-rendering-browser-mocks/*": ["packages/core/rendering/core-rendering-browser-mocks/*"], - "@kbn/core-rendering-server-internal": ["packages/core/rendering/core-rendering-server-internal"], - "@kbn/core-rendering-server-internal/*": ["packages/core/rendering/core-rendering-server-internal/*"], - "@kbn/core-rendering-server-mocks": ["packages/core/rendering/core-rendering-server-mocks"], - "@kbn/core-rendering-server-mocks/*": ["packages/core/rendering/core-rendering-server-mocks/*"], - "@kbn/core-root-browser-internal": ["packages/core/root/core-root-browser-internal"], - "@kbn/core-root-browser-internal/*": ["packages/core/root/core-root-browser-internal/*"], - "@kbn/core-saved-objects-api-browser": ["packages/core/saved-objects/core-saved-objects-api-browser"], - "@kbn/core-saved-objects-api-browser/*": ["packages/core/saved-objects/core-saved-objects-api-browser/*"], - "@kbn/core-saved-objects-api-server": ["packages/core/saved-objects/core-saved-objects-api-server"], - "@kbn/core-saved-objects-api-server/*": ["packages/core/saved-objects/core-saved-objects-api-server/*"], - "@kbn/core-saved-objects-api-server-internal": ["packages/core/saved-objects/core-saved-objects-api-server-internal"], - "@kbn/core-saved-objects-api-server-internal/*": ["packages/core/saved-objects/core-saved-objects-api-server-internal/*"], - "@kbn/core-saved-objects-api-server-mocks": ["packages/core/saved-objects/core-saved-objects-api-server-mocks"], - "@kbn/core-saved-objects-api-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-api-server-mocks/*"], - "@kbn/core-saved-objects-base-server-internal": ["packages/core/saved-objects/core-saved-objects-base-server-internal"], - "@kbn/core-saved-objects-base-server-internal/*": ["packages/core/saved-objects/core-saved-objects-base-server-internal/*"], - "@kbn/core-saved-objects-base-server-mocks": ["packages/core/saved-objects/core-saved-objects-base-server-mocks"], - "@kbn/core-saved-objects-base-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-base-server-mocks/*"], - "@kbn/core-saved-objects-browser": ["packages/core/saved-objects/core-saved-objects-browser"], - "@kbn/core-saved-objects-browser/*": ["packages/core/saved-objects/core-saved-objects-browser/*"], - "@kbn/core-saved-objects-browser-internal": ["packages/core/saved-objects/core-saved-objects-browser-internal"], - "@kbn/core-saved-objects-browser-internal/*": ["packages/core/saved-objects/core-saved-objects-browser-internal/*"], - "@kbn/core-saved-objects-browser-mocks": ["packages/core/saved-objects/core-saved-objects-browser-mocks"], - "@kbn/core-saved-objects-browser-mocks/*": ["packages/core/saved-objects/core-saved-objects-browser-mocks/*"], - "@kbn/core-saved-objects-common": ["packages/core/saved-objects/core-saved-objects-common"], - "@kbn/core-saved-objects-common/*": ["packages/core/saved-objects/core-saved-objects-common/*"], - "@kbn/core-saved-objects-import-export-server-internal": ["packages/core/saved-objects/core-saved-objects-import-export-server-internal"], - "@kbn/core-saved-objects-import-export-server-internal/*": ["packages/core/saved-objects/core-saved-objects-import-export-server-internal/*"], - "@kbn/core-saved-objects-import-export-server-mocks": ["packages/core/saved-objects/core-saved-objects-import-export-server-mocks"], - "@kbn/core-saved-objects-import-export-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-import-export-server-mocks/*"], - "@kbn/core-saved-objects-migration-server-internal": ["packages/core/saved-objects/core-saved-objects-migration-server-internal"], - "@kbn/core-saved-objects-migration-server-internal/*": ["packages/core/saved-objects/core-saved-objects-migration-server-internal/*"], - "@kbn/core-saved-objects-migration-server-mocks": ["packages/core/saved-objects/core-saved-objects-migration-server-mocks"], - "@kbn/core-saved-objects-migration-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-migration-server-mocks/*"], - "@kbn/core-saved-objects-server": ["packages/core/saved-objects/core-saved-objects-server"], - "@kbn/core-saved-objects-server/*": ["packages/core/saved-objects/core-saved-objects-server/*"], - "@kbn/core-saved-objects-server-internal": ["packages/core/saved-objects/core-saved-objects-server-internal"], - "@kbn/core-saved-objects-server-internal/*": ["packages/core/saved-objects/core-saved-objects-server-internal/*"], - "@kbn/core-saved-objects-server-mocks": ["packages/core/saved-objects/core-saved-objects-server-mocks"], - "@kbn/core-saved-objects-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-server-mocks/*"], - "@kbn/core-saved-objects-utils-server": ["packages/core/saved-objects/core-saved-objects-utils-server"], - "@kbn/core-saved-objects-utils-server/*": ["packages/core/saved-objects/core-saved-objects-utils-server/*"], - "@kbn/core-status-common": ["packages/core/status/core-status-common"], - "@kbn/core-status-common/*": ["packages/core/status/core-status-common/*"], - "@kbn/core-status-common-internal": ["packages/core/status/core-status-common-internal"], - "@kbn/core-status-common-internal/*": ["packages/core/status/core-status-common-internal/*"], - "@kbn/core-status-server": ["packages/core/status/core-status-server"], - "@kbn/core-status-server/*": ["packages/core/status/core-status-server/*"], - "@kbn/core-status-server-internal": ["packages/core/status/core-status-server-internal"], - "@kbn/core-status-server-internal/*": ["packages/core/status/core-status-server-internal/*"], - "@kbn/core-status-server-mocks": ["packages/core/status/core-status-server-mocks"], - "@kbn/core-status-server-mocks/*": ["packages/core/status/core-status-server-mocks/*"], - "@kbn/core-test-helpers-deprecations-getters": ["packages/core/test-helpers/core-test-helpers-deprecations-getters"], - "@kbn/core-test-helpers-deprecations-getters/*": ["packages/core/test-helpers/core-test-helpers-deprecations-getters/*"], - "@kbn/core-test-helpers-http-setup-browser": ["packages/core/test-helpers/core-test-helpers-http-setup-browser"], - "@kbn/core-test-helpers-http-setup-browser/*": ["packages/core/test-helpers/core-test-helpers-http-setup-browser/*"], - "@kbn/core-test-helpers-so-type-serializer": ["packages/core/test-helpers/core-test-helpers-so-type-serializer"], - "@kbn/core-test-helpers-so-type-serializer/*": ["packages/core/test-helpers/core-test-helpers-so-type-serializer/*"], - "@kbn/core-test-helpers-test-utils": ["packages/core/test-helpers/core-test-helpers-test-utils"], - "@kbn/core-test-helpers-test-utils/*": ["packages/core/test-helpers/core-test-helpers-test-utils/*"], - "@kbn/core-theme-browser": ["packages/core/theme/core-theme-browser"], - "@kbn/core-theme-browser/*": ["packages/core/theme/core-theme-browser/*"], - "@kbn/core-theme-browser-internal": ["packages/core/theme/core-theme-browser-internal"], - "@kbn/core-theme-browser-internal/*": ["packages/core/theme/core-theme-browser-internal/*"], - "@kbn/core-theme-browser-mocks": ["packages/core/theme/core-theme-browser-mocks"], - "@kbn/core-theme-browser-mocks/*": ["packages/core/theme/core-theme-browser-mocks/*"], - "@kbn/core-ui-settings-browser": ["packages/core/ui-settings/core-ui-settings-browser"], - "@kbn/core-ui-settings-browser/*": ["packages/core/ui-settings/core-ui-settings-browser/*"], - "@kbn/core-ui-settings-browser-internal": ["packages/core/ui-settings/core-ui-settings-browser-internal"], - "@kbn/core-ui-settings-browser-internal/*": ["packages/core/ui-settings/core-ui-settings-browser-internal/*"], - "@kbn/core-ui-settings-browser-mocks": ["packages/core/ui-settings/core-ui-settings-browser-mocks"], - "@kbn/core-ui-settings-browser-mocks/*": ["packages/core/ui-settings/core-ui-settings-browser-mocks/*"], - "@kbn/core-ui-settings-common": ["packages/core/ui-settings/core-ui-settings-common"], - "@kbn/core-ui-settings-common/*": ["packages/core/ui-settings/core-ui-settings-common/*"], - "@kbn/core-ui-settings-server": ["packages/core/ui-settings/core-ui-settings-server"], - "@kbn/core-ui-settings-server/*": ["packages/core/ui-settings/core-ui-settings-server/*"], - "@kbn/core-ui-settings-server-internal": ["packages/core/ui-settings/core-ui-settings-server-internal"], - "@kbn/core-ui-settings-server-internal/*": ["packages/core/ui-settings/core-ui-settings-server-internal/*"], - "@kbn/core-ui-settings-server-mocks": ["packages/core/ui-settings/core-ui-settings-server-mocks"], - "@kbn/core-ui-settings-server-mocks/*": ["packages/core/ui-settings/core-ui-settings-server-mocks/*"], - "@kbn/core-usage-data-base-server-internal": ["packages/core/usage-data/core-usage-data-base-server-internal"], - "@kbn/core-usage-data-base-server-internal/*": ["packages/core/usage-data/core-usage-data-base-server-internal/*"], - "@kbn/core-usage-data-server": ["packages/core/usage-data/core-usage-data-server"], - "@kbn/core-usage-data-server/*": ["packages/core/usage-data/core-usage-data-server/*"], - "@kbn/core-usage-data-server-internal": ["packages/core/usage-data/core-usage-data-server-internal"], - "@kbn/core-usage-data-server-internal/*": ["packages/core/usage-data/core-usage-data-server-internal/*"], - "@kbn/core-usage-data-server-mocks": ["packages/core/usage-data/core-usage-data-server-mocks"], - "@kbn/core-usage-data-server-mocks/*": ["packages/core/usage-data/core-usage-data-server-mocks/*"], - "@kbn/home-sample-data-card": ["packages/home/sample_data_card"], - "@kbn/home-sample-data-card/*": ["packages/home/sample_data_card/*"], - "@kbn/home-sample-data-tab": ["packages/home/sample_data_tab"], - "@kbn/home-sample-data-tab/*": ["packages/home/sample_data_tab/*"], - "@kbn/home-sample-data-types": ["packages/home/sample_data_types"], - "@kbn/home-sample-data-types/*": ["packages/home/sample_data_types/*"], - "@kbn/ace": ["packages/kbn-ace"], - "@kbn/ace/*": ["packages/kbn-ace/*"], - "@kbn/alerts": ["packages/kbn-alerts"], - "@kbn/alerts/*": ["packages/kbn-alerts/*"], - "@kbn/ambient-storybook-types": ["packages/kbn-ambient-storybook-types"], - "@kbn/ambient-storybook-types/*": ["packages/kbn-ambient-storybook-types/*"], - "@kbn/ambient-ui-types": ["packages/kbn-ambient-ui-types"], - "@kbn/ambient-ui-types/*": ["packages/kbn-ambient-ui-types/*"], - "@kbn/analytics": ["packages/kbn-analytics"], - "@kbn/analytics/*": ["packages/kbn-analytics/*"], - "@kbn/apm-config-loader": ["packages/kbn-apm-config-loader"], - "@kbn/apm-config-loader/*": ["packages/kbn-apm-config-loader/*"], - "@kbn/apm-synthtrace": ["packages/kbn-apm-synthtrace"], - "@kbn/apm-synthtrace/*": ["packages/kbn-apm-synthtrace/*"], - "@kbn/apm-utils": ["packages/kbn-apm-utils"], - "@kbn/apm-utils/*": ["packages/kbn-apm-utils/*"], - "@kbn/axe-config": ["packages/kbn-axe-config"], - "@kbn/axe-config/*": ["packages/kbn-axe-config/*"], - "@kbn/babel-plugin-synthetic-packages": ["packages/kbn-babel-plugin-synthetic-packages"], - "@kbn/babel-plugin-synthetic-packages/*": ["packages/kbn-babel-plugin-synthetic-packages/*"], - "@kbn/babel-preset": ["packages/kbn-babel-preset"], - "@kbn/babel-preset/*": ["packages/kbn-babel-preset/*"], - "@kbn/bazel-packages": ["packages/kbn-bazel-packages"], - "@kbn/bazel-packages/*": ["packages/kbn-bazel-packages/*"], - "@kbn/bazel-runner": ["packages/kbn-bazel-runner"], - "@kbn/bazel-runner/*": ["packages/kbn-bazel-runner/*"], - "@kbn/cases-components": ["packages/kbn-cases-components"], - "@kbn/cases-components/*": ["packages/kbn-cases-components/*"], - "@kbn/chart-icons": ["packages/kbn-chart-icons"], - "@kbn/chart-icons/*": ["packages/kbn-chart-icons/*"], - "@kbn/ci-stats-core": ["packages/kbn-ci-stats-core"], - "@kbn/ci-stats-core/*": ["packages/kbn-ci-stats-core/*"], - "@kbn/ci-stats-performance-metrics": ["packages/kbn-ci-stats-performance-metrics"], - "@kbn/ci-stats-performance-metrics/*": ["packages/kbn-ci-stats-performance-metrics/*"], - "@kbn/ci-stats-reporter": ["packages/kbn-ci-stats-reporter"], - "@kbn/ci-stats-reporter/*": ["packages/kbn-ci-stats-reporter/*"], - "@kbn/cli-dev-mode": ["packages/kbn-cli-dev-mode"], - "@kbn/cli-dev-mode/*": ["packages/kbn-cli-dev-mode/*"], - "@kbn/coloring": ["packages/kbn-coloring"], - "@kbn/coloring/*": ["packages/kbn-coloring/*"], - "@kbn/config": ["packages/kbn-config"], - "@kbn/config/*": ["packages/kbn-config/*"], - "@kbn/config-mocks": ["packages/kbn-config-mocks"], - "@kbn/config-mocks/*": ["packages/kbn-config-mocks/*"], - "@kbn/config-schema": ["packages/kbn-config-schema"], - "@kbn/config-schema/*": ["packages/kbn-config-schema/*"], - "@kbn/crypto": ["packages/kbn-crypto"], - "@kbn/crypto/*": ["packages/kbn-crypto/*"], - "@kbn/crypto-browser": ["packages/kbn-crypto-browser"], - "@kbn/crypto-browser/*": ["packages/kbn-crypto-browser/*"], - "@kbn/datemath": ["packages/kbn-datemath"], - "@kbn/datemath/*": ["packages/kbn-datemath/*"], - "@kbn/dev-cli-errors": ["packages/kbn-dev-cli-errors"], - "@kbn/dev-cli-errors/*": ["packages/kbn-dev-cli-errors/*"], - "@kbn/dev-cli-runner": ["packages/kbn-dev-cli-runner"], - "@kbn/dev-cli-runner/*": ["packages/kbn-dev-cli-runner/*"], - "@kbn/dev-proc-runner": ["packages/kbn-dev-proc-runner"], - "@kbn/dev-proc-runner/*": ["packages/kbn-dev-proc-runner/*"], - "@kbn/dev-utils": ["packages/kbn-dev-utils"], - "@kbn/dev-utils/*": ["packages/kbn-dev-utils/*"], - "@kbn/doc-links": ["packages/kbn-doc-links"], - "@kbn/doc-links/*": ["packages/kbn-doc-links/*"], - "@kbn/docs-utils": ["packages/kbn-docs-utils"], - "@kbn/docs-utils/*": ["packages/kbn-docs-utils/*"], - "@kbn/ebt-tools": ["packages/kbn-ebt-tools"], - "@kbn/ebt-tools/*": ["packages/kbn-ebt-tools/*"], - "@kbn/es": ["packages/kbn-es"], - "@kbn/es/*": ["packages/kbn-es/*"], - "@kbn/es-archiver": ["packages/kbn-es-archiver"], - "@kbn/es-archiver/*": ["packages/kbn-es-archiver/*"], - "@kbn/es-errors": ["packages/kbn-es-errors"], - "@kbn/es-errors/*": ["packages/kbn-es-errors/*"], - "@kbn/es-query": ["packages/kbn-es-query"], - "@kbn/es-query/*": ["packages/kbn-es-query/*"], - "@kbn/es-types": ["packages/kbn-es-types"], - "@kbn/es-types/*": ["packages/kbn-es-types/*"], - "@kbn/eslint-config": ["packages/kbn-eslint-config"], - "@kbn/eslint-config/*": ["packages/kbn-eslint-config/*"], - "@kbn/eslint-plugin-disable": ["packages/kbn-eslint-plugin-disable"], - "@kbn/eslint-plugin-disable/*": ["packages/kbn-eslint-plugin-disable/*"], - "@kbn/eslint-plugin-eslint": ["packages/kbn-eslint-plugin-eslint"], - "@kbn/eslint-plugin-eslint/*": ["packages/kbn-eslint-plugin-eslint/*"], - "@kbn/eslint-plugin-imports": ["packages/kbn-eslint-plugin-imports"], - "@kbn/eslint-plugin-imports/*": ["packages/kbn-eslint-plugin-imports/*"], - "@kbn/expect": ["packages/kbn-expect"], - "@kbn/expect/*": ["packages/kbn-expect/*"], - "@kbn/failed-test-reporter-cli": ["packages/kbn-failed-test-reporter-cli"], - "@kbn/failed-test-reporter-cli/*": ["packages/kbn-failed-test-reporter-cli/*"], - "@kbn/field-types": ["packages/kbn-field-types"], - "@kbn/field-types/*": ["packages/kbn-field-types/*"], - "@kbn/find-used-node-modules": ["packages/kbn-find-used-node-modules"], - "@kbn/find-used-node-modules/*": ["packages/kbn-find-used-node-modules/*"], - "@kbn/flot-charts": ["packages/kbn-flot-charts"], - "@kbn/flot-charts/*": ["packages/kbn-flot-charts/*"], - "@kbn/ftr-common-functional-services": ["packages/kbn-ftr-common-functional-services"], - "@kbn/ftr-common-functional-services/*": ["packages/kbn-ftr-common-functional-services/*"], - "@kbn/ftr-screenshot-filename": ["packages/kbn-ftr-screenshot-filename"], - "@kbn/ftr-screenshot-filename/*": ["packages/kbn-ftr-screenshot-filename/*"], - "@kbn/generate": ["packages/kbn-generate"], - "@kbn/generate/*": ["packages/kbn-generate/*"], - "@kbn/get-repo-files": ["packages/kbn-get-repo-files"], - "@kbn/get-repo-files/*": ["packages/kbn-get-repo-files/*"], - "@kbn/guided-onboarding": ["packages/kbn-guided-onboarding"], - "@kbn/guided-onboarding/*": ["packages/kbn-guided-onboarding/*"], - "@kbn/handlebars": ["packages/kbn-handlebars"], - "@kbn/handlebars/*": ["packages/kbn-handlebars/*"], - "@kbn/hapi-mocks": ["packages/kbn-hapi-mocks"], - "@kbn/hapi-mocks/*": ["packages/kbn-hapi-mocks/*"], - "@kbn/i18n": ["packages/kbn-i18n"], - "@kbn/i18n/*": ["packages/kbn-i18n/*"], - "@kbn/i18n-react": ["packages/kbn-i18n-react"], - "@kbn/i18n-react/*": ["packages/kbn-i18n-react/*"], - "@kbn/import-resolver": ["packages/kbn-import-resolver"], - "@kbn/import-resolver/*": ["packages/kbn-import-resolver/*"], - "@kbn/interpreter": ["packages/kbn-interpreter"], - "@kbn/interpreter/*": ["packages/kbn-interpreter/*"], - "@kbn/io-ts-utils": ["packages/kbn-io-ts-utils"], - "@kbn/io-ts-utils/*": ["packages/kbn-io-ts-utils/*"], - "@kbn/jest-serializers": ["packages/kbn-jest-serializers"], - "@kbn/jest-serializers/*": ["packages/kbn-jest-serializers/*"], - "@kbn/journeys": ["packages/kbn-journeys"], - "@kbn/journeys/*": ["packages/kbn-journeys/*"], - "@kbn/kibana-manifest-schema": ["packages/kbn-kibana-manifest-schema"], - "@kbn/kibana-manifest-schema/*": ["packages/kbn-kibana-manifest-schema/*"], - "@kbn/language-documentation-popover": ["packages/kbn-language-documentation-popover"], - "@kbn/language-documentation-popover/*": ["packages/kbn-language-documentation-popover/*"], - "@kbn/logging": ["packages/kbn-logging"], - "@kbn/logging/*": ["packages/kbn-logging/*"], - "@kbn/logging-mocks": ["packages/kbn-logging-mocks"], - "@kbn/logging-mocks/*": ["packages/kbn-logging-mocks/*"], - "@kbn/managed-vscode-config": ["packages/kbn-managed-vscode-config"], - "@kbn/managed-vscode-config/*": ["packages/kbn-managed-vscode-config/*"], - "@kbn/managed-vscode-config-cli": ["packages/kbn-managed-vscode-config-cli"], - "@kbn/managed-vscode-config-cli/*": ["packages/kbn-managed-vscode-config-cli/*"], - "@kbn/mapbox-gl": ["packages/kbn-mapbox-gl"], - "@kbn/mapbox-gl/*": ["packages/kbn-mapbox-gl/*"], - "@kbn/monaco": ["packages/kbn-monaco"], - "@kbn/monaco/*": ["packages/kbn-monaco/*"], - "@kbn/optimizer": ["packages/kbn-optimizer"], - "@kbn/optimizer/*": ["packages/kbn-optimizer/*"], - "@kbn/optimizer-webpack-helpers": ["packages/kbn-optimizer-webpack-helpers"], - "@kbn/optimizer-webpack-helpers/*": ["packages/kbn-optimizer-webpack-helpers/*"], - "@kbn/osquery-io-ts-types": ["packages/kbn-osquery-io-ts-types"], - "@kbn/osquery-io-ts-types/*": ["packages/kbn-osquery-io-ts-types/*"], - "@kbn/performance-testing-dataset-extractor": ["packages/kbn-performance-testing-dataset-extractor"], - "@kbn/performance-testing-dataset-extractor/*": ["packages/kbn-performance-testing-dataset-extractor/*"], - "@kbn/plugin-discovery": ["packages/kbn-plugin-discovery"], - "@kbn/plugin-discovery/*": ["packages/kbn-plugin-discovery/*"], - "@kbn/plugin-generator": ["packages/kbn-plugin-generator"], - "@kbn/plugin-generator/*": ["packages/kbn-plugin-generator/*"], - "@kbn/plugin-helpers": ["packages/kbn-plugin-helpers"], - "@kbn/plugin-helpers/*": ["packages/kbn-plugin-helpers/*"], - "@kbn/react-field": ["packages/kbn-react-field"], - "@kbn/react-field/*": ["packages/kbn-react-field/*"], - "@kbn/repo-source-classifier": ["packages/kbn-repo-source-classifier"], - "@kbn/repo-source-classifier/*": ["packages/kbn-repo-source-classifier/*"], - "@kbn/repo-source-classifier-cli": ["packages/kbn-repo-source-classifier-cli"], - "@kbn/repo-source-classifier-cli/*": ["packages/kbn-repo-source-classifier-cli/*"], - "@kbn/rule-data-utils": ["packages/kbn-rule-data-utils"], - "@kbn/rule-data-utils/*": ["packages/kbn-rule-data-utils/*"], - "@kbn/safer-lodash-set": ["packages/kbn-safer-lodash-set"], - "@kbn/safer-lodash-set/*": ["packages/kbn-safer-lodash-set/*"], - "@kbn/securitysolution-autocomplete": ["packages/kbn-securitysolution-autocomplete"], - "@kbn/securitysolution-autocomplete/*": ["packages/kbn-securitysolution-autocomplete/*"], - "@kbn/securitysolution-es-utils": ["packages/kbn-securitysolution-es-utils"], - "@kbn/securitysolution-es-utils/*": ["packages/kbn-securitysolution-es-utils/*"], - "@kbn/securitysolution-exception-list-components": ["packages/kbn-securitysolution-exception-list-components"], - "@kbn/securitysolution-exception-list-components/*": ["packages/kbn-securitysolution-exception-list-components/*"], - "@kbn/securitysolution-hook-utils": ["packages/kbn-securitysolution-hook-utils"], - "@kbn/securitysolution-hook-utils/*": ["packages/kbn-securitysolution-hook-utils/*"], - "@kbn/securitysolution-io-ts-alerting-types": ["packages/kbn-securitysolution-io-ts-alerting-types"], - "@kbn/securitysolution-io-ts-alerting-types/*": ["packages/kbn-securitysolution-io-ts-alerting-types/*"], - "@kbn/securitysolution-io-ts-list-types": ["packages/kbn-securitysolution-io-ts-list-types"], - "@kbn/securitysolution-io-ts-list-types/*": ["packages/kbn-securitysolution-io-ts-list-types/*"], - "@kbn/securitysolution-io-ts-types": ["packages/kbn-securitysolution-io-ts-types"], - "@kbn/securitysolution-io-ts-types/*": ["packages/kbn-securitysolution-io-ts-types/*"], - "@kbn/securitysolution-io-ts-utils": ["packages/kbn-securitysolution-io-ts-utils"], - "@kbn/securitysolution-io-ts-utils/*": ["packages/kbn-securitysolution-io-ts-utils/*"], - "@kbn/securitysolution-list-api": ["packages/kbn-securitysolution-list-api"], - "@kbn/securitysolution-list-api/*": ["packages/kbn-securitysolution-list-api/*"], - "@kbn/securitysolution-list-constants": ["packages/kbn-securitysolution-list-constants"], - "@kbn/securitysolution-list-constants/*": ["packages/kbn-securitysolution-list-constants/*"], - "@kbn/securitysolution-list-hooks": ["packages/kbn-securitysolution-list-hooks"], - "@kbn/securitysolution-list-hooks/*": ["packages/kbn-securitysolution-list-hooks/*"], - "@kbn/securitysolution-list-utils": ["packages/kbn-securitysolution-list-utils"], - "@kbn/securitysolution-list-utils/*": ["packages/kbn-securitysolution-list-utils/*"], - "@kbn/securitysolution-rules": ["packages/kbn-securitysolution-rules"], - "@kbn/securitysolution-rules/*": ["packages/kbn-securitysolution-rules/*"], - "@kbn/securitysolution-t-grid": ["packages/kbn-securitysolution-t-grid"], - "@kbn/securitysolution-t-grid/*": ["packages/kbn-securitysolution-t-grid/*"], - "@kbn/securitysolution-utils": ["packages/kbn-securitysolution-utils"], - "@kbn/securitysolution-utils/*": ["packages/kbn-securitysolution-utils/*"], - "@kbn/server-http-tools": ["packages/kbn-server-http-tools"], - "@kbn/server-http-tools/*": ["packages/kbn-server-http-tools/*"], - "@kbn/server-route-repository": ["packages/kbn-server-route-repository"], - "@kbn/server-route-repository/*": ["packages/kbn-server-route-repository/*"], - "@kbn/shared-svg": ["packages/kbn-shared-svg"], - "@kbn/shared-svg/*": ["packages/kbn-shared-svg/*"], - "@kbn/shared-ux-utility": ["packages/kbn-shared-ux-utility"], - "@kbn/shared-ux-utility/*": ["packages/kbn-shared-ux-utility/*"], - "@kbn/some-dev-log": ["packages/kbn-some-dev-log"], - "@kbn/some-dev-log/*": ["packages/kbn-some-dev-log/*"], - "@kbn/sort-package-json": ["packages/kbn-sort-package-json"], - "@kbn/sort-package-json/*": ["packages/kbn-sort-package-json/*"], - "@kbn/spec-to-console": ["packages/kbn-spec-to-console"], - "@kbn/spec-to-console/*": ["packages/kbn-spec-to-console/*"], - "@kbn/std": ["packages/kbn-std"], - "@kbn/std/*": ["packages/kbn-std/*"], - "@kbn/stdio-dev-helpers": ["packages/kbn-stdio-dev-helpers"], - "@kbn/stdio-dev-helpers/*": ["packages/kbn-stdio-dev-helpers/*"], - "@kbn/storybook": ["packages/kbn-storybook"], - "@kbn/storybook/*": ["packages/kbn-storybook/*"], - "@kbn/synthetic-package-map": ["packages/kbn-synthetic-package-map"], - "@kbn/synthetic-package-map/*": ["packages/kbn-synthetic-package-map/*"], - "@kbn/telemetry-tools": ["packages/kbn-telemetry-tools"], - "@kbn/telemetry-tools/*": ["packages/kbn-telemetry-tools/*"], - "@kbn/test": ["packages/kbn-test"], - "@kbn/test/*": ["packages/kbn-test/*"], - "@kbn/test-jest-helpers": ["packages/kbn-test-jest-helpers"], - "@kbn/test-jest-helpers/*": ["packages/kbn-test-jest-helpers/*"], - "@kbn/test-subj-selector": ["packages/kbn-test-subj-selector"], - "@kbn/test-subj-selector/*": ["packages/kbn-test-subj-selector/*"], - "@kbn/timelion-grammar": ["packages/kbn-timelion-grammar"], - "@kbn/timelion-grammar/*": ["packages/kbn-timelion-grammar/*"], - "@kbn/tinymath": ["packages/kbn-tinymath"], - "@kbn/tinymath/*": ["packages/kbn-tinymath/*"], - "@kbn/tooling-log": ["packages/kbn-tooling-log"], - "@kbn/tooling-log/*": ["packages/kbn-tooling-log/*"], - "@kbn/type-summarizer": ["packages/kbn-type-summarizer"], - "@kbn/type-summarizer/*": ["packages/kbn-type-summarizer/*"], - "@kbn/type-summarizer-cli": ["packages/kbn-type-summarizer-cli"], - "@kbn/type-summarizer-cli/*": ["packages/kbn-type-summarizer-cli/*"], - "@kbn/type-summarizer-core": ["packages/kbn-type-summarizer-core"], - "@kbn/type-summarizer-core/*": ["packages/kbn-type-summarizer-core/*"], - "@kbn/typed-react-router-config": ["packages/kbn-typed-react-router-config"], - "@kbn/typed-react-router-config/*": ["packages/kbn-typed-react-router-config/*"], - "@kbn/ui-framework": ["packages/kbn-ui-framework"], - "@kbn/ui-framework/*": ["packages/kbn-ui-framework/*"], - "@kbn/ui-shared-deps-npm": ["packages/kbn-ui-shared-deps-npm"], - "@kbn/ui-shared-deps-npm/*": ["packages/kbn-ui-shared-deps-npm/*"], - "@kbn/ui-shared-deps-src": ["packages/kbn-ui-shared-deps-src"], - "@kbn/ui-shared-deps-src/*": ["packages/kbn-ui-shared-deps-src/*"], - "@kbn/ui-theme": ["packages/kbn-ui-theme"], - "@kbn/ui-theme/*": ["packages/kbn-ui-theme/*"], - "@kbn/user-profile-components": ["packages/kbn-user-profile-components"], - "@kbn/user-profile-components/*": ["packages/kbn-user-profile-components/*"], - "@kbn/utility-types": ["packages/kbn-utility-types"], - "@kbn/utility-types/*": ["packages/kbn-utility-types/*"], - "@kbn/utility-types-jest": ["packages/kbn-utility-types-jest"], - "@kbn/utility-types-jest/*": ["packages/kbn-utility-types-jest/*"], - "@kbn/utils": ["packages/kbn-utils"], - "@kbn/utils/*": ["packages/kbn-utils/*"], - "@kbn/yarn-lock-validator": ["packages/kbn-yarn-lock-validator"], - "@kbn/yarn-lock-validator/*": ["packages/kbn-yarn-lock-validator/*"], - "@kbn/shared-ux-avatar-solution": ["packages/shared-ux/avatar/solution"], - "@kbn/shared-ux-avatar-solution/*": ["packages/shared-ux/avatar/solution/*"], - "@kbn/shared-ux-avatar-user-profile-components": ["packages/shared-ux/avatar/user_profile/impl"], - "@kbn/shared-ux-avatar-user-profile-components/*": ["packages/shared-ux/avatar/user_profile/impl/*"], - "@kbn/shared-ux-button-toolbar": ["packages/shared-ux/button_toolbar"], - "@kbn/shared-ux-button-toolbar/*": ["packages/shared-ux/button_toolbar/*"], - "@kbn/shared-ux-button-exit-full-screen": ["packages/shared-ux/button/exit_full_screen/impl"], - "@kbn/shared-ux-button-exit-full-screen/*": ["packages/shared-ux/button/exit_full_screen/impl/*"], - "@kbn/shared-ux-button-exit-full-screen-mocks": ["packages/shared-ux/button/exit_full_screen/mocks"], - "@kbn/shared-ux-button-exit-full-screen-mocks/*": ["packages/shared-ux/button/exit_full_screen/mocks/*"], - "@kbn/shared-ux-button-exit-full-screen-types": ["packages/shared-ux/button/exit_full_screen/types"], - "@kbn/shared-ux-button-exit-full-screen-types/*": ["packages/shared-ux/button/exit_full_screen/types/*"], - "@kbn/shared-ux-card-no-data": ["packages/shared-ux/card/no_data/impl"], - "@kbn/shared-ux-card-no-data/*": ["packages/shared-ux/card/no_data/impl/*"], - "@kbn/shared-ux-card-no-data-mocks": ["packages/shared-ux/card/no_data/mocks"], - "@kbn/shared-ux-card-no-data-mocks/*": ["packages/shared-ux/card/no_data/mocks/*"], - "@kbn/shared-ux-card-no-data-types": ["packages/shared-ux/card/no_data/types"], - "@kbn/shared-ux-card-no-data-types/*": ["packages/shared-ux/card/no_data/types/*"], - "@kbn/shared-ux-link-redirect-app": ["packages/shared-ux/link/redirect_app/impl"], - "@kbn/shared-ux-link-redirect-app/*": ["packages/shared-ux/link/redirect_app/impl/*"], - "@kbn/shared-ux-link-redirect-app-mocks": ["packages/shared-ux/link/redirect_app/mocks"], - "@kbn/shared-ux-link-redirect-app-mocks/*": ["packages/shared-ux/link/redirect_app/mocks/*"], - "@kbn/shared-ux-link-redirect-app-types": ["packages/shared-ux/link/redirect_app/types"], - "@kbn/shared-ux-link-redirect-app-types/*": ["packages/shared-ux/link/redirect_app/types/*"], - "@kbn/shared-ux-markdown": ["packages/shared-ux/markdown/impl"], - "@kbn/shared-ux-markdown/*": ["packages/shared-ux/markdown/impl/*"], - "@kbn/shared-ux-markdown-mocks": ["packages/shared-ux/markdown/mocks"], - "@kbn/shared-ux-markdown-mocks/*": ["packages/shared-ux/markdown/mocks/*"], - "@kbn/shared-ux-markdown-types": ["packages/shared-ux/markdown/types"], - "@kbn/shared-ux-markdown-types/*": ["packages/shared-ux/markdown/types/*"], - "@kbn/shared-ux-page-analytics-no-data": ["packages/shared-ux/page/analytics_no_data/impl"], - "@kbn/shared-ux-page-analytics-no-data/*": ["packages/shared-ux/page/analytics_no_data/impl/*"], - "@kbn/shared-ux-page-analytics-no-data-mocks": ["packages/shared-ux/page/analytics_no_data/mocks"], - "@kbn/shared-ux-page-analytics-no-data-mocks/*": ["packages/shared-ux/page/analytics_no_data/mocks/*"], - "@kbn/shared-ux-page-analytics-no-data-types": ["packages/shared-ux/page/analytics_no_data/types"], - "@kbn/shared-ux-page-analytics-no-data-types/*": ["packages/shared-ux/page/analytics_no_data/types/*"], - "@kbn/shared-ux-page-kibana-no-data": ["packages/shared-ux/page/kibana_no_data/impl"], - "@kbn/shared-ux-page-kibana-no-data/*": ["packages/shared-ux/page/kibana_no_data/impl/*"], - "@kbn/shared-ux-page-kibana-no-data-mocks": ["packages/shared-ux/page/kibana_no_data/mocks"], - "@kbn/shared-ux-page-kibana-no-data-mocks/*": ["packages/shared-ux/page/kibana_no_data/mocks/*"], - "@kbn/shared-ux-page-kibana-no-data-types": ["packages/shared-ux/page/kibana_no_data/types"], - "@kbn/shared-ux-page-kibana-no-data-types/*": ["packages/shared-ux/page/kibana_no_data/types/*"], - "@kbn/shared-ux-page-kibana-template": ["packages/shared-ux/page/kibana_template/impl"], - "@kbn/shared-ux-page-kibana-template/*": ["packages/shared-ux/page/kibana_template/impl/*"], - "@kbn/shared-ux-page-kibana-template-mocks": ["packages/shared-ux/page/kibana_template/mocks"], - "@kbn/shared-ux-page-kibana-template-mocks/*": ["packages/shared-ux/page/kibana_template/mocks/*"], - "@kbn/shared-ux-page-kibana-template-types": ["packages/shared-ux/page/kibana_template/types"], - "@kbn/shared-ux-page-kibana-template-types/*": ["packages/shared-ux/page/kibana_template/types/*"], - "@kbn/shared-ux-page-no-data-config": ["packages/shared-ux/page/no_data_config/impl"], - "@kbn/shared-ux-page-no-data-config/*": ["packages/shared-ux/page/no_data_config/impl/*"], - "@kbn/shared-ux-page-no-data-config-mocks": ["packages/shared-ux/page/no_data_config/mocks"], - "@kbn/shared-ux-page-no-data-config-mocks/*": ["packages/shared-ux/page/no_data_config/mocks/*"], - "@kbn/shared-ux-page-no-data-config-types": ["packages/shared-ux/page/no_data_config/types"], - "@kbn/shared-ux-page-no-data-config-types/*": ["packages/shared-ux/page/no_data_config/types/*"], - "@kbn/shared-ux-page-no-data": ["packages/shared-ux/page/no_data/impl"], - "@kbn/shared-ux-page-no-data/*": ["packages/shared-ux/page/no_data/impl/*"], - "@kbn/shared-ux-page-no-data-mocks": ["packages/shared-ux/page/no_data/mocks"], - "@kbn/shared-ux-page-no-data-mocks/*": ["packages/shared-ux/page/no_data/mocks/*"], - "@kbn/shared-ux-page-no-data-types": ["packages/shared-ux/page/no_data/types"], - "@kbn/shared-ux-page-no-data-types/*": ["packages/shared-ux/page/no_data/types/*"], - "@kbn/shared-ux-page-solution-nav": ["packages/shared-ux/page/solution_nav"], - "@kbn/shared-ux-page-solution-nav/*": ["packages/shared-ux/page/solution_nav/*"], - "@kbn/shared-ux-prompt-no-data-views": ["packages/shared-ux/prompt/no_data_views/impl"], - "@kbn/shared-ux-prompt-no-data-views/*": ["packages/shared-ux/prompt/no_data_views/impl/*"], - "@kbn/shared-ux-prompt-no-data-views-mocks": ["packages/shared-ux/prompt/no_data_views/mocks"], - "@kbn/shared-ux-prompt-no-data-views-mocks/*": ["packages/shared-ux/prompt/no_data_views/mocks/*"], - "@kbn/shared-ux-prompt-no-data-views-types": ["packages/shared-ux/prompt/no_data_views/types"], - "@kbn/shared-ux-prompt-no-data-views-types/*": ["packages/shared-ux/prompt/no_data_views/types/*"], - "@kbn/shared-ux-router": ["packages/shared-ux/router/impl"], - "@kbn/shared-ux-router/*": ["packages/shared-ux/router/impl/*"], - "@kbn/shared-ux-router-mocks": ["packages/shared-ux/router/mocks"], - "@kbn/shared-ux-router-mocks/*": ["packages/shared-ux/router/mocks/*"], - "@kbn/shared-ux-router-types": ["packages/shared-ux/router/types"], - "@kbn/shared-ux-router-types/*": ["packages/shared-ux/router/types/*"], - "@kbn/shared-ux-storybook-config": ["packages/shared-ux/storybook/config"], - "@kbn/shared-ux-storybook-config/*": ["packages/shared-ux/storybook/config/*"], - "@kbn/shared-ux-storybook-mock": ["packages/shared-ux/storybook/mock"], - "@kbn/shared-ux-storybook-mock/*": ["packages/shared-ux/storybook/mock/*"], - "@kbn/ml-agg-utils": ["x-pack/packages/ml/agg_utils"], - "@kbn/ml-agg-utils/*": ["x-pack/packages/ml/agg_utils/*"], - "@kbn/aiops-components": ["x-pack/packages/ml/aiops_components"], - "@kbn/aiops-components/*": ["x-pack/packages/ml/aiops_components/*"], - "@kbn/aiops-utils": ["x-pack/packages/ml/aiops_utils"], - "@kbn/aiops-utils/*": ["x-pack/packages/ml/aiops_utils/*"], - "@kbn/ml-is-populated-object": ["x-pack/packages/ml/is_populated_object"], - "@kbn/ml-is-populated-object/*": ["x-pack/packages/ml/is_populated_object/*"], - "@kbn/ml-string-hash": ["x-pack/packages/ml/string_hash"], - "@kbn/ml-string-hash/*": ["x-pack/packages/ml/string_hash/*"], "@kbn/bfetch-explorer-plugin": ["examples/bfetch_explorer"], "@kbn/bfetch-explorer-plugin/*": ["examples/bfetch_explorer/*"], "@kbn/dashboard-embeddable-examples-plugin": ["examples/dashboard_embeddable_examples"], @@ -974,10 +278,6 @@ "@kbn/ui-settings-plugin/*": ["test/plugin_functional/plugins/ui_settings_plugin/*"], "@kbn/usage-collection-test-plugin": ["test/plugin_functional/plugins/usage_collection"], "@kbn/usage-collection-test-plugin/*": ["test/plugin_functional/plugins/usage_collection/*"], - "@kbn/status-plugin-a-plugin": ["test/server_integration/__fixtures__/plugins/status_plugin_a"], - "@kbn/status-plugin-a-plugin/*": ["test/server_integration/__fixtures__/plugins/status_plugin_a/*"], - "@kbn/status-plugin-b-plugin": ["test/server_integration/__fixtures__/plugins/status_plugin_b"], - "@kbn/status-plugin-b-plugin/*": ["test/server_integration/__fixtures__/plugins/status_plugin_b/*"], "@kbn/alerting-example-plugin": ["x-pack/examples/alerting_example"], "@kbn/alerting-example-plugin/*": ["x-pack/examples/alerting_example/*"], "@kbn/embedded-lens-example-plugin": ["x-pack/examples/embedded_lens_example"], diff --git a/x-pack/plugins/alerting/common/alert_summary.ts b/x-pack/plugins/alerting/common/alert_summary.ts index fc35e3403fe92..35fb4ee28b29f 100644 --- a/x-pack/plugins/alerting/common/alert_summary.ts +++ b/x-pack/plugins/alerting/common/alert_summary.ts @@ -20,7 +20,7 @@ export interface AlertSummary { ruleTypeId: string; consumer: string; muteAll: boolean; - throttle: string | null; + throttle?: string | null; enabled: boolean; statusStartDate: string; statusEndDate: string; diff --git a/x-pack/plugins/alerting/server/lib/alert_summary_from_event_log.ts b/x-pack/plugins/alerting/server/lib/alert_summary_from_event_log.ts index d8e5f4dea9b41..a4f29521d7d7b 100644 --- a/x-pack/plugins/alerting/server/lib/alert_summary_from_event_log.ts +++ b/x-pack/plugins/alerting/server/lib/alert_summary_from_event_log.ts @@ -31,7 +31,7 @@ export function alertSummaryFromEventLog(params: AlertSummaryFromEventLogParams) statusEndDate: dateEnd, status: 'OK', muteAll: rule.muteAll, - throttle: rule.throttle, + throttle: rule.throttle ?? null, enabled: rule.enabled, lastRun: undefined, errorMessages: [], diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index 0c6bbfbbd9866..bdd4afd9f2a03 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -257,8 +257,8 @@ export class TaskRunner< alertTypeId: ruleTypeId, consumer, schedule, - throttle, - notifyWhen, + throttle = null, + notifyWhen = null, mutedInstanceIds, name, tags, From ef435498e508b99f42452352dbeae989edebf11a Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Fri, 28 Oct 2022 22:32:49 +0000 Subject: [PATCH 07/85] [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' --- tsconfig.base.json | 700 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 700 insertions(+) diff --git a/tsconfig.base.json b/tsconfig.base.json index 97efbcf215827..55b307ddc81f7 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -6,6 +6,702 @@ "@kbn/core": ["src/core"], "@kbn/core/*": ["src/core/*"], // START AUTOMATED PACKAGE LISTING + "@kbn/analytics-client": ["packages/analytics/client"], + "@kbn/analytics-client/*": ["packages/analytics/client/*"], + "@kbn/analytics-shippers-elastic-v3-browser": ["packages/analytics/shippers/elastic_v3/browser"], + "@kbn/analytics-shippers-elastic-v3-browser/*": ["packages/analytics/shippers/elastic_v3/browser/*"], + "@kbn/analytics-shippers-elastic-v3-common": ["packages/analytics/shippers/elastic_v3/common"], + "@kbn/analytics-shippers-elastic-v3-common/*": ["packages/analytics/shippers/elastic_v3/common/*"], + "@kbn/analytics-shippers-elastic-v3-server": ["packages/analytics/shippers/elastic_v3/server"], + "@kbn/analytics-shippers-elastic-v3-server/*": ["packages/analytics/shippers/elastic_v3/server/*"], + "@kbn/analytics-shippers-fullstory": ["packages/analytics/shippers/fullstory"], + "@kbn/analytics-shippers-fullstory/*": ["packages/analytics/shippers/fullstory/*"], + "@kbn/analytics-shippers-gainsight": ["packages/analytics/shippers/gainsight"], + "@kbn/analytics-shippers-gainsight/*": ["packages/analytics/shippers/gainsight/*"], + "@kbn/content-management-table-list": ["packages/content-management/table_list"], + "@kbn/content-management-table-list/*": ["packages/content-management/table_list/*"], + "@kbn/core-analytics-browser": ["packages/core/analytics/core-analytics-browser"], + "@kbn/core-analytics-browser/*": ["packages/core/analytics/core-analytics-browser/*"], + "@kbn/core-analytics-browser-internal": ["packages/core/analytics/core-analytics-browser-internal"], + "@kbn/core-analytics-browser-internal/*": ["packages/core/analytics/core-analytics-browser-internal/*"], + "@kbn/core-analytics-browser-mocks": ["packages/core/analytics/core-analytics-browser-mocks"], + "@kbn/core-analytics-browser-mocks/*": ["packages/core/analytics/core-analytics-browser-mocks/*"], + "@kbn/core-analytics-server": ["packages/core/analytics/core-analytics-server"], + "@kbn/core-analytics-server/*": ["packages/core/analytics/core-analytics-server/*"], + "@kbn/core-analytics-server-internal": ["packages/core/analytics/core-analytics-server-internal"], + "@kbn/core-analytics-server-internal/*": ["packages/core/analytics/core-analytics-server-internal/*"], + "@kbn/core-analytics-server-mocks": ["packages/core/analytics/core-analytics-server-mocks"], + "@kbn/core-analytics-server-mocks/*": ["packages/core/analytics/core-analytics-server-mocks/*"], + "@kbn/core-application-browser": ["packages/core/application/core-application-browser"], + "@kbn/core-application-browser/*": ["packages/core/application/core-application-browser/*"], + "@kbn/core-application-browser-internal": ["packages/core/application/core-application-browser-internal"], + "@kbn/core-application-browser-internal/*": ["packages/core/application/core-application-browser-internal/*"], + "@kbn/core-application-browser-mocks": ["packages/core/application/core-application-browser-mocks"], + "@kbn/core-application-browser-mocks/*": ["packages/core/application/core-application-browser-mocks/*"], + "@kbn/core-application-common": ["packages/core/application/core-application-common"], + "@kbn/core-application-common/*": ["packages/core/application/core-application-common/*"], + "@kbn/core-apps-browser-internal": ["packages/core/apps/core-apps-browser-internal"], + "@kbn/core-apps-browser-internal/*": ["packages/core/apps/core-apps-browser-internal/*"], + "@kbn/core-apps-browser-mocks": ["packages/core/apps/core-apps-browser-mocks"], + "@kbn/core-apps-browser-mocks/*": ["packages/core/apps/core-apps-browser-mocks/*"], + "@kbn/core-base-browser-internal": ["packages/core/base/core-base-browser-internal"], + "@kbn/core-base-browser-internal/*": ["packages/core/base/core-base-browser-internal/*"], + "@kbn/core-base-browser-mocks": ["packages/core/base/core-base-browser-mocks"], + "@kbn/core-base-browser-mocks/*": ["packages/core/base/core-base-browser-mocks/*"], + "@kbn/core-base-common": ["packages/core/base/core-base-common"], + "@kbn/core-base-common/*": ["packages/core/base/core-base-common/*"], + "@kbn/core-base-common-internal": ["packages/core/base/core-base-common-internal"], + "@kbn/core-base-common-internal/*": ["packages/core/base/core-base-common-internal/*"], + "@kbn/core-base-server-internal": ["packages/core/base/core-base-server-internal"], + "@kbn/core-base-server-internal/*": ["packages/core/base/core-base-server-internal/*"], + "@kbn/core-base-server-mocks": ["packages/core/base/core-base-server-mocks"], + "@kbn/core-base-server-mocks/*": ["packages/core/base/core-base-server-mocks/*"], + "@kbn/core-capabilities-browser-internal": ["packages/core/capabilities/core-capabilities-browser-internal"], + "@kbn/core-capabilities-browser-internal/*": ["packages/core/capabilities/core-capabilities-browser-internal/*"], + "@kbn/core-capabilities-browser-mocks": ["packages/core/capabilities/core-capabilities-browser-mocks"], + "@kbn/core-capabilities-browser-mocks/*": ["packages/core/capabilities/core-capabilities-browser-mocks/*"], + "@kbn/core-capabilities-common": ["packages/core/capabilities/core-capabilities-common"], + "@kbn/core-capabilities-common/*": ["packages/core/capabilities/core-capabilities-common/*"], + "@kbn/core-capabilities-server": ["packages/core/capabilities/core-capabilities-server"], + "@kbn/core-capabilities-server/*": ["packages/core/capabilities/core-capabilities-server/*"], + "@kbn/core-capabilities-server-internal": ["packages/core/capabilities/core-capabilities-server-internal"], + "@kbn/core-capabilities-server-internal/*": ["packages/core/capabilities/core-capabilities-server-internal/*"], + "@kbn/core-capabilities-server-mocks": ["packages/core/capabilities/core-capabilities-server-mocks"], + "@kbn/core-capabilities-server-mocks/*": ["packages/core/capabilities/core-capabilities-server-mocks/*"], + "@kbn/core-chrome-browser": ["packages/core/chrome/core-chrome-browser"], + "@kbn/core-chrome-browser/*": ["packages/core/chrome/core-chrome-browser/*"], + "@kbn/core-chrome-browser-internal": ["packages/core/chrome/core-chrome-browser-internal"], + "@kbn/core-chrome-browser-internal/*": ["packages/core/chrome/core-chrome-browser-internal/*"], + "@kbn/core-chrome-browser-mocks": ["packages/core/chrome/core-chrome-browser-mocks"], + "@kbn/core-chrome-browser-mocks/*": ["packages/core/chrome/core-chrome-browser-mocks/*"], + "@kbn/core-config-server-internal": ["packages/core/config/core-config-server-internal"], + "@kbn/core-config-server-internal/*": ["packages/core/config/core-config-server-internal/*"], + "@kbn/core-deprecations-browser": ["packages/core/deprecations/core-deprecations-browser"], + "@kbn/core-deprecations-browser/*": ["packages/core/deprecations/core-deprecations-browser/*"], + "@kbn/core-deprecations-browser-internal": ["packages/core/deprecations/core-deprecations-browser-internal"], + "@kbn/core-deprecations-browser-internal/*": ["packages/core/deprecations/core-deprecations-browser-internal/*"], + "@kbn/core-deprecations-browser-mocks": ["packages/core/deprecations/core-deprecations-browser-mocks"], + "@kbn/core-deprecations-browser-mocks/*": ["packages/core/deprecations/core-deprecations-browser-mocks/*"], + "@kbn/core-deprecations-common": ["packages/core/deprecations/core-deprecations-common"], + "@kbn/core-deprecations-common/*": ["packages/core/deprecations/core-deprecations-common/*"], + "@kbn/core-deprecations-server": ["packages/core/deprecations/core-deprecations-server"], + "@kbn/core-deprecations-server/*": ["packages/core/deprecations/core-deprecations-server/*"], + "@kbn/core-deprecations-server-internal": ["packages/core/deprecations/core-deprecations-server-internal"], + "@kbn/core-deprecations-server-internal/*": ["packages/core/deprecations/core-deprecations-server-internal/*"], + "@kbn/core-deprecations-server-mocks": ["packages/core/deprecations/core-deprecations-server-mocks"], + "@kbn/core-deprecations-server-mocks/*": ["packages/core/deprecations/core-deprecations-server-mocks/*"], + "@kbn/core-doc-links-browser": ["packages/core/doc-links/core-doc-links-browser"], + "@kbn/core-doc-links-browser/*": ["packages/core/doc-links/core-doc-links-browser/*"], + "@kbn/core-doc-links-browser-internal": ["packages/core/doc-links/core-doc-links-browser-internal"], + "@kbn/core-doc-links-browser-internal/*": ["packages/core/doc-links/core-doc-links-browser-internal/*"], + "@kbn/core-doc-links-browser-mocks": ["packages/core/doc-links/core-doc-links-browser-mocks"], + "@kbn/core-doc-links-browser-mocks/*": ["packages/core/doc-links/core-doc-links-browser-mocks/*"], + "@kbn/core-doc-links-server": ["packages/core/doc-links/core-doc-links-server"], + "@kbn/core-doc-links-server/*": ["packages/core/doc-links/core-doc-links-server/*"], + "@kbn/core-doc-links-server-internal": ["packages/core/doc-links/core-doc-links-server-internal"], + "@kbn/core-doc-links-server-internal/*": ["packages/core/doc-links/core-doc-links-server-internal/*"], + "@kbn/core-doc-links-server-mocks": ["packages/core/doc-links/core-doc-links-server-mocks"], + "@kbn/core-doc-links-server-mocks/*": ["packages/core/doc-links/core-doc-links-server-mocks/*"], + "@kbn/core-elasticsearch-client-server-internal": ["packages/core/elasticsearch/core-elasticsearch-client-server-internal"], + "@kbn/core-elasticsearch-client-server-internal/*": ["packages/core/elasticsearch/core-elasticsearch-client-server-internal/*"], + "@kbn/core-elasticsearch-client-server-mocks": ["packages/core/elasticsearch/core-elasticsearch-client-server-mocks"], + "@kbn/core-elasticsearch-client-server-mocks/*": ["packages/core/elasticsearch/core-elasticsearch-client-server-mocks/*"], + "@kbn/core-elasticsearch-server": ["packages/core/elasticsearch/core-elasticsearch-server"], + "@kbn/core-elasticsearch-server/*": ["packages/core/elasticsearch/core-elasticsearch-server/*"], + "@kbn/core-elasticsearch-server-internal": ["packages/core/elasticsearch/core-elasticsearch-server-internal"], + "@kbn/core-elasticsearch-server-internal/*": ["packages/core/elasticsearch/core-elasticsearch-server-internal/*"], + "@kbn/core-elasticsearch-server-mocks": ["packages/core/elasticsearch/core-elasticsearch-server-mocks"], + "@kbn/core-elasticsearch-server-mocks/*": ["packages/core/elasticsearch/core-elasticsearch-server-mocks/*"], + "@kbn/core-environment-server-internal": ["packages/core/environment/core-environment-server-internal"], + "@kbn/core-environment-server-internal/*": ["packages/core/environment/core-environment-server-internal/*"], + "@kbn/core-environment-server-mocks": ["packages/core/environment/core-environment-server-mocks"], + "@kbn/core-environment-server-mocks/*": ["packages/core/environment/core-environment-server-mocks/*"], + "@kbn/core-execution-context-browser": ["packages/core/execution-context/core-execution-context-browser"], + "@kbn/core-execution-context-browser/*": ["packages/core/execution-context/core-execution-context-browser/*"], + "@kbn/core-execution-context-browser-internal": ["packages/core/execution-context/core-execution-context-browser-internal"], + "@kbn/core-execution-context-browser-internal/*": ["packages/core/execution-context/core-execution-context-browser-internal/*"], + "@kbn/core-execution-context-browser-mocks": ["packages/core/execution-context/core-execution-context-browser-mocks"], + "@kbn/core-execution-context-browser-mocks/*": ["packages/core/execution-context/core-execution-context-browser-mocks/*"], + "@kbn/core-execution-context-common": ["packages/core/execution-context/core-execution-context-common"], + "@kbn/core-execution-context-common/*": ["packages/core/execution-context/core-execution-context-common/*"], + "@kbn/core-execution-context-server": ["packages/core/execution-context/core-execution-context-server"], + "@kbn/core-execution-context-server/*": ["packages/core/execution-context/core-execution-context-server/*"], + "@kbn/core-execution-context-server-internal": ["packages/core/execution-context/core-execution-context-server-internal"], + "@kbn/core-execution-context-server-internal/*": ["packages/core/execution-context/core-execution-context-server-internal/*"], + "@kbn/core-execution-context-server-mocks": ["packages/core/execution-context/core-execution-context-server-mocks"], + "@kbn/core-execution-context-server-mocks/*": ["packages/core/execution-context/core-execution-context-server-mocks/*"], + "@kbn/core-fatal-errors-browser": ["packages/core/fatal-errors/core-fatal-errors-browser"], + "@kbn/core-fatal-errors-browser/*": ["packages/core/fatal-errors/core-fatal-errors-browser/*"], + "@kbn/core-fatal-errors-browser-internal": ["packages/core/fatal-errors/core-fatal-errors-browser-internal"], + "@kbn/core-fatal-errors-browser-internal/*": ["packages/core/fatal-errors/core-fatal-errors-browser-internal/*"], + "@kbn/core-fatal-errors-browser-mocks": ["packages/core/fatal-errors/core-fatal-errors-browser-mocks"], + "@kbn/core-fatal-errors-browser-mocks/*": ["packages/core/fatal-errors/core-fatal-errors-browser-mocks/*"], + "@kbn/core-http-browser": ["packages/core/http/core-http-browser"], + "@kbn/core-http-browser/*": ["packages/core/http/core-http-browser/*"], + "@kbn/core-http-browser-internal": ["packages/core/http/core-http-browser-internal"], + "@kbn/core-http-browser-internal/*": ["packages/core/http/core-http-browser-internal/*"], + "@kbn/core-http-browser-mocks": ["packages/core/http/core-http-browser-mocks"], + "@kbn/core-http-browser-mocks/*": ["packages/core/http/core-http-browser-mocks/*"], + "@kbn/core-http-common": ["packages/core/http/core-http-common"], + "@kbn/core-http-common/*": ["packages/core/http/core-http-common/*"], + "@kbn/core-http-context-server-internal": ["packages/core/http/core-http-context-server-internal"], + "@kbn/core-http-context-server-internal/*": ["packages/core/http/core-http-context-server-internal/*"], + "@kbn/core-http-context-server-mocks": ["packages/core/http/core-http-context-server-mocks"], + "@kbn/core-http-context-server-mocks/*": ["packages/core/http/core-http-context-server-mocks/*"], + "@kbn/core-http-request-handler-context-server": ["packages/core/http/core-http-request-handler-context-server"], + "@kbn/core-http-request-handler-context-server/*": ["packages/core/http/core-http-request-handler-context-server/*"], + "@kbn/core-http-request-handler-context-server-internal": ["packages/core/http/core-http-request-handler-context-server-internal"], + "@kbn/core-http-request-handler-context-server-internal/*": ["packages/core/http/core-http-request-handler-context-server-internal/*"], + "@kbn/core-http-resources-server": ["packages/core/http/core-http-resources-server"], + "@kbn/core-http-resources-server/*": ["packages/core/http/core-http-resources-server/*"], + "@kbn/core-http-resources-server-internal": ["packages/core/http/core-http-resources-server-internal"], + "@kbn/core-http-resources-server-internal/*": ["packages/core/http/core-http-resources-server-internal/*"], + "@kbn/core-http-resources-server-mocks": ["packages/core/http/core-http-resources-server-mocks"], + "@kbn/core-http-resources-server-mocks/*": ["packages/core/http/core-http-resources-server-mocks/*"], + "@kbn/core-http-router-server-internal": ["packages/core/http/core-http-router-server-internal"], + "@kbn/core-http-router-server-internal/*": ["packages/core/http/core-http-router-server-internal/*"], + "@kbn/core-http-router-server-mocks": ["packages/core/http/core-http-router-server-mocks"], + "@kbn/core-http-router-server-mocks/*": ["packages/core/http/core-http-router-server-mocks/*"], + "@kbn/core-http-server": ["packages/core/http/core-http-server"], + "@kbn/core-http-server/*": ["packages/core/http/core-http-server/*"], + "@kbn/core-http-server-internal": ["packages/core/http/core-http-server-internal"], + "@kbn/core-http-server-internal/*": ["packages/core/http/core-http-server-internal/*"], + "@kbn/core-http-server-mocks": ["packages/core/http/core-http-server-mocks"], + "@kbn/core-http-server-mocks/*": ["packages/core/http/core-http-server-mocks/*"], + "@kbn/core-i18n-browser": ["packages/core/i18n/core-i18n-browser"], + "@kbn/core-i18n-browser/*": ["packages/core/i18n/core-i18n-browser/*"], + "@kbn/core-i18n-browser-internal": ["packages/core/i18n/core-i18n-browser-internal"], + "@kbn/core-i18n-browser-internal/*": ["packages/core/i18n/core-i18n-browser-internal/*"], + "@kbn/core-i18n-browser-mocks": ["packages/core/i18n/core-i18n-browser-mocks"], + "@kbn/core-i18n-browser-mocks/*": ["packages/core/i18n/core-i18n-browser-mocks/*"], + "@kbn/core-i18n-server": ["packages/core/i18n/core-i18n-server"], + "@kbn/core-i18n-server/*": ["packages/core/i18n/core-i18n-server/*"], + "@kbn/core-i18n-server-internal": ["packages/core/i18n/core-i18n-server-internal"], + "@kbn/core-i18n-server-internal/*": ["packages/core/i18n/core-i18n-server-internal/*"], + "@kbn/core-i18n-server-mocks": ["packages/core/i18n/core-i18n-server-mocks"], + "@kbn/core-i18n-server-mocks/*": ["packages/core/i18n/core-i18n-server-mocks/*"], + "@kbn/core-injected-metadata-browser": ["packages/core/injected-metadata/core-injected-metadata-browser"], + "@kbn/core-injected-metadata-browser/*": ["packages/core/injected-metadata/core-injected-metadata-browser/*"], + "@kbn/core-injected-metadata-browser-internal": ["packages/core/injected-metadata/core-injected-metadata-browser-internal"], + "@kbn/core-injected-metadata-browser-internal/*": ["packages/core/injected-metadata/core-injected-metadata-browser-internal/*"], + "@kbn/core-injected-metadata-browser-mocks": ["packages/core/injected-metadata/core-injected-metadata-browser-mocks"], + "@kbn/core-injected-metadata-browser-mocks/*": ["packages/core/injected-metadata/core-injected-metadata-browser-mocks/*"], + "@kbn/core-injected-metadata-common-internal": ["packages/core/injected-metadata/core-injected-metadata-common-internal"], + "@kbn/core-injected-metadata-common-internal/*": ["packages/core/injected-metadata/core-injected-metadata-common-internal/*"], + "@kbn/core-integrations-browser-internal": ["packages/core/integrations/core-integrations-browser-internal"], + "@kbn/core-integrations-browser-internal/*": ["packages/core/integrations/core-integrations-browser-internal/*"], + "@kbn/core-integrations-browser-mocks": ["packages/core/integrations/core-integrations-browser-mocks"], + "@kbn/core-integrations-browser-mocks/*": ["packages/core/integrations/core-integrations-browser-mocks/*"], + "@kbn/core-lifecycle-browser": ["packages/core/lifecycle/core-lifecycle-browser"], + "@kbn/core-lifecycle-browser/*": ["packages/core/lifecycle/core-lifecycle-browser/*"], + "@kbn/core-lifecycle-browser-internal": ["packages/core/lifecycle/core-lifecycle-browser-internal"], + "@kbn/core-lifecycle-browser-internal/*": ["packages/core/lifecycle/core-lifecycle-browser-internal/*"], + "@kbn/core-lifecycle-browser-mocks": ["packages/core/lifecycle/core-lifecycle-browser-mocks"], + "@kbn/core-lifecycle-browser-mocks/*": ["packages/core/lifecycle/core-lifecycle-browser-mocks/*"], + "@kbn/core-lifecycle-server": ["packages/core/lifecycle/core-lifecycle-server"], + "@kbn/core-lifecycle-server/*": ["packages/core/lifecycle/core-lifecycle-server/*"], + "@kbn/core-lifecycle-server-internal": ["packages/core/lifecycle/core-lifecycle-server-internal"], + "@kbn/core-lifecycle-server-internal/*": ["packages/core/lifecycle/core-lifecycle-server-internal/*"], + "@kbn/core-lifecycle-server-mocks": ["packages/core/lifecycle/core-lifecycle-server-mocks"], + "@kbn/core-lifecycle-server-mocks/*": ["packages/core/lifecycle/core-lifecycle-server-mocks/*"], + "@kbn/core-logging-server": ["packages/core/logging/core-logging-server"], + "@kbn/core-logging-server/*": ["packages/core/logging/core-logging-server/*"], + "@kbn/core-logging-server-internal": ["packages/core/logging/core-logging-server-internal"], + "@kbn/core-logging-server-internal/*": ["packages/core/logging/core-logging-server-internal/*"], + "@kbn/core-logging-server-mocks": ["packages/core/logging/core-logging-server-mocks"], + "@kbn/core-logging-server-mocks/*": ["packages/core/logging/core-logging-server-mocks/*"], + "@kbn/core-metrics-collectors-server-internal": ["packages/core/metrics/core-metrics-collectors-server-internal"], + "@kbn/core-metrics-collectors-server-internal/*": ["packages/core/metrics/core-metrics-collectors-server-internal/*"], + "@kbn/core-metrics-collectors-server-mocks": ["packages/core/metrics/core-metrics-collectors-server-mocks"], + "@kbn/core-metrics-collectors-server-mocks/*": ["packages/core/metrics/core-metrics-collectors-server-mocks/*"], + "@kbn/core-metrics-server": ["packages/core/metrics/core-metrics-server"], + "@kbn/core-metrics-server/*": ["packages/core/metrics/core-metrics-server/*"], + "@kbn/core-metrics-server-internal": ["packages/core/metrics/core-metrics-server-internal"], + "@kbn/core-metrics-server-internal/*": ["packages/core/metrics/core-metrics-server-internal/*"], + "@kbn/core-metrics-server-mocks": ["packages/core/metrics/core-metrics-server-mocks"], + "@kbn/core-metrics-server-mocks/*": ["packages/core/metrics/core-metrics-server-mocks/*"], + "@kbn/core-mount-utils-browser": ["packages/core/mount-utils/core-mount-utils-browser"], + "@kbn/core-mount-utils-browser/*": ["packages/core/mount-utils/core-mount-utils-browser/*"], + "@kbn/core-mount-utils-browser-internal": ["packages/core/mount-utils/core-mount-utils-browser-internal"], + "@kbn/core-mount-utils-browser-internal/*": ["packages/core/mount-utils/core-mount-utils-browser-internal/*"], + "@kbn/core-node-server": ["packages/core/node/core-node-server"], + "@kbn/core-node-server/*": ["packages/core/node/core-node-server/*"], + "@kbn/core-node-server-internal": ["packages/core/node/core-node-server-internal"], + "@kbn/core-node-server-internal/*": ["packages/core/node/core-node-server-internal/*"], + "@kbn/core-node-server-mocks": ["packages/core/node/core-node-server-mocks"], + "@kbn/core-node-server-mocks/*": ["packages/core/node/core-node-server-mocks/*"], + "@kbn/core-notifications-browser": ["packages/core/notifications/core-notifications-browser"], + "@kbn/core-notifications-browser/*": ["packages/core/notifications/core-notifications-browser/*"], + "@kbn/core-notifications-browser-internal": ["packages/core/notifications/core-notifications-browser-internal"], + "@kbn/core-notifications-browser-internal/*": ["packages/core/notifications/core-notifications-browser-internal/*"], + "@kbn/core-notifications-browser-mocks": ["packages/core/notifications/core-notifications-browser-mocks"], + "@kbn/core-notifications-browser-mocks/*": ["packages/core/notifications/core-notifications-browser-mocks/*"], + "@kbn/core-overlays-browser": ["packages/core/overlays/core-overlays-browser"], + "@kbn/core-overlays-browser/*": ["packages/core/overlays/core-overlays-browser/*"], + "@kbn/core-overlays-browser-internal": ["packages/core/overlays/core-overlays-browser-internal"], + "@kbn/core-overlays-browser-internal/*": ["packages/core/overlays/core-overlays-browser-internal/*"], + "@kbn/core-overlays-browser-mocks": ["packages/core/overlays/core-overlays-browser-mocks"], + "@kbn/core-overlays-browser-mocks/*": ["packages/core/overlays/core-overlays-browser-mocks/*"], + "@kbn/core-plugins-base-server-internal": ["packages/core/plugins/core-plugins-base-server-internal"], + "@kbn/core-plugins-base-server-internal/*": ["packages/core/plugins/core-plugins-base-server-internal/*"], + "@kbn/core-plugins-browser": ["packages/core/plugins/core-plugins-browser"], + "@kbn/core-plugins-browser/*": ["packages/core/plugins/core-plugins-browser/*"], + "@kbn/core-plugins-browser-internal": ["packages/core/plugins/core-plugins-browser-internal"], + "@kbn/core-plugins-browser-internal/*": ["packages/core/plugins/core-plugins-browser-internal/*"], + "@kbn/core-plugins-browser-mocks": ["packages/core/plugins/core-plugins-browser-mocks"], + "@kbn/core-plugins-browser-mocks/*": ["packages/core/plugins/core-plugins-browser-mocks/*"], + "@kbn/core-plugins-server": ["packages/core/plugins/core-plugins-server"], + "@kbn/core-plugins-server/*": ["packages/core/plugins/core-plugins-server/*"], + "@kbn/core-plugins-server-internal": ["packages/core/plugins/core-plugins-server-internal"], + "@kbn/core-plugins-server-internal/*": ["packages/core/plugins/core-plugins-server-internal/*"], + "@kbn/core-plugins-server-mocks": ["packages/core/plugins/core-plugins-server-mocks"], + "@kbn/core-plugins-server-mocks/*": ["packages/core/plugins/core-plugins-server-mocks/*"], + "@kbn/core-preboot-server": ["packages/core/preboot/core-preboot-server"], + "@kbn/core-preboot-server/*": ["packages/core/preboot/core-preboot-server/*"], + "@kbn/core-preboot-server-internal": ["packages/core/preboot/core-preboot-server-internal"], + "@kbn/core-preboot-server-internal/*": ["packages/core/preboot/core-preboot-server-internal/*"], + "@kbn/core-preboot-server-mocks": ["packages/core/preboot/core-preboot-server-mocks"], + "@kbn/core-preboot-server-mocks/*": ["packages/core/preboot/core-preboot-server-mocks/*"], + "@kbn/core-rendering-browser-internal": ["packages/core/rendering/core-rendering-browser-internal"], + "@kbn/core-rendering-browser-internal/*": ["packages/core/rendering/core-rendering-browser-internal/*"], + "@kbn/core-rendering-browser-mocks": ["packages/core/rendering/core-rendering-browser-mocks"], + "@kbn/core-rendering-browser-mocks/*": ["packages/core/rendering/core-rendering-browser-mocks/*"], + "@kbn/core-rendering-server-internal": ["packages/core/rendering/core-rendering-server-internal"], + "@kbn/core-rendering-server-internal/*": ["packages/core/rendering/core-rendering-server-internal/*"], + "@kbn/core-rendering-server-mocks": ["packages/core/rendering/core-rendering-server-mocks"], + "@kbn/core-rendering-server-mocks/*": ["packages/core/rendering/core-rendering-server-mocks/*"], + "@kbn/core-root-browser-internal": ["packages/core/root/core-root-browser-internal"], + "@kbn/core-root-browser-internal/*": ["packages/core/root/core-root-browser-internal/*"], + "@kbn/core-saved-objects-api-browser": ["packages/core/saved-objects/core-saved-objects-api-browser"], + "@kbn/core-saved-objects-api-browser/*": ["packages/core/saved-objects/core-saved-objects-api-browser/*"], + "@kbn/core-saved-objects-api-server": ["packages/core/saved-objects/core-saved-objects-api-server"], + "@kbn/core-saved-objects-api-server/*": ["packages/core/saved-objects/core-saved-objects-api-server/*"], + "@kbn/core-saved-objects-api-server-internal": ["packages/core/saved-objects/core-saved-objects-api-server-internal"], + "@kbn/core-saved-objects-api-server-internal/*": ["packages/core/saved-objects/core-saved-objects-api-server-internal/*"], + "@kbn/core-saved-objects-api-server-mocks": ["packages/core/saved-objects/core-saved-objects-api-server-mocks"], + "@kbn/core-saved-objects-api-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-api-server-mocks/*"], + "@kbn/core-saved-objects-base-server-internal": ["packages/core/saved-objects/core-saved-objects-base-server-internal"], + "@kbn/core-saved-objects-base-server-internal/*": ["packages/core/saved-objects/core-saved-objects-base-server-internal/*"], + "@kbn/core-saved-objects-base-server-mocks": ["packages/core/saved-objects/core-saved-objects-base-server-mocks"], + "@kbn/core-saved-objects-base-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-base-server-mocks/*"], + "@kbn/core-saved-objects-browser": ["packages/core/saved-objects/core-saved-objects-browser"], + "@kbn/core-saved-objects-browser/*": ["packages/core/saved-objects/core-saved-objects-browser/*"], + "@kbn/core-saved-objects-browser-internal": ["packages/core/saved-objects/core-saved-objects-browser-internal"], + "@kbn/core-saved-objects-browser-internal/*": ["packages/core/saved-objects/core-saved-objects-browser-internal/*"], + "@kbn/core-saved-objects-browser-mocks": ["packages/core/saved-objects/core-saved-objects-browser-mocks"], + "@kbn/core-saved-objects-browser-mocks/*": ["packages/core/saved-objects/core-saved-objects-browser-mocks/*"], + "@kbn/core-saved-objects-common": ["packages/core/saved-objects/core-saved-objects-common"], + "@kbn/core-saved-objects-common/*": ["packages/core/saved-objects/core-saved-objects-common/*"], + "@kbn/core-saved-objects-import-export-server-internal": ["packages/core/saved-objects/core-saved-objects-import-export-server-internal"], + "@kbn/core-saved-objects-import-export-server-internal/*": ["packages/core/saved-objects/core-saved-objects-import-export-server-internal/*"], + "@kbn/core-saved-objects-import-export-server-mocks": ["packages/core/saved-objects/core-saved-objects-import-export-server-mocks"], + "@kbn/core-saved-objects-import-export-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-import-export-server-mocks/*"], + "@kbn/core-saved-objects-migration-server-internal": ["packages/core/saved-objects/core-saved-objects-migration-server-internal"], + "@kbn/core-saved-objects-migration-server-internal/*": ["packages/core/saved-objects/core-saved-objects-migration-server-internal/*"], + "@kbn/core-saved-objects-migration-server-mocks": ["packages/core/saved-objects/core-saved-objects-migration-server-mocks"], + "@kbn/core-saved-objects-migration-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-migration-server-mocks/*"], + "@kbn/core-saved-objects-server": ["packages/core/saved-objects/core-saved-objects-server"], + "@kbn/core-saved-objects-server/*": ["packages/core/saved-objects/core-saved-objects-server/*"], + "@kbn/core-saved-objects-server-internal": ["packages/core/saved-objects/core-saved-objects-server-internal"], + "@kbn/core-saved-objects-server-internal/*": ["packages/core/saved-objects/core-saved-objects-server-internal/*"], + "@kbn/core-saved-objects-server-mocks": ["packages/core/saved-objects/core-saved-objects-server-mocks"], + "@kbn/core-saved-objects-server-mocks/*": ["packages/core/saved-objects/core-saved-objects-server-mocks/*"], + "@kbn/core-saved-objects-utils-server": ["packages/core/saved-objects/core-saved-objects-utils-server"], + "@kbn/core-saved-objects-utils-server/*": ["packages/core/saved-objects/core-saved-objects-utils-server/*"], + "@kbn/core-status-common": ["packages/core/status/core-status-common"], + "@kbn/core-status-common/*": ["packages/core/status/core-status-common/*"], + "@kbn/core-status-common-internal": ["packages/core/status/core-status-common-internal"], + "@kbn/core-status-common-internal/*": ["packages/core/status/core-status-common-internal/*"], + "@kbn/core-status-server": ["packages/core/status/core-status-server"], + "@kbn/core-status-server/*": ["packages/core/status/core-status-server/*"], + "@kbn/core-status-server-internal": ["packages/core/status/core-status-server-internal"], + "@kbn/core-status-server-internal/*": ["packages/core/status/core-status-server-internal/*"], + "@kbn/core-status-server-mocks": ["packages/core/status/core-status-server-mocks"], + "@kbn/core-status-server-mocks/*": ["packages/core/status/core-status-server-mocks/*"], + "@kbn/core-test-helpers-deprecations-getters": ["packages/core/test-helpers/core-test-helpers-deprecations-getters"], + "@kbn/core-test-helpers-deprecations-getters/*": ["packages/core/test-helpers/core-test-helpers-deprecations-getters/*"], + "@kbn/core-test-helpers-http-setup-browser": ["packages/core/test-helpers/core-test-helpers-http-setup-browser"], + "@kbn/core-test-helpers-http-setup-browser/*": ["packages/core/test-helpers/core-test-helpers-http-setup-browser/*"], + "@kbn/core-test-helpers-so-type-serializer": ["packages/core/test-helpers/core-test-helpers-so-type-serializer"], + "@kbn/core-test-helpers-so-type-serializer/*": ["packages/core/test-helpers/core-test-helpers-so-type-serializer/*"], + "@kbn/core-test-helpers-test-utils": ["packages/core/test-helpers/core-test-helpers-test-utils"], + "@kbn/core-test-helpers-test-utils/*": ["packages/core/test-helpers/core-test-helpers-test-utils/*"], + "@kbn/core-theme-browser": ["packages/core/theme/core-theme-browser"], + "@kbn/core-theme-browser/*": ["packages/core/theme/core-theme-browser/*"], + "@kbn/core-theme-browser-internal": ["packages/core/theme/core-theme-browser-internal"], + "@kbn/core-theme-browser-internal/*": ["packages/core/theme/core-theme-browser-internal/*"], + "@kbn/core-theme-browser-mocks": ["packages/core/theme/core-theme-browser-mocks"], + "@kbn/core-theme-browser-mocks/*": ["packages/core/theme/core-theme-browser-mocks/*"], + "@kbn/core-ui-settings-browser": ["packages/core/ui-settings/core-ui-settings-browser"], + "@kbn/core-ui-settings-browser/*": ["packages/core/ui-settings/core-ui-settings-browser/*"], + "@kbn/core-ui-settings-browser-internal": ["packages/core/ui-settings/core-ui-settings-browser-internal"], + "@kbn/core-ui-settings-browser-internal/*": ["packages/core/ui-settings/core-ui-settings-browser-internal/*"], + "@kbn/core-ui-settings-browser-mocks": ["packages/core/ui-settings/core-ui-settings-browser-mocks"], + "@kbn/core-ui-settings-browser-mocks/*": ["packages/core/ui-settings/core-ui-settings-browser-mocks/*"], + "@kbn/core-ui-settings-common": ["packages/core/ui-settings/core-ui-settings-common"], + "@kbn/core-ui-settings-common/*": ["packages/core/ui-settings/core-ui-settings-common/*"], + "@kbn/core-ui-settings-server": ["packages/core/ui-settings/core-ui-settings-server"], + "@kbn/core-ui-settings-server/*": ["packages/core/ui-settings/core-ui-settings-server/*"], + "@kbn/core-ui-settings-server-internal": ["packages/core/ui-settings/core-ui-settings-server-internal"], + "@kbn/core-ui-settings-server-internal/*": ["packages/core/ui-settings/core-ui-settings-server-internal/*"], + "@kbn/core-ui-settings-server-mocks": ["packages/core/ui-settings/core-ui-settings-server-mocks"], + "@kbn/core-ui-settings-server-mocks/*": ["packages/core/ui-settings/core-ui-settings-server-mocks/*"], + "@kbn/core-usage-data-base-server-internal": ["packages/core/usage-data/core-usage-data-base-server-internal"], + "@kbn/core-usage-data-base-server-internal/*": ["packages/core/usage-data/core-usage-data-base-server-internal/*"], + "@kbn/core-usage-data-server": ["packages/core/usage-data/core-usage-data-server"], + "@kbn/core-usage-data-server/*": ["packages/core/usage-data/core-usage-data-server/*"], + "@kbn/core-usage-data-server-internal": ["packages/core/usage-data/core-usage-data-server-internal"], + "@kbn/core-usage-data-server-internal/*": ["packages/core/usage-data/core-usage-data-server-internal/*"], + "@kbn/core-usage-data-server-mocks": ["packages/core/usage-data/core-usage-data-server-mocks"], + "@kbn/core-usage-data-server-mocks/*": ["packages/core/usage-data/core-usage-data-server-mocks/*"], + "@kbn/home-sample-data-card": ["packages/home/sample_data_card"], + "@kbn/home-sample-data-card/*": ["packages/home/sample_data_card/*"], + "@kbn/home-sample-data-tab": ["packages/home/sample_data_tab"], + "@kbn/home-sample-data-tab/*": ["packages/home/sample_data_tab/*"], + "@kbn/home-sample-data-types": ["packages/home/sample_data_types"], + "@kbn/home-sample-data-types/*": ["packages/home/sample_data_types/*"], + "@kbn/ace": ["packages/kbn-ace"], + "@kbn/ace/*": ["packages/kbn-ace/*"], + "@kbn/alerts": ["packages/kbn-alerts"], + "@kbn/alerts/*": ["packages/kbn-alerts/*"], + "@kbn/ambient-storybook-types": ["packages/kbn-ambient-storybook-types"], + "@kbn/ambient-storybook-types/*": ["packages/kbn-ambient-storybook-types/*"], + "@kbn/ambient-ui-types": ["packages/kbn-ambient-ui-types"], + "@kbn/ambient-ui-types/*": ["packages/kbn-ambient-ui-types/*"], + "@kbn/analytics": ["packages/kbn-analytics"], + "@kbn/analytics/*": ["packages/kbn-analytics/*"], + "@kbn/apm-config-loader": ["packages/kbn-apm-config-loader"], + "@kbn/apm-config-loader/*": ["packages/kbn-apm-config-loader/*"], + "@kbn/apm-synthtrace": ["packages/kbn-apm-synthtrace"], + "@kbn/apm-synthtrace/*": ["packages/kbn-apm-synthtrace/*"], + "@kbn/apm-utils": ["packages/kbn-apm-utils"], + "@kbn/apm-utils/*": ["packages/kbn-apm-utils/*"], + "@kbn/axe-config": ["packages/kbn-axe-config"], + "@kbn/axe-config/*": ["packages/kbn-axe-config/*"], + "@kbn/babel-plugin-synthetic-packages": ["packages/kbn-babel-plugin-synthetic-packages"], + "@kbn/babel-plugin-synthetic-packages/*": ["packages/kbn-babel-plugin-synthetic-packages/*"], + "@kbn/babel-preset": ["packages/kbn-babel-preset"], + "@kbn/babel-preset/*": ["packages/kbn-babel-preset/*"], + "@kbn/bazel-packages": ["packages/kbn-bazel-packages"], + "@kbn/bazel-packages/*": ["packages/kbn-bazel-packages/*"], + "@kbn/bazel-runner": ["packages/kbn-bazel-runner"], + "@kbn/bazel-runner/*": ["packages/kbn-bazel-runner/*"], + "@kbn/cases-components": ["packages/kbn-cases-components"], + "@kbn/cases-components/*": ["packages/kbn-cases-components/*"], + "@kbn/chart-icons": ["packages/kbn-chart-icons"], + "@kbn/chart-icons/*": ["packages/kbn-chart-icons/*"], + "@kbn/ci-stats-core": ["packages/kbn-ci-stats-core"], + "@kbn/ci-stats-core/*": ["packages/kbn-ci-stats-core/*"], + "@kbn/ci-stats-performance-metrics": ["packages/kbn-ci-stats-performance-metrics"], + "@kbn/ci-stats-performance-metrics/*": ["packages/kbn-ci-stats-performance-metrics/*"], + "@kbn/ci-stats-reporter": ["packages/kbn-ci-stats-reporter"], + "@kbn/ci-stats-reporter/*": ["packages/kbn-ci-stats-reporter/*"], + "@kbn/cli-dev-mode": ["packages/kbn-cli-dev-mode"], + "@kbn/cli-dev-mode/*": ["packages/kbn-cli-dev-mode/*"], + "@kbn/coloring": ["packages/kbn-coloring"], + "@kbn/coloring/*": ["packages/kbn-coloring/*"], + "@kbn/config": ["packages/kbn-config"], + "@kbn/config/*": ["packages/kbn-config/*"], + "@kbn/config-mocks": ["packages/kbn-config-mocks"], + "@kbn/config-mocks/*": ["packages/kbn-config-mocks/*"], + "@kbn/config-schema": ["packages/kbn-config-schema"], + "@kbn/config-schema/*": ["packages/kbn-config-schema/*"], + "@kbn/crypto": ["packages/kbn-crypto"], + "@kbn/crypto/*": ["packages/kbn-crypto/*"], + "@kbn/crypto-browser": ["packages/kbn-crypto-browser"], + "@kbn/crypto-browser/*": ["packages/kbn-crypto-browser/*"], + "@kbn/datemath": ["packages/kbn-datemath"], + "@kbn/datemath/*": ["packages/kbn-datemath/*"], + "@kbn/dev-cli-errors": ["packages/kbn-dev-cli-errors"], + "@kbn/dev-cli-errors/*": ["packages/kbn-dev-cli-errors/*"], + "@kbn/dev-cli-runner": ["packages/kbn-dev-cli-runner"], + "@kbn/dev-cli-runner/*": ["packages/kbn-dev-cli-runner/*"], + "@kbn/dev-proc-runner": ["packages/kbn-dev-proc-runner"], + "@kbn/dev-proc-runner/*": ["packages/kbn-dev-proc-runner/*"], + "@kbn/dev-utils": ["packages/kbn-dev-utils"], + "@kbn/dev-utils/*": ["packages/kbn-dev-utils/*"], + "@kbn/doc-links": ["packages/kbn-doc-links"], + "@kbn/doc-links/*": ["packages/kbn-doc-links/*"], + "@kbn/docs-utils": ["packages/kbn-docs-utils"], + "@kbn/docs-utils/*": ["packages/kbn-docs-utils/*"], + "@kbn/ebt-tools": ["packages/kbn-ebt-tools"], + "@kbn/ebt-tools/*": ["packages/kbn-ebt-tools/*"], + "@kbn/es": ["packages/kbn-es"], + "@kbn/es/*": ["packages/kbn-es/*"], + "@kbn/es-archiver": ["packages/kbn-es-archiver"], + "@kbn/es-archiver/*": ["packages/kbn-es-archiver/*"], + "@kbn/es-errors": ["packages/kbn-es-errors"], + "@kbn/es-errors/*": ["packages/kbn-es-errors/*"], + "@kbn/es-query": ["packages/kbn-es-query"], + "@kbn/es-query/*": ["packages/kbn-es-query/*"], + "@kbn/es-types": ["packages/kbn-es-types"], + "@kbn/es-types/*": ["packages/kbn-es-types/*"], + "@kbn/eslint-config": ["packages/kbn-eslint-config"], + "@kbn/eslint-config/*": ["packages/kbn-eslint-config/*"], + "@kbn/eslint-plugin-disable": ["packages/kbn-eslint-plugin-disable"], + "@kbn/eslint-plugin-disable/*": ["packages/kbn-eslint-plugin-disable/*"], + "@kbn/eslint-plugin-eslint": ["packages/kbn-eslint-plugin-eslint"], + "@kbn/eslint-plugin-eslint/*": ["packages/kbn-eslint-plugin-eslint/*"], + "@kbn/eslint-plugin-imports": ["packages/kbn-eslint-plugin-imports"], + "@kbn/eslint-plugin-imports/*": ["packages/kbn-eslint-plugin-imports/*"], + "@kbn/expect": ["packages/kbn-expect"], + "@kbn/expect/*": ["packages/kbn-expect/*"], + "@kbn/failed-test-reporter-cli": ["packages/kbn-failed-test-reporter-cli"], + "@kbn/failed-test-reporter-cli/*": ["packages/kbn-failed-test-reporter-cli/*"], + "@kbn/field-types": ["packages/kbn-field-types"], + "@kbn/field-types/*": ["packages/kbn-field-types/*"], + "@kbn/find-used-node-modules": ["packages/kbn-find-used-node-modules"], + "@kbn/find-used-node-modules/*": ["packages/kbn-find-used-node-modules/*"], + "@kbn/flot-charts": ["packages/kbn-flot-charts"], + "@kbn/flot-charts/*": ["packages/kbn-flot-charts/*"], + "@kbn/ftr-common-functional-services": ["packages/kbn-ftr-common-functional-services"], + "@kbn/ftr-common-functional-services/*": ["packages/kbn-ftr-common-functional-services/*"], + "@kbn/ftr-screenshot-filename": ["packages/kbn-ftr-screenshot-filename"], + "@kbn/ftr-screenshot-filename/*": ["packages/kbn-ftr-screenshot-filename/*"], + "@kbn/generate": ["packages/kbn-generate"], + "@kbn/generate/*": ["packages/kbn-generate/*"], + "@kbn/get-repo-files": ["packages/kbn-get-repo-files"], + "@kbn/get-repo-files/*": ["packages/kbn-get-repo-files/*"], + "@kbn/guided-onboarding": ["packages/kbn-guided-onboarding"], + "@kbn/guided-onboarding/*": ["packages/kbn-guided-onboarding/*"], + "@kbn/handlebars": ["packages/kbn-handlebars"], + "@kbn/handlebars/*": ["packages/kbn-handlebars/*"], + "@kbn/hapi-mocks": ["packages/kbn-hapi-mocks"], + "@kbn/hapi-mocks/*": ["packages/kbn-hapi-mocks/*"], + "@kbn/i18n": ["packages/kbn-i18n"], + "@kbn/i18n/*": ["packages/kbn-i18n/*"], + "@kbn/i18n-react": ["packages/kbn-i18n-react"], + "@kbn/i18n-react/*": ["packages/kbn-i18n-react/*"], + "@kbn/import-resolver": ["packages/kbn-import-resolver"], + "@kbn/import-resolver/*": ["packages/kbn-import-resolver/*"], + "@kbn/interpreter": ["packages/kbn-interpreter"], + "@kbn/interpreter/*": ["packages/kbn-interpreter/*"], + "@kbn/io-ts-utils": ["packages/kbn-io-ts-utils"], + "@kbn/io-ts-utils/*": ["packages/kbn-io-ts-utils/*"], + "@kbn/jest-serializers": ["packages/kbn-jest-serializers"], + "@kbn/jest-serializers/*": ["packages/kbn-jest-serializers/*"], + "@kbn/journeys": ["packages/kbn-journeys"], + "@kbn/journeys/*": ["packages/kbn-journeys/*"], + "@kbn/kibana-manifest-schema": ["packages/kbn-kibana-manifest-schema"], + "@kbn/kibana-manifest-schema/*": ["packages/kbn-kibana-manifest-schema/*"], + "@kbn/language-documentation-popover": ["packages/kbn-language-documentation-popover"], + "@kbn/language-documentation-popover/*": ["packages/kbn-language-documentation-popover/*"], + "@kbn/logging": ["packages/kbn-logging"], + "@kbn/logging/*": ["packages/kbn-logging/*"], + "@kbn/logging-mocks": ["packages/kbn-logging-mocks"], + "@kbn/logging-mocks/*": ["packages/kbn-logging-mocks/*"], + "@kbn/managed-vscode-config": ["packages/kbn-managed-vscode-config"], + "@kbn/managed-vscode-config/*": ["packages/kbn-managed-vscode-config/*"], + "@kbn/managed-vscode-config-cli": ["packages/kbn-managed-vscode-config-cli"], + "@kbn/managed-vscode-config-cli/*": ["packages/kbn-managed-vscode-config-cli/*"], + "@kbn/mapbox-gl": ["packages/kbn-mapbox-gl"], + "@kbn/mapbox-gl/*": ["packages/kbn-mapbox-gl/*"], + "@kbn/monaco": ["packages/kbn-monaco"], + "@kbn/monaco/*": ["packages/kbn-monaco/*"], + "@kbn/optimizer": ["packages/kbn-optimizer"], + "@kbn/optimizer/*": ["packages/kbn-optimizer/*"], + "@kbn/optimizer-webpack-helpers": ["packages/kbn-optimizer-webpack-helpers"], + "@kbn/optimizer-webpack-helpers/*": ["packages/kbn-optimizer-webpack-helpers/*"], + "@kbn/osquery-io-ts-types": ["packages/kbn-osquery-io-ts-types"], + "@kbn/osquery-io-ts-types/*": ["packages/kbn-osquery-io-ts-types/*"], + "@kbn/performance-testing-dataset-extractor": ["packages/kbn-performance-testing-dataset-extractor"], + "@kbn/performance-testing-dataset-extractor/*": ["packages/kbn-performance-testing-dataset-extractor/*"], + "@kbn/plugin-discovery": ["packages/kbn-plugin-discovery"], + "@kbn/plugin-discovery/*": ["packages/kbn-plugin-discovery/*"], + "@kbn/plugin-generator": ["packages/kbn-plugin-generator"], + "@kbn/plugin-generator/*": ["packages/kbn-plugin-generator/*"], + "@kbn/plugin-helpers": ["packages/kbn-plugin-helpers"], + "@kbn/plugin-helpers/*": ["packages/kbn-plugin-helpers/*"], + "@kbn/react-field": ["packages/kbn-react-field"], + "@kbn/react-field/*": ["packages/kbn-react-field/*"], + "@kbn/repo-source-classifier": ["packages/kbn-repo-source-classifier"], + "@kbn/repo-source-classifier/*": ["packages/kbn-repo-source-classifier/*"], + "@kbn/repo-source-classifier-cli": ["packages/kbn-repo-source-classifier-cli"], + "@kbn/repo-source-classifier-cli/*": ["packages/kbn-repo-source-classifier-cli/*"], + "@kbn/rule-data-utils": ["packages/kbn-rule-data-utils"], + "@kbn/rule-data-utils/*": ["packages/kbn-rule-data-utils/*"], + "@kbn/safer-lodash-set": ["packages/kbn-safer-lodash-set"], + "@kbn/safer-lodash-set/*": ["packages/kbn-safer-lodash-set/*"], + "@kbn/securitysolution-autocomplete": ["packages/kbn-securitysolution-autocomplete"], + "@kbn/securitysolution-autocomplete/*": ["packages/kbn-securitysolution-autocomplete/*"], + "@kbn/securitysolution-es-utils": ["packages/kbn-securitysolution-es-utils"], + "@kbn/securitysolution-es-utils/*": ["packages/kbn-securitysolution-es-utils/*"], + "@kbn/securitysolution-exception-list-components": ["packages/kbn-securitysolution-exception-list-components"], + "@kbn/securitysolution-exception-list-components/*": ["packages/kbn-securitysolution-exception-list-components/*"], + "@kbn/securitysolution-hook-utils": ["packages/kbn-securitysolution-hook-utils"], + "@kbn/securitysolution-hook-utils/*": ["packages/kbn-securitysolution-hook-utils/*"], + "@kbn/securitysolution-io-ts-alerting-types": ["packages/kbn-securitysolution-io-ts-alerting-types"], + "@kbn/securitysolution-io-ts-alerting-types/*": ["packages/kbn-securitysolution-io-ts-alerting-types/*"], + "@kbn/securitysolution-io-ts-list-types": ["packages/kbn-securitysolution-io-ts-list-types"], + "@kbn/securitysolution-io-ts-list-types/*": ["packages/kbn-securitysolution-io-ts-list-types/*"], + "@kbn/securitysolution-io-ts-types": ["packages/kbn-securitysolution-io-ts-types"], + "@kbn/securitysolution-io-ts-types/*": ["packages/kbn-securitysolution-io-ts-types/*"], + "@kbn/securitysolution-io-ts-utils": ["packages/kbn-securitysolution-io-ts-utils"], + "@kbn/securitysolution-io-ts-utils/*": ["packages/kbn-securitysolution-io-ts-utils/*"], + "@kbn/securitysolution-list-api": ["packages/kbn-securitysolution-list-api"], + "@kbn/securitysolution-list-api/*": ["packages/kbn-securitysolution-list-api/*"], + "@kbn/securitysolution-list-constants": ["packages/kbn-securitysolution-list-constants"], + "@kbn/securitysolution-list-constants/*": ["packages/kbn-securitysolution-list-constants/*"], + "@kbn/securitysolution-list-hooks": ["packages/kbn-securitysolution-list-hooks"], + "@kbn/securitysolution-list-hooks/*": ["packages/kbn-securitysolution-list-hooks/*"], + "@kbn/securitysolution-list-utils": ["packages/kbn-securitysolution-list-utils"], + "@kbn/securitysolution-list-utils/*": ["packages/kbn-securitysolution-list-utils/*"], + "@kbn/securitysolution-rules": ["packages/kbn-securitysolution-rules"], + "@kbn/securitysolution-rules/*": ["packages/kbn-securitysolution-rules/*"], + "@kbn/securitysolution-t-grid": ["packages/kbn-securitysolution-t-grid"], + "@kbn/securitysolution-t-grid/*": ["packages/kbn-securitysolution-t-grid/*"], + "@kbn/securitysolution-utils": ["packages/kbn-securitysolution-utils"], + "@kbn/securitysolution-utils/*": ["packages/kbn-securitysolution-utils/*"], + "@kbn/server-http-tools": ["packages/kbn-server-http-tools"], + "@kbn/server-http-tools/*": ["packages/kbn-server-http-tools/*"], + "@kbn/server-route-repository": ["packages/kbn-server-route-repository"], + "@kbn/server-route-repository/*": ["packages/kbn-server-route-repository/*"], + "@kbn/shared-svg": ["packages/kbn-shared-svg"], + "@kbn/shared-svg/*": ["packages/kbn-shared-svg/*"], + "@kbn/shared-ux-utility": ["packages/kbn-shared-ux-utility"], + "@kbn/shared-ux-utility/*": ["packages/kbn-shared-ux-utility/*"], + "@kbn/some-dev-log": ["packages/kbn-some-dev-log"], + "@kbn/some-dev-log/*": ["packages/kbn-some-dev-log/*"], + "@kbn/sort-package-json": ["packages/kbn-sort-package-json"], + "@kbn/sort-package-json/*": ["packages/kbn-sort-package-json/*"], + "@kbn/spec-to-console": ["packages/kbn-spec-to-console"], + "@kbn/spec-to-console/*": ["packages/kbn-spec-to-console/*"], + "@kbn/std": ["packages/kbn-std"], + "@kbn/std/*": ["packages/kbn-std/*"], + "@kbn/stdio-dev-helpers": ["packages/kbn-stdio-dev-helpers"], + "@kbn/stdio-dev-helpers/*": ["packages/kbn-stdio-dev-helpers/*"], + "@kbn/storybook": ["packages/kbn-storybook"], + "@kbn/storybook/*": ["packages/kbn-storybook/*"], + "@kbn/synthetic-package-map": ["packages/kbn-synthetic-package-map"], + "@kbn/synthetic-package-map/*": ["packages/kbn-synthetic-package-map/*"], + "@kbn/telemetry-tools": ["packages/kbn-telemetry-tools"], + "@kbn/telemetry-tools/*": ["packages/kbn-telemetry-tools/*"], + "@kbn/test": ["packages/kbn-test"], + "@kbn/test/*": ["packages/kbn-test/*"], + "@kbn/test-jest-helpers": ["packages/kbn-test-jest-helpers"], + "@kbn/test-jest-helpers/*": ["packages/kbn-test-jest-helpers/*"], + "@kbn/test-subj-selector": ["packages/kbn-test-subj-selector"], + "@kbn/test-subj-selector/*": ["packages/kbn-test-subj-selector/*"], + "@kbn/timelion-grammar": ["packages/kbn-timelion-grammar"], + "@kbn/timelion-grammar/*": ["packages/kbn-timelion-grammar/*"], + "@kbn/tinymath": ["packages/kbn-tinymath"], + "@kbn/tinymath/*": ["packages/kbn-tinymath/*"], + "@kbn/tooling-log": ["packages/kbn-tooling-log"], + "@kbn/tooling-log/*": ["packages/kbn-tooling-log/*"], + "@kbn/type-summarizer": ["packages/kbn-type-summarizer"], + "@kbn/type-summarizer/*": ["packages/kbn-type-summarizer/*"], + "@kbn/type-summarizer-cli": ["packages/kbn-type-summarizer-cli"], + "@kbn/type-summarizer-cli/*": ["packages/kbn-type-summarizer-cli/*"], + "@kbn/type-summarizer-core": ["packages/kbn-type-summarizer-core"], + "@kbn/type-summarizer-core/*": ["packages/kbn-type-summarizer-core/*"], + "@kbn/typed-react-router-config": ["packages/kbn-typed-react-router-config"], + "@kbn/typed-react-router-config/*": ["packages/kbn-typed-react-router-config/*"], + "@kbn/ui-framework": ["packages/kbn-ui-framework"], + "@kbn/ui-framework/*": ["packages/kbn-ui-framework/*"], + "@kbn/ui-shared-deps-npm": ["packages/kbn-ui-shared-deps-npm"], + "@kbn/ui-shared-deps-npm/*": ["packages/kbn-ui-shared-deps-npm/*"], + "@kbn/ui-shared-deps-src": ["packages/kbn-ui-shared-deps-src"], + "@kbn/ui-shared-deps-src/*": ["packages/kbn-ui-shared-deps-src/*"], + "@kbn/ui-theme": ["packages/kbn-ui-theme"], + "@kbn/ui-theme/*": ["packages/kbn-ui-theme/*"], + "@kbn/user-profile-components": ["packages/kbn-user-profile-components"], + "@kbn/user-profile-components/*": ["packages/kbn-user-profile-components/*"], + "@kbn/utility-types": ["packages/kbn-utility-types"], + "@kbn/utility-types/*": ["packages/kbn-utility-types/*"], + "@kbn/utility-types-jest": ["packages/kbn-utility-types-jest"], + "@kbn/utility-types-jest/*": ["packages/kbn-utility-types-jest/*"], + "@kbn/utils": ["packages/kbn-utils"], + "@kbn/utils/*": ["packages/kbn-utils/*"], + "@kbn/yarn-lock-validator": ["packages/kbn-yarn-lock-validator"], + "@kbn/yarn-lock-validator/*": ["packages/kbn-yarn-lock-validator/*"], + "@kbn/shared-ux-avatar-solution": ["packages/shared-ux/avatar/solution"], + "@kbn/shared-ux-avatar-solution/*": ["packages/shared-ux/avatar/solution/*"], + "@kbn/shared-ux-avatar-user-profile-components": ["packages/shared-ux/avatar/user_profile/impl"], + "@kbn/shared-ux-avatar-user-profile-components/*": ["packages/shared-ux/avatar/user_profile/impl/*"], + "@kbn/shared-ux-button-toolbar": ["packages/shared-ux/button_toolbar"], + "@kbn/shared-ux-button-toolbar/*": ["packages/shared-ux/button_toolbar/*"], + "@kbn/shared-ux-button-exit-full-screen": ["packages/shared-ux/button/exit_full_screen/impl"], + "@kbn/shared-ux-button-exit-full-screen/*": ["packages/shared-ux/button/exit_full_screen/impl/*"], + "@kbn/shared-ux-button-exit-full-screen-mocks": ["packages/shared-ux/button/exit_full_screen/mocks"], + "@kbn/shared-ux-button-exit-full-screen-mocks/*": ["packages/shared-ux/button/exit_full_screen/mocks/*"], + "@kbn/shared-ux-button-exit-full-screen-types": ["packages/shared-ux/button/exit_full_screen/types"], + "@kbn/shared-ux-button-exit-full-screen-types/*": ["packages/shared-ux/button/exit_full_screen/types/*"], + "@kbn/shared-ux-card-no-data": ["packages/shared-ux/card/no_data/impl"], + "@kbn/shared-ux-card-no-data/*": ["packages/shared-ux/card/no_data/impl/*"], + "@kbn/shared-ux-card-no-data-mocks": ["packages/shared-ux/card/no_data/mocks"], + "@kbn/shared-ux-card-no-data-mocks/*": ["packages/shared-ux/card/no_data/mocks/*"], + "@kbn/shared-ux-card-no-data-types": ["packages/shared-ux/card/no_data/types"], + "@kbn/shared-ux-card-no-data-types/*": ["packages/shared-ux/card/no_data/types/*"], + "@kbn/shared-ux-link-redirect-app": ["packages/shared-ux/link/redirect_app/impl"], + "@kbn/shared-ux-link-redirect-app/*": ["packages/shared-ux/link/redirect_app/impl/*"], + "@kbn/shared-ux-link-redirect-app-mocks": ["packages/shared-ux/link/redirect_app/mocks"], + "@kbn/shared-ux-link-redirect-app-mocks/*": ["packages/shared-ux/link/redirect_app/mocks/*"], + "@kbn/shared-ux-link-redirect-app-types": ["packages/shared-ux/link/redirect_app/types"], + "@kbn/shared-ux-link-redirect-app-types/*": ["packages/shared-ux/link/redirect_app/types/*"], + "@kbn/shared-ux-markdown": ["packages/shared-ux/markdown/impl"], + "@kbn/shared-ux-markdown/*": ["packages/shared-ux/markdown/impl/*"], + "@kbn/shared-ux-markdown-mocks": ["packages/shared-ux/markdown/mocks"], + "@kbn/shared-ux-markdown-mocks/*": ["packages/shared-ux/markdown/mocks/*"], + "@kbn/shared-ux-markdown-types": ["packages/shared-ux/markdown/types"], + "@kbn/shared-ux-markdown-types/*": ["packages/shared-ux/markdown/types/*"], + "@kbn/shared-ux-page-analytics-no-data": ["packages/shared-ux/page/analytics_no_data/impl"], + "@kbn/shared-ux-page-analytics-no-data/*": ["packages/shared-ux/page/analytics_no_data/impl/*"], + "@kbn/shared-ux-page-analytics-no-data-mocks": ["packages/shared-ux/page/analytics_no_data/mocks"], + "@kbn/shared-ux-page-analytics-no-data-mocks/*": ["packages/shared-ux/page/analytics_no_data/mocks/*"], + "@kbn/shared-ux-page-analytics-no-data-types": ["packages/shared-ux/page/analytics_no_data/types"], + "@kbn/shared-ux-page-analytics-no-data-types/*": ["packages/shared-ux/page/analytics_no_data/types/*"], + "@kbn/shared-ux-page-kibana-no-data": ["packages/shared-ux/page/kibana_no_data/impl"], + "@kbn/shared-ux-page-kibana-no-data/*": ["packages/shared-ux/page/kibana_no_data/impl/*"], + "@kbn/shared-ux-page-kibana-no-data-mocks": ["packages/shared-ux/page/kibana_no_data/mocks"], + "@kbn/shared-ux-page-kibana-no-data-mocks/*": ["packages/shared-ux/page/kibana_no_data/mocks/*"], + "@kbn/shared-ux-page-kibana-no-data-types": ["packages/shared-ux/page/kibana_no_data/types"], + "@kbn/shared-ux-page-kibana-no-data-types/*": ["packages/shared-ux/page/kibana_no_data/types/*"], + "@kbn/shared-ux-page-kibana-template": ["packages/shared-ux/page/kibana_template/impl"], + "@kbn/shared-ux-page-kibana-template/*": ["packages/shared-ux/page/kibana_template/impl/*"], + "@kbn/shared-ux-page-kibana-template-mocks": ["packages/shared-ux/page/kibana_template/mocks"], + "@kbn/shared-ux-page-kibana-template-mocks/*": ["packages/shared-ux/page/kibana_template/mocks/*"], + "@kbn/shared-ux-page-kibana-template-types": ["packages/shared-ux/page/kibana_template/types"], + "@kbn/shared-ux-page-kibana-template-types/*": ["packages/shared-ux/page/kibana_template/types/*"], + "@kbn/shared-ux-page-no-data-config": ["packages/shared-ux/page/no_data_config/impl"], + "@kbn/shared-ux-page-no-data-config/*": ["packages/shared-ux/page/no_data_config/impl/*"], + "@kbn/shared-ux-page-no-data-config-mocks": ["packages/shared-ux/page/no_data_config/mocks"], + "@kbn/shared-ux-page-no-data-config-mocks/*": ["packages/shared-ux/page/no_data_config/mocks/*"], + "@kbn/shared-ux-page-no-data-config-types": ["packages/shared-ux/page/no_data_config/types"], + "@kbn/shared-ux-page-no-data-config-types/*": ["packages/shared-ux/page/no_data_config/types/*"], + "@kbn/shared-ux-page-no-data": ["packages/shared-ux/page/no_data/impl"], + "@kbn/shared-ux-page-no-data/*": ["packages/shared-ux/page/no_data/impl/*"], + "@kbn/shared-ux-page-no-data-mocks": ["packages/shared-ux/page/no_data/mocks"], + "@kbn/shared-ux-page-no-data-mocks/*": ["packages/shared-ux/page/no_data/mocks/*"], + "@kbn/shared-ux-page-no-data-types": ["packages/shared-ux/page/no_data/types"], + "@kbn/shared-ux-page-no-data-types/*": ["packages/shared-ux/page/no_data/types/*"], + "@kbn/shared-ux-page-solution-nav": ["packages/shared-ux/page/solution_nav"], + "@kbn/shared-ux-page-solution-nav/*": ["packages/shared-ux/page/solution_nav/*"], + "@kbn/shared-ux-prompt-no-data-views": ["packages/shared-ux/prompt/no_data_views/impl"], + "@kbn/shared-ux-prompt-no-data-views/*": ["packages/shared-ux/prompt/no_data_views/impl/*"], + "@kbn/shared-ux-prompt-no-data-views-mocks": ["packages/shared-ux/prompt/no_data_views/mocks"], + "@kbn/shared-ux-prompt-no-data-views-mocks/*": ["packages/shared-ux/prompt/no_data_views/mocks/*"], + "@kbn/shared-ux-prompt-no-data-views-types": ["packages/shared-ux/prompt/no_data_views/types"], + "@kbn/shared-ux-prompt-no-data-views-types/*": ["packages/shared-ux/prompt/no_data_views/types/*"], + "@kbn/shared-ux-router": ["packages/shared-ux/router/impl"], + "@kbn/shared-ux-router/*": ["packages/shared-ux/router/impl/*"], + "@kbn/shared-ux-router-mocks": ["packages/shared-ux/router/mocks"], + "@kbn/shared-ux-router-mocks/*": ["packages/shared-ux/router/mocks/*"], + "@kbn/shared-ux-router-types": ["packages/shared-ux/router/types"], + "@kbn/shared-ux-router-types/*": ["packages/shared-ux/router/types/*"], + "@kbn/shared-ux-storybook-config": ["packages/shared-ux/storybook/config"], + "@kbn/shared-ux-storybook-config/*": ["packages/shared-ux/storybook/config/*"], + "@kbn/shared-ux-storybook-mock": ["packages/shared-ux/storybook/mock"], + "@kbn/shared-ux-storybook-mock/*": ["packages/shared-ux/storybook/mock/*"], + "@kbn/ml-agg-utils": ["x-pack/packages/ml/agg_utils"], + "@kbn/ml-agg-utils/*": ["x-pack/packages/ml/agg_utils/*"], + "@kbn/aiops-components": ["x-pack/packages/ml/aiops_components"], + "@kbn/aiops-components/*": ["x-pack/packages/ml/aiops_components/*"], + "@kbn/aiops-utils": ["x-pack/packages/ml/aiops_utils"], + "@kbn/aiops-utils/*": ["x-pack/packages/ml/aiops_utils/*"], + "@kbn/ml-is-populated-object": ["x-pack/packages/ml/is_populated_object"], + "@kbn/ml-is-populated-object/*": ["x-pack/packages/ml/is_populated_object/*"], + "@kbn/ml-string-hash": ["x-pack/packages/ml/string_hash"], + "@kbn/ml-string-hash/*": ["x-pack/packages/ml/string_hash/*"], "@kbn/bfetch-explorer-plugin": ["examples/bfetch_explorer"], "@kbn/bfetch-explorer-plugin/*": ["examples/bfetch_explorer/*"], "@kbn/dashboard-embeddable-examples-plugin": ["examples/dashboard_embeddable_examples"], @@ -278,6 +974,10 @@ "@kbn/ui-settings-plugin/*": ["test/plugin_functional/plugins/ui_settings_plugin/*"], "@kbn/usage-collection-test-plugin": ["test/plugin_functional/plugins/usage_collection"], "@kbn/usage-collection-test-plugin/*": ["test/plugin_functional/plugins/usage_collection/*"], + "@kbn/status-plugin-a-plugin": ["test/server_integration/__fixtures__/plugins/status_plugin_a"], + "@kbn/status-plugin-a-plugin/*": ["test/server_integration/__fixtures__/plugins/status_plugin_a/*"], + "@kbn/status-plugin-b-plugin": ["test/server_integration/__fixtures__/plugins/status_plugin_b"], + "@kbn/status-plugin-b-plugin/*": ["test/server_integration/__fixtures__/plugins/status_plugin_b/*"], "@kbn/alerting-example-plugin": ["x-pack/examples/alerting_example"], "@kbn/alerting-example-plugin/*": ["x-pack/examples/alerting_example/*"], "@kbn/embedded-lens-example-plugin": ["x-pack/examples/embedded_lens_example"], From cb3f976e5eb7516af41dba9b4a4e98c3f2b23384 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 31 Oct 2022 13:18:15 -0500 Subject: [PATCH 08/85] Fix types --- .../alerting/server/rules_client/rules_client.ts | 6 +++--- .../normalization/rule_converters.ts | 4 ++-- .../rule_schema/model/rule_schemas.ts | 16 ++++++++++++++-- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 6485572397b17..850f55f3559c6 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -387,8 +387,8 @@ export interface UpdateOptions { schedule: IntervalSchedule; actions: NormalizedAlertAction[]; params: Params; - throttle: string | null; - notifyWhen: RuleNotifyWhenType | null; + throttle?: string | null; + notifyWhen?: RuleNotifyWhenType | null; }; } @@ -1661,7 +1661,7 @@ export class RulesClient { } const apiKeyAttributes = this.apiKeyAsAlertAttributes(createdAPIKey, username); - const notifyWhen = getRuleNotifyWhenType(data.notifyWhen, data.throttle); + const notifyWhen = getRuleNotifyWhenType(data.notifyWhen ?? null, data.throttle ?? null); let updatedObject: SavedObject; const createAttributes = this.updateMeta({ diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.ts index 82d6ee6b1c4b2..628e74287cc46 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_converters.ts @@ -462,10 +462,10 @@ export const convertPatchAPIToInternalSchema = ( : existingRule.actions, throttle: nextParams.throttle ? transformToAlertThrottle(nextParams.throttle) - : existingRule.throttle, + : existingRule.throttle ?? null, notifyWhen: nextParams.throttle ? transformToNotifyWhen(nextParams.throttle) - : existingRule.notifyWhen, + : existingRule.notifyWhen ?? null, }; }; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts index 0e64cc3788a12..357398c28c87f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts @@ -274,7 +274,7 @@ export const allRuleTypes = t.union([ t.literal(NEW_TERMS_RULE_TYPE_ID), ]); -export const internalRuleCreate = t.type({ +const internalRuleCreateRequired = t.type({ name: RuleName, tags: RuleTagArray, alertTypeId: allRuleTypes, @@ -285,12 +285,18 @@ export const internalRuleCreate = t.type({ enabled: IsRuleEnabled, actions: RuleActionArrayCamel, params: ruleParams, +}); +const internalRuleCreateOptional = t.type({ throttle: t.union([RuleActionThrottle, t.null]), notifyWhen, }); +export const internalRuleCreate = t.intersection([ + internalRuleCreateOptional, + internalRuleCreateRequired, +]); export type InternalRuleCreate = t.TypeOf; -export const internalRuleUpdate = t.type({ +const internalRuleUpdateRequired = t.type({ name: RuleName, tags: RuleTagArray, schedule: t.type({ @@ -298,7 +304,13 @@ export const internalRuleUpdate = t.type({ }), actions: RuleActionArrayCamel, params: ruleParams, +}); +const internalRuleUpdateOptional = t.type({ throttle: t.union([RuleActionThrottle, t.null]), notifyWhen, }); +export const internalRuleUpdate = t.intersection([ + internalRuleUpdateOptional, + internalRuleUpdateRequired, +]); export type InternalRuleUpdate = t.TypeOf; From 77711c2f6322cc0809995c548d5f01dfa39ffa5f Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 31 Oct 2022 13:23:57 -0500 Subject: [PATCH 09/85] Fix jest --- x-pack/plugins/alerting/server/routes/legacy/create.ts | 2 +- x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/alerting/server/routes/legacy/create.ts b/x-pack/plugins/alerting/server/routes/legacy/create.ts index 331cc4734f4f1..e658a2e5cfee5 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/create.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/create.ts @@ -71,7 +71,7 @@ export const createAlertRoute = ({ router, licenseState, usageCounter }: RouteOp try { const alertRes: SanitizedRule = await rulesClient.create({ - data: { ...alert, notifyWhen, actions: rewriteActions(alert.actions) }, + data: { ...alert, notifyWhen, actions: rewriteActions(alert?.actions) }, options: { id: params?.id }, }); return res.ok({ diff --git a/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts b/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts index 669cb2c3cfe51..37b39548c610f 100644 --- a/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts +++ b/x-pack/plugins/alerting/server/routes/lib/rewrite_actions.ts @@ -15,12 +15,13 @@ type ReqRuleAction = Omit & { }; }; export const rewriteActions: ( - actions: ReqRuleAction[] + actions?: ReqRuleAction[] ) => Array> = (actions) => { const rewriteFrequency: RewriteRequestCase> = ({ notify_when: notifyWhen, ...rest }) => ({ ...rest, notifyWhen }); + if (!actions) return []; return actions.map( (action) => ({ From 2abc7ae37d0c53574bd16553ff208be4555294c2 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 31 Oct 2022 14:08:48 -0500 Subject: [PATCH 10/85] Fix validating global freq params --- .../plugins/alerting/server/rules_client/rules_client.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 850f55f3559c6..08ad4832dcdf6 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -568,7 +568,8 @@ export class RulesClient { throw Boom.badRequest(`Error creating rule: could not create API key - ${error.message}`); } - const usesGlobalFreqParams = Boolean(data.notifyWhen && data.throttle); + const usesGlobalFreqParams = + typeof data.notifyWhen !== 'undefined' && typeof data.throttle !== 'undefined'; await this.validateActions(ruleType, data.actions, usesGlobalFreqParams); // Throw error if schedule interval is less than the minimum and we are enforcing it @@ -1631,7 +1632,8 @@ export class RulesClient { // Validate const validatedAlertTypeParams = validateRuleTypeParams(data.params, ruleType.validate?.params); - const usesGlobalFreqParams = Boolean(data.notifyWhen && data.throttle); + const usesGlobalFreqParams = + typeof data.notifyWhen !== 'undefined' && typeof data.throttle !== 'undefined'; await this.validateActions(ruleType, data.actions, usesGlobalFreqParams); // Throw error if schedule interval is less than the minimum and we are enforcing it @@ -2154,7 +2156,8 @@ export class RulesClient { switch (operation.field) { case 'actions': const usesGlobalFreqParams = Boolean( - attributes.notifyWhen && attributes.throttle + typeof attributes.notifyWhen !== 'undefined' && + typeof attributes.throttle !== 'undefined' ); await this.validateActions(ruleType, operation.value, usesGlobalFreqParams); ruleActions = applyBulkEditOperation(operation, ruleActions); From 66810ae74345f71343da91be79a195eea388bd69 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 31 Oct 2022 16:15:21 -0500 Subject: [PATCH 11/85] Add tests for create and edit --- .../server/rules_client/rules_client.ts | 6 +- .../server/rules_client/tests/create.test.ts | 159 ++++++++++++++++ .../server/rules_client/tests/update.test.ts | 170 ++++++++++++++++++ 3 files changed, 332 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 08ad4832dcdf6..fc0d62eff7bab 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -3484,9 +3484,9 @@ export class RulesClient { throw Boom.badRequest( i18n.translate('xpack.alerting.rulesClient.validateActions.mixAndMatchFreqParams', { defaultMessage: - 'Cannot mix and match per-action frequency params when notify_when and throttle are globally defined: {groups}', + 'Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: {groups}', values: { - groups: actionsWithFrequency.join(', '), + groups: actionsWithFrequency.map((a) => a.group).join(', '), }, }) ); @@ -3498,7 +3498,7 @@ export class RulesClient { i18n.translate('xpack.alerting.rulesClient.validateActions.notAllActionsWithFreq', { defaultMessage: 'Actions missing frequency parameters: {groups}', values: { - groups: actionsWithoutFrequency.join(', '), + groups: actionsWithoutFrequency.map((a) => a.group).join(', '), }, }) ); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index f5192bf6cbe65..d71b74a3f1211 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -2631,4 +2631,163 @@ describe('create()', () => { expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); }); + + test('throws error when mixing and matching global and per-action frequency values', async () => { + rulesClient = new RulesClient({ + ...rulesClientParams, + minimumScheduleInterval: { value: '1m', enforce: true }, + }); + ruleTypeRegistry.get.mockImplementation(() => ({ + id: '123', + name: 'Test', + actionGroups: [{ id: 'default', name: 'Default' }], + recoveryActionGroup: RecoveredActionGroup, + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + async executor() {}, + producer: 'alerts', + useSavedObjectReferences: { + extractReferences: jest.fn(), + injectReferences: jest.fn(), + }, + })); + + const data = getMockData({ + notifyWhen: 'onActionGroupChange', + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + { + group: 'default', + id: '2', + params: { + foo: true, + }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + ], + }); + await expect(rulesClient.create({ data })).rejects.toThrowErrorMatchingInlineSnapshot( + `"Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: default, default"` + ); + expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); + expect(taskManager.schedule).not.toHaveBeenCalled(); + + const data2 = getMockData({ + notifyWhen: null, + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + { + group: 'default', + id: '2', + params: { + foo: true, + }, + }, + ], + }); + await expect(rulesClient.create({ data: data2 })).rejects.toThrowErrorMatchingInlineSnapshot( + `"Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: default"` + ); + expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); + expect(taskManager.schedule).not.toHaveBeenCalled(); + }); + + test('throws error when neither global frequency nor action frequency are defined', async () => { + rulesClient = new RulesClient({ + ...rulesClientParams, + minimumScheduleInterval: { value: '1m', enforce: true }, + }); + ruleTypeRegistry.get.mockImplementation(() => ({ + id: '123', + name: 'Test', + actionGroups: [{ id: 'default', name: 'Default' }], + recoveryActionGroup: RecoveredActionGroup, + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + async executor() {}, + producer: 'alerts', + useSavedObjectReferences: { + extractReferences: jest.fn(), + injectReferences: jest.fn(), + }, + })); + + const data = getMockData({ + notifyWhen: undefined, + throttle: undefined, + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + { + group: 'default', + id: '2', + params: { + foo: true, + }, + }, + ], + }); + await expect(rulesClient.create({ data })).rejects.toThrowErrorMatchingInlineSnapshot( + `"Actions missing frequency parameters: default"` + ); + expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); + expect(taskManager.schedule).not.toHaveBeenCalled(); + + const data2 = getMockData({ + notifyWhen: undefined, + throttle: undefined, + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + }, + ], + }); + await expect(rulesClient.create({ data: data2 })).rejects.toThrowErrorMatchingInlineSnapshot( + `"Actions missing frequency parameters: default"` + ); + expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); + expect(taskManager.schedule).not.toHaveBeenCalled(); + }); }); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index 9071099ed3aaf..817553d1ef151 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -1652,6 +1652,176 @@ describe('update()', () => { expect(taskManager.bulkUpdateSchedules).not.toHaveBeenCalled(); }); + test('throws error when mixing and matching global and per-action frequency values', async () => { + const alertId = uuid.v4(); + const taskId = uuid.v4(); + + mockApiCalls(alertId, taskId, { interval: '1m' }, { interval: '1m' }); + await expect( + rulesClient.update({ + id: alertId, + data: { + schedule: { interval: '1m' }, + name: 'abc', + tags: ['foo'], + params: { + bar: true, + }, + throttle: null, + notifyWhen: 'onActionGroupChange', + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + { + group: 'default', + id: '2', + params: { + foo: true, + }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + ], + }, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: default, default"` + ); + expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); + expect(taskManager.schedule).not.toHaveBeenCalled(); + + await expect( + rulesClient.update({ + id: alertId, + data: { + schedule: { interval: '1m' }, + name: 'abc', + tags: ['foo'], + params: { + bar: true, + }, + throttle: null, + notifyWhen: null, + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + { + group: 'default', + id: '2', + params: { + foo: true, + }, + }, + ], + }, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: default"` + ); + expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); + expect(taskManager.schedule).not.toHaveBeenCalled(); + }); + + test('throws error when neither global frequency nor action frequency are defined', async () => { + const alertId = uuid.v4(); + const taskId = uuid.v4(); + + mockApiCalls(alertId, taskId, { interval: '1m' }, { interval: '1m' }); + + await expect( + rulesClient.update({ + id: alertId, + data: { + schedule: { interval: '1m' }, + name: 'abc', + tags: ['foo'], + params: { + bar: true, + }, + notifyWhen: undefined, + throttle: undefined, + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + { + group: 'default', + id: '2', + params: { + foo: true, + }, + }, + ], + }, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Actions missing frequency parameters: default"` + ); + expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); + expect(taskManager.schedule).not.toHaveBeenCalled(); + + await expect( + rulesClient.update({ + id: alertId, + data: { + schedule: { interval: '1m' }, + name: 'abc', + tags: ['foo'], + params: { + bar: true, + }, + notifyWhen: undefined, + throttle: undefined, + actions: [ + { + group: 'default', + id: '1', + params: { + foo: true, + }, + }, + ], + }, + }) + ).rejects.toThrowErrorMatchingInlineSnapshot( + `"Actions missing frequency parameters: default"` + ); + expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); + expect(taskManager.schedule).not.toHaveBeenCalled(); + }); + test('logs when update of schedule of an alerts underlying task fails', async () => { const alertId = uuid.v4(); const taskId = uuid.v4(); From 20d49838d6654538b8abab6ef1c3ff477e38bc6a Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 2 Nov 2022 15:49:14 -0500 Subject: [PATCH 12/85] Reset legacy api --- .../alerting/server/routes/legacy/create.ts | 14 +++++++++++--- .../alerting/server/routes/legacy/update.ts | 13 ++++++++++--- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/alerting/server/routes/legacy/create.ts b/x-pack/plugins/alerting/server/routes/legacy/create.ts index e658a2e5cfee5..e7583033ae4ba 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/create.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/create.ts @@ -18,7 +18,7 @@ import { } from '../../types'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { RouteOptions } from '..'; -import { countUsageOfPredefinedIds, actionsSchema, rewriteActions } from '../lib'; +import { countUsageOfPredefinedIds } from '../lib'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; export const bodySchema = schema.object({ @@ -32,7 +32,15 @@ export const bodySchema = schema.object({ schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), }), - actions: actionsSchema, + actions: schema.arrayOf( + schema.object({ + group: schema.string(), + id: schema.string(), + actionTypeId: schema.maybe(schema.string()), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + }), + { defaultValue: [] } + ), notifyWhen: schema.nullable(schema.string({ validate: validateNotifyWhenType })), }); @@ -71,7 +79,7 @@ export const createAlertRoute = ({ router, licenseState, usageCounter }: RouteOp try { const alertRes: SanitizedRule = await rulesClient.create({ - data: { ...alert, notifyWhen, actions: rewriteActions(alert?.actions) }, + data: { ...alert, notifyWhen }, options: { id: params?.id }, }); return res.ok({ diff --git a/x-pack/plugins/alerting/server/routes/legacy/update.ts b/x-pack/plugins/alerting/server/routes/legacy/update.ts index 065c69e4d5d68..07bde524076c1 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update.ts @@ -14,7 +14,6 @@ import { validateDurationSchema } from '../../lib'; import { handleDisabledApiKeysError } from '../lib/error_handler'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; -import { actionsSchema, rewriteActions } from '../lib'; import { RuleNotifyWhenType, LEGACY_BASE_ALERT_API_PATH, @@ -33,7 +32,15 @@ const bodySchema = schema.object({ }), throttle: schema.nullable(schema.string({ validate: validateDurationSchema })), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - actions: actionsSchema, + actions: schema.arrayOf( + schema.object({ + group: schema.string(), + id: schema.string(), + params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + actionTypeId: schema.maybe(schema.string()), + }), + { defaultValue: [] } + ), notifyWhen: schema.nullable(schema.string({ validate: validateNotifyWhenType })), }); @@ -65,7 +72,7 @@ export const updateAlertRoute = ( id, data: { name, - actions: rewriteActions(actions), + actions, params, schedule, tags, From 24fe88ce9b27e684444845bdd5c689efebdc63b0 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 2 Nov 2022 16:31:00 -0500 Subject: [PATCH 13/85] Make notify and throttle optional in route schemas --- x-pack/plugins/alerting/server/routes/create_rule.ts | 4 ++-- x-pack/plugins/alerting/server/routes/update_rule.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/alerting/server/routes/create_rule.ts b/x-pack/plugins/alerting/server/routes/create_rule.ts index 739f0952b0841..5e514cf07ae23 100644 --- a/x-pack/plugins/alerting/server/routes/create_rule.ts +++ b/x-pack/plugins/alerting/server/routes/create_rule.ts @@ -32,13 +32,13 @@ export const bodySchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), consumer: schema.string(), tags: schema.arrayOf(schema.string(), { defaultValue: [] }), - throttle: schema.nullable(schema.string({ validate: validateDurationSchema })), + throttle: schema.maybe(schema.nullable(schema.string({ validate: validateDurationSchema }))), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), }), actions: actionsSchema, - notify_when: schema.string({ validate: validateNotifyWhenType }), + notify_when: schema.maybe(schema.string({ validate: validateNotifyWhenType })), }); const rewriteBodyReq: RewriteRequestCase['data']> = ({ diff --git a/x-pack/plugins/alerting/server/routes/update_rule.ts b/x-pack/plugins/alerting/server/routes/update_rule.ts index 93ef40407dd45..9f9d013e04353 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule.ts @@ -36,10 +36,10 @@ const bodySchema = schema.object({ schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), }), - throttle: schema.nullable(schema.string({ validate: validateDurationSchema })), + throttle: schema.maybe(schema.nullable(schema.string({ validate: validateDurationSchema }))), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), actions: actionsSchema, - notify_when: schema.string({ validate: validateNotifyWhenType }), + notify_when: schema.maybe(schema.string({ validate: validateNotifyWhenType })), }); const rewriteBodyReq: RewriteRequestCase> = (result) => { From bed44bcd4497ef4c998d1a50db773fbd14f3fc09 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 3 Nov 2022 11:53:06 -0500 Subject: [PATCH 14/85] Fix tests --- x-pack/plugins/alerting/server/routes/create_rule.ts | 2 +- x-pack/plugins/alerting/server/routes/update_rule.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/alerting/server/routes/create_rule.ts b/x-pack/plugins/alerting/server/routes/create_rule.ts index 5e514cf07ae23..19e0d8ba0497f 100644 --- a/x-pack/plugins/alerting/server/routes/create_rule.ts +++ b/x-pack/plugins/alerting/server/routes/create_rule.ts @@ -32,7 +32,7 @@ export const bodySchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), consumer: schema.string(), tags: schema.arrayOf(schema.string(), { defaultValue: [] }), - throttle: schema.maybe(schema.nullable(schema.string({ validate: validateDurationSchema }))), + throttle: schema.nullable(schema.maybe(schema.string({ validate: validateDurationSchema }))), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), diff --git a/x-pack/plugins/alerting/server/routes/update_rule.ts b/x-pack/plugins/alerting/server/routes/update_rule.ts index 9f9d013e04353..7392a33d81ad5 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule.ts @@ -36,7 +36,7 @@ const bodySchema = schema.object({ schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), }), - throttle: schema.maybe(schema.nullable(schema.string({ validate: validateDurationSchema }))), + throttle: schema.nullable(schema.maybe(schema.string({ validate: validateDurationSchema }))), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), actions: actionsSchema, notify_when: schema.maybe(schema.string({ validate: validateNotifyWhenType })), From 3b12f0f0b15efc5b3336b63d68f5e4ab1a57eb79 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Fri, 4 Nov 2022 11:26:18 -0500 Subject: [PATCH 15/85] Split missing frequency test cases --- .../server/rules_client/tests/create.test.ts | 49 +++++++++++++------ .../server/rules_client/tests/update.test.ts | 31 +++++++----- 2 files changed, 54 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index d71b74a3f1211..ae7b96765830f 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -2750,18 +2750,6 @@ describe('create()', () => { params: { foo: true, }, - frequency: { - summary: false, - notifyWhen: 'onActionGroupChange', - throttle: null, - }, - }, - { - group: 'default', - id: '2', - params: { - foo: true, - }, }, ], }); @@ -2770,8 +2758,29 @@ describe('create()', () => { ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); + }); + test('throws error when some actions are missing frequency params', async () => { + rulesClient = new RulesClient({ + ...rulesClientParams, + minimumScheduleInterval: { value: '1m', enforce: true }, + }); + ruleTypeRegistry.get.mockImplementation(() => ({ + id: '123', + name: 'Test', + actionGroups: [{ id: 'default', name: 'Default' }], + recoveryActionGroup: RecoveredActionGroup, + defaultActionGroupId: 'default', + minimumLicenseRequired: 'basic', + isExportable: true, + async executor() {}, + producer: 'alerts', + useSavedObjectReferences: { + extractReferences: jest.fn(), + injectReferences: jest.fn(), + }, + })); - const data2 = getMockData({ + const data = getMockData({ notifyWhen: undefined, throttle: undefined, actions: [ @@ -2781,10 +2790,22 @@ describe('create()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + { + group: 'default', + id: '2', + params: { + foo: true, + }, }, ], }); - await expect(rulesClient.create({ data: data2 })).rejects.toThrowErrorMatchingInlineSnapshot( + await expect(rulesClient.create({ data })).rejects.toThrowErrorMatchingInlineSnapshot( `"Actions missing frequency parameters: default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index 817553d1ef151..391dc0d051a2d 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -1770,18 +1770,6 @@ describe('update()', () => { params: { foo: true, }, - frequency: { - summary: false, - notifyWhen: 'onActionGroupChange', - throttle: null, - }, - }, - { - group: 'default', - id: '2', - params: { - foo: true, - }, }, ], }, @@ -1791,6 +1779,13 @@ describe('update()', () => { ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); + }); + + test('throws error when when some actions are missing frequency params', async () => { + const alertId = uuid.v4(); + const taskId = uuid.v4(); + + mockApiCalls(alertId, taskId, { interval: '1m' }, { interval: '1m' }); await expect( rulesClient.update({ @@ -1811,6 +1806,18 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, + }, + { + group: 'default', + id: '2', + params: { + foo: true, + }, }, ], }, From b2bebdf524260f51642ddfae2b260540205ba229 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 7 Nov 2022 11:12:20 -0600 Subject: [PATCH 16/85] Handle xor undefined global frequency params --- .../server/rules_client/rules_client.ts | 26 +++++++++++++------ .../rule_schema/model/rule_schemas.ts | 4 +-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 7993e0d59a657..c9ec4141cdf94 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -574,8 +574,7 @@ export class RulesClient { throw Boom.badRequest(`Error creating rule: could not create API key - ${error.message}`); } - const usesGlobalFreqParams = - typeof data.notifyWhen !== 'undefined' && typeof data.throttle !== 'undefined'; + const usesGlobalFreqParams = this.usesValidGlobalFreqParams(data); await this.validateActions(ruleType, data.actions, usesGlobalFreqParams); // Throw error if schedule interval is less than the minimum and we are enforcing it @@ -1715,8 +1714,7 @@ export class RulesClient { // Validate const validatedAlertTypeParams = validateRuleTypeParams(data.params, ruleType.validate?.params); - const usesGlobalFreqParams = - typeof data.notifyWhen !== 'undefined' && typeof data.throttle !== 'undefined'; + const usesGlobalFreqParams = this.usesValidGlobalFreqParams(data); await this.validateActions(ruleType, data.actions, usesGlobalFreqParams); // Throw error if schedule interval is less than the minimum and we are enforcing it @@ -2238,10 +2236,7 @@ export class RulesClient { for (const operation of operations) { switch (operation.field) { case 'actions': - const usesGlobalFreqParams = Boolean( - typeof attributes.notifyWhen !== 'undefined' && - typeof attributes.throttle !== 'undefined' - ); + const usesGlobalFreqParams = this.usesValidGlobalFreqParams(attributes); await this.validateActions(ruleType, operation.value, usesGlobalFreqParams); ruleActions = applyBulkEditOperation(operation, ruleActions); break; @@ -3512,6 +3507,21 @@ export class RulesClient { : (rule as PartialRule); } + private usesValidGlobalFreqParams({ + notifyWhen, + throttle, + }: Pick) { + const hasNotifyWhen = typeof notifyWhen !== 'undefined'; + const hasThrottle = typeof throttle !== 'undefined'; + if (hasNotifyWhen && hasThrottle) return true; + if (!hasNotifyWhen && !hasThrottle) return false; + throw Boom.badRequest( + i18n.translate('xpack.alerting.rulesClient.usesValidGlobalFreqParams.oneUndefined', { + defaultMessage: 'Global notifyWhen and throttle must both be defined or both be undefined', + }) + ); + } + private async validateActions( alertType: UntypedNormalizedRuleType, actions: NormalizedAlertAction[], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts index 357398c28c87f..f9c7bac7f74ad 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_schema/model/rule_schemas.ts @@ -286,7 +286,7 @@ const internalRuleCreateRequired = t.type({ actions: RuleActionArrayCamel, params: ruleParams, }); -const internalRuleCreateOptional = t.type({ +const internalRuleCreateOptional = t.partial({ throttle: t.union([RuleActionThrottle, t.null]), notifyWhen, }); @@ -305,7 +305,7 @@ const internalRuleUpdateRequired = t.type({ actions: RuleActionArrayCamel, params: ruleParams, }); -const internalRuleUpdateOptional = t.type({ +const internalRuleUpdateOptional = t.partial({ throttle: t.union([RuleActionThrottle, t.null]), notifyWhen, }); From 11e16a57d321b62e23b4ef8a0e907179a59c0aa4 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 7 Nov 2022 14:54:45 -0600 Subject: [PATCH 17/85] Fix typecheck --- x-pack/plugins/alerting/server/task_runner/execution_handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/alerting/server/task_runner/execution_handler.ts b/x-pack/plugins/alerting/server/task_runner/execution_handler.ts index 2d72bcd284a66..eebd8b667a42b 100644 --- a/x-pack/plugins/alerting/server/task_runner/execution_handler.ts +++ b/x-pack/plugins/alerting/server/task_runner/execution_handler.ts @@ -359,7 +359,7 @@ export class ExecutionHandler< } = this; const muted = mutedAlertIdsSet!.has(alertId); - const throttled = alert.isThrottled(throttle); + const throttled = alert.isThrottled(throttle ?? null); if (muted) { if ( From bed575376dcea1691aab5895a70552e781824278 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 9 Nov 2022 11:27:48 -0600 Subject: [PATCH 18/85] Refactor global freq param validation and clarify error messages --- .../server/rules_client/rules_client.ts | 48 +++++++++---------- 1 file changed, 22 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 2025754a51cbc..071a43e6b5765 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -566,8 +566,7 @@ export class RulesClient { throw Boom.badRequest(`Error creating rule: could not create API key - ${error.message}`); } - const usesGlobalFreqParams = this.usesValidGlobalFreqParams(data); - await this.validateActions(ruleType, data.actions, usesGlobalFreqParams); + await this.validateActions(ruleType, data); // Throw error if schedule interval is less than the minimum and we are enforcing it const intervalInMs = parseDuration(data.schedule.interval); @@ -1706,8 +1705,7 @@ export class RulesClient { // Validate const validatedAlertTypeParams = validateRuleTypeParams(data.params, ruleType.validate?.params); - const usesGlobalFreqParams = this.usesValidGlobalFreqParams(data); - await this.validateActions(ruleType, data.actions, usesGlobalFreqParams); + await this.validateActions(ruleType, data); // Throw error if schedule interval is less than the minimum and we are enforcing it const intervalInMs = parseDuration(data.schedule.interval); @@ -2234,8 +2232,7 @@ export class RulesClient { for (const operation of operations) { switch (operation.field) { case 'actions': - const usesGlobalFreqParams = this.usesValidGlobalFreqParams(attributes); - await this.validateActions(ruleType, operation.value, usesGlobalFreqParams); + await this.validateActions(ruleType, { ...attributes, actions: operation.value }); ruleActions = applyBulkEditOperation(operation, ruleActions); break; case 'snoozeSchedule': @@ -3505,26 +3502,25 @@ export class RulesClient { : (rule as PartialRule); } - private usesValidGlobalFreqParams({ - notifyWhen, - throttle, - }: Pick) { - const hasNotifyWhen = typeof notifyWhen !== 'undefined'; - const hasThrottle = typeof throttle !== 'undefined'; - if (hasNotifyWhen && hasThrottle) return true; - if (!hasNotifyWhen && !hasThrottle) return false; - throw Boom.badRequest( - i18n.translate('xpack.alerting.rulesClient.usesValidGlobalFreqParams.oneUndefined', { - defaultMessage: 'Global notifyWhen and throttle must both be defined or both be undefined', - }) - ); - } - private async validateActions( alertType: UntypedNormalizedRuleType, - actions: NormalizedAlertAction[], - usesGlobalFreqParams: boolean + data: Pick & { actions: NormalizedAlertAction[] } ): Promise { + const { actions, notifyWhen, throttle } = data; + const hasNotifyWhen = typeof notifyWhen !== 'undefined'; + const hasThrottle = typeof throttle !== 'undefined'; + let usesRuleLevelFreqParams; + if (hasNotifyWhen && hasThrottle) usesRuleLevelFreqParams = true; + else if (!hasNotifyWhen && !hasThrottle) usesRuleLevelFreqParams = false; + else { + throw Boom.badRequest( + i18n.translate('xpack.alerting.rulesClient.usesValidGlobalFreqParams.oneUndefined', { + defaultMessage: + 'Rule-level notifyWhen and throttle must both be defined or both be undefined', + }) + ); + } + if (actions.length === 0) { return; } @@ -3568,14 +3564,14 @@ export class RulesClient { ); } - // check for actions using frequency params if the rule has global frequency params defined - if (usesGlobalFreqParams) { + // check for actions using frequency params if the rule has rule-level frequency params defined + if (usesRuleLevelFreqParams) { const actionsWithFrequency = actions.filter((action) => Boolean(action.frequency)); if (actionsWithFrequency.length) { throw Boom.badRequest( i18n.translate('xpack.alerting.rulesClient.validateActions.mixAndMatchFreqParams', { defaultMessage: - 'Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: {groups}', + 'Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: {groups}', values: { groups: actionsWithFrequency.map((a) => a.group).join(', '), }, From 26df5b503cb6bc8dc8bdb1125c43820d2d57bbfc Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 9 Nov 2022 13:28:08 -0600 Subject: [PATCH 19/85] Update jest snapshots --- .../plugins/alerting/server/rules_client/tests/create.test.ts | 4 ++-- .../plugins/alerting/server/rules_client/tests/update.test.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index ae7b96765830f..48e02656d591b 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -2683,7 +2683,7 @@ describe('create()', () => { ], }); await expect(rulesClient.create({ data })).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: default, default"` + `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default, default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); @@ -2713,7 +2713,7 @@ describe('create()', () => { ], }); await expect(rulesClient.create({ data: data2 })).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: default"` + `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index 391dc0d051a2d..ae566c107862a 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -1698,7 +1698,7 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: default, default"` + `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default, default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); @@ -1739,7 +1739,7 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot mix and match per-action frequency params when notify_when or throttle are globally defined: default"` + `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); From 023cb650f69ea06e62690cce164240de3fc0c40f Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 15 Nov 2022 13:14:11 -0600 Subject: [PATCH 20/85] Fix bad merge --- x-pack/plugins/alerting/server/routes/update_rule.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/x-pack/plugins/alerting/server/routes/update_rule.ts b/x-pack/plugins/alerting/server/routes/update_rule.ts index 57150266101c0..c998d5eb50a51 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule.ts @@ -15,13 +15,9 @@ import { RewriteResponseCase, RewriteRequestCase, handleDisabledApiKeysError, -<<<<<<< HEAD rewriteActions, actionsSchema, -||||||| 6672962d19b -======= rewriteRuleLastRun, ->>>>>>> upstream/main } from './lib'; import { RuleTypeParams, From 36d0843d61ddaa6ccd11adf755956cae87501592 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 15 Nov 2022 15:50:27 -0600 Subject: [PATCH 21/85] Remove extraneous file --- .../server/lib/validate_rule_frequency.ts | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 x-pack/plugins/alerting/server/lib/validate_rule_frequency.ts diff --git a/x-pack/plugins/alerting/server/lib/validate_rule_frequency.ts b/x-pack/plugins/alerting/server/lib/validate_rule_frequency.ts deleted file mode 100644 index b791b05499263..0000000000000 --- a/x-pack/plugins/alerting/server/lib/validate_rule_frequency.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 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 Boom from '@hapi/boom'; -import { RuleTypeParams, RuleTypeParamsValidator } from '../types'; - -export function validateRuleTypeParams( - params: Record, - validator?: RuleTypeParamsValidator -): Params { - if (!validator) { - return params as Params; - } - - try { - return validator.validate(params); - } catch (err) { - throw Boom.badRequest(`params invalid: ${err.message}`); - } -} From 62b43346bc62c0581ef9758e0623ea163798a5c1 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 10 Nov 2022 16:36:43 -0600 Subject: [PATCH 22/85] Move frequency controls into actions form --- .../action_notify_when.tsx | 237 ++++++++++++++++++ .../action_type_form.tsx | 54 +++- .../sections/rule_form/rule_form.tsx | 231 ++++++++--------- 3 files changed, 390 insertions(+), 132 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx new file mode 100644 index 0000000000000..be244fb0ee174 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -0,0 +1,237 @@ +/* + * 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 React, { useState, useEffect, useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { + EuiFlexGroup, + EuiFlexItem, + EuiIconTip, + EuiFormRow, + EuiFieldNumber, + EuiSelect, + EuiText, + EuiSpacer, + EuiSuperSelect, + EuiSuperSelectOption, +} from '@elastic/eui'; +import { some, filter, map } from 'fp-ts/lib/Option'; +import { pipe } from 'fp-ts/lib/pipeable'; +import { getTimeOptions } from '../../../common/lib/get_time_options'; +import { RuleNotifyWhenType, RuleAction } from '../../../types'; + +const DEFAULT_NOTIFY_WHEN_VALUE: RuleNotifyWhenType = 'onActionGroupChange'; + +export const DEFAULT_FREQUENCY = { + notifyWhen: DEFAULT_NOTIFY_WHEN_VALUE, + throttle: null, + summary: false, +}; + +export const NOTIFY_WHEN_OPTIONS: Array> = [ + { + value: 'onActionGroupChange', + inputDisplay: i18n.translate( + 'xpack.triggersActionsUI.sections.ruleForm.ruleNotifyWhen.onActionGroupChange.display', + { + defaultMessage: 'On status changes', + } + ), + 'data-test-subj': 'onActionGroupChange', + dropdownDisplay: ( + <> + + + + +

+ +

+
+ + ), + }, + { + value: 'onActiveAlert', + inputDisplay: i18n.translate( + 'xpack.triggersActionsUI.sections.ruleForm.ruleNotifyWhen.onActiveAlert.display', + { + defaultMessage: 'On check intervals', + } + ), + 'data-test-subj': 'onActiveAlert', + dropdownDisplay: ( + <> + + + + +

+ +

+
+ + ), + }, + { + value: 'onThrottleInterval', + inputDisplay: i18n.translate( + 'xpack.triggersActionsUI.sections.ruleForm.ruleNotifyWhen.onThrottleInterval.display', + { + defaultMessage: 'On custom action intervals', + } + ), + 'data-test-subj': 'onThrottleInterval', + dropdownDisplay: ( + <> + + + + +

+ +

+
+ + ), + }, +]; + +interface RuleNotifyWhenProps { + frequency: RuleAction['frequency']; + throttle: number | null; + throttleUnit: string; + onNotifyWhenChange: (notifyWhen: RuleNotifyWhenType) => void; + onThrottleChange: (throttle: number | null, throttleUnit: string) => void; +} + +export const ActionNotifyWhen = ({ + frequency = DEFAULT_FREQUENCY, + throttle, + throttleUnit, + onNotifyWhenChange, + onThrottleChange, +}: RuleNotifyWhenProps) => { + const [ruleThrottle, setRuleThrottle] = useState(throttle || 1); + const [showCustomThrottleOpts, setShowCustomThrottleOpts] = useState(false); + const [notifyWhenValue, setNotifyWhenValue] = + useState(DEFAULT_NOTIFY_WHEN_VALUE); + + useEffect(() => { + if (frequency.notifyWhen) { + setNotifyWhenValue(frequency.notifyWhen); + } else { + // If 'notifyWhen' is not set, derive value from existence of throttle value + setNotifyWhenValue(frequency.throttle ? 'onThrottleInterval' : 'onActiveAlert'); + } + }, [frequency]); + + useEffect(() => { + setShowCustomThrottleOpts(notifyWhenValue === 'onThrottleInterval'); + }, [notifyWhenValue]); + + const onNotifyWhenValueChange = useCallback((newValue: RuleNotifyWhenType) => { + onThrottleChange(newValue === 'onThrottleInterval' ? ruleThrottle : null, throttleUnit); + onNotifyWhenChange(newValue); + setNotifyWhenValue(newValue); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const labelForRuleRenotify = [ + i18n.translate('xpack.triggersActionsUI.sections.ruleForm.renotifyFieldLabel', { + defaultMessage: 'Notify', + }), + , + ]; + + return ( + <> + + + + {showCustomThrottleOpts && ( + <> + + + + + { + pipe( + some(e.target.value.trim()), + filter((value) => value !== ''), + map((value) => parseInt(value, 10)), + filter((value) => !isNaN(value)), + map((value) => { + setRuleThrottle(value); + onThrottleChange(value, throttleUnit); + }) + ); + }} + /> + + + { + onThrottleChange(throttle, e.target.value); + }} + /> + + + + + )} + + + + ); +}; 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 eff0ff126d3bc..5fbc3a190cdd0 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 @@ -5,7 +5,7 @@ * 2.0. */ -import React, { Suspense, useEffect, useState } from 'react'; +import React, { Suspense, useEffect, useState, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { @@ -28,6 +28,10 @@ import { } from '@elastic/eui'; import { isEmpty, partition, some } from 'lodash'; import { ActionVariable, RuleActionParam } from '@kbn/alerting-plugin/common'; +import { + getDurationNumberInItsUnit, + getDurationUnitValue, +} from '@kbn/alerting-plugin/common/parse_duration'; import { betaBadgeProps } from './beta_badge_props'; import { IErrorObject, @@ -44,6 +48,7 @@ import { ActionAccordionFormProps, ActionGroupWithMessageVariables } from './act import { transformActionVariables } from '../../lib/action_variables'; import { useKibana } from '../../../common/lib/kibana'; import { ConnectorsSelection } from './connectors_selection'; +import { ActionNotifyWhen, DEFAULT_FREQUENCY } from './action_notify_when'; export type ActionTypeFormProps = { actionItem: RuleAction; @@ -75,6 +80,8 @@ const preconfiguredMessage = i18n.translate( } ); +type ActionFrequency = NonNullable; + export const ActionTypeForm = ({ actionItem, actionConnector, @@ -106,7 +113,28 @@ export const ActionTypeForm = ({ const [actionParamsErrors, setActionParamsErrors] = useState<{ errors: IErrorObject }>({ errors: {}, }); + const [actionThrottle, setActionThrottle] = useState( + actionItem.frequency?.throttle + ? getDurationNumberInItsUnit(actionItem.frequency.throttle) + : null + ); + const [actionThrottleUnit, setActionThrottleUnit] = useState( + actionItem.frequency?.throttle ? getDurationUnitValue(actionItem.frequency?.throttle) : 'h' + ); + const setActionFrequencyProperty = useCallback( + (key: Key, value: ActionFrequency[Key]) => { + setActionParamsProperty( + 'frequency', + { + ...(actionItem.frequency ?? DEFAULT_FREQUENCY), + [key]: value, + }, + index + ); + }, + [setActionParamsProperty, actionItem.frequency, index] + ); const getDefaultParams = async () => { const connectorType = await actionTypeRegistry.get(actionItem.actionTypeId); let defaultParams; @@ -185,6 +213,28 @@ export const ActionTypeForm = ({ ? isActionGroupDisabledForActionType(actionGroupId, actionTypeId) : false; + const actionNotifyWhen = ( + { + setActionFrequencyProperty('notifyWhen', notifyWhen); + }, + [setActionFrequencyProperty] + )} + onThrottleChange={useCallback( + (throttle: number | null, throttleUnit: string) => { + setActionThrottle(throttle); + setActionThrottleUnit(throttleUnit); + setActionFrequencyProperty('throttle', throttle ? `${throttle}${throttleUnit}` : null); + }, + [setActionFrequencyProperty] + )} + /> + ); + const actionTypeRegistered = actionTypeRegistry.get(actionConnector.actionTypeId); if (!actionTypeRegistered) return null; @@ -200,8 +250,10 @@ export const ActionTypeForm = ({ const accordionContent = checkEnabledResult.isEnabled ? ( <> + {actionNotifyWhen} {actionGroups && selectedActionGroup && setActionGroupIdByIndex && ( <> + diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx index ed2b6c27a0604..dd07430388ce3 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx @@ -69,7 +69,6 @@ import './rule_form.scss'; import { useKibana } from '../../../common/lib/kibana'; import { recoveredActionGroupMessage } from '../../constants'; import { IsEnabledResult, IsDisabledResult } from '../../lib/check_rule_type_enabled'; -import { RuleNotifyWhen } from './rule_notify_when'; import { checkRuleTypeEnabled } from '../../lib/check_rule_type_enabled'; import { ruleTypeCompare, ruleTypeGroupCompare } from '../../lib/rule_type_compare'; import { VIEW_LICENSE_OPTIONS_LINK } from '../../../common/constants'; @@ -146,12 +145,6 @@ export const RuleForm = ({ ? getDurationUnitValue(rule.schedule.interval) : defaultScheduleIntervalUnit ); - const [ruleThrottle, setRuleThrottle] = useState( - rule.throttle ? getDurationNumberInItsUnit(rule.throttle) : null - ); - const [ruleThrottleUnit, setRuleThrottleUnit] = useState( - rule.throttle ? getDurationUnitValue(rule.throttle) : 'h' - ); const [defaultActionGroupId, setDefaultActionGroupId] = useState(undefined); const [availableRuleTypes, setAvailableRuleTypes] = useState< @@ -434,6 +427,58 @@ export const RuleForm = ({ )); + const labelForRuleChecked = [ + i18n.translate('xpack.triggersActionsUI.sections.ruleForm.checkFieldLabel', { + defaultMessage: 'Check every', + }), + , + ]; + + const getHelpTextForInterval = () => { + if (!config || !config.minimumScheduleInterval) { + return ''; + } + + // No help text if there is an error + if (errors['schedule.interval'].length > 0) { + return ''; + } + + if (config.minimumScheduleInterval.enforce) { + // Always show help text if minimum is enforced + return i18n.translate('xpack.triggersActionsUI.sections.ruleForm.checkEveryHelpText', { + defaultMessage: 'Interval must be at least {minimum}.', + values: { + minimum: formatDuration(config.minimumScheduleInterval.value, true), + }, + }); + } else if ( + rule.schedule.interval && + parseDuration(rule.schedule.interval) < parseDuration(config.minimumScheduleInterval.value) + ) { + // Only show help text if current interval is less than suggested + return i18n.translate( + 'xpack.triggersActionsUI.sections.ruleForm.checkEveryHelpSuggestionText', + { + defaultMessage: + 'Intervals less than {minimum} are not recommended due to performance considerations.', + values: { + minimum: formatDuration(config.minimumScheduleInterval.value, true), + }, + } + ); + } else { + return ''; + } + }; + const ruleTypeDetails = ( <> @@ -542,6 +587,53 @@ export const RuleForm = ({ ) : null} + + + 0} + error={errors['schedule.interval']} + > + + + 0} + value={ruleInterval || ''} + name="interval" + data-test-subj="intervalInput" + onChange={(e) => { + const value = e.target.value; + if (value === '' || INTEGER_REGEX.test(value)) { + const parsedValue = value === '' ? '' : parseInt(value, 10); + setRuleInterval(parsedValue || undefined); + setScheduleProperty('interval', `${parsedValue}${ruleIntervalUnit}`); + } + }} + /> + + + { + setRuleIntervalUnit(e.target.value); + setScheduleProperty('interval', `${ruleInterval}${e.target.value}`); + }} + data-test-subj="intervalInputUnit" + /> + + + + + + ); - const labelForRuleChecked = ( - <> - {' '} - - - ); - - const getHelpTextForInterval = () => { - if (!config || !config.minimumScheduleInterval) { - return ''; - } - - // No help text if there is an error - if (errors['schedule.interval'].length > 0) { - return ''; - } - - if (config.minimumScheduleInterval.enforce) { - // Always show help text if minimum is enforced - return i18n.translate('xpack.triggersActionsUI.sections.ruleForm.checkEveryHelpText', { - defaultMessage: 'Interval must be at least {minimum}.', - values: { - minimum: formatDuration(config.minimumScheduleInterval.value, true), - }, - }); - } else if ( - rule.schedule.interval && - parseDuration(rule.schedule.interval) < parseDuration(config.minimumScheduleInterval.value) - ) { - // Only show help text if current interval is less than suggested - return i18n.translate( - 'xpack.triggersActionsUI.sections.ruleForm.checkEveryHelpSuggestionText', - { - defaultMessage: - 'Intervals less than {minimum} are not recommended due to performance considerations.', - values: { - minimum: formatDuration(config.minimumScheduleInterval.value, true), - }, - } - ); - } else { - return ''; - } - }; - return ( - + - - - 0} - error={errors['schedule.interval']} - > - - - 0} - value={ruleInterval || ''} - name="interval" - data-test-subj="intervalInput" - onChange={(e) => { - const value = e.target.value; - if (value === '' || INTEGER_REGEX.test(value)) { - const parsedValue = value === '' ? '' : parseInt(value, 10); - setRuleInterval(parsedValue || undefined); - setScheduleProperty('interval', `${parsedValue}${ruleIntervalUnit}`); - } - }} - /> - - - { - setRuleIntervalUnit(e.target.value); - setScheduleProperty('interval', `${ruleInterval}${e.target.value}`); - }} - data-test-subj="intervalInputUnit" - /> - - - - - - { - setRuleProperty('notifyWhen', notifyWhen); - }, - [setRuleProperty] - )} - onThrottleChange={useCallback( - (throttle: number | null, throttleUnit: string) => { - setRuleThrottle(throttle); - setRuleThrottleUnit(throttleUnit); - setRuleProperty('throttle', throttle ? `${throttle}${throttleUnit}` : null); - }, - [setRuleProperty] - )} - /> - - - {ruleTypeModel ? ( <>{ruleTypeDetails} ) : availableRuleTypes.length ? ( From 54024f949a59b865d764b42427df716255cb4ca2 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 17 Nov 2022 16:01:37 -0600 Subject: [PATCH 23/85] Add Integrate action frequency params with frontend --- .../alerting/server/routes/clone_rule.ts | 3 +- .../alerting/server/routes/create_rule.ts | 2 +- .../alerting/server/routes/get_rule.ts | 3 +- .../server/routes/lib/rewrite_rule.ts | 5 +- .../alerting/server/routes/resolve_rule.ts | 3 +- .../alerting/server/routes/update_rule.ts | 5 +- .../alerting/server/saved_objects/mappings.ts | 14 ++++++ .../lib/rule_api/common_transformations.ts | 2 + .../public/application/lib/rule_api/create.ts | 9 ++-- .../public/application/lib/rule_api/update.ts | 23 ++++----- .../action_connector_form/action_form.tsx | 7 ++- .../action_notify_when.tsx | 25 +++++----- .../action_type_form.tsx | 38 +++++++-------- .../sections/rule_form/rule_add.tsx | 1 - .../sections/rule_form/rule_form.tsx | 10 +++- .../sections/rule_form/rule_reducer.ts | 47 +++++++++++++++++-- .../constants/action_frequency_types.ts | 14 ++++++ .../public/common/constants/index.ts | 1 + 18 files changed, 147 insertions(+), 65 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/common/constants/action_frequency_types.ts diff --git a/x-pack/plugins/alerting/server/routes/clone_rule.ts b/x-pack/plugins/alerting/server/routes/clone_rule.ts index 3e57b4aa1c122..a09098930c1d5 100644 --- a/x-pack/plugins/alerting/server/routes/clone_rule.ts +++ b/x-pack/plugins/alerting/server/routes/clone_rule.ts @@ -69,11 +69,12 @@ const rewriteBodyRes: RewriteResponseCase> = ({ : {}), ...(actions ? { - actions: actions.map(({ group, id, actionTypeId, params }) => ({ + actions: actions.map(({ group, id, actionTypeId, params, frequency }) => ({ group, id, params, connector_type_id: actionTypeId, + frequency, })), } : {}), diff --git a/x-pack/plugins/alerting/server/routes/create_rule.ts b/x-pack/plugins/alerting/server/routes/create_rule.ts index 8d418f8497cb3..f8757b1376983 100644 --- a/x-pack/plugins/alerting/server/routes/create_rule.ts +++ b/x-pack/plugins/alerting/server/routes/create_rule.ts @@ -33,7 +33,7 @@ export const bodySchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), consumer: schema.string(), tags: schema.arrayOf(schema.string(), { defaultValue: [] }), - throttle: schema.nullable(schema.maybe(schema.string({ validate: validateDurationSchema }))), + throttle: schema.maybe(schema.nullable(schema.string({ validate: validateDurationSchema }))), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), diff --git a/x-pack/plugins/alerting/server/routes/get_rule.ts b/x-pack/plugins/alerting/server/routes/get_rule.ts index 0b529b35fa466..80bd320e309fd 100644 --- a/x-pack/plugins/alerting/server/routes/get_rule.ts +++ b/x-pack/plugins/alerting/server/routes/get_rule.ts @@ -59,11 +59,12 @@ const rewriteBodyRes: RewriteResponseCase> = ({ last_execution_date: executionStatus.lastExecutionDate, last_duration: executionStatus.lastDuration, }, - actions: actions.map(({ group, id, actionTypeId, params }) => ({ + actions: actions.map(({ group, id, actionTypeId, params, frequency }) => ({ group, id, params, connector_type_id: actionTypeId, + frequency, })), ...(lastRun ? { last_run: rewriteRuleLastRun(lastRun) } : {}), ...(nextRun ? { next_run: nextRun } : {}), diff --git a/x-pack/plugins/alerting/server/routes/lib/rewrite_rule.ts b/x-pack/plugins/alerting/server/routes/lib/rewrite_rule.ts index 47dc3a78c278c..fde5ac590b86e 100644 --- a/x-pack/plugins/alerting/server/routes/lib/rewrite_rule.ts +++ b/x-pack/plugins/alerting/server/routes/lib/rewrite_rule.ts @@ -63,10 +63,7 @@ export const rewriteRule = ({ connector_type_id: actionTypeId, ...(frequency ? { - frequency: { - ...frequency, - notify_when: frequency.notifyWhen, - }, + frequency, } : {}), })), diff --git a/x-pack/plugins/alerting/server/routes/resolve_rule.ts b/x-pack/plugins/alerting/server/routes/resolve_rule.ts index 48d2253a03fc9..add6ab1c871c2 100644 --- a/x-pack/plugins/alerting/server/routes/resolve_rule.ts +++ b/x-pack/plugins/alerting/server/routes/resolve_rule.ts @@ -54,11 +54,12 @@ const rewriteBodyRes: RewriteResponseCase> last_execution_date: executionStatus.lastExecutionDate, last_duration: executionStatus.lastDuration, }, - actions: actions.map(({ group, id, actionTypeId, params }) => ({ + actions: actions.map(({ group, id, actionTypeId, params, frequency }) => ({ group, id, params, connector_type_id: actionTypeId, + frequency, })), ...(lastRun ? { last_run: rewriteRuleLastRun(lastRun) } : {}), ...(nextRun ? { next_run: nextRun } : {}), diff --git a/x-pack/plugins/alerting/server/routes/update_rule.ts b/x-pack/plugins/alerting/server/routes/update_rule.ts index c998d5eb50a51..5993c069b2592 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule.ts @@ -37,7 +37,7 @@ const bodySchema = schema.object({ schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), }), - throttle: schema.nullable(schema.maybe(schema.string({ validate: validateDurationSchema }))), + throttle: schema.maybe(schema.nullable(schema.string({ validate: validateDurationSchema }))), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), actions: actionsSchema, notify_when: schema.maybe(schema.string({ validate: validateNotifyWhenType })), @@ -96,11 +96,12 @@ const rewriteBodyRes: RewriteResponseCase> = ({ : {}), ...(actions ? { - actions: actions.map(({ group, id, actionTypeId, params }) => ({ + actions: actions.map(({ group, id, actionTypeId, params, frequency }) => ({ group, id, params, connector_type_id: actionTypeId, + frequency, })), } : {}), diff --git a/x-pack/plugins/alerting/server/saved_objects/mappings.ts b/x-pack/plugins/alerting/server/saved_objects/mappings.ts index 727e70e26055e..9092f1af877d3 100644 --- a/x-pack/plugins/alerting/server/saved_objects/mappings.ts +++ b/x-pack/plugins/alerting/server/saved_objects/mappings.ts @@ -56,6 +56,20 @@ export const alertMappings: SavedObjectsTypeMappingDefinition = { enabled: false, type: 'object', }, + frequency: { + type: 'nested', + properties: { + notifyWhen: { + type: 'keyword', + }, + throttle: { + type: 'keyword', + }, + summary: { + type: 'boolean', + }, + }, + }, }, }, params: { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/common_transformations.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/common_transformations.ts index 9f514893d1836..2a1bf52027180 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/common_transformations.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/common_transformations.ts @@ -13,11 +13,13 @@ const transformAction: RewriteRequestCase = ({ id, connector_type_id: actionTypeId, params, + frequency, }) => ({ group, id, params, actionTypeId, + frequency, }); const transformExecutionStatus: RewriteRequestCase = ({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/create.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/create.ts index c04b55ff6db49..9d13b5f909c23 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/create.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/create.ts @@ -22,17 +22,20 @@ type RuleCreateBody = Omit< >; const rewriteBodyRequest: RewriteResponseCase = ({ ruleTypeId, - notifyWhen, actions, ...res }): any => ({ ...res, rule_type_id: ruleTypeId, - notify_when: notifyWhen, - actions: actions.map(({ group, id, params }) => ({ + actions: actions.map(({ group, id, params, frequency }) => ({ group, id, params, + frequency: { + notify_when: frequency!.notifyWhen, + throttle: frequency!.throttle, + summary: frequency!.summary, + }, })), }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.ts index 76383b405e82a..aefaf9019a967 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.ts @@ -15,17 +15,17 @@ type RuleUpdatesBody = Pick< RuleUpdates, 'name' | 'tags' | 'schedule' | 'actions' | 'params' | 'throttle' | 'notifyWhen' >; -const rewriteBodyRequest: RewriteResponseCase = ({ - notifyWhen, - actions, - ...res -}): any => ({ +const rewriteBodyRequest: RewriteResponseCase = ({ actions, ...res }): any => ({ ...res, - notify_when: notifyWhen, - actions: actions.map(({ group, id, params }) => ({ + actions: actions.map(({ group, id, params, frequency }) => ({ group, id, params, + frequency: { + notify_when: frequency!.notifyWhen, + throttle: frequency!.throttle, + summary: frequency!.summary, + }, })), }); @@ -35,19 +35,14 @@ export async function updateRule({ id, }: { http: HttpSetup; - rule: Pick< - RuleUpdates, - 'throttle' | 'name' | 'tags' | 'schedule' | 'params' | 'actions' | 'notifyWhen' - >; + rule: Pick; id: string; }): Promise { const res = await http.put>( `${BASE_ALERTING_API_PATH}/rule/${encodeURIComponent(id)}`, { body: JSON.stringify( - rewriteBodyRequest( - pick(rule, ['throttle', 'name', 'tags', 'schedule', 'params', 'actions', 'notifyWhen']) - ) + rewriteBodyRequest(pick(rule, ['name', 'tags', 'schedule', 'params', 'actions'])) ), } ); 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 f499ab5bfa94f..fd429b5442214 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 @@ -35,7 +35,7 @@ import { ActionTypeForm } from './action_type_form'; import { AddConnectorInline } from './connector_add_inline'; import { actionTypeCompare } from '../../lib/action_type_compare'; import { checkActionFormActionTypeEnabled } from '../../lib/check_action_type_enabled'; -import { VIEW_LICENSE_OPTIONS_LINK } from '../../../common/constants'; +import { DEFAULT_FREQUENCY, VIEW_LICENSE_OPTIONS_LINK } from '../../../common/constants'; import { useKibana } from '../../../common/lib/kibana'; import { ConnectorAddModal } from '.'; import { suspendedComponentWithProps } from '../../lib/suspended_component_with_props'; @@ -55,6 +55,7 @@ export interface ActionAccordionFormProps { setActionGroupIdByIndex?: (group: string, index: number) => void; setActions: (actions: RuleAction[]) => void; setActionParamsProperty: (key: string, value: RuleActionParam, index: number) => void; + setActionFrequencyProperty: (key: string, value: RuleActionParam, index: number) => void; featureId: string; messageVariables?: ActionVariables; setHasActionsDisabled?: (value: boolean) => void; @@ -77,6 +78,7 @@ export const ActionForm = ({ setActionGroupIdByIndex, setActions, setActionParamsProperty, + setActionFrequencyProperty, featureId, messageVariables, actionGroups, @@ -210,6 +212,7 @@ export const ActionForm = ({ actionTypeId: actionTypeModel.id, group: defaultActionGroupId, params: {}, + frequency: DEFAULT_FREQUENCY, }); setActionIdByIndex(actionTypeConnectors[0].id, actions.length - 1); } @@ -221,6 +224,7 @@ export const ActionForm = ({ actionTypeId: actionTypeModel.id, group: defaultActionGroupId, params: {}, + frequency: DEFAULT_FREQUENCY, }); setActionIdByIndex(actions.length.toString(), actions.length - 1); setEmptyActionsIds([...emptyActionsIds, actions.length.toString()]); @@ -360,6 +364,7 @@ export const ActionForm = ({ index={index} key={`action-form-action-at-${index}`} setActionParamsProperty={setActionParamsProperty} + setActionFrequencyProperty={setActionFrequencyProperty} actionTypesIndex={actionTypesIndex} connectors={connectors} defaultActionGroupId={defaultActionGroupId} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx index be244fb0ee174..92fc56c2b63f6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -24,15 +24,10 @@ import { some, filter, map } from 'fp-ts/lib/Option'; import { pipe } from 'fp-ts/lib/pipeable'; import { getTimeOptions } from '../../../common/lib/get_time_options'; import { RuleNotifyWhenType, RuleAction } from '../../../types'; +import { DEFAULT_FREQUENCY } from '../../../common/constants'; const DEFAULT_NOTIFY_WHEN_VALUE: RuleNotifyWhenType = 'onActionGroupChange'; -export const DEFAULT_FREQUENCY = { - notifyWhen: DEFAULT_NOTIFY_WHEN_VALUE, - throttle: null, - summary: false, -}; - export const NOTIFY_WHEN_OPTIONS: Array> = [ { value: 'onActionGroupChange', @@ -153,12 +148,18 @@ export const ActionNotifyWhen = ({ setShowCustomThrottleOpts(notifyWhenValue === 'onThrottleInterval'); }, [notifyWhenValue]); - const onNotifyWhenValueChange = useCallback((newValue: RuleNotifyWhenType) => { - onThrottleChange(newValue === 'onThrottleInterval' ? ruleThrottle : null, throttleUnit); - onNotifyWhenChange(newValue); - setNotifyWhenValue(newValue); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + const onNotifyWhenValueChange = useCallback( + (newValue: RuleNotifyWhenType) => { + onNotifyWhenChange(newValue); + setNotifyWhenValue(newValue); + setTimeout( + () => + onThrottleChange(newValue === 'onThrottleInterval' ? ruleThrottle : null, throttleUnit), + 100 + ); + }, + [onNotifyWhenChange, setNotifyWhenValue, onThrottleChange, ruleThrottle, throttleUnit] + ); const labelForRuleRenotify = [ i18n.translate('xpack.triggersActionsUI.sections.ruleForm.renotifyFieldLabel', { 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 5fbc3a190cdd0..9a7b2a190f01e 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 @@ -48,7 +48,7 @@ import { ActionAccordionFormProps, ActionGroupWithMessageVariables } from './act import { transformActionVariables } from '../../lib/action_variables'; import { useKibana } from '../../../common/lib/kibana'; import { ConnectorsSelection } from './connectors_selection'; -import { ActionNotifyWhen, DEFAULT_FREQUENCY } from './action_notify_when'; +import { ActionNotifyWhen } from './action_notify_when'; export type ActionTypeFormProps = { actionItem: RuleAction; @@ -58,6 +58,7 @@ export type ActionTypeFormProps = { onConnectorSelected: (id: string) => void; onDeleteAction: () => void; setActionParamsProperty: (key: string, value: RuleActionParam, index: number) => void; + setActionFrequencyProperty: (key: string, value: RuleActionParam, index: number) => void; actionTypesIndex: ActionTypeIndex; connectors: ActionConnector[]; actionTypeRegistry: ActionTypeRegistryContract; @@ -80,8 +81,6 @@ const preconfiguredMessage = i18n.translate( } ); -type ActionFrequency = NonNullable; - export const ActionTypeForm = ({ actionItem, actionConnector, @@ -90,6 +89,7 @@ export const ActionTypeForm = ({ onConnectorSelected, onDeleteAction, setActionParamsProperty, + setActionFrequencyProperty, actionTypesIndex, connectors, defaultActionGroupId, @@ -122,19 +122,6 @@ export const ActionTypeForm = ({ actionItem.frequency?.throttle ? getDurationUnitValue(actionItem.frequency?.throttle) : 'h' ); - const setActionFrequencyProperty = useCallback( - (key: Key, value: ActionFrequency[Key]) => { - setActionParamsProperty( - 'frequency', - { - ...(actionItem.frequency ?? DEFAULT_FREQUENCY), - [key]: value, - }, - index - ); - }, - [setActionParamsProperty, actionItem.frequency, index] - ); const getDefaultParams = async () => { const connectorType = await actionTypeRegistry.get(actionItem.actionTypeId); let defaultParams; @@ -189,6 +176,13 @@ export const ActionTypeForm = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [actionItem]); + // useEffect(() => { + // if (!actionItem.frequency) { + // setActionFrequency(DEFAULT_FREQUENCY, index); + // } + // // eslint-disable-next-line react-hooks/exhaustive-deps + // }, [actionItem.frequency]); + const canSave = hasSaveActionsCapability(capabilities); const actionGroupDisplay = ( @@ -220,17 +214,21 @@ export const ActionTypeForm = ({ throttleUnit={actionThrottleUnit} onNotifyWhenChange={useCallback( (notifyWhen) => { - setActionFrequencyProperty('notifyWhen', notifyWhen); + setActionFrequencyProperty('notifyWhen', notifyWhen, index); }, - [setActionFrequencyProperty] + [setActionFrequencyProperty, index] )} onThrottleChange={useCallback( (throttle: number | null, throttleUnit: string) => { setActionThrottle(throttle); setActionThrottleUnit(throttleUnit); - setActionFrequencyProperty('throttle', throttle ? `${throttle}${throttleUnit}` : null); + setActionFrequencyProperty( + 'throttle', + throttle ? `${throttle}${throttleUnit}` : null, + index + ); }, - [setActionFrequencyProperty] + [setActionFrequencyProperty, index] )} /> ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx index b12a3c07c7875..3e2f1f3d60ee6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.tsx @@ -65,7 +65,6 @@ const RuleAdd = ({ }, actions: [], tags: [], - notifyWhen: 'onActionGroupChange', ...(initialValues ? initialValues : {}), }; }, [ruleTypeId, consumer, initialValues]); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx index dd07430388ce3..19517821c3834 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx @@ -281,6 +281,13 @@ export const RuleForm = ({ [dispatch] ); + const setActionFrequencyProperty = useCallback( + (key: string, value: RuleActionParam, index: number) => { + dispatch({ command: { type: 'setRuleActionFrequency' }, payload: { key, value, index } }); + }, + [dispatch] + ); + useEffect(() => { const searchValue = searchText ? searchText.trim().toLocaleLowerCase() : null; setFilteredRuleTypes( @@ -557,7 +564,7 @@ export const RuleForm = ({ ) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts index 7f9950ddd5d0c..15e4d2f9c7924 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts @@ -9,10 +9,10 @@ import { SavedObjectAttribute } from '@kbn/core/public'; import { isEqual } from 'lodash'; import { Reducer } from 'react'; import { RuleActionParam, IntervalSchedule } from '@kbn/alerting-plugin/common'; -import { Rule, RuleAction } from '../../../types'; +import { Rule, RuleAction, RuleNotifyWhenType } from '../../../types'; export type InitialRule = Partial & - Pick; + Pick; interface CommandType< T extends @@ -22,10 +22,17 @@ interface CommandType< | 'setRuleParams' | 'setRuleActionParams' | 'setRuleActionProperty' + | 'setRuleActionFrequency' > { type: T; } +export const DEFAULT_FREQUENCY = { + notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, + throttle: null, + summary: false, +}; + export interface RuleState { rule: InitialRule; } @@ -77,7 +84,11 @@ export type RuleReducerAction = } | { command: CommandType<'setRuleActionProperty'>; - payload: RuleActionPayload; + payload: Payload; + } + | { + command: CommandType<'setRuleActionFrequency'>; + payload: Payload; }; export type InitialRuleReducer = Reducer<{ rule: InitialRule }, RuleReducerAction>; @@ -179,6 +190,36 @@ export const ruleReducer = ( }; } } + case 'setRuleActionFrequency': { + const { key, value, index } = action.payload as Payload< + keyof RuleAction, + SavedObjectAttribute + >; + if ( + index === undefined || + rule.actions[index] == null || + (!!rule.actions[index][key] && isEqual(rule.actions[index][key], value)) + ) { + return state; + } else { + const oldAction = rule.actions.splice(index, 1)[0]; + const updatedAction = { + ...oldAction, + frequency: { + ...(oldAction.frequency ?? DEFAULT_FREQUENCY), + [key]: value, + }, + }; + rule.actions.splice(index, 0, updatedAction); + return { + ...state, + rule: { + ...rule, + actions: [...rule.actions], + }, + }; + } + } case 'setRuleActionProperty': { const { key, value, index } = action.payload as RuleActionPayload; if (index === undefined || isEqual(rule.actions[index][key], value)) { diff --git a/x-pack/plugins/triggers_actions_ui/public/common/constants/action_frequency_types.ts b/x-pack/plugins/triggers_actions_ui/public/common/constants/action_frequency_types.ts new file mode 100644 index 0000000000000..be5b7a5ff79ba --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/common/constants/action_frequency_types.ts @@ -0,0 +1,14 @@ +/* + * 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 { RuleNotifyWhenType } from '../../types'; + +export const DEFAULT_FREQUENCY = { + notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, + throttle: null, + summary: false, +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts index 1db1551ecfd38..33d859b378c17 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts @@ -8,6 +8,7 @@ export { COMPARATORS, builtInComparators } from './comparators'; export { AGGREGATION_TYPES, builtInAggregationTypes } from './aggregation_types'; export { builtInGroupByTypes } from './group_by_types'; +export * from './action_frequency_types'; export const VIEW_LICENSE_OPTIONS_LINK = 'https://www.elastic.co/subscriptions'; From 1c8e2cf05545fe9477346951a2b11524d328b488 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 17 Nov 2022 16:18:46 -0600 Subject: [PATCH 24/85] Add action notification UI --- .../rule_details/components/rule_actions.tsx | 24 ++++++++++++++++++- .../components/rule_definition.tsx | 14 ----------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.tsx index 0f4d1b76dcdcb..6d38f1855cc38 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.tsx @@ -17,11 +17,17 @@ import { import { i18n } from '@kbn/i18n'; import { ActionTypeRegistryContract, RuleAction, suspendedComponentWithProps } from '../../../..'; import { useFetchRuleActionConnectors } from '../../../hooks/use_fetch_rule_action_connectors'; +import { NOTIFY_WHEN_OPTIONS } from '../../rule_form/rule_notify_when'; + +const getNotifyText = (action: RuleAction) => + NOTIFY_WHEN_OPTIONS.find((options) => options.value === action.frequency?.notifyWhen) + ?.inputDisplay || action.frequency?.notifyWhen; export interface RuleActionsProps { ruleActions: RuleAction[]; actionTypeRegistry: ActionTypeRegistryContract; } + export function RuleActions({ ruleActions, actionTypeRegistry }: RuleActionsProps) { const { isLoadingActionConnectors, actionConnectors } = useFetchRuleActionConnectors({ ruleActions, @@ -58,7 +64,8 @@ export function RuleActions({ ruleActions, actionTypeRegistry }: RuleActionsProp if (isLoadingActionConnectors) return ; return ( - {ruleActions.map(({ actionTypeId, id }, index) => { + {ruleActions.map((action, index) => { + const { actionTypeId, id } = action; const actionName = getActionName(id); return ( @@ -73,8 +80,23 @@ export function RuleActions({ ruleActions, actionTypeRegistry }: RuleActionsProp > {actionName} + + + + + + + + {String(getNotifyText(action))} + + + + ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_definition.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_definition.tsx index 6e24030cd60e1..217288ddbe535 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_definition.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_definition.tsx @@ -22,7 +22,6 @@ import { RuleDefinitionProps } from '../../../../types'; import { RuleType, useLoadRuleTypes } from '../../../..'; import { useKibana } from '../../../../common/lib/kibana'; import { hasAllPrivilege, hasExecuteActionsCapability } from '../../../lib/capabilities'; -import { NOTIFY_WHEN_OPTIONS } from '../../rule_form/rule_notify_when'; import { RuleActions } from './rule_actions'; import { RuleEdit } from '../../rule_form'; @@ -61,10 +60,6 @@ export const RuleDefinition: React.FunctionComponent = ({ values: { numberOfConditions }, }); }; - const getNotifyText = () => - NOTIFY_WHEN_OPTIONS.find((options) => options.value === rule?.notifyWhen)?.inputDisplay || - rule?.notifyWhen; - const canExecuteActions = hasExecuteActionsCapability(capabilities); const canSaveRule = rule && @@ -205,15 +200,6 @@ export const RuleDefinition: React.FunctionComponent = ({ - - - - {i18n.translate('xpack.triggersActionsUI.ruleDetails.notifyWhen', { - defaultMessage: 'Notify', - })} - - - From 366e023b02763fa9a0d5ec4d5c661ac7ac0f19aa Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 17 Nov 2022 16:21:51 -0600 Subject: [PATCH 25/85] Add legacy notifywhen to action notification UI --- .../rule_details/components/rule_actions.tsx | 18 +++++++++++++----- .../components/rule_definition.tsx | 6 +++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.tsx index 6d38f1855cc38..6ff952e7f30bb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.tsx @@ -15,20 +15,22 @@ import { EuiLoadingSpinner, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import { RuleNotifyWhenType } from '@kbn/alerting-plugin/common'; import { ActionTypeRegistryContract, RuleAction, suspendedComponentWithProps } from '../../../..'; import { useFetchRuleActionConnectors } from '../../../hooks/use_fetch_rule_action_connectors'; import { NOTIFY_WHEN_OPTIONS } from '../../rule_form/rule_notify_when'; -const getNotifyText = (action: RuleAction) => - NOTIFY_WHEN_OPTIONS.find((options) => options.value === action.frequency?.notifyWhen) - ?.inputDisplay || action.frequency?.notifyWhen; - export interface RuleActionsProps { ruleActions: RuleAction[]; actionTypeRegistry: ActionTypeRegistryContract; + legacyNotifyWhen?: RuleNotifyWhenType | null; } -export function RuleActions({ ruleActions, actionTypeRegistry }: RuleActionsProps) { +export function RuleActions({ + ruleActions, + actionTypeRegistry, + legacyNotifyWhen, +}: RuleActionsProps) { const { isLoadingActionConnectors, actionConnectors } = useFetchRuleActionConnectors({ ruleActions, }); @@ -49,6 +51,12 @@ export function RuleActions({ ruleActions, actionTypeRegistry }: RuleActionsProp ); } + const getNotifyText = (action: RuleAction) => + (NOTIFY_WHEN_OPTIONS.find((options) => options.value === action.frequency?.notifyWhen) + ?.inputDisplay || + action.frequency?.notifyWhen) ?? + legacyNotifyWhen; + const getActionIconClass = (actionGroupId?: string): IconType | undefined => { const actionGroup = actionTypeRegistry.list().find((group) => group.id === actionGroupId); return typeof actionGroup?.iconClass === 'string' diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_definition.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_definition.tsx index 217288ddbe535..0ea50d65d6594 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_definition.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_definition.tsx @@ -209,7 +209,11 @@ export const RuleDefinition: React.FunctionComponent = ({ })} - + From d6a2f3491136f2c433eeac994539c55c24ee61df Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Fri, 18 Nov 2022 11:29:33 -0600 Subject: [PATCH 26/85] Fix typecheck --- .../sections/action_connector_form/action_form.test.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 6beece7c983a6..5c4aaa79f0d95 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -341,6 +341,12 @@ describe('action_form', () => { setActionParamsProperty={(key: string, value: any, index: number) => (initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value }) } + setActionFrequencyProperty={(key: string, value: any, index: number) => + (initialAlert.actions[index] = { + ...initialAlert.actions[index], + frequency: { ...initialAlert.actions[index].frequency!, [key]: value }, + }) + } actionTypeRegistry={actionTypeRegistry} setHasActionsWithBrokenConnector={setHasActionsWithBrokenConnector} /> From c59a399f7cb1118948b74d25498b3e2e374d35f6 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 21 Nov 2022 11:34:33 -0600 Subject: [PATCH 27/85] Fix null throttle issue with tests --- x-pack/plugins/alerting/server/routes/create_rule.ts | 2 +- x-pack/plugins/alerting/server/routes/update_rule.ts | 2 +- x-pack/plugins/alerting/server/rules_client/rules_client.ts | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/alerting/server/routes/create_rule.ts b/x-pack/plugins/alerting/server/routes/create_rule.ts index f8757b1376983..8d418f8497cb3 100644 --- a/x-pack/plugins/alerting/server/routes/create_rule.ts +++ b/x-pack/plugins/alerting/server/routes/create_rule.ts @@ -33,7 +33,7 @@ export const bodySchema = schema.object({ enabled: schema.boolean({ defaultValue: true }), consumer: schema.string(), tags: schema.arrayOf(schema.string(), { defaultValue: [] }), - throttle: schema.maybe(schema.nullable(schema.string({ validate: validateDurationSchema }))), + throttle: schema.nullable(schema.maybe(schema.string({ validate: validateDurationSchema }))), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), diff --git a/x-pack/plugins/alerting/server/routes/update_rule.ts b/x-pack/plugins/alerting/server/routes/update_rule.ts index 5993c069b2592..1616cca43e713 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule.ts @@ -37,7 +37,7 @@ const bodySchema = schema.object({ schedule: schema.object({ interval: schema.string({ validate: validateDurationSchema }), }), - throttle: schema.maybe(schema.nullable(schema.string({ validate: validateDurationSchema }))), + throttle: schema.nullable(schema.maybe(schema.string({ validate: validateDurationSchema }))), params: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), actions: actionsSchema, notify_when: schema.maybe(schema.string({ validate: validateNotifyWhenType })), diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 93754d5e1cd9b..66a17cda6ef92 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -3923,7 +3923,8 @@ export class RulesClient { ): Promise { const { actions, notifyWhen, throttle } = data; const hasNotifyWhen = typeof notifyWhen !== 'undefined'; - const hasThrottle = typeof throttle !== 'undefined'; + // Due to a limitation in kbn-config-schema, undefined throttle will be converted to 'null' at the route level. Allow this. + const hasThrottle = typeof throttle !== 'undefined' && throttle !== null; let usesRuleLevelFreqParams; if (hasNotifyWhen && hasThrottle) usesRuleLevelFreqParams = true; else if (!hasNotifyWhen && !hasThrottle) usesRuleLevelFreqParams = false; From 22eed606c4f71e73aab74fe8bd7fd5365223c1cd Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 21 Nov 2022 13:20:22 -0600 Subject: [PATCH 28/85] Fix validateActions route processing --- .../plugins/alerting/server/rules_client/rules_client.ts | 8 +++++--- .../detection_engine_api_integration/utils/create_rule.ts | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 66a17cda6ef92..050ede6faa3f4 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -3922,9 +3922,11 @@ export class RulesClient { data: Pick & { actions: NormalizedAlertAction[] } ): Promise { const { actions, notifyWhen, throttle } = data; - const hasNotifyWhen = typeof notifyWhen !== 'undefined'; - // Due to a limitation in kbn-config-schema, undefined throttle will be converted to 'null' at the route level. Allow this. - const hasThrottle = typeof throttle !== 'undefined' && throttle !== null; + // Due to a limitation in kbn-config-schema, undefined throttle or notifyWhen + // will be converted to 'null' at the route level. + const hasNotifyWhen = Boolean(notifyWhen); + const hasThrottle = Boolean(throttle); + let usesRuleLevelFreqParams; if (hasNotifyWhen && hasThrottle) usesRuleLevelFreqParams = true; else if (!hasNotifyWhen && !hasThrottle) usesRuleLevelFreqParams = false; diff --git a/x-pack/test/detection_engine_api_integration/utils/create_rule.ts b/x-pack/test/detection_engine_api_integration/utils/create_rule.ts index 278bf0a92b40f..b110b8afb905d 100644 --- a/x-pack/test/detection_engine_api_integration/utils/create_rule.ts +++ b/x-pack/test/detection_engine_api_integration/utils/create_rule.ts @@ -59,7 +59,9 @@ export const createRule = async ( } } else if (response.status !== 200) { throw new Error( - `Unexpected non 200 ok when attempting to create a rule: ${JSON.stringify(response.status)}` + `Unexpected non 200 ok when attempting to create a rule: ${JSON.stringify( + response.status + )},${JSON.stringify(response, null, 4)}` ); } else { return response.body; From 5830ba1162e3fc4c880c8a8ecb891ebc3a6f007d Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 21 Nov 2022 13:33:29 -0600 Subject: [PATCH 29/85] Fix i18n --- x-pack/plugins/translations/translations/fr-FR.json | 1 - x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 3 files changed, 3 deletions(-) diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index f1633386a6ea9..5fd6a1e45a32e 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -32178,7 +32178,6 @@ "xpack.triggersActionsUI.ruleDetails.definition": "Définition", "xpack.triggersActionsUI.ruleDetails.description": "Description", "xpack.triggersActionsUI.ruleDetails.noActions": "Aucune action", - "xpack.triggersActionsUI.ruleDetails.notifyWhen": "Notifier", "xpack.triggersActionsUI.ruleDetails.ruleType": "Type de règle", "xpack.triggersActionsUI.ruleDetails.runsEvery": "S'exécute toutes les", "xpack.triggersActionsUI.rules.breadcrumbTitle": "Règles", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index f817015c2ee9a..7b99471198bd8 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -32152,7 +32152,6 @@ "xpack.triggersActionsUI.ruleDetails.definition": "定義", "xpack.triggersActionsUI.ruleDetails.description": "説明", "xpack.triggersActionsUI.ruleDetails.noActions": "アクションなし", - "xpack.triggersActionsUI.ruleDetails.notifyWhen": "通知", "xpack.triggersActionsUI.ruleDetails.ruleType": "ルールタイプ", "xpack.triggersActionsUI.ruleDetails.runsEvery": "次の間隔で実行", "xpack.triggersActionsUI.rules.breadcrumbTitle": "ルール", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 02e20106947ea..947f9dc3d8f4b 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -32189,7 +32189,6 @@ "xpack.triggersActionsUI.ruleDetails.definition": "定义", "xpack.triggersActionsUI.ruleDetails.description": "描述", "xpack.triggersActionsUI.ruleDetails.noActions": "无操作", - "xpack.triggersActionsUI.ruleDetails.notifyWhen": "通知", "xpack.triggersActionsUI.ruleDetails.ruleType": "规则类型", "xpack.triggersActionsUI.ruleDetails.runsEvery": "运行间隔", "xpack.triggersActionsUI.rules.breadcrumbTitle": "规则", From 02059231e5e06a866a69c11f9453ac348265f0f5 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 21 Nov 2022 13:48:08 -0600 Subject: [PATCH 30/85] Fix types --- .../sections/action_connector_form/action_type_form.test.tsx | 1 + 1 file changed, 1 insertion(+) 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 3005c86e17d6f..a759f7439272c 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 @@ -351,6 +351,7 @@ function getActionTypeForm( onConnectorSelected={onConnectorSelected ?? jest.fn()} defaultActionGroupId={defaultActionGroupId ?? 'default'} setActionParamsProperty={jest.fn()} + setActionFrequencyProperty={jest.fn()} index={index ?? 1} actionTypesIndex={actionTypeIndex ?? actionTypeIndexDefault} actionTypeRegistry={actionTypeRegistry} From 9d626f2b2c9eccb7d04187409a0739b3fb1de9bf Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 21 Nov 2022 14:46:08 -0600 Subject: [PATCH 31/85] Fix update test --- .../server/rules_client/rules_client.ts | 2 +- .../server/rules_client/tests/update.test.ts | 83 +++++++++++++++++-- 2 files changed, 79 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 050ede6faa3f4..f3b90a9c19604 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -3928,7 +3928,7 @@ export class RulesClient { const hasThrottle = Boolean(throttle); let usesRuleLevelFreqParams; - if (hasNotifyWhen && hasThrottle) usesRuleLevelFreqParams = true; + if (hasNotifyWhen && typeof throttle !== 'undefined') usesRuleLevelFreqParams = true; else if (!hasNotifyWhen && !hasThrottle) usesRuleLevelFreqParams = false; else { throw Boom.badRequest( diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index ae566c107862a..c2b11f6d81c4a 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -12,7 +12,7 @@ import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mock import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; import { ruleTypeRegistryMock } from '../../rule_type_registry.mock'; import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock'; -import { IntervalSchedule } from '../../types'; +import { IntervalSchedule, RuleNotifyWhenType } from '../../types'; import { RecoveredActionGroup } from '../../../common'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; @@ -98,6 +98,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, + throttle: null, + }, }, ], }, @@ -886,7 +891,7 @@ describe('update()', () => { bar: true, }, throttle: '5m', - notifyWhen: null, + notifyWhen: 'onThrottleInterval', actions: [ { group: 'default', @@ -1249,6 +1254,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], scheduledTaskId: 'task-123', @@ -1292,6 +1302,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], scheduledTaskId: 'task-123', @@ -1323,6 +1338,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], }, @@ -1390,6 +1410,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, { group: 'default', @@ -1398,6 +1423,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, { group: 'default', @@ -1406,6 +1436,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], scheduledTaskId: 'task-123', @@ -1439,8 +1474,6 @@ describe('update()', () => { params: { bar: true, }, - throttle: '5m', - notifyWhen: null, actions: [ { group: 'default', @@ -1448,6 +1481,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onThrottleInterval', + throttle: '5m', + }, }, { group: 'default', @@ -1455,6 +1493,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onThrottleInterval', + throttle: '5m', + }, }, { group: 'default', @@ -1462,6 +1505,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onThrottleInterval', + throttle: '5m', + }, }, ], }, @@ -1497,6 +1545,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], }, @@ -1572,6 +1625,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], scheduledTaskId: taskId, @@ -1612,6 +1670,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], }, @@ -1644,6 +1707,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], }, @@ -1739,7 +1807,7 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default"` + `"Actions missing frequency parameters: default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); @@ -1856,6 +1924,11 @@ describe('update()', () => { params: { foo: true, }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], }, From 074307eb94c086b77ab652459bdcdc56003ac2ae Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 21 Nov 2022 15:02:13 -0600 Subject: [PATCH 32/85] Remove check for undefined throttle entirely --- .../server/rules_client/rules_client.ts | 23 ++++--------------- 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index f3b90a9c19604..2e801a0c341fb 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -3921,23 +3921,8 @@ export class RulesClient { alertType: UntypedNormalizedRuleType, data: Pick & { actions: NormalizedAlertAction[] } ): Promise { - const { actions, notifyWhen, throttle } = data; - // Due to a limitation in kbn-config-schema, undefined throttle or notifyWhen - // will be converted to 'null' at the route level. - const hasNotifyWhen = Boolean(notifyWhen); - const hasThrottle = Boolean(throttle); - - let usesRuleLevelFreqParams; - if (hasNotifyWhen && typeof throttle !== 'undefined') usesRuleLevelFreqParams = true; - else if (!hasNotifyWhen && !hasThrottle) usesRuleLevelFreqParams = false; - else { - throw Boom.badRequest( - i18n.translate('xpack.alerting.rulesClient.usesValidGlobalFreqParams.oneUndefined', { - defaultMessage: - 'Rule-level notifyWhen and throttle must both be defined or both be undefined', - }) - ); - } + const { actions, notifyWhen } = data; + const hasRuleLevelNotifyWhen = Boolean(notifyWhen); if (actions.length === 0) { return; @@ -3983,7 +3968,9 @@ export class RulesClient { } // check for actions using frequency params if the rule has rule-level frequency params defined - if (usesRuleLevelFreqParams) { + // ONLY CHECK if rule-level notifyWhen is defined. We need to maintain backwards compatibility for + // cases where a rule-level throttle is still stored, but rule-level notifyWhen is null or undefined + if (hasRuleLevelNotifyWhen) { const actionsWithFrequency = actions.filter((action) => Boolean(action.frequency)); if (actionsWithFrequency.length) { throw Boom.badRequest( From 8ea7895f9b9be49e25acdb56744c19b07e6254a6 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 21 Nov 2022 15:35:53 -0600 Subject: [PATCH 33/85] Remove throttle value test --- .../monitoring/public/alerts/alert_form.test.tsx | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) 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 cefbc371e156d..ecf11fa122b36 100644 --- a/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx +++ b/x-pack/plugins/monitoring/public/alerts/alert_form.test.tsx @@ -165,19 +165,6 @@ describe('alert_form', () => { const alertTypeSelectOptions = wrapper.find('[data-test-subj="selectedRuleTypeTitle"]'); expect(alertTypeSelectOptions.exists()).toBeTruthy(); }); - - it('should update throttle value', async () => { - wrapper.find('button[data-test-subj="notifyWhenSelect"]').simulate('click'); - wrapper.update(); - wrapper.find('button[data-test-subj="onThrottleInterval"]').simulate('click'); - wrapper.update(); - const newThrottle = 17; - const throttleField = wrapper.find('[data-test-subj="throttleInput"]'); - expect(throttleField.exists()).toBeTruthy(); - throttleField.at(1).simulate('change', { target: { value: newThrottle.toString() } }); - const throttleFieldAfterUpdate = wrapper.find('[data-test-subj="throttleInput"]'); - expect(throttleFieldAfterUpdate.at(1).prop('value')).toEqual(newThrottle); - }); }); describe('alert_form > action_form', () => { @@ -253,6 +240,9 @@ describe('alert_form', () => { setActionParamsProperty={(key: string, value: any, index: number) => (initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value }) } + setActionFrequencyProperty={(key: string, value: any, index: number) => + (initialAlert.actions[index] = { ...initialAlert.actions[index], [key]: value }) + } actionTypeRegistry={actionTypeRegistry} featureId="alerting" /> From 5c578ca82a31bd74559876c15f3730e916841d01 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 21 Nov 2022 16:12:04 -0600 Subject: [PATCH 34/85] Fix security solution action frequency typecheck --- .../rules/rule_actions_field/index.tsx | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) 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 4cc5aed8aab69..fc1dc23a846e5 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 @@ -13,7 +13,7 @@ import ReactMarkdown from 'react-markdown'; import styled from 'styled-components'; import type { ActionVariables } from '@kbn/triggers-actions-ui-plugin/public'; -import type { RuleAction } from '@kbn/alerting-plugin/common'; +import type { RuleAction, RuleNotifyWhenType } from '@kbn/alerting-plugin/common'; import { SecurityConnectorFeatureId } from '@kbn/actions-plugin/common'; import type { FieldHook } from '../../../../shared_imports'; import { useFormContext } from '../../../../shared_imports'; @@ -29,6 +29,12 @@ const DEFAULT_ACTION_GROUP_ID = 'default'; const DEFAULT_ACTION_MESSAGE = 'Rule {{context.rule.name}} generated {{state.signals_count}} alerts'; +const DEFAULT_ACTION_FREQUENCY = { + notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, + throttle: null, + summary: false, +}; + const FieldErrorsContainer = styled.div` p { margin-bottom: 0; @@ -119,6 +125,28 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = [field] ); + const setActionFrequencyProperty = useCallback( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (key: string, value: any, index: number) => { + setTimeout( + () => + field.setValue((prevValue: RuleAction[]) => { + const updatedActions = [...prevValue]; + updatedActions[index] = { + ...updatedActions[index], + frequency: { + ...(updatedActions[index].frequency ?? DEFAULT_ACTION_FREQUENCY), + [key]: value, + }, + }; + return updatedActions; + }), + 0 + ); + }, + [field] + ); + const actionForm = useMemo( () => getActionForm({ @@ -128,6 +156,7 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = setActionIdByIndex, setActions: setAlertActionsProperty, setActionParamsProperty, + setActionFrequencyProperty, featureId: SecurityConnectorFeatureId, defaultActionMessage: DEFAULT_ACTION_MESSAGE, hideActionHeader: true, @@ -139,6 +168,7 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = setActionIdByIndex, setActionParamsProperty, setAlertActionsProperty, + setActionFrequencyProperty, ] ); From 6c577d6d952ec0dbcef961f3a33522488f731330 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 22 Nov 2022 11:52:20 -0600 Subject: [PATCH 35/85] Fix monitoring alerts creation and fix legacy tests --- .../alerting/common/rule_notify_when_type.ts | 6 +++++ x-pack/plugins/alerting/server/index.ts | 1 + .../server/routes/legacy/update.test.ts | 4 ++-- .../server/routes/update_rule.test.ts | 4 ++-- .../server/rules_client/rules_client.ts | 2 +- .../server/rules_client/tests/update.test.ts | 4 ++-- .../monitoring/server/alerts/base_rule.ts | 23 +++++++++++-------- .../rules/rule_actions_field/index.tsx | 5 ++-- .../application/lib/rule_api/update.test.ts | 5 ++-- .../constants/action_frequency_types.ts | 4 ++-- 10 files changed, 36 insertions(+), 22 deletions(-) diff --git a/x-pack/plugins/alerting/common/rule_notify_when_type.ts b/x-pack/plugins/alerting/common/rule_notify_when_type.ts index 4be2e35f2d392..0059938ed8667 100644 --- a/x-pack/plugins/alerting/common/rule_notify_when_type.ts +++ b/x-pack/plugins/alerting/common/rule_notify_when_type.ts @@ -12,6 +12,12 @@ export const RuleNotifyWhenTypeValues = [ ] as const; export type RuleNotifyWhenType = typeof RuleNotifyWhenTypeValues[number]; +export const RuleNotifyWhen: Record = { + CHANGE: 'onActionGroupChange', + ACTIVE: 'onActiveAlert', + THROTTLE: 'onThrottleInterval', +}; + export function validateNotifyWhenType(notifyWhen: string) { if (RuleNotifyWhenTypeValues.includes(notifyWhen as RuleNotifyWhenType)) { return; diff --git a/x-pack/plugins/alerting/server/index.ts b/x-pack/plugins/alerting/server/index.ts index 48f293fdd0043..b26a50ee2a050 100644 --- a/x-pack/plugins/alerting/server/index.ts +++ b/x-pack/plugins/alerting/server/index.ts @@ -30,6 +30,7 @@ export type { RuleParamsAndRefs, GetSummarizedAlertsFnOpts, } from './types'; +export { RuleNotifyWhen } from '../common'; export { DEFAULT_MAX_EPHEMERAL_ACTIONS_PER_ALERT } from './config'; export type { PluginSetupContract, PluginStartContract } from './plugin'; export type { diff --git a/x-pack/plugins/alerting/server/routes/legacy/update.test.ts b/x-pack/plugins/alerting/server/routes/legacy/update.test.ts index 61073c0d4e3bf..756e751e5c6e4 100644 --- a/x-pack/plugins/alerting/server/routes/legacy/update.test.ts +++ b/x-pack/plugins/alerting/server/routes/legacy/update.test.ts @@ -13,7 +13,7 @@ import { verifyApiAccess } from '../../lib/license_api_access'; import { mockHandlerArguments } from '../_mock_handler_arguments'; import { rulesClientMock } from '../../rules_client.mock'; import { RuleTypeDisabledError } from '../../lib/errors/rule_type_disabled'; -import { RuleNotifyWhenType } from '../../../common'; +import { RuleNotifyWhen } from '../../../common'; import { trackLegacyRouteUsage } from '../../lib/track_legacy_route_usage'; const rulesClient = rulesClientMock.create(); @@ -50,7 +50,7 @@ describe('updateAlertRoute', () => { }, }, ], - notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, + notifyWhen: RuleNotifyWhen.CHANGE, }; it('updates an alert with proper parameters', async () => { diff --git a/x-pack/plugins/alerting/server/routes/update_rule.test.ts b/x-pack/plugins/alerting/server/routes/update_rule.test.ts index 853a002ade57c..8c335a9bf9864 100644 --- a/x-pack/plugins/alerting/server/routes/update_rule.test.ts +++ b/x-pack/plugins/alerting/server/routes/update_rule.test.ts @@ -14,7 +14,7 @@ import { mockHandlerArguments } from './_mock_handler_arguments'; import { UpdateOptions } from '../rules_client'; import { rulesClientMock } from '../rules_client.mock'; import { RuleTypeDisabledError } from '../lib/errors/rule_type_disabled'; -import { RuleNotifyWhenType } from '../../common'; +import { RuleNotifyWhen } from '../../common'; import { AsApiContract } from './lib'; import { PartialRule } from '../types'; @@ -50,7 +50,7 @@ describe('updateRuleRoute', () => { }, }, ], - notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, + notifyWhen: RuleNotifyWhen.CHANGE, }; const updateRequest: AsApiContract['data']> = { diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 2e801a0c341fb..04171b370ca16 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -3922,7 +3922,7 @@ export class RulesClient { data: Pick & { actions: NormalizedAlertAction[] } ): Promise { const { actions, notifyWhen } = data; - const hasRuleLevelNotifyWhen = Boolean(notifyWhen); + const hasRuleLevelNotifyWhen = typeof notifyWhen !== 'undefined'; if (actions.length === 0) { return; diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index c2b11f6d81c4a..f77a156d6f3dc 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -12,7 +12,7 @@ import { savedObjectsClientMock, loggingSystemMock } from '@kbn/core/server/mock import { taskManagerMock } from '@kbn/task-manager-plugin/server/mocks'; import { ruleTypeRegistryMock } from '../../rule_type_registry.mock'; import { alertingAuthorizationMock } from '../../authorization/alerting_authorization.mock'; -import { IntervalSchedule, RuleNotifyWhenType } from '../../types'; +import { IntervalSchedule, RuleNotifyWhen } from '../../types'; import { RecoveredActionGroup } from '../../../common'; import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/server/mocks'; import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; @@ -100,7 +100,7 @@ describe('update()', () => { }, frequency: { summary: false, - notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, + notifyWhen: RuleNotifyWhen.CHANGE, throttle: null, }, }, diff --git a/x-pack/plugins/monitoring/server/alerts/base_rule.ts b/x-pack/plugins/monitoring/server/alerts/base_rule.ts index 1888265c124f6..3e08d370af56b 100644 --- a/x-pack/plugins/monitoring/server/alerts/base_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/base_rule.ts @@ -9,6 +9,7 @@ import { Logger, ElasticsearchClient } from '@kbn/core/server'; import { i18n } from '@kbn/i18n'; import { RuleType, + RuleNotifyWhen, RuleExecutorOptions, Alert, RulesClient, @@ -124,6 +125,14 @@ export class BaseRule { return existingRuleData.data[0] as Rule; } + const { + defaultParams: params = {}, + name, + id: alertTypeId, + throttle = '1d', + interval = '1m', + } = this.ruleOptions; + const ruleActions = []; for (const actionData of actions) { const action = await actionsClient.get({ id: actionData.id }); @@ -137,16 +146,14 @@ export class BaseRule { message: '{{context.internalShortMessage}}', ...actionData.config, }, + frequency: { + summary: false, + notifyWhen: RuleNotifyWhen.THROTTLE, + throttle, + }, }); } - const { - defaultParams: params = {}, - name, - id: alertTypeId, - throttle = '1d', - interval = '1m', - } = this.ruleOptions; return await rulesClient.create({ data: { enabled: true, @@ -155,8 +162,6 @@ export class BaseRule { consumer: 'monitoring', name, alertTypeId, - throttle, - notifyWhen: null, schedule: { interval }, actions: ruleActions, }, 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 fc1dc23a846e5..08e97da1ba57b 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 @@ -13,7 +13,8 @@ import ReactMarkdown from 'react-markdown'; import styled from 'styled-components'; import type { ActionVariables } from '@kbn/triggers-actions-ui-plugin/public'; -import type { RuleAction, RuleNotifyWhenType } from '@kbn/alerting-plugin/common'; +import type { RuleAction } from '@kbn/alerting-plugin/common'; +import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import { SecurityConnectorFeatureId } from '@kbn/actions-plugin/common'; import type { FieldHook } from '../../../../shared_imports'; import { useFormContext } from '../../../../shared_imports'; @@ -30,7 +31,7 @@ const DEFAULT_ACTION_MESSAGE = 'Rule {{context.rule.name}} generated {{state.signals_count}} alerts'; const DEFAULT_ACTION_FREQUENCY = { - notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, + notifyWhen: RuleNotifyWhen.CHANGE, throttle: null, summary: false, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.test.ts index 29bf8027bfe47..afa64ea4b8d45 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.test.ts @@ -5,7 +5,8 @@ * 2.0. */ -import { Rule, RuleNotifyWhenType } from '../../../types'; +import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; +import { Rule } from '../../../types'; import { httpServiceMock } from '@kbn/core/public/mocks'; import { updateRule } from './update'; @@ -27,7 +28,7 @@ describe('updateRule', () => { updatedAt: new Date('1970-01-01T00:00:00.000Z'), apiKey: null, apiKeyOwner: null, - notifyWhen: 'onThrottleInterval' as RuleNotifyWhenType, + notifyWhen: RuleNotifyWhen.THROTTLE, }; const resolvedValue: Rule = { ...ruleToUpdate, diff --git a/x-pack/plugins/triggers_actions_ui/public/common/constants/action_frequency_types.ts b/x-pack/plugins/triggers_actions_ui/public/common/constants/action_frequency_types.ts index be5b7a5ff79ba..7ebfc502ed07d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/constants/action_frequency_types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/constants/action_frequency_types.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { RuleNotifyWhenType } from '../../types'; +import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; export const DEFAULT_FREQUENCY = { - notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, + notifyWhen: RuleNotifyWhen.CHANGE, throttle: null, summary: false, }; From bd6f4f16efd7424bbe218faa30afc3435336c8b5 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 22 Nov 2022 12:03:54 -0600 Subject: [PATCH 36/85] Fix jest for create rule --- .../plugins/alerting/server/rules_client/tests/create.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index 4d9b84e53a2f4..448917bfb1606 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -15,6 +15,7 @@ import { encryptedSavedObjectsMock } from '@kbn/encrypted-saved-objects-plugin/s import { actionsAuthorizationMock } from '@kbn/actions-plugin/server/mocks'; import { AlertingAuthorization } from '../../authorization/alerting_authorization'; import { ActionsAuthorization, ActionsClient } from '@kbn/actions-plugin/server'; +import { RuleNotifyWhen } from '../../types'; import { TaskStatus } from '@kbn/task-manager-plugin/server'; import { auditLoggerMock } from '@kbn/security-plugin/server/audit/mocks'; import { getBeforeSetup, setGlobalDate } from './lib'; @@ -165,6 +166,7 @@ describe('create()', () => { params: { foo: true, }, + frequency: { summary: false, notifyWhen: RuleNotifyWhen.CHANGE, throttle: null }, }, ], }, From 966d2ce46e13f8fd8bf45903a1f97821b15cdb13 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 22 Nov 2022 14:20:47 -0600 Subject: [PATCH 37/85] Fix update jest --- .../server/rules_client/tests/update.test.ts | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index f77a156d6f3dc..8dd1cd0181f31 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -87,8 +87,6 @@ describe('update()', () => { consumer: 'myApp', scheduledTaskId: 'task-123', params: {}, - throttle: null, - notifyWhen: null, actions: [ { group: 'default', @@ -1329,8 +1327,6 @@ describe('update()', () => { params: { bar: true, }, - throttle: null, - notifyWhen: null, actions: [ { group: 'default', @@ -1536,8 +1532,6 @@ describe('update()', () => { params: { bar: true, }, - throttle: null, - notifyWhen: null, actions: [ { group: 'default', @@ -1661,8 +1655,6 @@ describe('update()', () => { params: { bar: true, }, - throttle: null, - notifyWhen: null, actions: [ { group: 'default', @@ -1698,8 +1690,6 @@ describe('update()', () => { params: { bar: true, }, - throttle: null, - notifyWhen: null, actions: [ { group: 'default', @@ -1807,7 +1797,7 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Actions missing frequency parameters: default"` + `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); @@ -1915,8 +1905,6 @@ describe('update()', () => { params: { bar: true, }, - throttle: null, - notifyWhen: null, actions: [ { group: 'default', From d3e9e60922aabcf2673bc175b1420510dd4ae34d Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 22 Nov 2022 14:22:02 -0600 Subject: [PATCH 38/85] Fix baseRule test --- x-pack/plugins/monitoring/server/alerts/base_rule.test.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/monitoring/server/alerts/base_rule.test.ts b/x-pack/plugins/monitoring/server/alerts/base_rule.test.ts index 5234fcfce5cbf..c5f528d1b19b1 100644 --- a/x-pack/plugins/monitoring/server/alerts/base_rule.test.ts +++ b/x-pack/plugins/monitoring/server/alerts/base_rule.test.ts @@ -51,6 +51,11 @@ describe('BaseRule', () => { params: { message: '{{context.internalShortMessage}}', }, + frequency: { + summary: false, + notifyWhen: 'onThrottleInterval', + throttle: '1d', + }, }, ], alertTypeId: '', @@ -65,8 +70,6 @@ describe('BaseRule', () => { interval: '1m', }, tags: [], - throttle: '1d', - notifyWhen: null, }, }); }); From 63cec0d29aa232af6e28fd668132419b0f90a229 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 22 Nov 2022 15:14:21 -0600 Subject: [PATCH 39/85] Fix alert create flyout test --- .../apps/triggers_actions_ui/alert_create_flyout.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts index 042605c0ae585..b788b4f875c6e 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alert_create_flyout.ts @@ -89,10 +89,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const alertName = generateUniqueKey(); await rules.common.defineIndexThresholdAlert(alertName); - await testSubjects.click('notifyWhenSelect'); - await testSubjects.click('onThrottleInterval'); - await testSubjects.setValue('throttleInput', '10'); - // filterKuery validation await testSubjects.setValue('filterKuery', 'group:'); const filterKueryInput = await testSubjects.find('filterKuery'); @@ -108,6 +104,9 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await find.clickByCssSelector('[data-test-subj="saveActionButtonModal"]:not(disabled)'); const createdConnectorToastTitle = await pageObjects.common.closeToast(); expect(createdConnectorToastTitle).to.eql(`Created '${slackConnectorName}'`); + await testSubjects.click('notifyWhenSelect'); + await testSubjects.click('onThrottleInterval'); + await testSubjects.setValue('throttleInput', '10'); const messageTextArea = await find.byCssSelector('[data-test-subj="messageTextArea"]'); expect(await messageTextArea.getAttribute('value')).to.eql( `alert '{{alertName}}' is active for group '{{context.group}}': @@ -236,7 +235,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await testSubjects.missingOrFail('confirmRuleCloseModal'); await pageObjects.triggersActionsUI.clickCreateAlertButton(); - await testSubjects.setValue('intervalInput', '10'); + await testSubjects.setValue('ruleNameInput', 'alertName'); await testSubjects.click('cancelSaveRuleButton'); await testSubjects.existOrFail('confirmRuleCloseModal'); await testSubjects.click('confirmRuleCloseModal > confirmModalCancelButton'); From 0cb91c27437cf4fdb8ce7a17a953c51022120e96 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 22 Nov 2022 16:37:37 -0600 Subject: [PATCH 40/85] Fix rule details tests and editing legacy alerts --- .../server/rules_client/rules_client.ts | 10 +-- .../sections/rule_form/rule_edit.tsx | 28 +++++- .../apps/triggers_actions_ui/details.ts | 90 ++++++++++++++++++- .../lib/get_test_data.ts | 2 - 4 files changed, 119 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/rules_client.ts b/x-pack/plugins/alerting/server/rules_client/rules_client.ts index 9530ed0bef696..611a3b7e387be 100644 --- a/x-pack/plugins/alerting/server/rules_client/rules_client.ts +++ b/x-pack/plugins/alerting/server/rules_client/rules_client.ts @@ -3924,8 +3924,9 @@ export class RulesClient { alertType: UntypedNormalizedRuleType, data: Pick & { actions: NormalizedAlertAction[] } ): Promise { - const { actions, notifyWhen } = data; + const { actions, notifyWhen, throttle } = data; const hasRuleLevelNotifyWhen = typeof notifyWhen !== 'undefined'; + const hasRuleLevelThrottle = Boolean(throttle); if (actions.length === 0) { return; @@ -3970,16 +3971,13 @@ export class RulesClient { ); } - // check for actions using frequency params if the rule has rule-level frequency params defined - // ONLY CHECK if rule-level notifyWhen is defined. We need to maintain backwards compatibility for - // cases where a rule-level throttle is still stored, but rule-level notifyWhen is null or undefined - if (hasRuleLevelNotifyWhen) { + if (hasRuleLevelNotifyWhen || hasRuleLevelThrottle) { const actionsWithFrequency = actions.filter((action) => Boolean(action.frequency)); if (actionsWithFrequency.length) { throw Boom.badRequest( i18n.translate('xpack.alerting.rulesClient.validateActions.mixAndMatchFreqParams', { defaultMessage: - 'Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: {groups}', + 'Cannot specify per-action frequency params when notify_when or throttle are defined at the rule level: {groups}', values: { groups: actionsWithFrequency.map((a) => a.group).join(', '), }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx index a03ba8dc92620..4cf79206ffe38 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx @@ -7,6 +7,7 @@ import React, { useReducer, useState, useEffect, useCallback } from 'react'; import { FormattedMessage } from '@kbn/i18n-react'; +import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import { EuiTitle, EuiFlyoutHeader, @@ -23,7 +24,7 @@ import { EuiLoadingSpinner, EuiIconTip, } from '@elastic/eui'; -import { cloneDeep } from 'lodash'; +import { cloneDeep, omit } from 'lodash'; import { i18n } from '@kbn/i18n'; import { Rule, @@ -32,6 +33,7 @@ import { IErrorObject, RuleType, TriggersActionsUiConfig, + RuleNotifyWhenType, } from '../../../types'; import { RuleForm } from './rule_form'; import { getRuleActionErrors, getRuleErrors, isValidRule } from './rule_errors'; @@ -45,6 +47,28 @@ import { hasRuleChanged } from './has_rule_changed'; import { getRuleWithInvalidatedFields } from '../../lib/value_validators'; import { triggersActionsUiConfig } from '../../../common/lib/config_api'; +const cloneAndMigrateRule = (initialRule: Rule) => { + const clonedRule = cloneDeep(omit(initialRule, 'notifyWhen', 'throttle')); + + const hasRuleLevelNotifyWhen = Boolean(initialRule.notifyWhen); + const hasRuleLevelThrottle = Boolean(initialRule.throttle); + + if (hasRuleLevelNotifyWhen || hasRuleLevelThrottle) { + const frequency = hasRuleLevelNotifyWhen + ? { + summary: false, + notifyWhen: initialRule.notifyWhen as RuleNotifyWhenType, + throttle: null, + } + : { summary: false, notifyWhen: RuleNotifyWhen.THROTTLE, throttle: initialRule.throttle! }; + clonedRule.actions = clonedRule.actions.map((action) => ({ + ...action, + frequency, + })); + } + return clonedRule; +}; + export const RuleEdit = ({ initialRule, onClose, @@ -57,7 +81,7 @@ export const RuleEdit = ({ }: RuleEditProps) => { const onSaveHandler = onSave ?? reloadRules; const [{ rule }, dispatch] = useReducer(ruleReducer as ConcreteRuleReducer, { - rule: cloneDeep(initialRule), + rule: cloneAndMigrateRule(initialRule), }); const [isSaving, setIsSaving] = useState(false); const [hasActionsDisabled, setHasActionsDisabled] = useState(false); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index 6c5de895ed1fd..8bdccc97fe562 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -11,6 +11,7 @@ import { omit, mapValues, range, flatten } from 'lodash'; import moment from 'moment'; import { asyncForEach } from '@kbn/std'; import { alwaysFiringAlertType } from '@kbn/alerting-fixture-plugin/server/plugin'; +import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import { FtrProviderContext } from '../../ftr_provider_context'; import { ObjectRemover } from '../../lib/object_remover'; import { getTestAlertData, getTestActionData } from '../../lib/get_test_data'; @@ -88,6 +89,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { message: 'from alert 1s', level: 'warn', }, + frequency: { + summary: false, + notify_when: RuleNotifyWhen.THROTTLE, + throttle: '1m', + }, })), params, ...overwrites, @@ -111,6 +117,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { message: 'from alert 1s', level: 'warn', }, + frequency: { + summary: false, + notify_when: RuleNotifyWhen.THROTTLE, + throttle: '1m', + }, })), params, }); @@ -329,6 +340,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { group: 'threshold met', id: 'my-server-log', params: { level: 'info', message: ' {{context.message}}' }, + frequency: { + summary: false, + notify_when: RuleNotifyWhen.THROTTLE, + throttle: '1m', + }, }, ], }); @@ -425,6 +441,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { group: 'default', id: connector.id, params: { level: 'info', message: ' {{context.message}}' }, + frequency: { + summary: false, + notify_when: RuleNotifyWhen.THROTTLE, + throttle: '1m', + }, }, ], }); @@ -487,11 +508,21 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { group: 'default', id: connector.id, params: { level: 'info', message: ' {{context.message}}' }, + frequency: { + summary: false, + notify_when: RuleNotifyWhen.THROTTLE, + throttle: '1m', + }, }, { group: 'other', id: connector.id, params: { level: 'info', message: ' {{context.message}}' }, + frequency: { + summary: false, + notify_when: RuleNotifyWhen.THROTTLE, + throttle: '1m', + }, }, ], }); @@ -568,6 +599,64 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); + describe('Edit rule with legacy global notify values', function () { + const testRunUuid = uuid.v4(); + + afterEach(async () => { + await objectRemover.removeAll(); + }); + + it('should convert global params to action-level params and save the alert successfully', async () => { + const connectors = await createConnectors(testRunUuid); + await pageObjects.common.navigateToApp('triggersActions'); + const rule = await createAlwaysFiringRule({ + name: `test-rule-${testRunUuid}`, + schedule: { + interval: '1s', + }, + notify_when: RuleNotifyWhen.THROTTLE, + throttle: '1m', + actions: connectors.map((connector) => ({ + id: connector.id, + group: 'default', + params: { + message: 'from alert 1s', + level: 'warn', + }, + })), + }); + const updatedRuleName = `Changed rule ${rule.name}`; + + // refresh to see rule + await browser.refresh(); + await pageObjects.header.waitUntilLoadingHasFinished(); + + // verify content + await testSubjects.existOrFail('rulesList'); + + // Wait to ensure the table is finished loading + await pageObjects.triggersActionsUI.tableFinishedLoading(); + + // click on first alert + await pageObjects.common.navigateToApp('triggersActions'); + await pageObjects.triggersActionsUI.clickOnAlertInAlertsList(rule.name); + + const editButton = await testSubjects.find('openEditRuleFlyoutButton'); + await editButton.click(); + const notifyWhenSelect = await testSubjects.find('notifyWhenSelect'); + expect(await notifyWhenSelect.getVisibleText()).to.eql('On custom action intervals'); + + await testSubjects.setValue('ruleNameInput', updatedRuleName, { + clearWithKeyboard: true, + }); + + await find.clickByCssSelector('[data-test-subj="saveEditedRuleButton"]:not(disabled)'); + + const toastTitle = await pageObjects.common.closeToast(); + expect(toastTitle).to.eql(`Updated '${updatedRuleName}'`); + }); + }); + describe('View In App', function () { const ruleName = uuid.v4(); @@ -921,7 +1010,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }, { schedule: { interval: '1s' }, - throttle: null, } ); diff --git a/x-pack/test/functional_with_es_ssl/lib/get_test_data.ts b/x-pack/test/functional_with_es_ssl/lib/get_test_data.ts index 8dc8a5e06645c..51157932eee3d 100644 --- a/x-pack/test/functional_with_es_ssl/lib/get_test_data.ts +++ b/x-pack/test/functional_with_es_ssl/lib/get_test_data.ts @@ -19,8 +19,6 @@ export function getTestAlertData(overwrites = {}) { rule_type_id: 'test.noop', consumer: 'alerts', schedule: { interval: '1m' }, - throttle: '1m', - notify_when: 'onThrottleInterval', actions: [], params: {}, ...overwrites, From 969a963ef9ed49c802c045908661e5e37815c53c Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 5 Dec 2022 15:28:03 -0600 Subject: [PATCH 41/85] Fix alerts list test 400 error --- .../apps/triggers_actions_ui/alerts_list.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts_list.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts_list.ts index bb6d8a46988a5..8c336a960638b 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts_list.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/alerts_list.ts @@ -493,6 +493,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { id: action.id, group: 'default', params: { level: 'info', message: 'gfghfhg' }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], }, @@ -669,6 +674,11 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { id: action.id, group: 'default', params: { level: 'info', message: 'gfghfhg' }, + frequency: { + summary: false, + notifyWhen: 'onActionGroupChange', + throttle: null, + }, }, ], }, From 275ee6366fc8bea2465a93a8dbc3a20375e9b276 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 5 Dec 2022 15:31:42 -0600 Subject: [PATCH 42/85] Update snapshots --- .../saved_objects/migrations/check_registered_types.test.ts | 2 +- .../plugins/alerting/server/rules_client/tests/create.test.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts index ff50b46b9b3f3..db909b08709ba 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts @@ -57,7 +57,7 @@ describe('checking migration metadata changes on all registered SO types', () => Object { "action": "7858e6d5a9f231bf23f6f2e57328eb0095b26735", "action_task_params": "bbd38cbfd74bf6713586fe078e3fa92db2234299", - "alert": "eefada4a02ce05962387c0679d7b292771a931c4", + "alert": "4cfdc31b6a2d48e5399a00674022f302479cd978", "api_key_pending_invalidation": "9b4bc1235337da9a87ef05a1d1f4858b2a3b77c6", "apm-indices": "ceb0870f3a74e2ffc3a1cd3a3c73af76baca0999", "apm-server-schema": "2bfd2998d3873872e1366458ce553def85418f91", diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index 448917bfb1606..e4756b6db5a34 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -2715,7 +2715,7 @@ describe('create()', () => { ], }); await expect(rulesClient.create({ data })).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default, default"` + `"Cannot specify per-action frequency params when notify_when or throttle are defined at the rule level: default, default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); @@ -2745,7 +2745,7 @@ describe('create()', () => { ], }); await expect(rulesClient.create({ data: data2 })).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default"` + `"Cannot specify per-action frequency params when notify_when or throttle are defined at the rule level: default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); From ca2b24c651360e63a859f5903ebaa13ade0a9ef4 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 5 Dec 2022 16:16:00 -0600 Subject: [PATCH 43/85] Update snapshots --- .../plugins/alerting/server/rules_client/tests/update.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts index 8dd1cd0181f31..99a7c32004f46 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/update.test.ts @@ -1756,7 +1756,7 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default, default"` + `"Cannot specify per-action frequency params when notify_when or throttle are defined at the rule level: default, default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); @@ -1797,7 +1797,7 @@ describe('update()', () => { }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Cannot specify per-action frequency params when notify_when and throttle are defined at the rule level: default"` + `"Cannot specify per-action frequency params when notify_when or throttle are defined at the rule level: default"` ); expect(unsecuredSavedObjectsClient.create).not.toHaveBeenCalled(); expect(taskManager.schedule).not.toHaveBeenCalled(); From 302f6d87d1261914f8dcda3b7d97defd9a962c88 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 6 Dec 2022 16:23:29 -0600 Subject: [PATCH 44/85] Update security solution actions form --- .../src/actions/index.ts | 41 +++++++++++++------ .../rules/bulk_actions/request_schema.test.ts | 18 ++++++-- .../api/rules/bulk_actions/request_schema.ts | 15 ++++--- .../bulk_actions/forms/rule_actions_form.tsx | 18 +++++++- .../rules/rule_actions_field/index.tsx | 1 + .../action_connector_form/action_form.tsx | 3 ++ .../action_type_form.tsx | 11 +++-- 7 files changed, 80 insertions(+), 27 deletions(-) diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts index 2e0d814bf93c5..85badce161871 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts @@ -25,14 +25,28 @@ export const RuleActionTypeId = t.string; export type RuleActionParams = t.TypeOf; export const RuleActionParams = saved_object_attributes; +export type RuleActionFrequency = t.TypeOf; +export const RuleActionFrequency = t.type({ + summary: t.boolean, + notifyWhen: t.union([ + t.literal('onActionGroupChange'), + t.literal('onActiveAlert'), + t.literal('onThrottleInterval'), + ]), + throttle: t.union([t.string, t.null]), +}); + export type RuleAction = t.TypeOf; export const RuleAction = t.exact( - t.type({ - group: RuleActionGroup, - id: RuleActionId, - action_type_id: RuleActionTypeId, - params: RuleActionParams, - }) + t.intersection([ + t.type({ + group: RuleActionGroup, + id: RuleActionId, + action_type_id: RuleActionTypeId, + params: RuleActionParams, + }), + t.partial({ frequency: RuleActionFrequency }), + ]) ); export type RuleActionArray = t.TypeOf; @@ -40,12 +54,15 @@ export const RuleActionArray = t.array(RuleAction); export type RuleActionCamel = t.TypeOf; export const RuleActionCamel = t.exact( - t.type({ - group: RuleActionGroup, - id: RuleActionId, - actionTypeId: RuleActionTypeId, - params: RuleActionParams, - }) + t.intersection([ + t.type({ + group: RuleActionGroup, + id: RuleActionId, + actionTypeId: RuleActionTypeId, + params: RuleActionParams, + }), + t.partial({ frequency: RuleActionFrequency }), + ]) ); export type RuleActionArrayCamel = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts index 3cee4c3dbe384..0a0d201fd5c6d 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts @@ -564,7 +564,6 @@ describe('Perform bulk action request schema', () => { { type: BulkActionEditType.add_rule_actions, value: { - throttle: '1h', actions: [ { action_type_id: '.webhook', @@ -575,6 +574,11 @@ describe('Perform bulk action request schema', () => { rule_id: '{{rule.id}}', }, }, + frequency: { + notifyWhen: 'onThrottleInterval', + throttle: '1h', + summary: false, + }, }, ], }, @@ -597,7 +601,6 @@ describe('Perform bulk action request schema', () => { { type: BulkActionEditType.add_rule_actions, value: { - throttle: '1h', actions: [ { group: 'default', @@ -607,6 +610,11 @@ describe('Perform bulk action request schema', () => { rule_id: '{{rule.id}}', }, }, + frequency: { + notifyWhen: 'onThrottleInterval', + throttle: '1h', + summary: false, + }, }, ], }, @@ -628,7 +636,6 @@ describe('Perform bulk action request schema', () => { { type: BulkActionEditType.set_rule_actions, value: { - throttle: '1h', actions: [ { group: 'default', @@ -640,6 +647,11 @@ describe('Perform bulk action request schema', () => { }, ], }, + frequency: { + notifyWhen: 'onThrottleInterval', + throttle: '1h', + summary: false, + }, }, ], }, diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts index d595dc88441cc..c760e47d1f26a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts @@ -12,6 +12,7 @@ import { RuleActionGroup, RuleActionId, RuleActionParams, + RuleActionFrequency, } from '@kbn/securitysolution-io-ts-alerting-types'; import { @@ -94,11 +95,14 @@ const BulkActionEditPayloadTimeline = t.type({ */ type NormalizedRuleAction = t.TypeOf; const NormalizedRuleAction = t.exact( - t.type({ - group: RuleActionGroup, - id: RuleActionId, - params: RuleActionParams, - }) + t.intersection([ + t.type({ + group: RuleActionGroup, + id: RuleActionId, + params: RuleActionParams, + }), + t.partial({ frequency: RuleActionFrequency }), + ]) ); export type BulkActionEditPayloadRuleActions = t.TypeOf; @@ -108,7 +112,6 @@ export const BulkActionEditPayloadRuleActions = t.type({ t.literal(BulkActionEditType.set_rule_actions), ]), value: t.type({ - throttle: ThrottleForBulkActions, actions: t.array(NormalizedRuleAction), }), }); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx index 0bff754f20f4f..3c6fddb20c1c1 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx @@ -7,6 +7,7 @@ import React, { useCallback, useMemo } from 'react'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; +import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import type { RuleAction, @@ -110,11 +111,24 @@ const RuleActionsFormComponent = ({ rulesCount, onClose, onConfirm }: RuleAction ? BulkActionEditType.set_rule_actions : BulkActionEditType.add_rule_actions; + const frequencyToSubmit = + throttleToSubmit === NOTIFICATION_THROTTLE_RULE + ? { + notifyWhen: RuleNotifyWhen.ACTIVE, + throttle: null, + } + : { + notifyWhen: RuleNotifyWhen.THROTTLE, + throttle: throttleToSubmit, + }; + onConfirm({ type: editAction, value: { - actions: actions.map(({ actionTypeId, ...action }) => action), - throttle: throttleToSubmit, + actions: actions.map(({ actionTypeId, ...action }) => ({ + ...action, + frequency: { ...frequencyToSubmit, summary: false }, + })), }, }); }, [form, onConfirm]); 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 08e97da1ba57b..8b32864e449e7 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 @@ -161,6 +161,7 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = featureId: SecurityConnectorFeatureId, defaultActionMessage: DEFAULT_ACTION_MESSAGE, hideActionHeader: true, + hideNotifyWhen: true, }), [ actions, 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 fd429b5442214..1edf372334757 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 @@ -64,6 +64,7 @@ export interface ActionAccordionFormProps { recoveryActionGroup?: string; isActionGroupDisabledForActionType?: (actionGroupId: string, actionTypeId: string) => boolean; hideActionHeader?: boolean; + hideNotifyWhen?: boolean; } interface ActiveActionConnectorState { @@ -89,6 +90,7 @@ export const ActionForm = ({ recoveryActionGroup, isActionGroupDisabledForActionType, hideActionHeader, + hideNotifyWhen, }: ActionAccordionFormProps) => { const { http, @@ -393,6 +395,7 @@ export const ActionForm = ({ ); setActiveActionItem(undefined); }} + hideNotifyWhen={hideNotifyWhen} /> ); })} 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 9a7b2a190f01e..dec32a931d95a 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 @@ -64,6 +64,7 @@ export type ActionTypeFormProps = { actionTypeRegistry: ActionTypeRegistryContract; recoveryActionGroup?: string; isActionGroupDisabledForActionType?: (actionGroupId: string, actionTypeId: string) => boolean; + hideNotifyWhen?: boolean; } & Pick< ActionAccordionFormProps, | 'defaultActionGroupId' @@ -100,6 +101,7 @@ export const ActionTypeForm = ({ actionTypeRegistry, isActionGroupDisabledForActionType, recoveryActionGroup, + hideNotifyWhen = false, }: ActionTypeFormProps) => { const { application: { capabilities }, @@ -246,10 +248,12 @@ export const ActionTypeForm = ({ connectors.filter((connector) => connector.isPreconfigured) ); + const showSelectActionGroup = actionGroups && selectedActionGroup && setActionGroupIdByIndex; + const accordionContent = checkEnabledResult.isEnabled ? ( <> - {actionNotifyWhen} - {actionGroups && selectedActionGroup && setActionGroupIdByIndex && ( + {!hideNotifyWhen && actionNotifyWhen} + {showSelectActionGroup && ( <> - - )} + {(showSelectActionGroup || !hideNotifyWhen) && } Date: Tue, 6 Dec 2022 17:09:20 -0600 Subject: [PATCH 45/85] Fix bulk action editing --- .../server/rules_client/methods/bulk_edit.ts | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts index 0ac7c8d24d0fe..5399cf63043d5 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts @@ -344,13 +344,27 @@ async function bulkEditOcc( for (const operation of operations) { switch (operation.field) { - case 'actions': - await validateActions(context, ruleType, { - ...attributes, - actions: operation.value, - }); - ruleActions = applyBulkEditOperation(operation, ruleActions); + case 'actions': { + // Prepare to handle the case of when the rule attributes contain legacy rule-level throttle or notifyWhen, + // and we're bulk adding actions with action-level frequency params. + let attempts = 0; + while (attempts < 2) { + attempts++; + try { + await validateActions(context, ruleType, { + ...attributes, + actions: operation.value, + }); + ruleActions = applyBulkEditOperation(operation, ruleActions); + } catch (e) { + // If validateActions fails on the first attempt, try to remove the rule-level frequency params. + // The loop will attempt to validate again. Only allow the error to throw uncaught if it happens twice. + if (typeof attributes.notifyWhen !== 'undefined') delete attributes.notifyWhen; + if (attributes.throttle) delete attributes.throttle; + } + } break; + } case 'snoozeSchedule': // Silently skip adding snooze or snooze schedules on security // rules until we implement snoozing of their rules From 2e88eea3b94c642e5c413aa746a5c9f5a5865277 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 7 Dec 2022 11:04:08 -0600 Subject: [PATCH 46/85] Fix typecheck --- .../utils/compute_dry_run_edit_payload.ts | 2 +- .../action_to_rules_client_operation.ts | 20 ------------------- .../logic/bulk_actions/bulk_edit_rules.ts | 7 ++----- 3 files changed, 3 insertions(+), 26 deletions(-) diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_edit_payload.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_edit_payload.ts index c8f49ebe4a6c6..f25b1331d766a 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_edit_payload.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_edit_payload.ts @@ -50,7 +50,7 @@ export function computeDryRunEditPayload(editAction: BulkActionEditType): BulkAc return [ { type: editAction, - value: { throttle: '1h', actions: [] }, + value: { actions: [] }, }, ]; case BulkActionEditType.set_schedule: diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts index f767a5c246056..fbfacf2ec2f07 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts @@ -11,22 +11,6 @@ import type { BulkActionEditForRuleAttributes } from '../../../../../../common/d import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { assertUnreachable } from '../../../../../../common/utility_types'; -import { transformToAlertThrottle, transformToNotifyWhen } from '../../normalization/rule_actions'; - -const getThrottleOperation = (throttle: string) => - ({ - field: 'throttle', - operation: 'set', - value: transformToAlertThrottle(throttle), - } as const); - -const getNotifyWhenOperation = (throttle: string) => - ({ - field: 'notifyWhen', - operation: 'set', - value: transformToNotifyWhen(throttle), - } as const); - /** * converts bulk edit action to format of rulesClient.bulkEdit operation * @param action BulkActionEditForRuleAttributes @@ -72,8 +56,6 @@ export const bulkEditActionToRulesClientOperation = ( operation: 'add', value: action.value.actions, }, - getThrottleOperation(action.value.throttle), - getNotifyWhenOperation(action.value.throttle), ]; case BulkActionEditType.set_rule_actions: @@ -83,8 +65,6 @@ export const bulkEditActionToRulesClientOperation = ( operation: 'set', value: action.value.actions, }, - getThrottleOperation(action.value.throttle), - getNotifyWhenOperation(action.value.throttle), ]; // schedule actions diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts index 89abe357bb58b..6fe9dc1aac627 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts @@ -8,10 +8,7 @@ import type { BulkOperationError, RulesClient } from '@kbn/alerting-plugin/server'; import pMap from 'p-map'; -import { - MAX_RULES_TO_UPDATE_IN_PARALLEL, - NOTIFICATION_THROTTLE_NO_ACTIONS, -} from '../../../../../../common/constants'; +import { MAX_RULES_TO_UPDATE_IN_PARALLEL } from '../../../../../../common/constants'; import type { BulkActionEditPayload, @@ -87,7 +84,7 @@ export const bulkEditRules = async ({ result.rules, async (rule) => { try { - if (rule.muteAll && rulesAction.value.throttle !== NOTIFICATION_THROTTLE_NO_ACTIONS) { + if (rule.muteAll && rulesAction.value.actions.length !== 0) { await rulesClient.unmuteAll({ id: rule.id }); return (await readRules({ rulesClient, id: rule.id, ruleId: undefined })) ?? rule; } From 3441667ea2709cf1b19146e96284f2979fccf288 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 7 Dec 2022 11:05:08 -0600 Subject: [PATCH 47/85] Fix request schema test --- .../rules/bulk_actions/request_schema.test.ts | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts index 0a0d201fd5c6d..67e1df47962d7 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts @@ -512,28 +512,6 @@ describe('Perform bulk action request schema', () => { expect(message.schema).toEqual({}); }); - test('invalid request: missing throttle in payload', () => { - const payload = { - query: 'name: test', - action: BulkActionType.edit, - [BulkActionType.edit]: [ - { - type: BulkActionEditType.add_rule_actions, - value: { - actions: [], - }, - }, - ], - }; - - const message = retrieveValidationMessage(payload); - - expect(getPaths(left(message.errors))).toEqual( - expect.arrayContaining(['Invalid value "undefined" supplied to "edit,value,throttle"']) - ); - expect(message.schema).toEqual({}); - }); - test('invalid request: missing actions in payload', () => { const payload = { query: 'name: test', From 71ce77be64c384071e7d496ee8dfc796979520bf Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 7 Dec 2022 11:29:38 -0600 Subject: [PATCH 48/85] Clean up try catch block --- .../alerting/server/rules_client/methods/bulk_edit.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts index 5399cf63043d5..a6287c4b88628 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts @@ -344,7 +344,7 @@ async function bulkEditOcc( for (const operation of operations) { switch (operation.field) { - case 'actions': { + case 'actions': // Prepare to handle the case of when the rule attributes contain legacy rule-level throttle or notifyWhen, // and we're bulk adding actions with action-level frequency params. let attempts = 0; @@ -355,7 +355,6 @@ async function bulkEditOcc( ...attributes, actions: operation.value, }); - ruleActions = applyBulkEditOperation(operation, ruleActions); } catch (e) { // If validateActions fails on the first attempt, try to remove the rule-level frequency params. // The loop will attempt to validate again. Only allow the error to throw uncaught if it happens twice. @@ -363,8 +362,8 @@ async function bulkEditOcc( if (attributes.throttle) delete attributes.throttle; } } + ruleActions = applyBulkEditOperation(operation, ruleActions); break; - } case 'snoozeSchedule': // Silently skip adding snooze or snooze schedules on security // rules until we implement snoozing of their rules From 8c0a66f4a8ec0adde24e376c915f5d950c64cdd8 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 8 Dec 2022 14:50:17 -0600 Subject: [PATCH 49/85] More security solution fixes --- .../api/rules/bulk_actions/request_schema.ts | 11 +++++++--- .../bulk_actions/forms/rule_actions_form.tsx | 1 + .../action_to_rules_client_operation.ts | 20 +++++++++++++++++++ .../group10/perform_bulk_action.ts | 15 +++++++------- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts index c760e47d1f26a..067d7225424bc 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts @@ -111,9 +111,14 @@ export const BulkActionEditPayloadRuleActions = t.type({ t.literal(BulkActionEditType.add_rule_actions), t.literal(BulkActionEditType.set_rule_actions), ]), - value: t.type({ - actions: t.array(NormalizedRuleAction), - }), + value: t.intersection([ + t.type({ + actions: t.array(NormalizedRuleAction), + }), + t.partial({ + throttle: ThrottleForBulkActions, + }), + ]), }); type BulkActionEditPayloadSchedule = t.TypeOf; diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx index 3c6fddb20c1c1..c8c54353411bf 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx @@ -125,6 +125,7 @@ const RuleActionsFormComponent = ({ rulesCount, onClose, onConfirm }: RuleAction onConfirm({ type: editAction, value: { + throttle: actions.length === 0 ? throttleToSubmit : undefined, actions: actions.map(({ actionTypeId, ...action }) => ({ ...action, frequency: { ...frequencyToSubmit, summary: false }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts index fbfacf2ec2f07..162a3c58ad31c 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts @@ -11,6 +11,22 @@ import type { BulkActionEditForRuleAttributes } from '../../../../../../common/d import { BulkActionEditType } from '../../../../../../common/detection_engine/rule_management/api/rules/bulk_actions/request_schema'; import { assertUnreachable } from '../../../../../../common/utility_types'; +import { transformToAlertThrottle, transformToNotifyWhen } from '../../normalization/rule_actions'; + +const getThrottleOperation = (throttle?: string) => + ({ + field: 'throttle', + operation: 'set', + value: transformToAlertThrottle(throttle), + } as const); + +const getNotifyWhenOperation = (throttle?: string) => + ({ + field: 'notifyWhen', + operation: 'set', + value: transformToNotifyWhen(throttle), + } as const); + /** * converts bulk edit action to format of rulesClient.bulkEdit operation * @param action BulkActionEditForRuleAttributes @@ -56,6 +72,8 @@ export const bulkEditActionToRulesClientOperation = ( operation: 'add', value: action.value.actions, }, + getThrottleOperation(action.value.throttle), + getNotifyWhenOperation(action.value.throttle), ]; case BulkActionEditType.set_rule_actions: @@ -65,6 +83,8 @@ export const bulkEditActionToRulesClientOperation = ( operation: 'set', value: action.value.actions, }, + getThrottleOperation(action.value.throttle), + getNotifyWhenOperation(action.value.throttle), ]; // schedule actions diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts index 48117cc08ecf6..7ba997a52ecb6 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts @@ -1675,10 +1675,6 @@ export default ({ getService }: FtrProviderContext): void => { }); const casesForNonEmptyActions = [ - { - payloadThrottle: NOTIFICATION_THROTTLE_RULE, - expectedThrottle: NOTIFICATION_THROTTLE_RULE, - }, { payloadThrottle: '1h', expectedThrottle: '1h', @@ -1710,12 +1706,16 @@ export default ({ getService }: FtrProviderContext): void => { { type: BulkActionEditType.set_rule_actions, value: { - throttle: payloadThrottle, actions: [ { id: webHookConnector.id, group: 'default', params: { body: '{}' }, + frequency: { + summary: false, + notifyWhen: 'onThrottleInterval', + throttle: payloadThrottle, + }, }, ], }, @@ -1725,12 +1725,13 @@ export default ({ getService }: FtrProviderContext): void => { .expect(200); // Check that the updated rule is returned with the response - expect(body.attributes.results.updated[0].throttle).to.eql(expectedThrottle); + expect(body.attributes.results.updated[0].throttle).to.eql(undefined); // Check that the updates have been persisted const { body: rule } = await fetchRule(ruleId).expect(200); - expect(rule.throttle).to.eql(expectedThrottle); + expect(rule.throttle).to.be(undefined); + expect(rule.actions[0].frequency.throttle).to.be(expectedThrottle); }); }); } From eadef7881e2688eebf826d15b1b282c5fa2a52bb Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 12 Dec 2022 15:52:18 -0600 Subject: [PATCH 50/85] Fix i18n --- x-pack/plugins/translations/translations/fr-FR.json | 1 - x-pack/plugins/translations/translations/ja-JP.json | 1 - x-pack/plugins/translations/translations/zh-CN.json | 1 - 3 files changed, 3 deletions(-) diff --git a/x-pack/plugins/translations/translations/fr-FR.json b/x-pack/plugins/translations/translations/fr-FR.json index 727a3c60f48d9..e8387caf78b29 100644 --- a/x-pack/plugins/translations/translations/fr-FR.json +++ b/x-pack/plugins/translations/translations/fr-FR.json @@ -6775,7 +6775,6 @@ "xpack.alerting.rulesClient.runSoon.disabledRuleError": "Erreur lors de l'exécution de la règle : la règle est désactivée", "xpack.alerting.rulesClient.runSoon.ruleIsRunning": "La règle est déjà en cours d'exécution", "xpack.alerting.rulesClient.snoozeSchedule.limitReached": "La règle ne peut pas avoir plus de 5 planifications en répétition", - "xpack.alerting.rulesClient.usesValidGlobalFreqParams.oneUndefined": "Les paramètres de niveau de règle notifyWhen et throttle doivent être tous les deux définis ou non définis", "xpack.alerting.savedObjects.goToRulesButtonText": "Accéder aux règles", "xpack.alerting.serverSideErrors.unavailableLicenseInformationErrorMessage": "Les alertes sont indisponibles – les informations de licence ne sont pas disponibles actuellement.", "xpack.alerting.taskRunner.warning.maxAlerts": "La règle a dépassé le nombre maximal d'alertes au cours d'une même exécution. Les alertes ont peut-être été manquées et les notifications de récupération retardées", diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index fa47cd51f3443..263a4dc4276ec 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -6770,7 +6770,6 @@ "xpack.alerting.rulesClient.runSoon.disabledRuleError": "ルールの実行エラー:ルールが無効です", "xpack.alerting.rulesClient.runSoon.ruleIsRunning": "ルールはすでに実行中です", "xpack.alerting.rulesClient.snoozeSchedule.limitReached": "ルールに含めることができるスヌーズスケジュールは5つまでです", - "xpack.alerting.rulesClient.usesValidGlobalFreqParams.oneUndefined": "ルールレベル notifyWhen と調整の両方を定義するか、両方を未定義にする必要があります", "xpack.alerting.savedObjects.goToRulesButtonText": "ルールに移動", "xpack.alerting.serverSideErrors.unavailableLicenseInformationErrorMessage": "アラートを利用できません。現在ライセンス情報が利用できません。", "xpack.alerting.taskRunner.warning.maxAlerts": "ルールは、1回の実行のアラートの最大回数を超えたことを報告しました。アラートを受信できないか、回復通知が遅延する可能性があります", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 80ff5e3a87b60..b322f8f8a91f1 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -6778,7 +6778,6 @@ "xpack.alerting.rulesClient.runSoon.disabledRuleError": "运行规则时出错:规则已禁用", "xpack.alerting.rulesClient.runSoon.ruleIsRunning": "规则已在运行", "xpack.alerting.rulesClient.snoozeSchedule.limitReached": "规则不能具有 5 个以上的暂停计划", - "xpack.alerting.rulesClient.usesValidGlobalFreqParams.oneUndefined": "规则级别 notifyWhen 和限制必须同时进行定义或取消定义", "xpack.alerting.savedObjects.goToRulesButtonText": "前往规则", "xpack.alerting.serverSideErrors.unavailableLicenseInformationErrorMessage": "告警不可用 - 许可信息当前不可用。", "xpack.alerting.taskRunner.warning.maxAlerts": "规则在单次运行中报告了多个最大告警数。可能错过了告警并延迟了恢复通知", From 43f84e912ddc1c3f7e4db491b9573367d40f9df9 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 13 Dec 2022 11:32:41 -0600 Subject: [PATCH 51/85] Fix bulk actions test --- .../security_and_spaces/group10/perform_bulk_action.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts index 7ba997a52ecb6..0d6782a5e69d7 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts @@ -1725,7 +1725,7 @@ export default ({ getService }: FtrProviderContext): void => { .expect(200); // Check that the updated rule is returned with the response - expect(body.attributes.results.updated[0].throttle).to.eql(undefined); + expect(body.attributes.results.updated[0].throttle).to.eql('rule'); // Check that the updates have been persisted const { body: rule } = await fetchRule(ruleId).expect(200); From 44d95ebb021b6b58bc6803439fbf41a6136576e5 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 13 Dec 2022 11:34:35 -0600 Subject: [PATCH 52/85] Update registered types test --- .../saved_objects/migrations/check_registered_types.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts index e7426108ce9e6..1935aba9ac60a 100644 --- a/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts +++ b/src/core/server/integration_tests/saved_objects/migrations/check_registered_types.test.ts @@ -57,7 +57,7 @@ describe('checking migration metadata changes on all registered SO types', () => Object { "action": "7858e6d5a9f231bf23f6f2e57328eb0095b26735", "action_task_params": "bbd38cbfd74bf6713586fe078e3fa92db2234299", - "alert": "4cfdc31b6a2d48e5399a00674022f302479cd978", + "alert": "d95e8ef645ae9f797b93a9a64d8ab9d35d484064", "api_key_pending_invalidation": "9b4bc1235337da9a87ef05a1d1f4858b2a3b77c6", "apm-indices": "ceb0870f3a74e2ffc3a1cd3a3c73af76baca0999", "apm-server-schema": "2bfd2998d3873872e1366458ce553def85418f91", From 49e5ff28f900dccf07a04e852cb7a8c17f450e66 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 13 Dec 2022 12:26:12 -0600 Subject: [PATCH 53/85] Fix bulk edit and security solution throttle transform --- .../server/lib/get_rule_notify_when_type.ts | 4 ++-- .../server/rules_client/methods/bulk_edit.ts | 5 +++-- .../detection_engine/transform_actions.ts | 17 +++++++++++------ .../normalization/rule_actions.ts | 11 +++++++---- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/alerting/server/lib/get_rule_notify_when_type.ts b/x-pack/plugins/alerting/server/lib/get_rule_notify_when_type.ts index 53ccacde75e5c..d9e508a5257c8 100644 --- a/x-pack/plugins/alerting/server/lib/get_rule_notify_when_type.ts +++ b/x-pack/plugins/alerting/server/lib/get_rule_notify_when_type.ts @@ -10,8 +10,8 @@ import { RuleNotifyWhenType } from '../types'; export function getRuleNotifyWhenType( notifyWhen: RuleNotifyWhenType | null, throttle: string | null -): RuleNotifyWhenType { +): RuleNotifyWhenType | null { // We allow notifyWhen to be null for backwards compatibility. If it is null, determine its // value based on whether the throttle is set to a value or null - return notifyWhen ? notifyWhen! : throttle ? 'onThrottleInterval' : 'onActiveAlert'; + return notifyWhen ? notifyWhen! : throttle ? 'onThrottleInterval' : null; } diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts index a6287c4b88628..fffe53af17edc 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts @@ -358,8 +358,9 @@ async function bulkEditOcc( } catch (e) { // If validateActions fails on the first attempt, try to remove the rule-level frequency params. // The loop will attempt to validate again. Only allow the error to throw uncaught if it happens twice. - if (typeof attributes.notifyWhen !== 'undefined') delete attributes.notifyWhen; - if (attributes.throttle) delete attributes.throttle; + if (typeof attributes.notifyWhen !== 'undefined') + attributes.notifyWhen = undefined; + if (attributes.throttle) attributes.throttle = undefined; } } ruleActions = applyBulkEditOperation(operation, ruleActions); diff --git a/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts index da720b578bc65..a80a68aaef2cf 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts @@ -26,12 +26,17 @@ export const transformAlertToRuleAction = ({ id, actionTypeId, params, -}: RuleAction): RuleAlertAction => ({ - group, - id, - params, - action_type_id: actionTypeId, -}); + frequency, +}: RuleAction): RuleAlertAction => { + const action = { + group, + id, + params, + action_type_id: actionTypeId, + } as RuleAlertAction; + if (frequency) action.frequency = frequency; + return action; +}; export const transformRuleToAlertResponseAction = ({ action_type_id: actionTypeId, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts index 99b97ea6d89ec..f1963f73e432f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts @@ -68,12 +68,15 @@ export const transformFromAlertThrottle = ( legacyRuleActions: LegacyRuleActions | null | undefined ): string => { if (legacyRuleActions == null || (rule.actions != null && rule.actions.length > 0)) { + console.log('TRANSFORM', rule.notifyWhen, rule.actions, rule.actions[0]?.frequency); if (rule.muteAll || rule.actions.length === 0) { return NOTIFICATION_THROTTLE_NO_ACTIONS; - } else if ( - rule.notifyWhen === 'onActiveAlert' || - (rule.throttle == null && rule.notifyWhen == null) - ) { + } else if (rule.notifyWhen == null) { + const frequency = rule.actions[0].frequency ?? null; + if (!frequency || frequency.notifyWhen !== 'onThrottleInterval' || frequency.throttle == null) + return NOTIFICATION_THROTTLE_RULE; + return frequency.throttle; + } else if (rule.notifyWhen === 'onActiveAlert') { return NOTIFICATION_THROTTLE_RULE; } else if (rule.throttle == null) { return NOTIFICATION_THROTTLE_NO_ACTIONS; From 13268855d7ae760186ce46c5175456572884fefb Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 13 Dec 2022 12:40:11 -0600 Subject: [PATCH 54/85] Fix rule changed compare for notifyWhen --- .../application/sections/rule_form/has_rule_changed.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/has_rule_changed.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/has_rule_changed.ts index a79e820e2cfd8..4b3920e9a241f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/has_rule_changed.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/has_rule_changed.ts @@ -10,14 +10,15 @@ import { pick } from 'lodash'; import { RuleTypeParams } from '../../../types'; import { InitialRule } from './rule_reducer'; -const DEEP_COMPARE_FIELDS = ['tags', 'schedule', 'actions', 'notifyWhen']; +const DEEP_COMPARE_FIELDS = ['tags', 'schedule', 'actions']; function getNonNullCompareFields(rule: InitialRule) { - const { name, ruleTypeId, throttle } = rule; + const { name, ruleTypeId, throttle, notifyWhen } = rule; return { ...(!!(name && name.length > 0) ? { name } : {}), ...(!!(ruleTypeId && ruleTypeId.length > 0) ? { ruleTypeId } : {}), ...(!!(throttle && throttle.length > 0) ? { throttle } : {}), + ...(!!(notifyWhen && notifyWhen.length > 0) ? { notifyWhen } : {}), }; } From 6a36797b565c62774ca1eca9a265a12538fe327d Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 13 Dec 2022 14:31:24 -0600 Subject: [PATCH 55/85] Fix lint --- .../rule_management/normalization/rule_actions.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts index f1963f73e432f..f76ce44efb521 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts @@ -68,7 +68,6 @@ export const transformFromAlertThrottle = ( legacyRuleActions: LegacyRuleActions | null | undefined ): string => { if (legacyRuleActions == null || (rule.actions != null && rule.actions.length > 0)) { - console.log('TRANSFORM', rule.notifyWhen, rule.actions, rule.actions[0]?.frequency); if (rule.muteAll || rule.actions.length === 0) { return NOTIFICATION_THROTTLE_NO_ACTIONS; } else if (rule.notifyWhen == null) { From ad90176289c32e07bd01f634eb3fea9503559fbc Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 13 Dec 2022 14:36:44 -0600 Subject: [PATCH 56/85] Fix group10 tests --- .../server/rules_client/tests/create.test.ts | 4 +-- .../group10/perform_bulk_action.ts | 2 +- .../security_and_spaces/group10/throttle.ts | 32 +++++++++---------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index 50dc1027c842a..1efa1556ea2fc 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -444,7 +444,7 @@ describe('create()', () => { "muteAll": false, "mutedInstanceIds": Array [], "name": "abc", - "notifyWhen": "onActiveAlert", + "notifyWhen": null, "params": Object { "bar": true, }, @@ -661,7 +661,7 @@ describe('create()', () => { "muteAll": false, "mutedInstanceIds": Array [], "name": "abc", - "notifyWhen": "onActiveAlert", + "notifyWhen": null, "params": Object { "bar": true, }, diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts index 0d6782a5e69d7..e3c332839bc98 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts @@ -1725,7 +1725,7 @@ export default ({ getService }: FtrProviderContext): void => { .expect(200); // Check that the updated rule is returned with the response - expect(body.attributes.results.updated[0].throttle).to.eql('rule'); + expect(body.attributes.results.updated[0].throttle).to.eql(expectedThrottle); // Check that the updates have been persisted const { body: rule } = await fetchRule(ruleId).expect(200); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts index fc3dc32483ba4..b9d29120770af 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts @@ -56,7 +56,7 @@ export default ({ getService }: FtrProviderContext) => { }); describe('creating a rule', () => { - it('When creating a new action and attaching it to a rule, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onActiveAlert"', async () => { + it('When creating a new action and attaching it to a rule, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { // create a new action const { body: hookAction } = await supertest .post('/api/actions/action') @@ -69,10 +69,10 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql('onActiveAlert'); + expect(notifyWhen).to.eql(null); }); - it('When creating throttle with "NOTIFICATION_THROTTLE_NO_ACTIONS" set and no actions, the rule should have its kibana alerting "mute_all" set to "true" and notify_when set to "onActiveAlert"', async () => { + it('When creating throttle with "NOTIFICATION_THROTTLE_NO_ACTIONS" set and no actions, the rule should have its kibana alerting "mute_all" set to "true"', async () => { const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: NOTIFICATION_THROTTLE_NO_ACTIONS, @@ -82,10 +82,10 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(true); - expect(notifyWhen).to.eql('onActiveAlert'); + expect(notifyWhen).to.eql(null); }); - it('When creating throttle with "NOTIFICATION_THROTTLE_NO_ACTIONS" set and with actions set, the rule should have its kibana alerting "mute_all" set to "true" and notify_when set to "onActiveAlert"', async () => { + it('When creating throttle with "NOTIFICATION_THROTTLE_NO_ACTIONS" set and with actions set, the rule should have its kibana alerting "mute_all" set to "true" and notify_when set to null', async () => { // create a new action const { body: hookAction } = await supertest .post('/api/actions/action') @@ -102,10 +102,10 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(true); - expect(notifyWhen).to.eql('onActiveAlert'); + expect(notifyWhen).to.eql(null); }); - it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onActiveAlert"', async () => { + it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: NOTIFICATION_THROTTLE_RULE, @@ -115,7 +115,7 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql('onActiveAlert'); + expect(notifyWhen).to.eql(null); }); // NOTE: This shows A side effect of how we do not set data on side cars anymore where the user is told they have no actions since the array is empty. @@ -128,7 +128,7 @@ export default ({ getService }: FtrProviderContext) => { expect(rule.throttle).to.eql(NOTIFICATION_THROTTLE_NO_ACTIONS); }); - it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and actions set, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onActiveAlert"', async () => { + it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and actions set, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { // create a new action const { body: hookAction } = await supertest .post('/api/actions/action') @@ -145,10 +145,10 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql('onActiveAlert'); + expect(notifyWhen).to.eql(null); }); - it('When creating throttle with "1h" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onThrottleInterval"', async () => { + it('When creating throttle with "1h" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: '1h', @@ -158,10 +158,10 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql('onThrottleInterval'); + expect(notifyWhen).to.eql(null); }); - it('When creating throttle with "1h" set and actions set, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onThrottleInterval"', async () => { + it('When creating throttle with "1h" set and actions set, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { // create a new action const { body: hookAction } = await supertest .post('/api/actions/action') @@ -178,7 +178,7 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql('onThrottleInterval'); + expect(notifyWhen).to.eql(null); }); }); @@ -268,7 +268,7 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${updated.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql('onActiveAlert'); + expect(notifyWhen).to.eql(null); }); // NOTE: This shows A side effect of how we do not set data on side cars anymore where the user is told they have no actions since the array is empty. @@ -329,7 +329,7 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql('onActiveAlert'); + expect(notifyWhen).to.eql(null); }); // NOTE: This shows A side effect of how we do not set data on side cars anymore where the user is told they have no actions since the array is empty. From d839d89a161edfa4d023cab71cabe67f2b5b4043 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 13 Dec 2022 15:27:24 -0600 Subject: [PATCH 57/85] Fix jest --- .../server/rules_client/tests/create.test.ts | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts index 1efa1556ea2fc..795c5e9f176df 100644 --- a/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts +++ b/x-pack/plugins/alerting/server/rules_client/tests/create.test.ts @@ -751,7 +751,7 @@ describe('create()', () => { }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), - notifyWhen: 'onActiveAlert', + notifyWhen: null, actions: [ { group: 'default', @@ -838,7 +838,7 @@ describe('create()', () => { "alertTypeId": "123", "createdAt": 2019-02-12T21:01:22.479Z, "id": "1", - "notifyWhen": "onActiveAlert", + "notifyWhen": null, "params": Object { "bar": true, }, @@ -943,7 +943,7 @@ describe('create()', () => { }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), - notifyWhen: 'onActiveAlert', + notifyWhen: null, actions: [ { group: 'default', @@ -1025,7 +1025,7 @@ describe('create()', () => { "alertTypeId": "123", "createdAt": 2019-02-12T21:01:22.479Z, "id": "1", - "notifyWhen": "onActiveAlert", + "notifyWhen": null, "params": Object { "bar": true, }, @@ -1085,7 +1085,7 @@ describe('create()', () => { snoozeSchedule: [], mutedInstanceIds: [], name: 'abc', - notifyWhen: 'onActiveAlert', + notifyWhen: null, params: { bar: true }, schedule: { interval: '1m' }, tags: ['foo'], @@ -1118,7 +1118,7 @@ describe('create()', () => { }, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), - notifyWhen: 'onActiveAlert', + notifyWhen: null, actions: [ { group: 'default', @@ -1155,7 +1155,7 @@ describe('create()', () => { "createdAt": 2019-02-12T21:01:22.479Z, "enabled": false, "id": "1", - "notifyWhen": "onActiveAlert", + "notifyWhen": null, "params": Object { "bar": true, }, @@ -1284,7 +1284,7 @@ describe('create()', () => { snoozeSchedule: [], mutedInstanceIds: [], name: 'abc', - notifyWhen: 'onActiveAlert', + notifyWhen: null, params: { bar: true, parameterThatIsSavedObjectRef: 'soRef_0' }, schedule: { interval: '1m' }, tags: ['foo'], @@ -1452,7 +1452,7 @@ describe('create()', () => { snoozeSchedule: [], mutedInstanceIds: [], name: 'abc', - notifyWhen: 'onActiveAlert', + notifyWhen: null, params: { bar: true, parameterThatIsSavedObjectRef: 'action_0' }, schedule: { interval: '1m' }, tags: ['foo'], @@ -1824,7 +1824,7 @@ describe('create()', () => { muteAll: false, snoozeSchedule: [], mutedInstanceIds: [], - notifyWhen: 'onActiveAlert', + notifyWhen: null, actions: [ { group: 'default', @@ -1877,7 +1877,7 @@ describe('create()', () => { }, schedule: { interval: '1m' }, throttle: null, - notifyWhen: 'onActiveAlert', + notifyWhen: null, muteAll: false, snoozeSchedule: [], mutedInstanceIds: [], @@ -1922,7 +1922,7 @@ describe('create()', () => { "muteAll": false, "mutedInstanceIds": Array [], "name": "abc", - "notifyWhen": "onActiveAlert", + "notifyWhen": null, "params": Object { "bar": true, }, @@ -2003,7 +2003,7 @@ describe('create()', () => { interval: '1m', }, throttle: null, - notifyWhen: 'onActiveAlert', + notifyWhen: null, params: { bar: true, risk_score: 42, @@ -2397,7 +2397,7 @@ describe('create()', () => { }, schedule: { interval: '1m' }, throttle: null, - notifyWhen: 'onActiveAlert', + notifyWhen: null, muteAll: false, snoozeSchedule: [], mutedInstanceIds: [], @@ -2499,7 +2499,7 @@ describe('create()', () => { }, schedule: { interval: '1m' }, throttle: null, - notifyWhen: 'onActiveAlert', + notifyWhen: null, muteAll: false, snoozeSchedule: [], mutedInstanceIds: [], From 5a50078448855bf48cfe48d025c8a4e6e61ee622 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 13 Dec 2022 16:35:15 -0600 Subject: [PATCH 58/85] Fix notifywhen type jest --- .../alerting/server/lib/get_rule_notify_when_type.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/alerting/server/lib/get_rule_notify_when_type.test.ts b/x-pack/plugins/alerting/server/lib/get_rule_notify_when_type.test.ts index 747f5a8a8cd21..a49067caee967 100644 --- a/x-pack/plugins/alerting/server/lib/get_rule_notify_when_type.test.ts +++ b/x-pack/plugins/alerting/server/lib/get_rule_notify_when_type.test.ts @@ -19,6 +19,6 @@ test(`should return 'onThrottleInterval' value if 'notifyWhen' is null and throt expect(getRuleNotifyWhenType(null, '10m')).toEqual('onThrottleInterval'); }); -test(`should return 'onActiveAlert' value if 'notifyWhen' is null and throttle is null`, () => { - expect(getRuleNotifyWhenType(null, null)).toEqual('onActiveAlert'); +test(`should return null value if 'notifyWhen' is null and throttle is null`, () => { + expect(getRuleNotifyWhenType(null, null)).toEqual(null); }); From d1c330f1f53afe3ef743d956adc7fde38a5e9b85 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 14 Dec 2022 11:08:24 -0600 Subject: [PATCH 59/85] Fix group10 tests --- .../group10/perform_bulk_action.ts | 2 +- .../security_and_spaces/group10/throttle.ts | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts index e3c332839bc98..4a424461a7c5d 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts @@ -1730,7 +1730,7 @@ export default ({ getService }: FtrProviderContext): void => { // Check that the updates have been persisted const { body: rule } = await fetchRule(ruleId).expect(200); - expect(rule.throttle).to.be(undefined); + expect(rule.throttle).to.be(expectedThrottle); expect(rule.actions[0].frequency.throttle).to.be(expectedThrottle); }); }); diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts index b9d29120770af..10089383b1028 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/throttle.ts @@ -56,7 +56,7 @@ export default ({ getService }: FtrProviderContext) => { }); describe('creating a rule', () => { - it('When creating a new action and attaching it to a rule, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { + it('When creating a new action and attaching it to a rule, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onActiveAlert"', async () => { // create a new action const { body: hookAction } = await supertest .post('/api/actions/action') @@ -69,10 +69,10 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql(null); + expect(notifyWhen).to.eql('onActiveAlert'); }); - it('When creating throttle with "NOTIFICATION_THROTTLE_NO_ACTIONS" set and no actions, the rule should have its kibana alerting "mute_all" set to "true"', async () => { + it('When creating throttle with "NOTIFICATION_THROTTLE_NO_ACTIONS" set and no actions, the rule should have its kibana alerting "mute_all" set to "true" and notify_when set to null', async () => { const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: NOTIFICATION_THROTTLE_NO_ACTIONS, @@ -105,7 +105,7 @@ export default ({ getService }: FtrProviderContext) => { expect(notifyWhen).to.eql(null); }); - it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { + it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onActiveAlert"', async () => { const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: NOTIFICATION_THROTTLE_RULE, @@ -115,7 +115,7 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql(null); + expect(notifyWhen).to.eql('onActiveAlert'); }); // NOTE: This shows A side effect of how we do not set data on side cars anymore where the user is told they have no actions since the array is empty. @@ -128,7 +128,7 @@ export default ({ getService }: FtrProviderContext) => { expect(rule.throttle).to.eql(NOTIFICATION_THROTTLE_NO_ACTIONS); }); - it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and actions set, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { + it('When creating throttle with "NOTIFICATION_THROTTLE_RULE" set and actions set, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onActiveAlert"', async () => { // create a new action const { body: hookAction } = await supertest .post('/api/actions/action') @@ -145,10 +145,10 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql(null); + expect(notifyWhen).to.eql('onActiveAlert'); }); - it('When creating throttle with "1h" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { + it('When creating throttle with "1h" set and no actions, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onThrottleInterval"', async () => { const ruleWithThrottle: RuleCreateProps = { ...getSimpleRule(), throttle: '1h', @@ -158,10 +158,10 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql(null); + expect(notifyWhen).to.eql('onThrottleInterval'); }); - it('When creating throttle with "1h" set and actions set, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to null', async () => { + it('When creating throttle with "1h" set and actions set, the rule should have its kibana alerting "mute_all" set to "false" and notify_when set to "onThrottleInterval"', async () => { // create a new action const { body: hookAction } = await supertest .post('/api/actions/action') @@ -178,7 +178,7 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql(null); + expect(notifyWhen).to.eql('onThrottleInterval'); }); }); @@ -268,7 +268,7 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${updated.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql(null); + expect(notifyWhen).to.eql('onActiveAlert'); }); // NOTE: This shows A side effect of how we do not set data on side cars anymore where the user is told they have no actions since the array is empty. @@ -329,7 +329,7 @@ export default ({ getService }: FtrProviderContext) => { body: { mute_all: muteAll, notify_when: notifyWhen }, } = await supertest.get(`/api/alerting/rule/${rule.id}`); expect(muteAll).to.eql(false); - expect(notifyWhen).to.eql(null); + expect(notifyWhen).to.eql('onActiveAlert'); }); // NOTE: This shows A side effect of how we do not set data on side cars anymore where the user is told they have no actions since the array is empty. From 9ffa1a12e6a0cb5fbf6e2a234089b98c87183751 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 14 Dec 2022 13:01:15 -0600 Subject: [PATCH 60/85] Fix functional tests --- .../apps/triggers_actions_ui/connectors/opsgenie.ts | 3 +-- .../apps/triggers_actions_ui/details.ts | 3 --- .../functional_with_es_ssl/apps/uptime/alert_flyout.ts | 8 -------- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/opsgenie.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/opsgenie.ts index e88c776f498c6..e7d5bf18d84d1 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/opsgenie.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors/opsgenie.ts @@ -356,13 +356,12 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await retry.try(async () => { await rules.common.defineIndexThresholdAlert(alertName); }); - - await rules.common.setNotifyThrottleInput(); }; const selectOpsgenieConnectorInRuleAction = async (name: string) => { await testSubjects.click('.opsgenie-alerting-ActionTypeSelectOption'); await testSubjects.selectValue('comboBoxInput', name); + await rules.common.setNotifyThrottleInput(); }; const createOpsgenieConnector = async (name: string) => { diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index 8bdccc97fe562..9ae36dac4e8a8 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -634,9 +634,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { // verify content await testSubjects.existOrFail('rulesList'); - // Wait to ensure the table is finished loading - await pageObjects.triggersActionsUI.tableFinishedLoading(); - // click on first alert await pageObjects.common.navigateToApp('triggersActions'); await pageObjects.triggersActionsUI.clickOnAlertInAlertsList(rule.name); diff --git a/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts b/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts index 636f16c5b98ff..140f85ff068ef 100644 --- a/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts +++ b/x-pack/test/functional_with_es_ssl/apps/uptime/alert_flyout.ts @@ -49,10 +49,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await alerts.setAlertInterval('11'); }); - it('can set alert throttle interval', async () => { - await alerts.setAlertThrottleInterval('30'); - }); - it('can set alert status number of time', async () => { await alerts.setAlertStatusNumTimes('3'); }); @@ -172,10 +168,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await alerts.setAlertInterval('11'); }); - it('can set alert throttle interval', async () => { - await alerts.setAlertThrottleInterval('30'); - }); - it('can save alert', async () => { await alerts.clickSaveRuleButton(alertId); await alerts.clickSaveAlertsConfirmButton(); From 265a6c10f3d433cca7a42cb88b665c38ab9cde2d Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 15 Dec 2022 12:04:29 -0600 Subject: [PATCH 61/85] Fix security solution bulk edit --- .../server/rules_client/methods/bulk_edit.ts | 12 ++++++++++++ .../bulk_actions/action_to_rules_client_operation.ts | 1 + 2 files changed, 13 insertions(+) diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts index fffe53af17edc..b35c358ef1070 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts @@ -63,6 +63,7 @@ export type BulkEditOperation = operation: 'add' | 'set'; field: Extract; value: NormalizedAlertAction[]; + syncFrequency?: boolean; } | { operation: 'set'; @@ -364,6 +365,17 @@ async function bulkEditOcc( } } ruleActions = applyBulkEditOperation(operation, ruleActions); + if (operation.syncFrequency) { + const frequency = operation.value[0].frequency; + if (!frequency) + throw Error( + `Cannot sync frequency of existing actions when new bulk edit action has no frequency` + ); + ruleActions.actions = ruleActions.actions.map((action) => ({ + ...action, + frequency, + })); + } break; case 'snoozeSchedule': // Silently skip adding snooze or snooze schedules on security diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts index 162a3c58ad31c..4c4eb6146823d 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts @@ -71,6 +71,7 @@ export const bulkEditActionToRulesClientOperation = ( field: 'actions', operation: 'add', value: action.value.actions, + syncFrequency: true, }, getThrottleOperation(action.value.throttle), getNotifyWhenOperation(action.value.throttle), From 593fd956fda5d54f37408ac0325fa08ccd161a2e Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 15 Dec 2022 16:08:31 -0600 Subject: [PATCH 62/85] Fix group10 --- .../server/rules_client/methods/bulk_edit.ts | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts index b35c358ef1070..e57bd6ab7d0aa 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts @@ -366,15 +366,13 @@ async function bulkEditOcc( } ruleActions = applyBulkEditOperation(operation, ruleActions); if (operation.syncFrequency) { - const frequency = operation.value[0].frequency; - if (!frequency) - throw Error( - `Cannot sync frequency of existing actions when new bulk edit action has no frequency` - ); - ruleActions.actions = ruleActions.actions.map((action) => ({ - ...action, - frequency, - })); + const frequency = operation.value[0]?.frequency; + if (frequency) { + ruleActions.actions = ruleActions.actions.map((action) => ({ + ...action, + frequency, + })); + } } break; case 'snoozeSchedule': From dfdf80f88e0292ef549d7d9e9b5a0d9b16703ef5 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 19 Dec 2022 10:52:11 -0600 Subject: [PATCH 63/85] Move Notify When field below Run When --- .../sections/action_connector_form/action_type_form.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 dec32a931d95a..4853abb756ab6 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 @@ -252,7 +252,6 @@ export const ActionTypeForm = ({ const accordionContent = checkEnabledResult.isEnabled ? ( <> - {!hideNotifyWhen && actionNotifyWhen} {showSelectActionGroup && ( <> @@ -282,6 +281,7 @@ export const ActionTypeForm = ({ /> )} + {!hideNotifyWhen && actionNotifyWhen} {(showSelectActionGroup || !hideNotifyWhen) && } Date: Mon, 19 Dec 2022 15:14:03 -0600 Subject: [PATCH 64/85] Lock throttle interval to check interval --- .../action_connector_form/action_form.tsx | 3 + .../action_notify_when.tsx | 10 ++-- .../action_type_form.tsx | 59 +++++++++++++++---- .../sections/rule_form/rule_form.tsx | 1 + 4 files changed, 55 insertions(+), 18 deletions(-) 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 1edf372334757..17b27bf509d3b 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 @@ -65,6 +65,7 @@ export interface ActionAccordionFormProps { isActionGroupDisabledForActionType?: (actionGroupId: string, actionTypeId: string) => boolean; hideActionHeader?: boolean; hideNotifyWhen?: boolean; + minimumThrottleInterval?: [number | undefined, string]; } interface ActiveActionConnectorState { @@ -91,6 +92,7 @@ export const ActionForm = ({ isActionGroupDisabledForActionType, hideActionHeader, hideNotifyWhen, + minimumThrottleInterval, }: ActionAccordionFormProps) => { const { http, @@ -396,6 +398,7 @@ export const ActionForm = ({ setActiveActionItem(undefined); }} hideNotifyWhen={hideNotifyWhen} + minimumThrottleInterval={minimumThrottleInterval} /> ); })} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx index 92fc56c2b63f6..e71a4214f8e37 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState, useEffect, useCallback } from 'react'; +import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { @@ -130,7 +130,6 @@ export const ActionNotifyWhen = ({ onNotifyWhenChange, onThrottleChange, }: RuleNotifyWhenProps) => { - const [ruleThrottle, setRuleThrottle] = useState(throttle || 1); const [showCustomThrottleOpts, setShowCustomThrottleOpts] = useState(false); const [notifyWhenValue, setNotifyWhenValue] = useState(DEFAULT_NOTIFY_WHEN_VALUE); @@ -154,11 +153,11 @@ export const ActionNotifyWhen = ({ setNotifyWhenValue(newValue); setTimeout( () => - onThrottleChange(newValue === 'onThrottleInterval' ? ruleThrottle : null, throttleUnit), + onThrottleChange(newValue === 'onThrottleInterval' ? throttle ?? 1 : null, throttleUnit), 100 ); }, - [onNotifyWhenChange, setNotifyWhenValue, onThrottleChange, ruleThrottle, throttleUnit] + [onNotifyWhenChange, setNotifyWhenValue, onThrottleChange, throttle, throttleUnit] ); const labelForRuleRenotify = [ @@ -194,7 +193,7 @@ export const ActionNotifyWhen = ({ parseInt(value, 10)), filter((value) => !isNaN(value)), map((value) => { - setRuleThrottle(value); onThrottleChange(value, throttleUnit); }) ); 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 4853abb756ab6..d731cf2f37816 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 @@ -31,6 +31,7 @@ import { ActionVariable, RuleActionParam } from '@kbn/alerting-plugin/common'; import { getDurationNumberInItsUnit, getDurationUnitValue, + parseDuration, } from '@kbn/alerting-plugin/common/parse_duration'; import { betaBadgeProps } from './beta_badge_props'; import { @@ -65,6 +66,7 @@ export type ActionTypeFormProps = { recoveryActionGroup?: string; isActionGroupDisabledForActionType?: (actionGroupId: string, actionTypeId: string) => boolean; hideNotifyWhen?: boolean; + minimumThrottleInterval?: [number | undefined, string]; } & Pick< ActionAccordionFormProps, | 'defaultActionGroupId' @@ -102,6 +104,7 @@ export const ActionTypeForm = ({ isActionGroupDisabledForActionType, recoveryActionGroup, hideNotifyWhen = false, + minimumThrottleInterval, }: ActionTypeFormProps) => { const { application: { capabilities }, @@ -123,6 +126,10 @@ export const ActionTypeForm = ({ const [actionThrottleUnit, setActionThrottleUnit] = useState( actionItem.frequency?.throttle ? getDurationUnitValue(actionItem.frequency?.throttle) : 'h' ); + const [minimumActionThrottle = -1, minimumActionThrottleUnit] = minimumThrottleInterval ?? [ + -1, + 's', + ]; const getDefaultParams = async () => { const connectorType = await actionTypeRegistry.get(actionItem.actionTypeId); @@ -138,6 +145,40 @@ export const ActionTypeForm = ({ return defaultParams; }; + const getBoundThrottle = useCallback( + (throttle: number | null, throttleUnit: string) => { + try { + const throttleUnitDuration = parseDuration(`1${throttleUnit}`); + const minThrottleUnitDuration = parseDuration(`1${minimumActionThrottleUnit}`); + const boundedThrottle = + throttleUnitDuration > minThrottleUnitDuration || !throttle + ? throttle + : Math.max(throttle, minimumActionThrottle); + const boundedThrottleUnit = + throttleUnitDuration >= minThrottleUnitDuration + ? throttleUnit + : minimumActionThrottleUnit; + return [boundedThrottle, boundedThrottleUnit] as [number | null, string]; + } catch (e) { + return [throttle, throttleUnit] as [number | null, string]; + } + }, + [minimumActionThrottle, minimumActionThrottleUnit] + ); + + useEffect(() => { + const [boundThrottle, boundThrottleUnit] = getBoundThrottle(actionThrottle, actionThrottleUnit); + if (boundThrottle !== actionThrottle) setActionThrottle(boundThrottle); + if (boundThrottleUnit !== actionThrottleUnit) setActionThrottleUnit(boundThrottleUnit); + }, [ + getBoundThrottle, + actionThrottle, + actionThrottleUnit, + setActionThrottle, + setActionThrottleUnit, + minimumThrottleInterval, + ]); + useEffect(() => { (async () => { setAvailableActionVariables( @@ -178,13 +219,6 @@ export const ActionTypeForm = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [actionItem]); - // useEffect(() => { - // if (!actionItem.frequency) { - // setActionFrequency(DEFAULT_FREQUENCY, index); - // } - // // eslint-disable-next-line react-hooks/exhaustive-deps - // }, [actionItem.frequency]); - const canSave = hasSaveActionsCapability(capabilities); const actionGroupDisplay = ( @@ -222,15 +256,16 @@ export const ActionTypeForm = ({ )} onThrottleChange={useCallback( (throttle: number | null, throttleUnit: string) => { - setActionThrottle(throttle); - setActionThrottleUnit(throttleUnit); + const [boundedThrottle, boundedThrottleUnit] = getBoundThrottle(throttle, throttleUnit); + setActionThrottle(boundedThrottle); + setActionThrottleUnit(boundedThrottleUnit); setActionFrequencyProperty( 'throttle', - throttle ? `${throttle}${throttleUnit}` : null, + boundedThrottle ? `${boundedThrottle}${boundedThrottleUnit}` : null, index ); }, - [setActionFrequencyProperty, index] + [setActionFrequencyProperty, index, getBoundThrottle] )} /> ); @@ -254,7 +289,6 @@ export const ActionTypeForm = ({ <> {showSelectActionGroup && ( <> - @@ -279,6 +313,7 @@ export const ActionTypeForm = ({ setActionGroup(group); }} /> + {!hideNotifyWhen && } )} {!hideNotifyWhen && actionNotifyWhen} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx index 5aeb15cbe17d7..94830ce7170d0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx @@ -673,6 +673,7 @@ export const RuleForm = ({ setActionParamsProperty={setActionParamsProperty} actionTypeRegistry={actionTypeRegistry} setActionFrequencyProperty={setActionFrequencyProperty} + minimumThrottleInterval={[ruleInterval, ruleIntervalUnit]} /> ) : null} From 6e2a74ad4e62d22b0304b1e0280b4a84f56b6da9 Mon Sep 17 00:00:00 2001 From: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Date: Mon, 19 Dec 2022 21:21:02 +0000 Subject: [PATCH 65/85] [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' --- .../sections/action_connector_form/action_notify_when.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx index e71a4214f8e37..30b4d9388e6bd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState, useEffect, useCallback, useMemo } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { From cf1ba824ed0d9cda78f583956a422da2961e354f Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 19 Dec 2022 15:45:59 -0600 Subject: [PATCH 66/85] Remove unused import --- .../sections/action_connector_form/action_notify_when.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx index e71a4214f8e37..30b4d9388e6bd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { useState, useEffect, useCallback, useMemo } from 'react'; +import React, { useState, useEffect, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; import { From faa989c5008737937cf6a51e59ef3d405473100d Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 21 Dec 2022 11:24:29 -0600 Subject: [PATCH 67/85] Move interval outside actiontype conditional --- .../sections/rule_form/rule_form.tsx | 93 +++++++++---------- 1 file changed, 46 insertions(+), 47 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx index 94830ce7170d0..53eb971b7ec2f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx @@ -420,8 +420,8 @@ export const RuleForm = ({ isDisabled={!item.checkEnabledResult.isEnabled} onClick={() => { setRuleProperty('ruleTypeId', item.id); - setActions([]); setRuleTypeModel(item.ruleTypeItem); + setActions([]); setRuleProperty('params', {}); if (ruleTypeIndex && ruleTypeIndex.has(item.id)) { setDefaultActionGroupId(ruleTypeIndex.get(item.id)!.defaultActionGroupId); @@ -582,6 +582,51 @@ export const RuleForm = ({ ) : null} + + 0} + error={errors['schedule.interval']} + > + + + 0} + value={ruleInterval || ''} + name="interval" + data-test-subj="intervalInput" + onChange={(e) => { + const value = e.target.value; + if (value === '' || INTEGER_REGEX.test(value)) { + const parsedValue = value === '' ? '' : parseInt(value, 10); + setRuleInterval(parsedValue || undefined); + setScheduleProperty('interval', `${parsedValue}${ruleIntervalUnit}`); + } + }} + /> + + + { + setRuleIntervalUnit(e.target.value); + setScheduleProperty('interval', `${ruleInterval}${e.target.value}`); + }} + data-test-subj="intervalInputUnit" + /> + + + + + {canShowActions && defaultActionGroupId && ruleTypeModel && @@ -595,52 +640,6 @@ export const RuleForm = ({ ) : null} - - - 0} - error={errors['schedule.interval']} - > - - - 0} - value={ruleInterval || ''} - name="interval" - data-test-subj="intervalInput" - onChange={(e) => { - const value = e.target.value; - if (value === '' || INTEGER_REGEX.test(value)) { - const parsedValue = value === '' ? '' : parseInt(value, 10); - setRuleInterval(parsedValue || undefined); - setScheduleProperty('interval', `${parsedValue}${ruleIntervalUnit}`); - } - }} - /> - - - { - setRuleIntervalUnit(e.target.value); - setScheduleProperty('interval', `${ruleInterval}${e.target.value}`); - }} - data-test-subj="intervalInputUnit" - /> - - - - - Date: Wed, 21 Dec 2022 11:36:32 -0600 Subject: [PATCH 68/85] Fix rule form tests --- .../sections/rule_form/rule_form.test.tsx | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx index 316bfbec19a54..f0de7e6e4ed60 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.test.tsx @@ -233,7 +233,12 @@ describe('rule_form', () => { describe('rule_form create rule', () => { let wrapper: ReactWrapper; - async function setup(enforceMinimum = false, schedule = '1m', featureId = 'alerting') { + async function setup( + showRulesList = false, + enforceMinimum = false, + schedule = '1m', + featureId = 'alerting' + ) { const mocks = coreMock.createSetup(); const { useLoadRuleTypes } = jest.requireMock('../../hooks/use_load_rule_types'); const ruleTypes: RuleType[] = [ @@ -320,6 +325,7 @@ describe('rule_form', () => { muteAll: false, enabled: false, mutedInstanceIds: [], + ...(!showRulesList ? { ruleTypeId: ruleType.id } : {}), } as unknown as Rule; wrapper = mountWithIntl( @@ -353,20 +359,20 @@ describe('rule_form', () => { }); it('renders registered selected rule type', async () => { - await setup(); + await setup(true); const ruleTypeSelectOptions = wrapper.find('[data-test-subj="my-rule-type-SelectOption"]'); expect(ruleTypeSelectOptions.exists()).toBeTruthy(); }); it('renders minimum schedule interval helper text when enforce = true', async () => { - await setup(true); + await setup(false, true); expect(wrapper.find('[data-test-subj="intervalFormRow"]').first().prop('helpText')).toEqual( `Interval must be at least 1 minute.` ); }); it('renders minimum schedule interval helper suggestion when enforce = false and schedule is less than configuration', async () => { - await setup(false, '10s'); + await setup(false, false, '10s'); expect(wrapper.find('[data-test-subj="intervalFormRow"]').first().prop('helpText')).toEqual( `Intervals less than 1 minute are not recommended due to performance considerations.` ); @@ -434,7 +440,7 @@ describe('rule_form', () => { }); it('renders uses feature id to load action types', async () => { - await setup(false, '1m', 'anotherFeature'); + await setup(false, false, '1m', 'anotherFeature'); const ruleTypeSelectOptions = wrapper.find( '[data-test-subj=".server-log-anotherFeature-ActionTypeSelectOption"]' ); @@ -442,7 +448,7 @@ describe('rule_form', () => { }); it('renders rule type description', async () => { - await setup(); + await setup(true); wrapper.find('button[data-test-subj="my-rule-type-SelectOption"]').first().simulate('click'); const ruleDescription = wrapper.find('[data-test-subj="ruleDescription"]'); expect(ruleDescription.exists()).toBeTruthy(); @@ -450,7 +456,7 @@ describe('rule_form', () => { }); it('renders rule type documentation link', async () => { - await setup(); + await setup(true); wrapper.find('button[data-test-subj="my-rule-type-SelectOption"]').first().simulate('click'); const ruleDocumentationLink = wrapper.find('[data-test-subj="ruleDocumentationLink"]'); expect(ruleDocumentationLink.exists()).toBeTruthy(); @@ -458,7 +464,7 @@ describe('rule_form', () => { }); it('renders rule types disabled by license', async () => { - await setup(); + await setup(true); const actionOption = wrapper.find(`[data-test-subj="disabled-by-license-SelectOption"]`); expect(actionOption.exists()).toBeTruthy(); expect( From 38dd49fc565e04747c7124af2e2f515ab0d2a06e Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 21 Dec 2022 12:39:14 -0600 Subject: [PATCH 69/85] Fix rule_add tests --- .../application/sections/rule_form/rule_add.test.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.test.tsx index 6735bb5637e74..4b1b4330b9071 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_add.test.tsx @@ -248,7 +248,9 @@ describe('rule_add', () => { interval: '1h', }, }, - onClose + onClose, + undefined, + 'my-rule-type' ); expect(wrapper.find('input#ruleName').props().value).toBe('Simple status rule'); @@ -259,7 +261,7 @@ describe('rule_add', () => { it('renders rule add flyout with DEFAULT_RULE_INTERVAL if no initialValues specified and no minimumScheduleInterval', async () => { (triggersActionsUiConfig as jest.Mock).mockResolvedValue({}); - await setup(); + await setup(undefined, undefined, undefined, 'my-rule-type'); expect(wrapper.find('[data-test-subj="intervalInput"]').first().props().value).toEqual(1); expect(wrapper.find('[data-test-subj="intervalInputUnit"]').first().props().value).toBe('m'); @@ -269,7 +271,7 @@ describe('rule_add', () => { (triggersActionsUiConfig as jest.Mock).mockResolvedValue({ minimumScheduleInterval: { value: '5m', enforce: false }, }); - await setup(); + await setup(undefined, undefined, undefined, 'my-rule-type'); expect(wrapper.find('[data-test-subj="intervalInput"]').first().props().value).toEqual(5); expect(wrapper.find('[data-test-subj="intervalInputUnit"]').first().props().value).toBe('m'); From 5c35ec0993eae7629ec3fed1d51f7e2182b9a3f2 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 21 Dec 2022 13:14:43 -0600 Subject: [PATCH 70/85] Fix rule actions test --- .../sections/rule_details/components/rule_actions.test.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.test.tsx index 0968c6acde56e..6e6aee64aaf58 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_details/components/rule_actions.test.tsx @@ -74,7 +74,9 @@ describe('Rule Actions', () => { it("renders rule action connector icons for user's selected rule actions", async () => { const wrapper = await setup(); expect(mockedUseFetchRuleActionConnectorsHook).toHaveBeenCalledTimes(1); - expect(wrapper.find('[data-euiicon-type]').length).toBe(2); + expect( + wrapper.find('[data-euiicon-type]').length - wrapper.find('[data-euiicon-type="bell"]').length + ).toBe(2); expect(wrapper.find('[data-euiicon-type="logsApp"]').length).toBe(1); expect(wrapper.find('[data-euiicon-type="logoSlack"]').length).toBe(1); expect(wrapper.find('[data-euiicon-type="index"]').length).toBe(0); From 1b259c93b909828bf7ba3f01477c26bc404cf0ea Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 21 Dec 2022 13:18:34 -0600 Subject: [PATCH 71/85] Update Rule API tests --- .../application/lib/rule_api/clone.test.ts | 13 +++++++++++-- .../application/lib/rule_api/create.test.ts | 18 +++++++++++++++--- .../application/lib/rule_api/update.test.ts | 5 +---- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/clone.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/clone.test.ts index 0de3b56f8693d..048b9e926be83 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/clone.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/clone.test.ts @@ -29,7 +29,6 @@ describe('cloneRule', () => { tags: [], name: 'test', rule_type_id: '.index-threshold', - notify_when: 'onActionGroupChange', actions: [ { group: 'threshold met', @@ -38,6 +37,11 @@ describe('cloneRule', () => { level: 'info', message: 'alert ', }, + frequency: { + notifyWhen: 'onActionGroupChange', + throttle: null, + summary: false, + }, connector_type_id: '.server-log', }, ], @@ -59,6 +63,11 @@ describe('cloneRule', () => { "actions": Array [ Object { "actionTypeId": ".server-log", + "frequency": Object { + "notifyWhen": "onActionGroupChange", + "summary": false, + "throttle": null, + }, "group": "threshold met", "id": "1", "params": Object { @@ -83,7 +92,7 @@ describe('cloneRule', () => { "muteAll": undefined, "mutedInstanceIds": undefined, "name": "test", - "notifyWhen": "onActionGroupChange", + "notifyWhen": undefined, "params": Object { "aggType": "count", "groupBy": "all", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/create.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/create.test.ts index d3138a115a27b..a16a4c8a64a41 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/create.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/create.test.ts @@ -32,7 +32,6 @@ describe('createRule', () => { tags: [], name: 'test', rule_type_id: '.index-threshold', - notify_when: 'onActionGroupChange', actions: [ { group: 'threshold met', @@ -42,6 +41,11 @@ describe('createRule', () => { message: 'alert ', }, connector_type_id: '.server-log', + frequency: { + notifyWhen: 'onActionGroupChange', + throttle: null, + summary: false, + }, }, ], scheduled_task_id: '1', @@ -71,7 +75,6 @@ describe('createRule', () => { enabled: true, throttle: null, ruleTypeId: '.index-threshold', - notifyWhen: 'onActionGroupChange', actions: [ { group: 'threshold met', @@ -82,6 +85,11 @@ describe('createRule', () => { "alert '{{alertName}}' is active for group '{{context.group}}':\n\n- Value: {{context.value}}\n- Conditions Met: {{context.conditions}} over {{params.timeWindowSize}}{{params.timeWindowUnit}}\n- Timestamp: {{context.date}}", }, actionTypeId: '.server-log', + frequency: { + notifyWhen: 'onActionGroupChange', + throttle: null, + summary: false, + }, }, ], createdAt: new Date('2021-04-01T21:33:13.247Z'), @@ -101,6 +109,11 @@ describe('createRule', () => { level: 'info', message: 'alert ', }, + frequency: { + notifyWhen: 'onActionGroupChange', + throttle: null, + summary: false, + }, }, ], ruleTypeId: '.index-threshold', @@ -116,7 +129,6 @@ describe('createRule', () => { muteAll: undefined, mutedInstanceIds: undefined, name: 'test', - notifyWhen: 'onActionGroupChange', params: { aggType: 'count', groupBy: 'all', diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.test.ts index afa64ea4b8d45..6b65e6cc64818 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/rule_api/update.test.ts @@ -5,7 +5,6 @@ * 2.0. */ -import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import { Rule } from '../../../types'; import { httpServiceMock } from '@kbn/core/public/mocks'; import { updateRule } from './update'; @@ -15,7 +14,6 @@ const http = httpServiceMock.createStartContract(); describe('updateRule', () => { test('should call rule update API', async () => { const ruleToUpdate = { - throttle: '1m', consumer: 'alerts', name: 'test', tags: ['foo'], @@ -28,7 +26,6 @@ describe('updateRule', () => { updatedAt: new Date('1970-01-01T00:00:00.000Z'), apiKey: null, apiKeyOwner: null, - notifyWhen: RuleNotifyWhen.THROTTLE, }; const resolvedValue: Rule = { ...ruleToUpdate, @@ -52,7 +49,7 @@ describe('updateRule', () => { Array [ "/api/alerting/rule/12%2F3", Object { - "body": "{\\"throttle\\":\\"1m\\",\\"name\\":\\"test\\",\\"tags\\":[\\"foo\\"],\\"schedule\\":{\\"interval\\":\\"1m\\"},\\"params\\":{},\\"notify_when\\":\\"onThrottleInterval\\",\\"actions\\":[]}", + "body": "{\\"name\\":\\"test\\",\\"tags\\":[\\"foo\\"],\\"schedule\\":{\\"interval\\":\\"1m\\"},\\"params\\":{},\\"actions\\":[]}", }, ] `); From 524a2c065baa072eef837f5258cbe12cfc3b9589 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 22 Dec 2022 14:41:19 -0600 Subject: [PATCH 72/85] Add test for reducer --- .../sections/rule_form/rule_reducer.test.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.test.ts index 259cb5ed3ecea..9b066bb1060a0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.test.ts @@ -186,4 +186,25 @@ describe('rule reducer', () => { ); expect(updatedRule.rule.actions[0].group).toBe('Warning'); }); + + test('if rule action frequency was updated', () => { + initialRule.actions.push({ + id: '', + actionTypeId: 'testId', + group: 'Rule', + params: {}, + }); + const updatedRule = ruleReducer( + { rule: initialRule }, + { + command: { type: 'setRuleActionFrequency' }, + payload: { + key: 'notifyWhen', + value: 'onThrottleInterval', + index: 0, + }, + } + ); + expect(updatedRule.rule.actions[0].frequency?.notifyWhen).toBe('onThrottleInterval'); + }); }); From 72ffb30892d48b9ff2f4aab3aa16f39965eb1669 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Thu, 22 Dec 2022 16:09:05 -0600 Subject: [PATCH 73/85] Add test for minimum throttle --- .../action_type_form.test.tsx | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) 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 3d51b918c7e4e..4a198be3e16b6 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 @@ -262,12 +262,87 @@ describe('action_type_form', () => { // Clearing all mocks will also reset fake timers. jest.clearAllMocks(); }); + + it('enforces the minimum throttle prop', async () => { + const actionType = actionTypeRegistryMock.createMockActionTypeModel({ + id: '.pagerduty', + iconClass: 'test', + selectMessage: 'test', + validateParams: (): Promise> => { + const validationResult = { errors: {} }; + return Promise.resolve(validationResult); + }, + actionConnectorFields: null, + actionParamsFields: mockedActionParamsFields, + defaultActionParams: { + dedupKey: 'test', + eventAction: 'resolve', + }, + }); + actionTypeRegistry.get.mockReturnValue(actionType); + + const wrapper = mountWithIntl( + getActionTypeForm( + 1, + undefined, + { + id: '123', + actionTypeId: '.pagerduty', + group: 'recovered', + params: { + eventAction: 'recovered', + dedupKey: undefined, + summary: '2323', + source: 'source', + severity: '1', + timestamp: new Date().toISOString(), + component: 'test', + group: 'group', + class: 'test class', + }, + frequency: { + throttle: '3m', + notifyWhen: 'onThrottleInterval', + summary: false, + }, + }, + [5, 'h'] + ) + ); + + // Wait for active space to resolve before requesting the component to update + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + const throttleField = wrapper.find('[data-test-subj="throttleInput"]'); + const throttleUnitField = wrapper.find('[data-test-subj="throttleUnitInput"]'); + expect(throttleField.exists()).toBeTruthy(); + expect(throttleUnitField.exists()).toBeTruthy(); + + // expect(throttleField.first().prop('value')).toEqual(5); + // expect(throttleUnitField.first().prop('value')).toEqual('h'); + + const newThrottle = 3; + throttleField.first().simulate('change', { target: { value: newThrottle.toString() } }); + await nextTick(); + wrapper.update(); + const throttleFieldAfterUpdate = wrapper.find('[data-test-subj="throttleInput"]'); + expect(throttleFieldAfterUpdate.first().prop('value')).toEqual(5); + + throttleUnitField.first().simulate('change', { target: { value: 'd' } }); + throttleField.first().simulate('change', { target: { value: newThrottle.toString() } }); + const throttleFieldAfterUpdate2 = wrapper.find('[data-test-subj="throttleInput"]'); + expect(throttleFieldAfterUpdate2.first().prop('value')).toEqual(5); + }); }); function getActionTypeForm( index?: number, actionConnector?: ActionConnector, Record>, actionItem?: RuleAction, + minimumThrottleInterval?: [number | undefined, string], defaultActionGroupId?: string, connectors?: Array, Record>>, actionTypeIndex?: Record, @@ -355,6 +430,7 @@ function getActionTypeForm( index={index ?? 1} actionTypesIndex={actionTypeIndex ?? actionTypeIndexDefault} actionTypeRegistry={actionTypeRegistry} + minimumThrottleInterval={minimumThrottleInterval} /> ); } From e4a6f175147b986694b4da1ae8fabca18efc8982 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 27 Dec 2022 13:16:37 -0600 Subject: [PATCH 74/85] Fix legacy throttle migration --- .../application/sections/rule_form/rule_edit.tsx | 3 ++- .../apps/triggers_actions_ui/details.ts | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx index 5855bc0b551c9..92e5a4b46a002 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_edit.tsx @@ -58,7 +58,8 @@ const cloneAndMigrateRule = (initialRule: Rule) => { ? { summary: false, notifyWhen: initialRule.notifyWhen as RuleNotifyWhenType, - throttle: null, + throttle: + initialRule.notifyWhen === RuleNotifyWhen.THROTTLE ? initialRule.throttle! : null, } : { summary: false, notifyWhen: RuleNotifyWhen.THROTTLE, throttle: initialRule.throttle! }; clonedRule.actions = clonedRule.actions.map((action) => ({ diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index 9ae36dac4e8a8..806844c71b57d 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -599,14 +599,14 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - describe('Edit rule with legacy global notify values', function () { + describe('Edit rule with legacy rule-level notify values', function () { const testRunUuid = uuid.v4(); afterEach(async () => { await objectRemover.removeAll(); }); - it('should convert global params to action-level params and save the alert successfully', async () => { + it('should convert rule-level params to action-level params and save the alert successfully', async () => { const connectors = await createConnectors(testRunUuid); await pageObjects.common.navigateToApp('triggersActions'); const rule = await createAlwaysFiringRule({ @@ -615,7 +615,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { interval: '1s', }, notify_when: RuleNotifyWhen.THROTTLE, - throttle: '1m', + throttle: '2d', actions: connectors.map((connector) => ({ id: connector.id, group: 'default', @@ -642,7 +642,10 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { await editButton.click(); const notifyWhenSelect = await testSubjects.find('notifyWhenSelect'); expect(await notifyWhenSelect.getVisibleText()).to.eql('On custom action intervals'); - + const throttleInput = await testSubjects.find('throttleInput'); + const throttleUnitInput = await testSubjects.find('throttleUnitInput'); + expect(await throttleInput.getAttribute('value')).to.be('2'); + expect(await throttleUnitInput.getAttribute('value')).to.be('d'); await testSubjects.setValue('ruleNameInput', updatedRuleName, { clearWithKeyboard: true, }); From b846f90581bae4a3a50fb2c776fcb93bcdd28387 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 3 Jan 2023 11:48:36 -0600 Subject: [PATCH 75/85] Fix PR nits --- .../src/actions/index.ts | 36 +++++------ .../alerting/common/rule_notify_when_type.ts | 10 +-- .../server/rules_client/methods/bulk_edit.ts | 63 ++++++++++++------- .../detection_engine/transform_actions.ts | 2 +- .../rules/rule_actions_field/index.tsx | 8 +-- .../normalization/rule_actions.ts | 12 ++-- 6 files changed, 74 insertions(+), 57 deletions(-) diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts index 85badce161871..4304cfbfcccf5 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts @@ -38,15 +38,15 @@ export const RuleActionFrequency = t.type({ export type RuleAction = t.TypeOf; export const RuleAction = t.exact( - t.intersection([ - t.type({ - group: RuleActionGroup, - id: RuleActionId, - action_type_id: RuleActionTypeId, - params: RuleActionParams, - }), - t.partial({ frequency: RuleActionFrequency }), - ]) + // t.intersection([ + t.type({ + group: RuleActionGroup, + id: RuleActionId, + action_type_id: RuleActionTypeId, + params: RuleActionParams, + }) + // t.partial({ frequency: RuleActionFrequency }), + // ]) ); export type RuleActionArray = t.TypeOf; @@ -54,15 +54,15 @@ export const RuleActionArray = t.array(RuleAction); export type RuleActionCamel = t.TypeOf; export const RuleActionCamel = t.exact( - t.intersection([ - t.type({ - group: RuleActionGroup, - id: RuleActionId, - actionTypeId: RuleActionTypeId, - params: RuleActionParams, - }), - t.partial({ frequency: RuleActionFrequency }), - ]) + // t.intersection([ + t.type({ + group: RuleActionGroup, + id: RuleActionId, + actionTypeId: RuleActionTypeId, + params: RuleActionParams, + }) + // t.partial({ frequency: RuleActionFrequency }), + // ]) ); export type RuleActionArrayCamel = t.TypeOf; diff --git a/x-pack/plugins/alerting/common/rule_notify_when_type.ts b/x-pack/plugins/alerting/common/rule_notify_when_type.ts index 0059938ed8667..76182636e9f71 100644 --- a/x-pack/plugins/alerting/common/rule_notify_when_type.ts +++ b/x-pack/plugins/alerting/common/rule_notify_when_type.ts @@ -12,11 +12,11 @@ export const RuleNotifyWhenTypeValues = [ ] as const; export type RuleNotifyWhenType = typeof RuleNotifyWhenTypeValues[number]; -export const RuleNotifyWhen: Record = { - CHANGE: 'onActionGroupChange', - ACTIVE: 'onActiveAlert', - THROTTLE: 'onThrottleInterval', -}; +export enum RuleNotifyWhen { + CHANGE = 'onActionGroupChange', + ACTIVE = 'onActiveAlert', + THROTTLE = 'onThrottleInterval', +} export function validateNotifyWhenType(notifyWhen: string) { if (RuleNotifyWhenTypeValues.includes(notifyWhen as RuleNotifyWhenType)) { diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts index a43bf3bedefef..195cdba02c659 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts @@ -541,22 +541,19 @@ async function getUpdatedAttributesFromOperations( // the `isAttributesUpdateSkipped` flag to false. switch (operation.field) { case 'actions': { - // Prepare to handle the case of when the rule attributes contain legacy rule-level throttle or notifyWhen, - // and we're bulk adding actions with action-level frequency params. - let attempts = 0; - while (attempts < 2) { - attempts++; - try { - await validateActions(context, ruleType, { - ...attributes, - actions: operation.value, - }); - } catch (e) { - // If validateActions fails on the first attempt, try to remove the rule-level frequency params. - // The loop will attempt to validate again. Only allow the error to throw uncaught if it happens twice. - if (typeof attributes.notifyWhen !== 'undefined') attributes.notifyWhen = undefined; - if (attributes.throttle) attributes.throttle = undefined; - } + try { + await validateActions(context, ruleType, { + ...attributes, + actions: operation.value, + }); + } catch (e) { + // If validateActions fails on the first attempt, it may be because of legacy rule-level frequency params + attributes = await attemptToMigrateLegacyFrequency( + context, + operation, + attributes, + ruleType + ); } const { modifiedAttributes, isAttributeModified } = applyBulkEditOperation( @@ -567,15 +564,15 @@ async function getUpdatedAttributesFromOperations( ruleActions = modifiedAttributes; isAttributesUpdateSkipped = false; } - if (operation.syncFrequency) { - const frequency = operation.value[0]?.frequency; - if (frequency) { - ruleActions.actions = ruleActions.actions.map((action) => ({ - ...action, - frequency, - })); - } + + const firstFrequency = operation.value[0]?.frequency; + if (operation.syncFrequency && firstFrequency) { + ruleActions.actions = ruleActions.actions.map((action) => ({ + ...action, + frequency: firstFrequency, + })); } + break; } case 'snoozeSchedule': { @@ -780,3 +777,21 @@ async function saveBulkUpdatedRules( return { result, apiKeysToInvalidate }; } + +async function attemptToMigrateLegacyFrequency( + context: RulesClientContext, + operation: BulkEditOperation, + attributes: SavedObjectsFindResult['attributes'], + ruleType: RuleType +) { + if (operation.field !== 'actions') + throw new Error('Can only perform frequency migration on an action operation'); + // Try to remove the rule-level frequency params, and then validate actions + if (typeof attributes.notifyWhen !== 'undefined') attributes.notifyWhen = undefined; + if (attributes.throttle) attributes.throttle = undefined; + await validateActions(context, ruleType, { + ...attributes, + actions: operation.value, + }); + return attributes; +} diff --git a/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts index a80a68aaef2cf..fe09aa749f806 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts @@ -33,8 +33,8 @@ export const transformAlertToRuleAction = ({ id, params, action_type_id: actionTypeId, + frequency, } as RuleAlertAction; - if (frequency) action.frequency = frequency; return action; }; 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 8b32864e449e7..b11f7b5d11df9 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 @@ -13,7 +13,7 @@ import ReactMarkdown from 'react-markdown'; import styled from 'styled-components'; import type { ActionVariables } from '@kbn/triggers-actions-ui-plugin/public'; -import type { RuleAction } from '@kbn/alerting-plugin/common'; +import type { RuleAction, RuleActionParam } from '@kbn/alerting-plugin/common'; import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import { SecurityConnectorFeatureId } from '@kbn/actions-plugin/common'; import type { FieldHook } from '../../../../shared_imports'; @@ -102,8 +102,7 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = ); const setActionParamsProperty = useCallback( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (key: string, value: any, index: number) => { + (key: string, value: RuleActionParam, index: number) => { // validation is not triggered correctly when actions params updated (more details in https://github.com/elastic/kibana/issues/142217) // wrapping field.setValue in setTimeout fixes the issue above // and triggers validation after params have been updated @@ -127,8 +126,7 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = ); const setActionFrequencyProperty = useCallback( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (key: string, value: any, index: number) => { + (key: string, value: RuleActionParam, index: number) => { setTimeout( () => field.setValue((prevValue: RuleAction[]) => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts index f76ce44efb521..bc2cb970ba7f3 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/normalization/rule_actions.ts @@ -71,10 +71,7 @@ export const transformFromAlertThrottle = ( if (rule.muteAll || rule.actions.length === 0) { return NOTIFICATION_THROTTLE_NO_ACTIONS; } else if (rule.notifyWhen == null) { - const frequency = rule.actions[0].frequency ?? null; - if (!frequency || frequency.notifyWhen !== 'onThrottleInterval' || frequency.throttle == null) - return NOTIFICATION_THROTTLE_RULE; - return frequency.throttle; + return transformFromFirstActionThrottle(rule); } else if (rule.notifyWhen === 'onActiveAlert') { return NOTIFICATION_THROTTLE_RULE; } else if (rule.throttle == null) { @@ -87,6 +84,13 @@ export const transformFromAlertThrottle = ( } }; +function transformFromFirstActionThrottle(rule: RuleAlertType) { + const frequency = rule.actions[0].frequency ?? null; + if (!frequency || frequency.notifyWhen !== 'onThrottleInterval' || frequency.throttle == null) + return NOTIFICATION_THROTTLE_RULE; + return frequency.throttle; +} + /** * Given a set of actions from an "alerting" Saved Object (SO) this will transform it into a "security_solution" alert action. * If this detects any legacy rule actions it will transform it. If both are sent in which is not typical but possible due to From a4e2ff04cf0499f731b1cb6257b84558d709c6c9 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Tue, 3 Jan 2023 12:24:36 -0600 Subject: [PATCH 76/85] Fix double defined default frequency --- .../src/actions/index.ts | 36 +++++++++---------- .../sections/rule_form/rule_reducer.ts | 9 ++--- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts index 4304cfbfcccf5..85badce161871 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts @@ -38,15 +38,15 @@ export const RuleActionFrequency = t.type({ export type RuleAction = t.TypeOf; export const RuleAction = t.exact( - // t.intersection([ - t.type({ - group: RuleActionGroup, - id: RuleActionId, - action_type_id: RuleActionTypeId, - params: RuleActionParams, - }) - // t.partial({ frequency: RuleActionFrequency }), - // ]) + t.intersection([ + t.type({ + group: RuleActionGroup, + id: RuleActionId, + action_type_id: RuleActionTypeId, + params: RuleActionParams, + }), + t.partial({ frequency: RuleActionFrequency }), + ]) ); export type RuleActionArray = t.TypeOf; @@ -54,15 +54,15 @@ export const RuleActionArray = t.array(RuleAction); export type RuleActionCamel = t.TypeOf; export const RuleActionCamel = t.exact( - // t.intersection([ - t.type({ - group: RuleActionGroup, - id: RuleActionId, - actionTypeId: RuleActionTypeId, - params: RuleActionParams, - }) - // t.partial({ frequency: RuleActionFrequency }), - // ]) + t.intersection([ + t.type({ + group: RuleActionGroup, + id: RuleActionId, + actionTypeId: RuleActionTypeId, + params: RuleActionParams, + }), + t.partial({ frequency: RuleActionFrequency }), + ]) ); export type RuleActionArrayCamel = t.TypeOf; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts index 15e4d2f9c7924..55ce45d592d00 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_reducer.ts @@ -9,7 +9,8 @@ import { SavedObjectAttribute } from '@kbn/core/public'; import { isEqual } from 'lodash'; import { Reducer } from 'react'; import { RuleActionParam, IntervalSchedule } from '@kbn/alerting-plugin/common'; -import { Rule, RuleAction, RuleNotifyWhenType } from '../../../types'; +import { Rule, RuleAction } from '../../../types'; +import { DEFAULT_FREQUENCY } from '../../../common/constants'; export type InitialRule = Partial & Pick; @@ -27,12 +28,6 @@ interface CommandType< type: T; } -export const DEFAULT_FREQUENCY = { - notifyWhen: 'onActionGroupChange' as RuleNotifyWhenType, - throttle: null, - summary: false, -}; - export interface RuleState { rule: InitialRule; } From c77579121e4e55300b818d06d9c480cbcbad1769 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 4 Jan 2023 12:46:06 -0600 Subject: [PATCH 77/85] Revert security solution APIs and add workarounds for frequency schema --- .../src/actions/index.ts | 41 ++++++------------- .../server/rules_client/methods/bulk_edit.ts | 5 ++- .../server/rules_client/methods/create.ts | 8 ++++ .../server/rules_client/methods/update.ts | 8 ++++ .../rules/bulk_actions/request_schema.test.ts | 40 +++++++++++------- .../api/rules/bulk_actions/request_schema.ts | 26 ++++-------- .../detection_engine/transform_actions.ts | 17 +++----- .../bulk_actions/forms/rule_actions_form.tsx | 19 +-------- .../bulk_actions/use_bulk_actions.tsx | 7 ++++ .../utils/compute_dry_run_edit_payload.ts | 2 +- .../rules/rule_actions_field/index.tsx | 31 +------------- .../action_to_rules_client_operation.ts | 5 +-- .../logic/bulk_actions/bulk_edit_rules.ts | 8 ++-- 13 files changed, 89 insertions(+), 128 deletions(-) diff --git a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts index 85badce161871..2e0d814bf93c5 100644 --- a/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts +++ b/packages/kbn-securitysolution-io-ts-alerting-types/src/actions/index.ts @@ -25,28 +25,14 @@ export const RuleActionTypeId = t.string; export type RuleActionParams = t.TypeOf; export const RuleActionParams = saved_object_attributes; -export type RuleActionFrequency = t.TypeOf; -export const RuleActionFrequency = t.type({ - summary: t.boolean, - notifyWhen: t.union([ - t.literal('onActionGroupChange'), - t.literal('onActiveAlert'), - t.literal('onThrottleInterval'), - ]), - throttle: t.union([t.string, t.null]), -}); - export type RuleAction = t.TypeOf; export const RuleAction = t.exact( - t.intersection([ - t.type({ - group: RuleActionGroup, - id: RuleActionId, - action_type_id: RuleActionTypeId, - params: RuleActionParams, - }), - t.partial({ frequency: RuleActionFrequency }), - ]) + t.type({ + group: RuleActionGroup, + id: RuleActionId, + action_type_id: RuleActionTypeId, + params: RuleActionParams, + }) ); export type RuleActionArray = t.TypeOf; @@ -54,15 +40,12 @@ export const RuleActionArray = t.array(RuleAction); export type RuleActionCamel = t.TypeOf; export const RuleActionCamel = t.exact( - t.intersection([ - t.type({ - group: RuleActionGroup, - id: RuleActionId, - actionTypeId: RuleActionTypeId, - params: RuleActionParams, - }), - t.partial({ frequency: RuleActionFrequency }), - ]) + t.type({ + group: RuleActionGroup, + id: RuleActionId, + actionTypeId: RuleActionTypeId, + params: RuleActionParams, + }) ); export type RuleActionArrayCamel = t.TypeOf; diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts index 195cdba02c659..0e0a67eced39a 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts @@ -78,7 +78,6 @@ export type BulkEditOperation = operation: 'add' | 'set'; field: Extract; value: NormalizedAlertAction[]; - syncFrequency?: boolean; } | { operation: 'set'; @@ -565,8 +564,10 @@ async function getUpdatedAttributesFromOperations( isAttributesUpdateSkipped = false; } + // TODO https://github.com/elastic/kibana/issues/148414 + // If any action-level frequencies get pushed into a SIEM rule, sync up their frequencies const firstFrequency = operation.value[0]?.frequency; - if (operation.syncFrequency && firstFrequency) { + if (rule.attributes.consumer === AlertConsumers.SIEM && firstFrequency) { ruleActions.actions = ruleActions.actions.map((action) => ({ ...action, frequency: firstFrequency, diff --git a/x-pack/plugins/alerting/server/rules_client/methods/create.ts b/x-pack/plugins/alerting/server/rules_client/methods/create.ts index 31707726b4e24..ed691524fe812 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/create.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/create.ts @@ -6,6 +6,7 @@ */ import Semver from 'semver'; import Boom from '@hapi/boom'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { SavedObjectsUtils } from '@kbn/core/server'; import { parseDuration } from '../../../common/parse_duration'; import { RawRule, SanitizedRule, RuleTypeParams, RuleAction, Rule } from '../../types'; @@ -86,6 +87,13 @@ export async function create( throw Boom.badRequest(`Error creating rule: could not create API key - ${error.message}`); } + // TODO https://github.com/elastic/kibana/issues/148414 + // If any action-level frequencies get pushed into a SIEM rule, sync up their frequencies + if (data.consumer === AlertConsumers.SIEM && data.actions[0]?.frequency) { + const firstFrequency = data.actions[0].frequency; + data.actions = data.actions.map((a) => ({ ...a, frequency: firstFrequency })); + } + await validateActions(context, ruleType, data); // Throw error if schedule interval is less than the minimum and we are enforcing it diff --git a/x-pack/plugins/alerting/server/rules_client/methods/update.ts b/x-pack/plugins/alerting/server/rules_client/methods/update.ts index 289f5fe007874..b0e5591b0e9e8 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/update.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/update.ts @@ -8,6 +8,7 @@ import Boom from '@hapi/boom'; import { isEqual } from 'lodash'; import { SavedObject } from '@kbn/core/server'; +import { AlertConsumers } from '@kbn/rule-data-utils'; import { PartialRule, RawRule, @@ -142,6 +143,13 @@ async function updateAlert( ): Promise> { const ruleType = context.ruleTypeRegistry.get(attributes.alertTypeId); + // TODO https://github.com/elastic/kibana/issues/148414 + // If any action-level frequencies get pushed into a SIEM rule, sync up their frequencies + if (attributes.consumer === AlertConsumers.SIEM && data.actions[0]?.frequency) { + const firstFrequency = data.actions[0].frequency; + data.actions = data.actions.map((a) => ({ ...a, frequency: firstFrequency })); + } + // Validate const validatedAlertTypeParams = validateRuleTypeParams(data.params, ruleType.validate?.params); await validateActions(context, ruleType, data); diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts index 67e1df47962d7..3cee4c3dbe384 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.test.ts @@ -512,6 +512,28 @@ describe('Perform bulk action request schema', () => { expect(message.schema).toEqual({}); }); + test('invalid request: missing throttle in payload', () => { + const payload = { + query: 'name: test', + action: BulkActionType.edit, + [BulkActionType.edit]: [ + { + type: BulkActionEditType.add_rule_actions, + value: { + actions: [], + }, + }, + ], + }; + + const message = retrieveValidationMessage(payload); + + expect(getPaths(left(message.errors))).toEqual( + expect.arrayContaining(['Invalid value "undefined" supplied to "edit,value,throttle"']) + ); + expect(message.schema).toEqual({}); + }); + test('invalid request: missing actions in payload', () => { const payload = { query: 'name: test', @@ -542,6 +564,7 @@ describe('Perform bulk action request schema', () => { { type: BulkActionEditType.add_rule_actions, value: { + throttle: '1h', actions: [ { action_type_id: '.webhook', @@ -552,11 +575,6 @@ describe('Perform bulk action request schema', () => { rule_id: '{{rule.id}}', }, }, - frequency: { - notifyWhen: 'onThrottleInterval', - throttle: '1h', - summary: false, - }, }, ], }, @@ -579,6 +597,7 @@ describe('Perform bulk action request schema', () => { { type: BulkActionEditType.add_rule_actions, value: { + throttle: '1h', actions: [ { group: 'default', @@ -588,11 +607,6 @@ describe('Perform bulk action request schema', () => { rule_id: '{{rule.id}}', }, }, - frequency: { - notifyWhen: 'onThrottleInterval', - throttle: '1h', - summary: false, - }, }, ], }, @@ -614,6 +628,7 @@ describe('Perform bulk action request schema', () => { { type: BulkActionEditType.set_rule_actions, value: { + throttle: '1h', actions: [ { group: 'default', @@ -625,11 +640,6 @@ describe('Perform bulk action request schema', () => { }, ], }, - frequency: { - notifyWhen: 'onThrottleInterval', - throttle: '1h', - summary: false, - }, }, ], }, diff --git a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts index a49bdf46fcb45..b0860c55ebd5a 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/rule_management/api/rules/bulk_actions/request_schema.ts @@ -12,7 +12,6 @@ import { RuleActionGroup, RuleActionId, RuleActionParams, - RuleActionFrequency, } from '@kbn/securitysolution-io-ts-alerting-types'; import { @@ -97,14 +96,11 @@ const BulkActionEditPayloadTimeline = t.type({ */ type NormalizedRuleAction = t.TypeOf; const NormalizedRuleAction = t.exact( - t.intersection([ - t.type({ - group: RuleActionGroup, - id: RuleActionId, - params: RuleActionParams, - }), - t.partial({ frequency: RuleActionFrequency }), - ]) + t.type({ + group: RuleActionGroup, + id: RuleActionId, + params: RuleActionParams, + }) ); export type BulkActionEditPayloadRuleActions = t.TypeOf; @@ -113,14 +109,10 @@ export const BulkActionEditPayloadRuleActions = t.type({ t.literal(BulkActionEditType.add_rule_actions), t.literal(BulkActionEditType.set_rule_actions), ]), - value: t.intersection([ - t.type({ - actions: t.array(NormalizedRuleAction), - }), - t.partial({ - throttle: ThrottleForBulkActions, - }), - ]), + value: t.type({ + throttle: ThrottleForBulkActions, + actions: t.array(NormalizedRuleAction), + }), }); type BulkActionEditPayloadSchedule = t.TypeOf; diff --git a/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts index fe09aa749f806..da720b578bc65 100644 --- a/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts +++ b/x-pack/plugins/security_solution/common/detection_engine/transform_actions.ts @@ -26,17 +26,12 @@ export const transformAlertToRuleAction = ({ id, actionTypeId, params, - frequency, -}: RuleAction): RuleAlertAction => { - const action = { - group, - id, - params, - action_type_id: actionTypeId, - frequency, - } as RuleAlertAction; - return action; -}; +}: RuleAction): RuleAlertAction => ({ + group, + id, + params, + action_type_id: actionTypeId, +}); export const transformRuleToAlertResponseAction = ({ action_type_id: actionTypeId, diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx index c8c54353411bf..0bff754f20f4f 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/forms/rule_actions_form.tsx @@ -7,7 +7,6 @@ import React, { useCallback, useMemo } from 'react'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n-react'; -import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import type { RuleAction, @@ -111,25 +110,11 @@ const RuleActionsFormComponent = ({ rulesCount, onClose, onConfirm }: RuleAction ? BulkActionEditType.set_rule_actions : BulkActionEditType.add_rule_actions; - const frequencyToSubmit = - throttleToSubmit === NOTIFICATION_THROTTLE_RULE - ? { - notifyWhen: RuleNotifyWhen.ACTIVE, - throttle: null, - } - : { - notifyWhen: RuleNotifyWhen.THROTTLE, - throttle: throttleToSubmit, - }; - onConfirm({ type: editAction, value: { - throttle: actions.length === 0 ? throttleToSubmit : undefined, - actions: actions.map(({ actionTypeId, ...action }) => ({ - ...action, - frequency: { ...frequencyToSubmit, summary: false }, - })), + actions: actions.map(({ actionTypeId, ...action }) => action), + throttle: throttleToSubmit, }, }); }, [form, onConfirm]); diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx index 1dca480377c32..91b89209b16aa 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx @@ -6,6 +6,7 @@ */ /* eslint-disable complexity */ +import { omit } from 'lodash'; import type { EuiContextMenuPanelDescriptor } from '@elastic/eui'; import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiTextColor } from '@elastic/eui'; import type { Toast } from '@kbn/core/public'; @@ -221,6 +222,12 @@ export const useBulkActions = ({ return; } + // TODO: https://github.com/elastic/kibana/issues/148414 + // Strip frequency from actions to comply with Security Solution alert API + if ('actions' in editPayload.value) { + editPayload.value.actions = editPayload.value.actions.map((a) => omit(a, 'frequency')); + } + startTransaction({ name: BULK_RULE_ACTIONS.EDIT }); const hideWarningToast = () => { diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_edit_payload.ts b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_edit_payload.ts index f25b1331d766a..c8f49ebe4a6c6 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_edit_payload.ts +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/utils/compute_dry_run_edit_payload.ts @@ -50,7 +50,7 @@ export function computeDryRunEditPayload(editAction: BulkActionEditType): BulkAc return [ { type: editAction, - value: { actions: [] }, + value: { throttle: '1h', actions: [] }, }, ]; case BulkActionEditType.set_schedule: 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 b11f7b5d11df9..339b81f752723 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 @@ -14,7 +14,6 @@ import styled from 'styled-components'; import type { ActionVariables } from '@kbn/triggers-actions-ui-plugin/public'; import type { RuleAction, RuleActionParam } from '@kbn/alerting-plugin/common'; -import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import { SecurityConnectorFeatureId } from '@kbn/actions-plugin/common'; import type { FieldHook } from '../../../../shared_imports'; import { useFormContext } from '../../../../shared_imports'; @@ -30,12 +29,6 @@ const DEFAULT_ACTION_GROUP_ID = 'default'; const DEFAULT_ACTION_MESSAGE = 'Rule {{context.rule.name}} generated {{state.signals_count}} alerts'; -const DEFAULT_ACTION_FREQUENCY = { - notifyWhen: RuleNotifyWhen.CHANGE, - throttle: null, - summary: false, -}; - const FieldErrorsContainer = styled.div` p { margin-bottom: 0; @@ -125,27 +118,6 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = [field] ); - const setActionFrequencyProperty = useCallback( - (key: string, value: RuleActionParam, index: number) => { - setTimeout( - () => - field.setValue((prevValue: RuleAction[]) => { - const updatedActions = [...prevValue]; - updatedActions[index] = { - ...updatedActions[index], - frequency: { - ...(updatedActions[index].frequency ?? DEFAULT_ACTION_FREQUENCY), - [key]: value, - }, - }; - return updatedActions; - }), - 0 - ); - }, - [field] - ); - const actionForm = useMemo( () => getActionForm({ @@ -155,7 +127,7 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = setActionIdByIndex, setActions: setAlertActionsProperty, setActionParamsProperty, - setActionFrequencyProperty, + setActionFrequencyProperty: () => {}, featureId: SecurityConnectorFeatureId, defaultActionMessage: DEFAULT_ACTION_MESSAGE, hideActionHeader: true, @@ -168,7 +140,6 @@ export const RuleActionsField: React.FC = ({ field, messageVariables }) = setActionIdByIndex, setActionParamsProperty, setAlertActionsProperty, - setActionFrequencyProperty, ] ); diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts index 4c4eb6146823d..f767a5c246056 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/action_to_rules_client_operation.ts @@ -13,14 +13,14 @@ import { assertUnreachable } from '../../../../../../common/utility_types'; import { transformToAlertThrottle, transformToNotifyWhen } from '../../normalization/rule_actions'; -const getThrottleOperation = (throttle?: string) => +const getThrottleOperation = (throttle: string) => ({ field: 'throttle', operation: 'set', value: transformToAlertThrottle(throttle), } as const); -const getNotifyWhenOperation = (throttle?: string) => +const getNotifyWhenOperation = (throttle: string) => ({ field: 'notifyWhen', operation: 'set', @@ -71,7 +71,6 @@ export const bulkEditActionToRulesClientOperation = ( field: 'actions', operation: 'add', value: action.value.actions, - syncFrequency: true, }, getThrottleOperation(action.value.throttle), getNotifyWhenOperation(action.value.throttle), diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts index 6fe9dc1aac627..6660ce730f84b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/rule_management/logic/bulk_actions/bulk_edit_rules.ts @@ -7,8 +7,10 @@ import type { BulkOperationError, RulesClient } from '@kbn/alerting-plugin/server'; import pMap from 'p-map'; - -import { MAX_RULES_TO_UPDATE_IN_PARALLEL } from '../../../../../../common/constants'; +import { + MAX_RULES_TO_UPDATE_IN_PARALLEL, + NOTIFICATION_THROTTLE_NO_ACTIONS, +} from '../../../../../../common/constants'; import type { BulkActionEditPayload, @@ -84,7 +86,7 @@ export const bulkEditRules = async ({ result.rules, async (rule) => { try { - if (rule.muteAll && rulesAction.value.actions.length !== 0) { + if (rule.muteAll && rulesAction.value.throttle !== NOTIFICATION_THROTTLE_NO_ACTIONS) { await rulesClient.unmuteAll({ id: rule.id }); return (await readRules({ rulesClient, id: rule.id, ruleId: undefined })) ?? rule; } From 4f30e42b5473e7058497c4caa0ffe33513e07efc Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Wed, 4 Jan 2023 14:38:26 -0600 Subject: [PATCH 78/85] Revert bulk action test --- .../group10/perform_bulk_action.ts | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts index 0246456ee0381..06e55fdfdda1b 100644 --- a/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts +++ b/x-pack/test/detection_engine_api_integration/security_and_spaces/group10/perform_bulk_action.ts @@ -1847,6 +1847,10 @@ export default ({ getService }: FtrProviderContext): void => { }); const casesForNonEmptyActions = [ + { + payloadThrottle: NOTIFICATION_THROTTLE_RULE, + expectedThrottle: NOTIFICATION_THROTTLE_RULE, + }, { payloadThrottle: '1h', expectedThrottle: '1h', @@ -1878,16 +1882,12 @@ export default ({ getService }: FtrProviderContext): void => { { type: BulkActionEditType.set_rule_actions, value: { + throttle: payloadThrottle, actions: [ { id: webHookConnector.id, group: 'default', params: { body: '{}' }, - frequency: { - summary: false, - notifyWhen: 'onThrottleInterval', - throttle: payloadThrottle, - }, }, ], }, @@ -1902,8 +1902,7 @@ export default ({ getService }: FtrProviderContext): void => { // Check that the updates have been persisted const { body: rule } = await fetchRule(ruleId).expect(200); - expect(rule.throttle).to.be(expectedThrottle); - expect(rule.actions[0].frequency.throttle).to.be(expectedThrottle); + expect(rule.throttle).to.eql(expectedThrottle); }); }); } From 18e277a43ab02702adb58b39ab7b3e37ab875dc6 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 9 Jan 2023 10:46:24 -0600 Subject: [PATCH 79/85] Add comment about typedef discrepancy --- .../server/rules_client/methods/bulk_edit.ts | 13 +++++++------ .../alerting/server/rules_client/methods/create.ts | 13 +++++++++---- .../alerting/server/rules_client/methods/update.ts | 14 +++++++++----- .../rules_table/bulk_actions/use_bulk_actions.tsx | 4 ++++ 4 files changed, 29 insertions(+), 15 deletions(-) diff --git a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts index 0e0a67eced39a..6f3c28437a48e 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/bulk_edit.ts @@ -7,7 +7,7 @@ import pMap from 'p-map'; import Boom from '@hapi/boom'; -import { cloneDeep } from 'lodash'; +import { cloneDeep, omit } from 'lodash'; import { AlertConsumers } from '@kbn/rule-data-utils'; import { KueryNode, nodeBuilder } from '@kbn/es-query'; import { @@ -565,13 +565,14 @@ async function getUpdatedAttributesFromOperations( } // TODO https://github.com/elastic/kibana/issues/148414 - // If any action-level frequencies get pushed into a SIEM rule, sync up their frequencies + // If any action-level frequencies get pushed into a SIEM rule, strip their frequencies const firstFrequency = operation.value[0]?.frequency; if (rule.attributes.consumer === AlertConsumers.SIEM && firstFrequency) { - ruleActions.actions = ruleActions.actions.map((action) => ({ - ...action, - frequency: firstFrequency, - })); + ruleActions.actions = ruleActions.actions.map((action) => omit(action, 'frequency')); + if (!attributes.notifyWhen) { + attributes.notifyWhen = firstFrequency.notifyWhen; + attributes.throttle = firstFrequency.throttle; + } } break; diff --git a/x-pack/plugins/alerting/server/rules_client/methods/create.ts b/x-pack/plugins/alerting/server/rules_client/methods/create.ts index ed691524fe812..6a64868103898 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/create.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/create.ts @@ -6,6 +6,7 @@ */ import Semver from 'semver'; import Boom from '@hapi/boom'; +import { omit } from 'lodash'; import { AlertConsumers } from '@kbn/rule-data-utils'; import { SavedObjectsUtils } from '@kbn/core/server'; import { parseDuration } from '../../../common/parse_duration'; @@ -88,10 +89,14 @@ export async function create( } // TODO https://github.com/elastic/kibana/issues/148414 - // If any action-level frequencies get pushed into a SIEM rule, sync up their frequencies - if (data.consumer === AlertConsumers.SIEM && data.actions[0]?.frequency) { - const firstFrequency = data.actions[0].frequency; - data.actions = data.actions.map((a) => ({ ...a, frequency: firstFrequency })); + // If any action-level frequencies get pushed into a SIEM rule, strip their frequencies + const firstFrequency = data.actions[0]?.frequency; + if (data.consumer === AlertConsumers.SIEM && firstFrequency) { + data.actions = data.actions.map((action) => omit(action, 'frequency')); + if (!data.notifyWhen) { + data.notifyWhen = firstFrequency.notifyWhen; + data.throttle = firstFrequency.throttle; + } } await validateActions(context, ruleType, data); diff --git a/x-pack/plugins/alerting/server/rules_client/methods/update.ts b/x-pack/plugins/alerting/server/rules_client/methods/update.ts index b0e5591b0e9e8..8fa3855b95707 100644 --- a/x-pack/plugins/alerting/server/rules_client/methods/update.ts +++ b/x-pack/plugins/alerting/server/rules_client/methods/update.ts @@ -6,7 +6,7 @@ */ import Boom from '@hapi/boom'; -import { isEqual } from 'lodash'; +import { isEqual, omit } from 'lodash'; import { SavedObject } from '@kbn/core/server'; import { AlertConsumers } from '@kbn/rule-data-utils'; import { @@ -144,10 +144,14 @@ async function updateAlert( const ruleType = context.ruleTypeRegistry.get(attributes.alertTypeId); // TODO https://github.com/elastic/kibana/issues/148414 - // If any action-level frequencies get pushed into a SIEM rule, sync up their frequencies - if (attributes.consumer === AlertConsumers.SIEM && data.actions[0]?.frequency) { - const firstFrequency = data.actions[0].frequency; - data.actions = data.actions.map((a) => ({ ...a, frequency: firstFrequency })); + // If any action-level frequencies get pushed into a SIEM rule, strip their frequencies + const firstFrequency = data.actions[0]?.frequency; + if (attributes.consumer === AlertConsumers.SIEM && firstFrequency) { + data.actions = data.actions.map((action) => omit(action, 'frequency')); + if (!attributes.notifyWhen) { + attributes.notifyWhen = firstFrequency.notifyWhen; + attributes.throttle = firstFrequency.throttle; + } } // Validate diff --git a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx index 91b89209b16aa..f9915777483a8 100644 --- a/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx +++ b/x-pack/plugins/security_solution/public/detection_engine/rule_management_ui/components/rules_table/bulk_actions/use_bulk_actions.tsx @@ -225,6 +225,10 @@ export const useBulkActions = ({ // TODO: https://github.com/elastic/kibana/issues/148414 // Strip frequency from actions to comply with Security Solution alert API if ('actions' in editPayload.value) { + // `actions.frequency` is included in the payload from TriggersActionsUI ActionForm + // but is not included in the type definition for the editPayload, because this type + // definition comes from the Security Solution alert API + // TODO https://github.com/elastic/kibana/issues/148414 fix this discrepancy editPayload.value.actions = editPayload.value.actions.map((a) => omit(a, 'frequency')); } From f3acddaa870d0ba383dfcd267617e4d56b73cd03 Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 9 Jan 2023 11:20:04 -0600 Subject: [PATCH 80/85] Revert "Lock throttle interval to check interval" This reverts commit 40ce55ad7ff63998e2fd941bb5176f53258731ca. --- .../action_connector_form/action_form.tsx | 3 - .../action_notify_when.tsx | 8 ++- .../action_type_form.tsx | 59 ++++--------------- .../sections/rule_form/rule_form.tsx | 1 - 4 files changed, 17 insertions(+), 54 deletions(-) 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 17b27bf509d3b..1edf372334757 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 @@ -65,7 +65,6 @@ export interface ActionAccordionFormProps { isActionGroupDisabledForActionType?: (actionGroupId: string, actionTypeId: string) => boolean; hideActionHeader?: boolean; hideNotifyWhen?: boolean; - minimumThrottleInterval?: [number | undefined, string]; } interface ActiveActionConnectorState { @@ -92,7 +91,6 @@ export const ActionForm = ({ isActionGroupDisabledForActionType, hideActionHeader, hideNotifyWhen, - minimumThrottleInterval, }: ActionAccordionFormProps) => { const { http, @@ -398,7 +396,6 @@ export const ActionForm = ({ setActiveActionItem(undefined); }} hideNotifyWhen={hideNotifyWhen} - minimumThrottleInterval={minimumThrottleInterval} /> ); })} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx index 30b4d9388e6bd..92fc56c2b63f6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -130,6 +130,7 @@ export const ActionNotifyWhen = ({ onNotifyWhenChange, onThrottleChange, }: RuleNotifyWhenProps) => { + const [ruleThrottle, setRuleThrottle] = useState(throttle || 1); const [showCustomThrottleOpts, setShowCustomThrottleOpts] = useState(false); const [notifyWhenValue, setNotifyWhenValue] = useState(DEFAULT_NOTIFY_WHEN_VALUE); @@ -153,11 +154,11 @@ export const ActionNotifyWhen = ({ setNotifyWhenValue(newValue); setTimeout( () => - onThrottleChange(newValue === 'onThrottleInterval' ? throttle ?? 1 : null, throttleUnit), + onThrottleChange(newValue === 'onThrottleInterval' ? ruleThrottle : null, throttleUnit), 100 ); }, - [onNotifyWhenChange, setNotifyWhenValue, onThrottleChange, throttle, throttleUnit] + [onNotifyWhenChange, setNotifyWhenValue, onThrottleChange, ruleThrottle, throttleUnit] ); const labelForRuleRenotify = [ @@ -193,7 +194,7 @@ export const ActionNotifyWhen = ({ parseInt(value, 10)), filter((value) => !isNaN(value)), map((value) => { + setRuleThrottle(value); onThrottleChange(value, throttleUnit); }) ); 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 d731cf2f37816..4853abb756ab6 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 @@ -31,7 +31,6 @@ import { ActionVariable, RuleActionParam } from '@kbn/alerting-plugin/common'; import { getDurationNumberInItsUnit, getDurationUnitValue, - parseDuration, } from '@kbn/alerting-plugin/common/parse_duration'; import { betaBadgeProps } from './beta_badge_props'; import { @@ -66,7 +65,6 @@ export type ActionTypeFormProps = { recoveryActionGroup?: string; isActionGroupDisabledForActionType?: (actionGroupId: string, actionTypeId: string) => boolean; hideNotifyWhen?: boolean; - minimumThrottleInterval?: [number | undefined, string]; } & Pick< ActionAccordionFormProps, | 'defaultActionGroupId' @@ -104,7 +102,6 @@ export const ActionTypeForm = ({ isActionGroupDisabledForActionType, recoveryActionGroup, hideNotifyWhen = false, - minimumThrottleInterval, }: ActionTypeFormProps) => { const { application: { capabilities }, @@ -126,10 +123,6 @@ export const ActionTypeForm = ({ const [actionThrottleUnit, setActionThrottleUnit] = useState( actionItem.frequency?.throttle ? getDurationUnitValue(actionItem.frequency?.throttle) : 'h' ); - const [minimumActionThrottle = -1, minimumActionThrottleUnit] = minimumThrottleInterval ?? [ - -1, - 's', - ]; const getDefaultParams = async () => { const connectorType = await actionTypeRegistry.get(actionItem.actionTypeId); @@ -145,40 +138,6 @@ export const ActionTypeForm = ({ return defaultParams; }; - const getBoundThrottle = useCallback( - (throttle: number | null, throttleUnit: string) => { - try { - const throttleUnitDuration = parseDuration(`1${throttleUnit}`); - const minThrottleUnitDuration = parseDuration(`1${minimumActionThrottleUnit}`); - const boundedThrottle = - throttleUnitDuration > minThrottleUnitDuration || !throttle - ? throttle - : Math.max(throttle, minimumActionThrottle); - const boundedThrottleUnit = - throttleUnitDuration >= minThrottleUnitDuration - ? throttleUnit - : minimumActionThrottleUnit; - return [boundedThrottle, boundedThrottleUnit] as [number | null, string]; - } catch (e) { - return [throttle, throttleUnit] as [number | null, string]; - } - }, - [minimumActionThrottle, minimumActionThrottleUnit] - ); - - useEffect(() => { - const [boundThrottle, boundThrottleUnit] = getBoundThrottle(actionThrottle, actionThrottleUnit); - if (boundThrottle !== actionThrottle) setActionThrottle(boundThrottle); - if (boundThrottleUnit !== actionThrottleUnit) setActionThrottleUnit(boundThrottleUnit); - }, [ - getBoundThrottle, - actionThrottle, - actionThrottleUnit, - setActionThrottle, - setActionThrottleUnit, - minimumThrottleInterval, - ]); - useEffect(() => { (async () => { setAvailableActionVariables( @@ -219,6 +178,13 @@ export const ActionTypeForm = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [actionItem]); + // useEffect(() => { + // if (!actionItem.frequency) { + // setActionFrequency(DEFAULT_FREQUENCY, index); + // } + // // eslint-disable-next-line react-hooks/exhaustive-deps + // }, [actionItem.frequency]); + const canSave = hasSaveActionsCapability(capabilities); const actionGroupDisplay = ( @@ -256,16 +222,15 @@ export const ActionTypeForm = ({ )} onThrottleChange={useCallback( (throttle: number | null, throttleUnit: string) => { - const [boundedThrottle, boundedThrottleUnit] = getBoundThrottle(throttle, throttleUnit); - setActionThrottle(boundedThrottle); - setActionThrottleUnit(boundedThrottleUnit); + setActionThrottle(throttle); + setActionThrottleUnit(throttleUnit); setActionFrequencyProperty( 'throttle', - boundedThrottle ? `${boundedThrottle}${boundedThrottleUnit}` : null, + throttle ? `${throttle}${throttleUnit}` : null, index ); }, - [setActionFrequencyProperty, index, getBoundThrottle] + [setActionFrequencyProperty, index] )} /> ); @@ -289,6 +254,7 @@ export const ActionTypeForm = ({ <> {showSelectActionGroup && ( <> + @@ -313,7 +279,6 @@ export const ActionTypeForm = ({ setActionGroup(group); }} /> - {!hideNotifyWhen && } )} {!hideNotifyWhen && actionNotifyWhen} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx index 8a0ad49e936f4..94a7cc5bba513 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/rule_form/rule_form.tsx @@ -672,7 +672,6 @@ export const RuleForm = ({ setActionParamsProperty={setActionParamsProperty} actionTypeRegistry={actionTypeRegistry} setActionFrequencyProperty={setActionFrequencyProperty} - minimumThrottleInterval={[ruleInterval, ruleIntervalUnit]} /> ) : null} From 9d37ce7c0ecd6ddbdc9a8d01b21bf589085055af Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 9 Jan 2023 11:42:50 -0600 Subject: [PATCH 81/85] Remove minimum throttle test --- .../action_type_form.test.tsx | 76 ------------------- 1 file changed, 76 deletions(-) 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 4a198be3e16b6..3d51b918c7e4e 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 @@ -262,87 +262,12 @@ describe('action_type_form', () => { // Clearing all mocks will also reset fake timers. jest.clearAllMocks(); }); - - it('enforces the minimum throttle prop', async () => { - const actionType = actionTypeRegistryMock.createMockActionTypeModel({ - id: '.pagerduty', - iconClass: 'test', - selectMessage: 'test', - validateParams: (): Promise> => { - const validationResult = { errors: {} }; - return Promise.resolve(validationResult); - }, - actionConnectorFields: null, - actionParamsFields: mockedActionParamsFields, - defaultActionParams: { - dedupKey: 'test', - eventAction: 'resolve', - }, - }); - actionTypeRegistry.get.mockReturnValue(actionType); - - const wrapper = mountWithIntl( - getActionTypeForm( - 1, - undefined, - { - id: '123', - actionTypeId: '.pagerduty', - group: 'recovered', - params: { - eventAction: 'recovered', - dedupKey: undefined, - summary: '2323', - source: 'source', - severity: '1', - timestamp: new Date().toISOString(), - component: 'test', - group: 'group', - class: 'test class', - }, - frequency: { - throttle: '3m', - notifyWhen: 'onThrottleInterval', - summary: false, - }, - }, - [5, 'h'] - ) - ); - - // Wait for active space to resolve before requesting the component to update - await act(async () => { - await nextTick(); - wrapper.update(); - }); - - const throttleField = wrapper.find('[data-test-subj="throttleInput"]'); - const throttleUnitField = wrapper.find('[data-test-subj="throttleUnitInput"]'); - expect(throttleField.exists()).toBeTruthy(); - expect(throttleUnitField.exists()).toBeTruthy(); - - // expect(throttleField.first().prop('value')).toEqual(5); - // expect(throttleUnitField.first().prop('value')).toEqual('h'); - - const newThrottle = 3; - throttleField.first().simulate('change', { target: { value: newThrottle.toString() } }); - await nextTick(); - wrapper.update(); - const throttleFieldAfterUpdate = wrapper.find('[data-test-subj="throttleInput"]'); - expect(throttleFieldAfterUpdate.first().prop('value')).toEqual(5); - - throttleUnitField.first().simulate('change', { target: { value: 'd' } }); - throttleField.first().simulate('change', { target: { value: newThrottle.toString() } }); - const throttleFieldAfterUpdate2 = wrapper.find('[data-test-subj="throttleInput"]'); - expect(throttleFieldAfterUpdate2.first().prop('value')).toEqual(5); - }); }); function getActionTypeForm( index?: number, actionConnector?: ActionConnector, Record>, actionItem?: RuleAction, - minimumThrottleInterval?: [number | undefined, string], defaultActionGroupId?: string, connectors?: Array, Record>>, actionTypeIndex?: Record, @@ -430,7 +355,6 @@ function getActionTypeForm( index={index ?? 1} actionTypesIndex={actionTypeIndex ?? actionTypeIndexDefault} actionTypeRegistry={actionTypeRegistry} - minimumThrottleInterval={minimumThrottleInterval} /> ); } From 2614f4aa7368ecb5398d272c3b4850f94a1c6d8e Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 9 Jan 2023 16:02:28 -0600 Subject: [PATCH 82/85] Add setTimeout comment --- .../sections/action_connector_form/action_notify_when.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx index 92fc56c2b63f6..cebc7ac5864ef 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -152,6 +152,8 @@ export const ActionNotifyWhen = ({ (newValue: RuleNotifyWhenType) => { onNotifyWhenChange(newValue); setNotifyWhenValue(newValue); + // Calling onNotifyWhenChange and onThrottleChange at the same time interferes with the React state lifecycle + // so wait for onNotifyWhenChange to process before calling onThrottleChange setTimeout( () => onThrottleChange(newValue === 'onThrottleInterval' ? ruleThrottle : null, throttleUnit), From 339c67e105690a1ef21ab5122a89845fa9aa636d Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 9 Jan 2023 16:04:45 -0600 Subject: [PATCH 83/85] Lint fix --- .../sections/action_connector_form/action_notify_when.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx index cebc7ac5864ef..32727a6235ff4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -5,6 +5,7 @@ * 2.0. */ +import { RuleNotifyWhen } from '@kbn/alerting-plugin/common'; import React, { useState, useEffect, useCallback } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n-react'; @@ -140,7 +141,7 @@ export const ActionNotifyWhen = ({ setNotifyWhenValue(frequency.notifyWhen); } else { // If 'notifyWhen' is not set, derive value from existence of throttle value - setNotifyWhenValue(frequency.throttle ? 'onThrottleInterval' : 'onActiveAlert'); + setNotifyWhenValue(frequency.throttle ? RuleNotifyWhen.THROTTLE : RuleNotifyWhen.ACTIVE); } }, [frequency]); From d748d54a5ff10c8de67c89a1d342cc44e05adf4d Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 9 Jan 2023 16:08:38 -0600 Subject: [PATCH 84/85] Remove ruleThrottle state --- .../sections/action_connector_form/action_notify_when.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx index 32727a6235ff4..b826590c03e26 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -131,7 +131,6 @@ export const ActionNotifyWhen = ({ onNotifyWhenChange, onThrottleChange, }: RuleNotifyWhenProps) => { - const [ruleThrottle, setRuleThrottle] = useState(throttle || 1); const [showCustomThrottleOpts, setShowCustomThrottleOpts] = useState(false); const [notifyWhenValue, setNotifyWhenValue] = useState(DEFAULT_NOTIFY_WHEN_VALUE); @@ -157,11 +156,11 @@ export const ActionNotifyWhen = ({ // so wait for onNotifyWhenChange to process before calling onThrottleChange setTimeout( () => - onThrottleChange(newValue === 'onThrottleInterval' ? ruleThrottle : null, throttleUnit), + onThrottleChange(newValue === 'onThrottleInterval' ? throttle ?? 1 : null, throttleUnit), 100 ); }, - [onNotifyWhenChange, setNotifyWhenValue, onThrottleChange, ruleThrottle, throttleUnit] + [onNotifyWhenChange, setNotifyWhenValue, onThrottleChange, throttleUnit] ); const labelForRuleRenotify = [ @@ -197,7 +196,7 @@ export const ActionNotifyWhen = ({ parseInt(value, 10)), filter((value) => !isNaN(value)), map((value) => { - setRuleThrottle(value); onThrottleChange(value, throttleUnit); }) ); From 6006849e000b4ad093c27cfada9c6e1a49aa1d3e Mon Sep 17 00:00:00 2001 From: Zacqary Xeper Date: Mon, 9 Jan 2023 16:46:45 -0600 Subject: [PATCH 85/85] Lint fix --- .../sections/action_connector_form/action_notify_when.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx index b826590c03e26..17113f7e1c40d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_notify_when.tsx @@ -160,7 +160,7 @@ export const ActionNotifyWhen = ({ 100 ); }, - [onNotifyWhenChange, setNotifyWhenValue, onThrottleChange, throttleUnit] + [onNotifyWhenChange, setNotifyWhenValue, onThrottleChange, throttle, throttleUnit] ); const labelForRuleRenotify = [