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

[Security Solution][Alerts] Remove legacy rules schema #137605

Merged
merged 19 commits into from
Sep 13, 2022

Conversation

marshallmain
Copy link
Contributor

Summary

Follow up to #82462

Removes remaining usages of the legacy RulesSchema, replacing it with FullResponseSchema which is built from the single source of truth for rules schemas.

@marshallmain marshallmain added release_note:skip Skip the PR/issue when compiling release notes Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Detection Alerts Security Detection Alerts Area Team v8.5.0 labels Jul 29, 2022
@marshallmain marshallmain marked this pull request as ready for review August 23, 2022 15:43
@marshallmain marshallmain requested review from a team as code owners August 23, 2022 15:43
@marshallmain marshallmain requested a review from jpdjere August 23, 2022 15:43
@elasticmachine
Copy link
Contributor

Pinging @elastic/security-detections-response (Team:Detections and Resp)

@elasticmachine
Copy link
Contributor

Pinging @elastic/security-solution (Team: SecuritySolution)

export const getThreatMatchingSchemaMock = (anchorDate: string = ANCHOR_DATE): RulesSchema => {
export const getThreatMatchingSchemaMock = (
anchorDate: string = ANCHOR_DATE
): FullResponseSchema => {
Copy link
Contributor

@jpdjere jpdjere Aug 24, 2022

Choose a reason for hiding this comment

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

Any reason why getThreatMatchingSchemaMock couldn't have return type of ThreatMatchResponseSchema?
As well as the above getRulesMlSchemaMock have a retrun type of MachineLearningResponseSchema?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, good point - updated to use more specific return types throughout this file.

return validateNonExact(transformed, rulesSchema);
}
};

export const newTransformValidate = (
Copy link
Contributor

Choose a reason for hiding this comment

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

If we are getting rid of the original transformValidate, couldn't we rename newTransformValidate to transformValidate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, updated to transformValidate

@banderror banderror self-requested a review August 24, 2022 16:04
Copy link
Contributor

@e40pud e40pud left a comment

Choose a reason for hiding this comment

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

lgtm

@banderror
Copy link
Contributor

@elasticmachine merge upstream

Copy link
Contributor

@banderror banderror left a comment

Choose a reason for hiding this comment

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

That's exciting @marshallmain -- another improvement of the rule schemas! 🙌

Overall the PR looks great. Left a few comments, most of which are about reinforcing static types.

6siswj

@@ -6,13 +6,18 @@
*/

import { DEFAULT_INDICATOR_SOURCE_PATH } from '../../../constants';
import type {
Copy link
Contributor

Choose a reason for hiding this comment

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

After the changes, now we have rules_schema.mocks.ts and rules_schema.test.ts under both directories: request and response. Some of the tests under response have been deleted.

  • What's the difference between those tests and mocks that are still there?
  • Can we consolidate all of them under the request folder?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What's the difference between those tests and mocks that are still there?

The tests and mocks in each folder still correspond to the request and response schemas respectively. It definitely deserves to be reorganized, but I tried to avoid doing reorganization at the same time as the more technical changes. request/rule_schemas.test.ts is focused on testing the createRulesSchema - we don't have independent tests for updateRulesSchema at this point, but it's almost identical to createRulesSchema. Similarly the mocks in request/rule_schemas.mock.ts are all for the create schemas.

Since request/rule_schemas.ts is where all of the core schema logic lives, it ends up being the source for the new response schemas and replaces response/rules_schema.ts - which is simply deleted. However, I kept response/rules_schema.test.ts and response/rules_schema.mock.ts and updated them to use the new schemas for better assurance that the switch over to the new schema isn't breaking things.

Can we consolidate all of them under the request folder?

I think we can consolidate by moving most of request/rule_schemas.ts to common/rule_schemas.ts and better separating the "base" and "type specific" schema logic from create, update, response, etc. This way we can keep request and response schemas organized into their own sections, and also remove the dependency of response on request/rule_schemas.ts.

Copy link
Contributor

Choose a reason for hiding this comment

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

Great, thank you for clarifying this! Could you please add a few comments to those files to explain this:

The tests and mocks in each folder still correspond to the request and response schemas respectively. It definitely deserves to be reorganized, but I tried to avoid doing reorganization at the same time as the more technical changes. request/rule_schemas.test.ts is focused on testing the createRulesSchema - we don't have independent tests for updateRulesSchema at this point, but it's almost identical to createRulesSchema. Similarly the mocks in request/rule_schemas.mock.ts are all for the create schemas.

Since request/rule_schemas.ts is where all of the core schema logic lives, it ends up being the source for the new response schemas and replaces response/rules_schema.ts - which is simply deleted. However, I kept response/rules_schema.test.ts and response/rules_schema.mock.ts and updated them to use the new schemas for better assurance that the switch over to the new schema isn't breaking things.

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 we can consolidate by moving most of request/rule_schemas.ts to common/rule_schemas.ts and better separating the "base" and "type specific" schema logic from create, update, response, etc. This way we can keep request and response schemas organized into their own sections, and also remove the dependency of response on request/rule_schemas.ts.

++ Makes total sense. I added this to #138606 as a sub-task.

Comment on lines 506 to 511
const sharedResponseSchema = t.intersection([
baseResponseParams,
responseTypeSpecific,
t.exact(t.type(responseRequiredFields)),
t.exact(t.partial(responseOptionalFields)),
]);
type SharedResponseSchema = t.TypeOf<typeof sharedResponseSchema>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: let's use either base or shared naming but not both

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sharedResponseSchema here is equivalent to sharedCreateSchema or sharedUpdateSchema but for the response instead, whereas base comes from the baseParams that form the basis of the create, update, patch, and response schemas. What do you think we should rename here?

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd probably rename baseParams to sharedParams etc. But I'm nitpicking here, the naming as it is now is clear enough, so feel free to ignore the suggestion.

Comment on lines 26 to 27
// We're only removing undefined values, so this cast correctly narrows the type
return pickBy(removedProperties, (value) => value !== undefined) as Omit<
Copy link
Contributor

Choose a reason for hiding this comment

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

Why removing undefined values is necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We have to remove them because in the switch to FullResponseSchema, the mock data now has to specify fields that are undefined explicitly (e.g. https://github.com/elastic/kibana/pull/137605/files#diff-d162965f34c11868eafde7e03ca9bfe234c93845bc38bc7c441494b4d7cf5ca9R47-R59), but when we compare the mocks to actual outputs in the integration tests the extra undefined fields cause the equality check to fail.

This should be fixed as a follow up when we make a response type that does not require all fields to be specified, but for now I figured getting everything onto the same base set of schemas should happen first, then we can continue to expand the capabilities of the schema definition system.

Copy link
Contributor

Choose a reason for hiding this comment

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

but when we compare the mocks to actual outputs in the integration tests the extra undefined fields cause the equality check to fail.

Ah, I see! Thank you.

This should be fixed as a follow up when we make a response type that does not require all fields to be specified

FWIW I think the problem could be in assertions rather than mocks. Instead of expect(<actual>).toEqual(<expected>) we could assert only a subset of the properties that would be relevant to each particular test: expect(<actual>).toEqual(expect.objectContaining(<expected subset>)).

Anyway, that would be a separate story to work on...

Copy link
Contributor

@banderror banderror left a comment

Choose a reason for hiding this comment

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

@marshallmain Thank you for addressing the comments! The rest of them are nits.
🚀

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

✅ unchanged

History

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

@marshallmain marshallmain merged commit 24d4865 into elastic:main Sep 13, 2022
@kibanamachine kibanamachine added the backport:skip This commit does not require backporting label Sep 13, 2022
@marshallmain marshallmain deleted the remove-legacy-rules-schema branch September 13, 2022 16:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:Detection Alerts Security Detection Alerts Area Team Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. v8.5.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants