Skip to content

Commit

Permalink
[Security Solution][Detections] Fix 409 conflict error happening when…
Browse files Browse the repository at this point in the history
… user enables a rule (#120088) (#120162)

**Tickets:** #119334, #119596

## Summary

With this PR, we do not update rule execution status to `going to run` for a rule immediately when the user enables this rule. Instead, the rule executor now does this as soon as the rule starts.

This should fix the 409 conflict error that has been happening due to a race condition between the route handler and the executor both changing the status to `going to run` at almost the same time.

### Checklist

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

# Conflicts:
#	x-pack/plugins/security_solution/server/lib/detection_engine/rules/enable_rule.ts
  • Loading branch information
banderror authored Dec 1, 2021
1 parent 749d1cf commit 042318c
Show file tree
Hide file tree
Showing 4 changed files with 3 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ export const performBulkActionRoute = (
await enableRule({
rule,
rulesClient,
ruleStatusClient,
spaceId: context.securitySolution.getSpaceId(),
});
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,51 +7,19 @@

import { SanitizedAlert } from '../../../../../alerting/common';
import { RulesClient } from '../../../../../alerting/server';
import { RuleExecutionStatus } from '../../../../common/detection_engine/schemas/common/schemas';
import { IRuleExecutionLogClient } from '../rule_execution_log/types';
import { RuleParams } from '../schemas/rule_schemas';

interface EnableRuleArgs {
rule: SanitizedAlert<RuleParams>;
rulesClient: RulesClient;
ruleStatusClient: IRuleExecutionLogClient;
spaceId: string;
}

/**
* Enables the rule and updates its status to 'going to run'
*
* @param rule - rule to enable
* @param rulesClient - Alerts client
* @param ruleStatusClient - ExecLog client
*/
export const enableRule = async ({
rule,
rulesClient,
ruleStatusClient,
spaceId,
}: EnableRuleArgs) => {
export const enableRule = async ({ rule, rulesClient }: EnableRuleArgs) => {
await rulesClient.enable({ id: rule.id });

const ruleCurrentStatus = await ruleStatusClient.find({
logsCount: 1,
ruleId: rule.id,
spaceId,
});

// set current status for this rule to be 'going to run'
if (ruleCurrentStatus && ruleCurrentStatus.length > 0) {
const currentStatusToDisable = ruleCurrentStatus[0];
await ruleStatusClient.update({
id: currentStatusToDisable.id,
ruleId: rule.id,
ruleName: rule.name,
ruleType: rule.alertTypeId,
attributes: {
...currentStatusToDisable.attributes,
status: RuleExecutionStatus['going to run'],
},
spaceId,
});
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ export const patchRules = async ({
if (rule.enabled && enabled === false) {
await rulesClient.disable({ id: rule.id });
} else if (!rule.enabled && enabled === true) {
await enableRule({ rule, rulesClient, ruleStatusClient, spaceId });
await enableRule({ rule, rulesClient });
} else {
// enabled is null or undefined and we do not touch the rule
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const updateRules = async ({
if (existingRule.enabled && enabled === false) {
await rulesClient.disable({ id: existingRule.id });
} else if (!existingRule.enabled && enabled === true) {
await enableRule({ rule: existingRule, rulesClient, ruleStatusClient, spaceId });
await enableRule({ rule: existingRule, rulesClient });
}
return { ...update, enabled };
};

0 comments on commit 042318c

Please sign in to comment.