-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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] Incorporates EQL options in EQL query validation on both Rule Creation and Timeline #178468
[Security Solution] Incorporates EQL options in EQL query validation on both Rule Creation and Timeline #178468
Conversation
The conclusion is that we currently need _both_ of these fields for the EQL rule to operate if the data doesn't have a @timestamp at all. However, the UI does not allow you to set both of these fields.
…rameters This is a sanity check to allowing our EQL validation functionality to leverage these same options.
This will break our calls, which is what we want (they need to pass options now).
Previously, the eqlOptions field was referenced in the schema of the Define Step form, but as there was no component controlling the field, it was unknown to the form data, and consequently unavailable to the queryBar validator (which is ultimately our goal here). By adding a component for the eqlOptions field (albeit hidden), and updating our onOptionsChange callback to additionally set that field data, the rule form now has eqlOptions available during validation of the EQL query.
This is one case where the form lib makes that super easy 👍.
This was mostly a sanity check, but good to document this API IMO.
By adding the field to the form itself (as a hidden field), and modifying the onOptionsChange callback to additionally update the form value, we now have that field value available to us when validating the EQL query itself. This is all near-identical to the changes just made to the Define Step rule creation form.
* The default value of `''` for `tiebreaker_field` is invalid and must be changed by the user * The redux store selector was using default values that both didn't make sense and were never used * Removes defaulting behavior for options in the timeline EQL search strategy, since sending `timestamp_field: undefined` is equivalent to not specifying any value (and thus falls back to the equivalent EQL default)
/ci |
While the data I wrote was "non-ECS," that's not a necessary feature of the bug here. It simply needs to _not_ have a @timestamp field. This also updates the corresponding FTR tests to not be exclusive (whoops).
While the '@' in the file/folder seems to work, I'm a little dubious of the portability. Using normal characters here just to be safe.
This is retrieving the general rule index pattern input (of which there is no other reference); I think the naming was due to it originally being introduced while testing the IM rule type.
/ci |
This automates the process that I've been using to test this: given data without an `@timestamp` (the default time field for EQL), you'll see errors when we attempt to validate the EQL query UNTIL you choose another timestamp field via the EQL options.
/ci |
An empty string is the default value for the EQL option `tiebreaker_field` in the timeline EQL form. However, if this is passed directly to ES an error will be thrown, as this is never a valid value for that option. A similar guard exists in the timeline EQL search strategy; we're adding one to our validation call as well now that it has to deal with those values.
These additional parameters do not need to be specified in order to produce a valid query, but I am requiring that the key be specified for sanity's sake.
@kqualters-elastic I split off the defaulting conversation into https://github.com/elastic/security-team/issues/8892. On this PR, I've reverted the defaulting changes, and added the necessary guard to prevent the behavior in the above video. |
@@ -814,17 +827,16 @@ const StepDefineRuleComponent: FC<StepDefineRuleProps> = ({ | |||
<> | |||
<StepContentWrapper addPadding={!isUpdateView}> | |||
<Form form={form} data-test-subj="stepDefineRule"> | |||
<StyledVisibleContainer isVisible={false}> |
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 wholly unrelated to this PR, but react was throwing dev warnings on this page and I couldn't help but fix it. See 3a9d040 for more details.
@@ -174,4 +183,34 @@ describe('EQL rules', { tags: ['@ess', '@serverless'] }, () => { | |||
}); | |||
}); | |||
}); | |||
|
|||
describe('with source data requiring EQL overrides', () => { |
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 the one true 🔴 -> 🟢 test in this PR; the rest are just documenting existing behavior.
@rylnd cool, I ran everything locally before that commit and all lgtm 👍 I think an easy solution (and could probably revert to how you had it) would be to just add the default field to either the form field description label or the input placeholder, and not have any defaults in the app state at all. Solves 2 and lets it work how you initially had it I think. |
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.
DataDiscovery code changes LGTM!
In elastic#178724, we added the ability to retrieve archives from another location (namely, where our FTR archives live). This allows me to delete the duplicated archive specific for the cypress usage, and share the FTR archive between both. Nice!
}: Params): Promise<{ valid: boolean; errors: string[] }> => { | ||
const { rawResponse: response } = await firstValueFrom( | ||
data.search.search<EqlSearchStrategyRequest, EqlSearchStrategyResponse>( | ||
{ | ||
params: { | ||
index: dataViewTitle, | ||
body: { query, runtime_mappings: runtimeMappings, size: 0 }, | ||
// @ts-expect-error top-level keys are unexpected in {@link EqlSearchRequest} |
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 this error happens here?
I don't see any top level await introduced here
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.
These @ts-expect-error
s were due to an incompatibility between the actual EQL endpoint, and the types in the search strategy. I managed to extend the type to make this all work without the need for the @ts-expect-error
: 6767182.
I'm not sure what you were referring to with the await
comment, though.
cy.task('esArchiverUnload', { archiveName: 'no_at_timestamp_field', type: 'ftr' }); | ||
}); | ||
|
||
it('includes EQL options in query validation', () => { |
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.
can you please run flaky test runner to ensure this test is not flaky?
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.
Do you see anything in the test itself that looks suspect?
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.
nothing suspicious, but when adding new test we usually run them in flaky test runner to ensure they are not flaky, as an effort to reduce overall Cypress tests flakiness.
Since even perfectly written code does not guarantee tests won't be flaky unfortunately
|
||
expect(_log.errors).to.be.empty(); | ||
expect(_log.warnings).to.eql([ | ||
'This rule reached the maximum alert limit for the rule execution. Some alerts were not created.', |
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.
test title suggests no alerts were generated, but they were
specifying only timestamp_field results in a warning, and no alerts are generated
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.
Oops! Good catch. f3e55d5
logs: [_log], | ||
} = await previewRule({ supertest, rule }); | ||
|
||
expect(_log.errors).to.be.empty(); |
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.
test title suggests no alerts were generated and error encountered
no error in test and alert were generated
specifying only timestamp_override results in an error, and no alerts are generated
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.
expect(previewAlerts.length).to.be.greaterThan(0); | ||
}); | ||
|
||
it('specifying both timestamp_override and timestamp_field behaves as expected', async () => { |
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.
can we add more details what is expected in this case.
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 catch, thank you! f3e55d5
The actual ES client/EQL endpoint allows for specifying options at both the top level _and_ within the request's `body` parameter. However, we had only typed the latter in our original implementation. This aligns the types with the actual (demonstrable, as evidenced by all the @ts-expect-errors) behavior of the server, using a union type cribbed from responseops (see elastic#171348). Consequently, all these `@ts-expect-error`s can now be removed.
A few of these were updated in the course of development without the title being updated. This clarifies the behavior in the case of data with `@timestamp`, as well as replacing the vague "behaves as expected" descriptions with more helpful ones.
@vitaliidm thanks for the diligence in your review! I fixed the type error, as well as the test descriptions, and the flaky runner is running now. Ready for another review! |
💚 Build Succeeded
Metrics [docs]Async chunks
History
To update your PR or re-run it, just comment with: cc @rylnd |
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.
Detection Engine area LGTM
@rylnd thank you for fixing it, adding extensive test coverage and addressing my review comments
…on both Rule Creation and Timeline (elastic#178468) ## Summary This PR updates the Detection Rule Creation and Timeline forms to account for the new(er) EQL options fields (`timestamp_field`, `event_category_field`, and `tiebreaker_field`) when validating the EQL query. While the rule query and timeline query (respectively) would correctly persist and use these options, they were unused during EQL validation, meaning that in certain situations it was impossible to produce a "valid" (from the perspective of the form) EQL query if your data necessitated one of those options (see elastic#158326 for more details). ### Changes The above was accomplished by: 1. Adding a hidden form field to the UI for `eqlOptions` * A lack of a field component meant that `formData` never held any value for this field * This meant that the form-based validations (i.e. `eqlValidator`) would not have access to `eqlOptions` 2. Updating the `onOptionsChange` hook to additionally inform the form of changes to `eqlOptions` * This allows the form to have updated values for `eqlOptions` with minimal changes * Not ideal from a data-flow perspective, since the field changes are updating two copies of `eqlOptions`. However, we're only using the "form copy" for the validation call, and everything else works as it did before. ### Additional changes __Update__: I've reverted the described changes to the default timeline values below, and moved that to a [separate issue](elastic/security-team#8892). In the course of performing the above tasks for timeline, I found the behavior there to be slightly different: we were specifying default values for these fields, which was redundant in some cases (`timestamp_field`, `event_category_field`), and invalid in the case of `tiebreaker_field`. You can see here how the `tiebreaker_field` must be changed to make the query valid: https://github.com/elastic/kibana/assets/657252/556bc998-c147-4825-8bde-5d8d03873e75 ~~I opted to remove these default values, as well as the defaulting behavior from the search strategy call (see 10a47fd). While these values may be persisted in existing saved timelines, this makes the EQL workflow much cleaner for new users, and those users with persisted EQL options can now modify and validate those options on the fly.~~ #### Steps to Review For @elastic/kibana-visualizations and/or @elastic/kibana-data-discovery : I've added a few tests to the EQL search strategy that document existing behavior RE EQL option fields. Nothing about the search strategy itself was changed. If you think the tests aren't useful, I'm happy to delete them. 1. Create an index without a `@timestamp` field, and insert some data: <details> <summary>Dev Tools</summary> PUT timestamp/ { "mappings": { "dynamic": "strict", "properties": { "timestamp": { "type": "date", "format": "epoch_second" }, "locale": { "type": "keyword" }, "created_at": { "type": "date", "format": "epoch_second" }, "event": { "properties": { "category": { "ignore_above": 1024, "type": "keyword" } } } } } } PUT timestamp/_doc/4 { "timestamp": 1710211630, "locale": "es", "created_at": 1710211630, "event.category": "configuration" } </details> 2. Create a new EQL detection rule, and choose `timestamp` as the index pattern 3. Type `any where true` as the query, and observe a validation error (`Found 1 problem line -1:-1: Unknown column [@timestamp]`) 4. Open EQL Settings popover, and select `timestamp` from the `Timestamp field` dropdown 5. Observe that the query has been revalidated, and found valid. ### New Behavior: https://github.com/elastic/kibana/assets/657252/22a63363-d597-4dfd-8f9a-647f4084ec0e ### Related Issues * Addresses elastic#158326 ### Checklist Delete any items that are not applicable to this PR. - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [x] [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 - [x] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed ### For maintainers - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) (cherry picked from commit 5be91c9)
💚 All backports created successfully
Note: Successful backport PRs will be merged automatically after passing CI. Questions ?Please refer to the Backport tool documentation |
…dation on both Rule Creation and Timeline (#178468) (#178994) # Backport This will backport the following commits from `main` to `8.13`: - [[Security Solution] Incorporates EQL options in EQL query validation on both Rule Creation and Timeline (#178468)](#178468) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Ryland Herrick","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-03-19T17:52:35Z","message":"[Security Solution] Incorporates EQL options in EQL query validation on both Rule Creation and Timeline (#178468)\n\n## Summary\r\n\r\nThis PR updates the Detection Rule Creation and Timeline forms to\r\naccount for the new(er) EQL options fields (`timestamp_field`,\r\n`event_category_field`, and `tiebreaker_field`) when validating the EQL\r\nquery. While the rule query and timeline query (respectively) would\r\ncorrectly persist and use these options, they were unused during EQL\r\nvalidation, meaning that in certain situations it was impossible to\r\nproduce a \"valid\" (from the perspective of the form) EQL query if your\r\ndata necessitated one of those options (see\r\nhttps://github.com//issues/158326 for more details).\r\n\r\n### Changes\r\nThe above was accomplished by:\r\n\r\n1. Adding a hidden form field to the UI for `eqlOptions`\r\n* A lack of a field component meant that `formData` never held any value\r\nfor this field\r\n* This meant that the form-based validations (i.e. `eqlValidator`) would\r\nnot have access to `eqlOptions`\r\n2. Updating the `onOptionsChange` hook to additionally inform the form\r\nof changes to `eqlOptions`\r\n* This allows the form to have updated values for `eqlOptions` with\r\nminimal changes\r\n* Not ideal from a data-flow perspective, since the field changes are\r\nupdating two copies of `eqlOptions`. However, we're only using the \"form\r\ncopy\" for the validation call, and everything else works as it did\r\nbefore.\r\n\r\n \r\n### Additional changes\r\n__Update__: I've reverted the described changes to the default timeline\r\nvalues below, and moved that to a [separate\r\nissue](https://github.com/elastic/security-team/issues/8892).\r\n\r\nIn the course of performing the above tasks for timeline, I found the\r\nbehavior there to be slightly different: we were specifying default\r\nvalues for these fields, which was redundant in some cases\r\n(`timestamp_field`, `event_category_field`), and invalid in the case of\r\n`tiebreaker_field`. You can see here how the `tiebreaker_field` must be\r\nchanged to make the query valid:\r\n\r\n\r\nhttps://github.com/elastic/kibana/assets/657252/556bc998-c147-4825-8bde-5d8d03873e75\r\n\r\n\r\n~~I opted to remove these default values, as well as the defaulting\r\nbehavior from the search strategy call (see\r\n10a47fdaba5860a44638aada78c0cf8c37b2c580). While these values may be\r\npersisted in existing saved timelines, this makes the EQL workflow much\r\ncleaner for new users, and those users with persisted EQL options can\r\nnow modify and validate those options on the fly.~~\r\n\r\n#### Steps to Review\r\n\r\nFor @elastic/kibana-visualizations and/or @elastic/kibana-data-discovery\r\n: I've added a few tests to the EQL search strategy that document\r\nexisting behavior RE EQL option fields. Nothing about the search\r\nstrategy itself was changed. If you think the tests aren't useful, I'm\r\nhappy to delete them.\r\n\r\n1. Create an index without a `@timestamp` field, and insert some data:\r\n <details>\r\n <summary>Dev Tools</summary>\r\n\r\n PUT timestamp/\r\n {\r\n \"mappings\": {\r\n \"dynamic\": \"strict\",\r\n \"properties\": {\r\n \"timestamp\": {\r\n \"type\": \"date\",\r\n \"format\": \"epoch_second\"\r\n },\r\n \"locale\": {\r\n \"type\": \"keyword\"\r\n },\r\n \"created_at\": {\r\n \"type\": \"date\",\r\n \"format\": \"epoch_second\"\r\n },\r\n \"event\": {\r\n \"properties\": {\r\n \"category\": {\r\n \"ignore_above\": 1024,\r\n \"type\": \"keyword\"\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n PUT timestamp/_doc/4\r\n {\r\n \"timestamp\": 1710211630,\r\n \"locale\": \"es\",\r\n \"created_at\": 1710211630,\r\n \"event.category\": \"configuration\"\r\n }\r\n </details>\r\n2. Create a new EQL detection rule, and choose `timestamp` as the index\r\npattern\r\n3. Type `any where true` as the query, and observe a validation error\r\n(`Found 1 problem line -1:-1: Unknown column [@timestamp]`)\r\n4. Open EQL Settings popover, and select `timestamp` from the `Timestamp\r\nfield` dropdown\r\n5. Observe that the query has been revalidated, and found valid.\r\n\r\n\r\n### New Behavior:\r\n\r\n\r\nhttps://github.com/elastic/kibana/assets/657252/22a63363-d597-4dfd-8f9a-647f4084ec0e\r\n\r\n\r\n\r\n### Related Issues\r\n* Addresses https://github.com/elastic/kibana/issues/158326\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n- [ ]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas added for features that require explanation or tutorials\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n- [x] [Flaky Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\r\nused on any tests changed\r\n\r\n### For maintainers\r\n\r\n- [x] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"5be91c94b1c7e6b1aebd5fe75c86e2bc17c90ad0","branchLabelMapping":{"^v8.14.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Feature:Timeline","Feature:Event Correlation (EQL) Rule","Feature:Rule Creation","backport:prev-minor","Team:Detection Engine","v8.14.0"],"title":"[Security Solution] Incorporates EQL options in EQL query validation on both Rule Creation and Timeline","number":178468,"url":"https://github.com/elastic/kibana/pull/178468","mergeCommit":{"message":"[Security Solution] Incorporates EQL options in EQL query validation on both Rule Creation and Timeline (#178468)\n\n## Summary\r\n\r\nThis PR updates the Detection Rule Creation and Timeline forms to\r\naccount for the new(er) EQL options fields (`timestamp_field`,\r\n`event_category_field`, and `tiebreaker_field`) when validating the EQL\r\nquery. While the rule query and timeline query (respectively) would\r\ncorrectly persist and use these options, they were unused during EQL\r\nvalidation, meaning that in certain situations it was impossible to\r\nproduce a \"valid\" (from the perspective of the form) EQL query if your\r\ndata necessitated one of those options (see\r\nhttps://github.com//issues/158326 for more details).\r\n\r\n### Changes\r\nThe above was accomplished by:\r\n\r\n1. Adding a hidden form field to the UI for `eqlOptions`\r\n* A lack of a field component meant that `formData` never held any value\r\nfor this field\r\n* This meant that the form-based validations (i.e. `eqlValidator`) would\r\nnot have access to `eqlOptions`\r\n2. Updating the `onOptionsChange` hook to additionally inform the form\r\nof changes to `eqlOptions`\r\n* This allows the form to have updated values for `eqlOptions` with\r\nminimal changes\r\n* Not ideal from a data-flow perspective, since the field changes are\r\nupdating two copies of `eqlOptions`. However, we're only using the \"form\r\ncopy\" for the validation call, and everything else works as it did\r\nbefore.\r\n\r\n \r\n### Additional changes\r\n__Update__: I've reverted the described changes to the default timeline\r\nvalues below, and moved that to a [separate\r\nissue](https://github.com/elastic/security-team/issues/8892).\r\n\r\nIn the course of performing the above tasks for timeline, I found the\r\nbehavior there to be slightly different: we were specifying default\r\nvalues for these fields, which was redundant in some cases\r\n(`timestamp_field`, `event_category_field`), and invalid in the case of\r\n`tiebreaker_field`. You can see here how the `tiebreaker_field` must be\r\nchanged to make the query valid:\r\n\r\n\r\nhttps://github.com/elastic/kibana/assets/657252/556bc998-c147-4825-8bde-5d8d03873e75\r\n\r\n\r\n~~I opted to remove these default values, as well as the defaulting\r\nbehavior from the search strategy call (see\r\n10a47fdaba5860a44638aada78c0cf8c37b2c580). While these values may be\r\npersisted in existing saved timelines, this makes the EQL workflow much\r\ncleaner for new users, and those users with persisted EQL options can\r\nnow modify and validate those options on the fly.~~\r\n\r\n#### Steps to Review\r\n\r\nFor @elastic/kibana-visualizations and/or @elastic/kibana-data-discovery\r\n: I've added a few tests to the EQL search strategy that document\r\nexisting behavior RE EQL option fields. Nothing about the search\r\nstrategy itself was changed. If you think the tests aren't useful, I'm\r\nhappy to delete them.\r\n\r\n1. Create an index without a `@timestamp` field, and insert some data:\r\n <details>\r\n <summary>Dev Tools</summary>\r\n\r\n PUT timestamp/\r\n {\r\n \"mappings\": {\r\n \"dynamic\": \"strict\",\r\n \"properties\": {\r\n \"timestamp\": {\r\n \"type\": \"date\",\r\n \"format\": \"epoch_second\"\r\n },\r\n \"locale\": {\r\n \"type\": \"keyword\"\r\n },\r\n \"created_at\": {\r\n \"type\": \"date\",\r\n \"format\": \"epoch_second\"\r\n },\r\n \"event\": {\r\n \"properties\": {\r\n \"category\": {\r\n \"ignore_above\": 1024,\r\n \"type\": \"keyword\"\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n PUT timestamp/_doc/4\r\n {\r\n \"timestamp\": 1710211630,\r\n \"locale\": \"es\",\r\n \"created_at\": 1710211630,\r\n \"event.category\": \"configuration\"\r\n }\r\n </details>\r\n2. Create a new EQL detection rule, and choose `timestamp` as the index\r\npattern\r\n3. Type `any where true` as the query, and observe a validation error\r\n(`Found 1 problem line -1:-1: Unknown column [@timestamp]`)\r\n4. Open EQL Settings popover, and select `timestamp` from the `Timestamp\r\nfield` dropdown\r\n5. Observe that the query has been revalidated, and found valid.\r\n\r\n\r\n### New Behavior:\r\n\r\n\r\nhttps://github.com/elastic/kibana/assets/657252/22a63363-d597-4dfd-8f9a-647f4084ec0e\r\n\r\n\r\n\r\n### Related Issues\r\n* Addresses https://github.com/elastic/kibana/issues/158326\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n- [ ]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas added for features that require explanation or tutorials\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n- [x] [Flaky Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\r\nused on any tests changed\r\n\r\n### For maintainers\r\n\r\n- [x] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"5be91c94b1c7e6b1aebd5fe75c86e2bc17c90ad0"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v8.14.0","branchLabelMappingKey":"^v8.14.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/178468","number":178468,"mergeCommit":{"message":"[Security Solution] Incorporates EQL options in EQL query validation on both Rule Creation and Timeline (#178468)\n\n## Summary\r\n\r\nThis PR updates the Detection Rule Creation and Timeline forms to\r\naccount for the new(er) EQL options fields (`timestamp_field`,\r\n`event_category_field`, and `tiebreaker_field`) when validating the EQL\r\nquery. While the rule query and timeline query (respectively) would\r\ncorrectly persist and use these options, they were unused during EQL\r\nvalidation, meaning that in certain situations it was impossible to\r\nproduce a \"valid\" (from the perspective of the form) EQL query if your\r\ndata necessitated one of those options (see\r\nhttps://github.com//issues/158326 for more details).\r\n\r\n### Changes\r\nThe above was accomplished by:\r\n\r\n1. Adding a hidden form field to the UI for `eqlOptions`\r\n* A lack of a field component meant that `formData` never held any value\r\nfor this field\r\n* This meant that the form-based validations (i.e. `eqlValidator`) would\r\nnot have access to `eqlOptions`\r\n2. Updating the `onOptionsChange` hook to additionally inform the form\r\nof changes to `eqlOptions`\r\n* This allows the form to have updated values for `eqlOptions` with\r\nminimal changes\r\n* Not ideal from a data-flow perspective, since the field changes are\r\nupdating two copies of `eqlOptions`. However, we're only using the \"form\r\ncopy\" for the validation call, and everything else works as it did\r\nbefore.\r\n\r\n \r\n### Additional changes\r\n__Update__: I've reverted the described changes to the default timeline\r\nvalues below, and moved that to a [separate\r\nissue](https://github.com/elastic/security-team/issues/8892).\r\n\r\nIn the course of performing the above tasks for timeline, I found the\r\nbehavior there to be slightly different: we were specifying default\r\nvalues for these fields, which was redundant in some cases\r\n(`timestamp_field`, `event_category_field`), and invalid in the case of\r\n`tiebreaker_field`. You can see here how the `tiebreaker_field` must be\r\nchanged to make the query valid:\r\n\r\n\r\nhttps://github.com/elastic/kibana/assets/657252/556bc998-c147-4825-8bde-5d8d03873e75\r\n\r\n\r\n~~I opted to remove these default values, as well as the defaulting\r\nbehavior from the search strategy call (see\r\n10a47fdaba5860a44638aada78c0cf8c37b2c580). While these values may be\r\npersisted in existing saved timelines, this makes the EQL workflow much\r\ncleaner for new users, and those users with persisted EQL options can\r\nnow modify and validate those options on the fly.~~\r\n\r\n#### Steps to Review\r\n\r\nFor @elastic/kibana-visualizations and/or @elastic/kibana-data-discovery\r\n: I've added a few tests to the EQL search strategy that document\r\nexisting behavior RE EQL option fields. Nothing about the search\r\nstrategy itself was changed. If you think the tests aren't useful, I'm\r\nhappy to delete them.\r\n\r\n1. Create an index without a `@timestamp` field, and insert some data:\r\n <details>\r\n <summary>Dev Tools</summary>\r\n\r\n PUT timestamp/\r\n {\r\n \"mappings\": {\r\n \"dynamic\": \"strict\",\r\n \"properties\": {\r\n \"timestamp\": {\r\n \"type\": \"date\",\r\n \"format\": \"epoch_second\"\r\n },\r\n \"locale\": {\r\n \"type\": \"keyword\"\r\n },\r\n \"created_at\": {\r\n \"type\": \"date\",\r\n \"format\": \"epoch_second\"\r\n },\r\n \"event\": {\r\n \"properties\": {\r\n \"category\": {\r\n \"ignore_above\": 1024,\r\n \"type\": \"keyword\"\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n PUT timestamp/_doc/4\r\n {\r\n \"timestamp\": 1710211630,\r\n \"locale\": \"es\",\r\n \"created_at\": 1710211630,\r\n \"event.category\": \"configuration\"\r\n }\r\n </details>\r\n2. Create a new EQL detection rule, and choose `timestamp` as the index\r\npattern\r\n3. Type `any where true` as the query, and observe a validation error\r\n(`Found 1 problem line -1:-1: Unknown column [@timestamp]`)\r\n4. Open EQL Settings popover, and select `timestamp` from the `Timestamp\r\nfield` dropdown\r\n5. Observe that the query has been revalidated, and found valid.\r\n\r\n\r\n### New Behavior:\r\n\r\n\r\nhttps://github.com/elastic/kibana/assets/657252/22a63363-d597-4dfd-8f9a-647f4084ec0e\r\n\r\n\r\n\r\n### Related Issues\r\n* Addresses https://github.com/elastic/kibana/issues/158326\r\n\r\n### Checklist\r\n\r\nDelete any items that are not applicable to this PR.\r\n\r\n- [ ]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas added for features that require explanation or tutorials\r\n- [x] [Unit or functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere updated or added to match the most common scenarios\r\n- [x] [Flaky Test\r\nRunner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was\r\nused on any tests changed\r\n\r\n### For maintainers\r\n\r\n- [x] This was checked for breaking API changes and was [labeled\r\nappropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)","sha":"5be91c94b1c7e6b1aebd5fe75c86e2bc17c90ad0"}}]}] BACKPORT--> --------- Co-authored-by: Ryland Herrick <[email protected]>
Summary
This PR updates the Detection Rule Creation and Timeline forms to account for the new(er) EQL options fields (
timestamp_field
,event_category_field
, andtiebreaker_field
) when validating the EQL query. While the rule query and timeline query (respectively) would correctly persist and use these options, they were unused during EQL validation, meaning that in certain situations it was impossible to produce a "valid" (from the perspective of the form) EQL query if your data necessitated one of those options (see #158326 for more details).Changes
The above was accomplished by:
eqlOptions
formData
never held any value for this fieldeqlValidator
) would not have access toeqlOptions
onOptionsChange
hook to additionally inform the form of changes toeqlOptions
eqlOptions
with minimal changeseqlOptions
. However, we're only using the "form copy" for the validation call, and everything else works as it did before.Additional changes
Update: I've reverted the described changes to the default timeline values below, and moved that to a separate issue.
In the course of performing the above tasks for timeline, I found the behavior there to be slightly different: we were specifying default values for these fields, which was redundant in some cases (
timestamp_field
,event_category_field
), and invalid in the case oftiebreaker_field
. You can see here how thetiebreaker_field
must be changed to make the query valid:Screen.Recording.2024-03-11.at.10.12.28.PM.mov
I opted to remove these default values, as well as the defaulting behavior from the search strategy call (see 10a47fd). While these values may be persisted in existing saved timelines, this makes the EQL workflow much cleaner for new users, and those users with persisted EQL options can now modify and validate those options on the fly.Steps to Review
For @elastic/kibana-visualizations and/or @elastic/kibana-data-discovery : I've added a few tests to the EQL search strategy that document existing behavior RE EQL option fields. Nothing about the search strategy itself was changed. If you think the tests aren't useful, I'm happy to delete them.
Create an index without a
@timestamp
field, and insert some data:Dev Tools
Create a new EQL detection rule, and choose
timestamp
as the index patternType
any where true
as the query, and observe a validation error (Found 1 problem line -1:-1: Unknown column [@timestamp]
)Open EQL Settings popover, and select
timestamp
from theTimestamp field
dropdownObserve that the query has been revalidated, and found valid.
New Behavior:
Screen.Recording.2024-03-11.at.10.06.19.PM.mov
Related Issues
Checklist
Delete any items that are not applicable to this PR.
For maintainers