-
Notifications
You must be signed in to change notification settings - Fork 8.2k
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
[Security Solution] Split rule executor by rule type and validate type specific rule params #94857
[Security Solution] Split rule executor by rule type and validate type specific rule params #94857
Conversation
); | ||
logger.warn(errorMessage); | ||
result.warning = true; | ||
// TODO: change this to partialFailure since we don't immediately exit rule function and still do actions at the end? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a new TODO: noticed this behavior when adding the warning logic to result. I think this error was added before we created partial errors, would it fit better as a partial error?
tags: rule.attributes.tags, | ||
buildRuleMessage, | ||
}); | ||
// The legacy ES client does not define failures when it can be present on the structure, hence why I have the & { failures: [] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we use the new ES client, we can revisit this
@elasticmachine merge upstream |
Pinging @elastic/security-solution (Team: SecuritySolution) |
Pinging @elastic/security-detections-response (Team:Detections and Resp) |
let results: SearchAfterAndBulkCreateReturnType = { | ||
success: true, | ||
warning: false, | ||
bulkCreateTimes: [], | ||
searchAfterTimes: [], | ||
lastLookBackDate: null, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we initialize this with the same createSearchAfterReturnType()
function used in the other executors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can, I just didn't do it in this PR to limit scope creep
💚 Build Succeeded
Metrics [docs]
History
To update your PR or re-run it, just comment with: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! I'm not sure I saw why we needed to change the typed partial filters to unknown
but that was about it. I pulled down and created different rules to test out that it's all still as expected. That executor file is looking so much better! Thanks for all the work!
@@ -22,7 +22,7 @@ import { Query, Language, Index, TimestampOverrideOrUndefined } from './schemas/ | |||
export const getQueryFilter = ( | |||
query: Query, | |||
language: Language, | |||
filters: Array<Partial<Filter>>, | |||
filters: unknown, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we turn this into an unknown
? It seems that everywhere we're using it we're passing in filters typed as Filter[]
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The source of the problem here is that we don't have validation for the Filter
type on the server side yet, so in attempting to make the server types more accurate the type of filters
in RuleTypeParams became unknown
. Then since we had a cast in here on line 51 already I thought we could just do the unsafe cast once at the end instead of passing in a partial then casting to unknown and then to Filter[]
.
I think you're right though that we should pass in Filter[]
and function callers should be responsible for casting the parameter if necessary. As part of the follow up updating server types I'll revisit this - want to get this merged before it conflicts with other work.
@@ -153,12 +161,19 @@ const thresholdSpecificRuleParams = t.type({ | |||
savedId: savedIdOrUndefined, | |||
threshold, | |||
}); | |||
export const thresholdRuleParams = t.intersection([baseRuleParams, thresholdSpecificRuleParams]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this! Reads easy
} catch (err) { | ||
if (err.statusCode === 403) { | ||
throw new Error( | ||
`EQL based rules require the user that created it to have the view_index_metadata, read, and write permissions for index: ${ruleParams.outputIndex}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if this is the place to do it. But would it be possible to guide our users more with our error messages. Like where to view these permissions for example.
ruleParams.eventCategoryOverride | ||
); | ||
const eqlSignalSearchStart = performance.now(); | ||
// TODO: fix this later |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this fix referring to the as
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah yeah this is referring to the use of transport.request
still, which was necessary with the legacy ES client because the EQL apis weren't in it - but the EQL api is in the new client, so we can switch over.
const eqlSignalSearchEnd = performance.now(); | ||
const eqlSearchDuration = makeFloatString(eqlSignalSearchEnd - eqlSignalSearchStart); | ||
result.searchAfterTimes = [eqlSearchDuration]; | ||
let newSignals: WrappedSignalHit[] | undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be cleaner to break this out into a function we can test and also then remove the let
just a const newSignals = determineNewSignals()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, that would be cleaner 👍 will do in follow up
…e specific rule params (elastic#94857) * Split rule executors into different files * Pass type-specific rule SOs to rule executor functions * Genericize function to narrow ruleSO type * Remove undefined return type from getExceptions * Remove unintentional change to SIGNALS_TEMPLATE_VERSION * Remove extra validation now covered by schemas * Remove extra validation from ML rule executor * Fix types * syncs schemas * Revert "syncs schemas" This reverts commit b1dd59e. * Fix api test and move threshold executor test * kinda adds eql test * Refactor and fix unit tests * fixes marshalls mistake Co-authored-by: Davis Plumlee <davis.plumlee@elastic.co> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
…e specific rule params (#94857) (#95607) * Split rule executors into different files * Pass type-specific rule SOs to rule executor functions * Genericize function to narrow ruleSO type * Remove undefined return type from getExceptions * Remove unintentional change to SIGNALS_TEMPLATE_VERSION * Remove extra validation now covered by schemas * Remove extra validation from ML rule executor * Fix types * syncs schemas * Revert "syncs schemas" This reverts commit b1dd59e. * Fix api test and move threshold executor test * kinda adds eql test * Refactor and fix unit tests * fixes marshalls mistake Co-authored-by: Davis Plumlee <davis.plumlee@elastic.co> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Marshall Main <55718608+marshallmain@users.noreply.github.com> Co-authored-by: Davis Plumlee <davis.plumlee@elastic.co>
Summary
This PR is copy paste with some refactoring thrown in to support the copy/paste.
Refactor changes include:
warning
boolean flag to the "search after return type" that each executor returns. This was a single variable that was shared across all rule types before, so to split the rule executors it has to be returned as part of the result object.SavedObject
that has already been validated to ensure it matches the schema for the rule type. The validation is non-exact, meaning if a rule has fields we don't expect then the validation still passes. However, validation fails if required fields are missing - e.g. ifquery
is missing from a rule that requires a query, or if requiredthreat_match
fields are missing. This allows us to rely entirely on the type specific schemas for validation and removeif
statements checking if certain required fields exist. For optional fields, e.g. timestamp override, of course we still have to check if the field exists when using it.filters
asFilter[]
fromunknown
. Instead,filters
andthreatFilters
are typed asunknown
until we have to cast them as params tobuildEsQuery
since we don't have validation forfilters
yet.Checklist
Delete any items that are not applicable to this PR.
For maintainers