Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Actions] Add support for system actions in Rules APIs #161726

Closed
wants to merge 149 commits into from

Conversation

cnasikas
Copy link
Member

@cnasikas cnasikas commented Jul 12, 2023

Summary

In this PR we allow the usage of system actions through the Rules APIs. Major decisions:

  • The actions will have the type property only inside the methods of the rule client.
  • The APIs will not accept the type of the action. The framework will detect this automatically.
  • All routes will add the type to the actions before passing the request to the rule client.
  • The rule client methods will return actions with the type.
  • All routes will remove the type from the actions before returning the response to the client.
  • Users should not be able to set the frequency, the group, or the alerts filter for system actions.
  • The group is now optional because system actions do not support it.
  • The type of the action will not be persisted to ES.

To keep the size of the PR small, and because it will be merged into a feature branch, I decided to work in the Create Rule, Update Rule, and Bulk Edit Rules APIs. I also follow TS errors and failed tests and update some of the other routes/client methods. Another PR will follow to handle the rest of the APIs and the CI errors produced by these APIs and another PR will follow to handle the APIs of Security Solution.

Issue: #160367
Depends on: #165671

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@@ -38,7 +38,7 @@ const ruleSnoozeScheduleSchemaWithValidation = schema.object(
);

const ruleActionSchema = schema.object({
group: schema.string(),
group: schema.maybe(schema.string()),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System actions do not have a group. Changing this to optional to allow system actions to be created without a group.

type: typeof RuleActionTypes.SYSTEM;
}

export type RuleAction = RuleDefaultAction | RuleSystemAction;
Copy link
Member Author

@cnasikas cnasikas Sep 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type is used internally by the rules client.

@@ -16,4 +16,4 @@ import { SanitizedRule } from '../../common';
* originally registered to {@link PluginSetupContract.registerNavigation}.
*
*/
export type AlertNavigationHandler = (rule: SanitizedRule) => string;
export type AlertNavigationHandler = (rule: SanitizedRuleResponse) => string;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The responses from the alerting APIs do not contain the type of action.

@@ -115,8 +118,15 @@ export async function bulkEditRules<Params extends RuleParams>(
context: RulesClientContext,
options: BulkEditOptions<Params>
): Promise<BulkEditResult<Params>> {
try {
bulkEditOperationsSchema.validate(options.operations);
Copy link
Member Author

@cnasikas cnasikas Sep 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Validation of the schema was missing from the method. The schema requires at least one operation to be set.

@@ -458,20 +472,15 @@ async function updateRuleAttributesAndParamsInMemory<Params extends RuleParams>(
rule.references = migratedActions.resultedReferences;
}

const ruleActions = injectReferencesIntoActions(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

transformRuleAttributesToRuleDomain calls transformRawActionsToDomainActions which in turn injects the references into the actions. No need to do it twice.

@@ -49,7 +59,7 @@ const bulkEditTagSchema = schema.object({
const bulkEditActionsSchema = schema.object({
operation: schema.oneOf([schema.literal('add'), schema.literal('set')]),
field: schema.literal('actions'),
value: schema.arrayOf(bulkEditActionSchema),
value: schema.arrayOf(schema.oneOf([bulkEditDefaultActionSchema, bulkEditSystemActionSchema])),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rule methods accept two types of actions.

type: schema.literal(RuleActionTypes.DEFAULT),
});

export const bulkEditSystemActionSchema = schema.object({
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System actions are not allowed to contain: group, alertsFilter, and frequency.

references?: SavedObjectReference[];
}

export const transformRawActionsToDomainActions = ({
Copy link
Member Author

@cnasikas cnasikas Sep 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function adds the id from the references and the type in all actions. The type is not persisted in ES.

@@ -149,13 +149,13 @@ export const transformRuleAttributesToRuleDomain = <Params extends RuleParams =
})?.toISOString()
: null;

let actions = esRule.actions
? injectReferencesIntoActions(id, esRule.actions as RawRule['actions'], references || [])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic moved inside transformRawActionsToDomainActions.

}

const connectorAdapter = connectorAdapterRegistry.get(connectorTypeId);
const schema = connectorAdapter.ruleActionParamsSchema;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the schema of the system action params persisted in the rule.

data: { ...alert, notifyWhen },
data: {
...alert,
actions: rewriteActionsReq(alert.actions, (connectorId: string) =>
Copy link
Member Author

@cnasikas cnasikas Sep 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds the type to the actions.

return res.ok({
body: alertRes,
body: { ...alertRes, actions: rewriteActionsResLegacy(alertRes.actions) },
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removes the type from the actions.

return [];
}

return actions.map((action) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds the type to the actions.

: {}),
}));

return actions.map((action) => {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removes the type from the actions.

@cnasikas cnasikas marked this pull request as ready for review September 18, 2023 17:10
@kibana-ci
Copy link
Collaborator

kibana-ci commented Sep 19, 2023

💔 Build Failed

Failed CI Steps

Test Failures

  • [job] [logs] x-pack/test/alerting_api_integration/security_and_spaces/group2/config_non_dedicated_task_runner.ts / alerting api integration security and spaces enabled - Group 2 Alerts alerts alerts superuser at space1 should schedule task, run alert and schedule actions when appropriate
  • [job] [logs] x-pack/test/alerting_api_integration/security_and_spaces/group2/config.ts / alerting api integration security and spaces enabled - Group 2 Alerts alerts alerts superuser at space1 should schedule task, run alert and schedule actions when appropriate
  • [job] [logs] x-pack/test/alerting_api_integration/security_and_spaces/group2/config_non_dedicated_task_runner.ts / alerting api integration security and spaces enabled - Group 2 Alerts alerts alerts superuser at space1 should schedule task, run alert and schedule actions when appropriate
  • [job] [logs] x-pack/test/alerting_api_integration/security_and_spaces/group2/config.ts / alerting api integration security and spaces enabled - Group 2 Alerts alerts alerts superuser at space1 should schedule task, run alert and schedule actions when appropriate
  • [job] [logs] FTR Configs #65 / Alerting create should store references correctly for actions
  • [job] [logs] FTR Configs #65 / Alerting create should store references correctly for actions
  • [job] [logs] FTR Configs #34 / Alerting update system actions should update a rule with a system action correctly
  • [job] [logs] FTR Configs #34 / Alerting update system actions should update a rule with a system action correctly
  • [job] [logs] Jest Tests #10 / bulkEdit() index pattern operations should skip operation when params modifiers does not modify index pattern array
  • [job] [logs] Jest Tests #10 / bulkEditRulesRoute actions adds the type of the actions correctly before passing the request to the rules client
  • [job] [logs] FTR Configs #9 / detection engine api security and spaces enabled - Group 1 add_actions adding actions should be able to create a new webhook action and attach it to a rule
  • [job] [logs] FTR Configs #9 / detection engine api security and spaces enabled - Group 1 add_actions adding actions should be able to create a new webhook action and attach it to a rule
  • [job] [logs] FTR Configs #23 / detection engine api security and spaces enabled - Group 10 import_rules importing rules with an index should migrate legacy actions in existing rule if overwrite is set to true
  • [job] [logs] FTR Configs #23 / detection engine api security and spaces enabled - Group 10 import_rules importing rules with an index should migrate legacy actions in existing rule if overwrite is set to true
  • [job] [logs] FTR Configs #23 / detection engine api security and spaces enabled - Group 4 Detection rule type telemetry Detection rule telemetry "kql" rule type should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"
  • [job] [logs] FTR Configs #23 / detection engine api security and spaces enabled - Group 4 Detection rule type telemetry Detection rule telemetry "kql" rule type should show "notifications_disabled" to be "1" for rule that has at least "1" action(s) and the alert is "disabled"/"in-active"
  • [job] [logs] FTR Configs #62 / Monitoring app Cluster listing Alerts should show a toast when alerts are created successfully
  • [job] [logs] FTR Configs #62 / Monitoring app Cluster listing Alerts should show a toast when alerts are created successfully
  • [job] [logs] FTR Configs #57 / Observability Rules Synthetics SyntheticsRules creates rule when settings are configured
  • [job] [logs] FTR Configs #57 / Observability Rules Synthetics SyntheticsRules creates rule when settings are configured

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
alerting 96 97 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
alerting 21.8KB 21.9KB +112.0B

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

cc @cnasikas

@@ -27,6 +34,7 @@ function transformAction(input: AsApiContract<RuleAction>): RuleAction {
},
}
: {}),
...(alertsFilter && { alertsFilter }),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing this.

Copy link
Contributor

@ersin-erdal ersin-erdal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through the code and left some comments.
I will run and test the PR locally then approve.

@@ -586,6 +587,12 @@ export class ActionsPlugin implements Plugin<PluginSetupContract, PluginStartCon
inMemoryConnectors: this.inMemoryConnectors,
renderActionParameterTemplates: (...args) =>
renderActionParameterTemplates(actionTypeRegistry, ...args),
isSystemActionConnector: (connectorId: string): boolean => {
return !!this.inMemoryConnectors.find(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: inMemoryConnectors.some could be better here.

throw error;
}

const systemActions = context.inMemoryConnectors.filter((connector) => connector.isSystemAction);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these are connectors not actions (I know isSystemAction is misleading :) )
Even the return type is FindConnectorResult

@@ -25,8 +25,12 @@ import {
import { MONITORING_HISTORY_LIMIT, RuleTypeParams } from '../../common';
import { AlertingEventLogger } from '../lib/alerting_event_logger/alerting_event_logger';

export interface RuleData<Params extends RuleTypeParams> extends LoadedIndirectParams<RawRule> {
indirectParams: RawRule;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think indirectParams has been removed by mistake

@cnasikas
Copy link
Member Author

cnasikas commented Oct 6, 2023

Closing the PR in favor of smaller PRs to aid the review process

@cnasikas cnasikas closed this Oct 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature:Actions/Framework Issues related to the Actions Framework Feature:Actions release_note:skip Skip the PR/issue when compiling release notes Team:ResponseOps Label for the ResponseOps team (formerly the Cases and Alerting teams) v8.10.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants