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][Detection Engine] move lists to data stream #162508

Merged
merged 78 commits into from
Aug 23, 2023

Conversation

vitaliidm
Copy link
Contributor

@vitaliidm vitaliidm commented Jul 25, 2023

Summary

  • addresses https://github.com/elastic/security-team/issues/7198
  • moves list/items indices to data stream
    • adds @timestamp mapping to indices mappings
    • migrate to data stream if indices already exist(for customers < 8.11) or create data stream(for customers 8.11+ or serverless)
    • adds DLM to index templates
    • replaces update/delete queries with update_by_query/delete_by_query which supported in data streams
    • fixes existing issues with update/patch APIs for lists/items
      • update/patch for lists didn't save version parameter in ES
      • update and patch APIs for lists/items were identical, i.e. for both routes was called the same update method w/o any changes
Technical detail on moving API to (update/delete)_by_query

update_by_query, delete_by_query do not support refresh=wait_for, only false/true values. Which might break some of the use cases on UI(when list is removed, we refetch all lists. Deleted list will be returned for some time. Default refresh time is 1s). So, we retry refetching deleted/updated document before finishing request, to return reindexed document

update_by_query does not support OCC as update API.
Which is supported in both list/list item updates through _version parameter.
_version is base64 encoded "_seq_no", "_primary_term" props used for OCC

So, to keep it without breaking changes: implemented check for version conflict within update method

Checklist

Delete any items that are not applicable to this PR.

@vitaliidm vitaliidm self-assigned this Jul 25, 2023
@vitaliidm vitaliidm added 8.10 candidate Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. Team:Detection Engine Security Solution Detection Engine Area labels Jul 25, 2023
@vitaliidm
Copy link
Contributor Author

vitaliidm commented Aug 4, 2023

there is still one failing test: #163197
Doesn't seem to be related to functionality in this PR and does not fail locally(on this PR) or on main, only in scope of all tests on CI

@dasansol92
Copy link
Contributor

We need to ensure that this still works with artifact-packager task which reads from .lists and packages Endpoint Exceptions, Trusted Apps, etc for the Endpoint.

We have our automated Defend Workflows Endpoint cypress tests which stand up real Endpoints and create artifacts, so if those pass, the basic create, read, and edit should work.

fyi @dasansol92 - could you also review this PR?

@kevinlog The x-pack/test/security_solution_endpoint/apps/integrations/artifact_entries_list.ts FTR test should ensure the artifact-packager task is still running as we expect.

@dasansol92
Copy link
Contributor

hey @vitaliidm , are these changes affecting also the exceptions lists/items types or only the regular lists/items? Thanks!

@vitaliidm
Copy link
Contributor Author

vitaliidm commented Aug 7, 2023

hey @vitaliidm , are these changes affecting also the exceptions lists/items types or only the regular lists/items? Thanks!

hey @dasansol92 , only .lists-*, .items-* indices, which moved to data stream in this PR. They can be used in exceptions, but it should not affect exceptions workflows

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.

Great work! I left a few comments, let me know what you think about those.

// needs to be migrated to data stream if index exists
if (!dataStreamExists) {
const indexExists = await lists.getListIndexExists();
if (indexExists) {
Copy link
Contributor

@e40pud e40pud Aug 17, 2023

Choose a reason for hiding this comment

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

what if it does not exist? or this is not possible?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this is going to be handled down the function execution, few lines below this one

  const list = await lists.patchList({ _version, description, id, meta, name, version });
        if (list == null) {
          return siemResponse.error({
            body: `list id: "${id}" not found`,
``

// needs to be migrated to data stream if index exists
if (!dataStreamExists) {
const indexExists = await lists.getListIndexExists();
if (indexExists) {
Copy link
Contributor

Choose a reason for hiding this comment

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

same as my previous question

Copy link
Contributor Author

Choose a reason for hiding this comment

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


await removeLegacyTemplatesIfExist(lists);

if (listDataStreamExists && listItemDataStreamExists) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I see that it was implemented this way earlier, but just curios whether we should do this check before setting templates above? since we know that this is an invalid request and we gonna return 409 error maybe we should not do any modifications and throw an exception earlier

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know the reason it was done like this before, but I can guess, if there are any updates to templates, that would the only way to update them - by calling that API. Otherwise, if no updates were made to templates, that action won't have any effect

const listItemDataStreamExists = await lists.getListItemDataStreamExists();

// data streams exists, it means indices were migrated
if (listDataStreamExists) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible that listItemDataStreamExists = true and listDataStreamExists = false? In case of indices we check that both exist listIndexExists and listItemIndexExists

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think, this could only happen, if you use patch/update listItem API, before loading Security Solution page(which performs migration to DS). Very unlikely, because, you have to use direct API call, since these APIs are not used in UI.
And those migration in patch/update was added recently, after delete method was migrated.

Thanks for noticing, I have updated the code, so it will account for this


if (listIndexExists || listItemIndexExists) {
if (listDataStreamExists || listItemDataStreamExists) {
Copy link
Contributor

Choose a reason for hiding this comment

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

These IF statements are not going to work as initially intended.

First if (listDataStreamExists || listItemDataStreamExists) { will handle three out of four possible cases:

  1. listDataStreamExists = true && listItemDataStreamExists = true
  2. listDataStreamExists = false && listItemDataStreamExists = true
  3. listDataStreamExists = true && listItemDataStreamExists = false

Then, second if (!listDataStreamExists && listItemDataStreamExists) { statement will handle the last possible case:

  1. listDataStreamExists = false && listItemDataStreamExists = false

This means, that last two statements (if (!listItemDataStreamExists && listDataStreamExists) { and final else case) will never be called.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you are right - I think, probably, its initial implementation meant to have the firs statement as AND, in that case the rest of statements would make sense.
I will change it AND, thanks for catching this

// needs to be migrated to data stream if index exists
if (!dataStreamExists) {
const indexExists = await lists.getListItemIndexExists();
if (indexExists) {
Copy link
Contributor

Choose a reason for hiding this comment

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

same as one of the previous questions about possibility of indexExists = false

Copy link
Contributor Author

Choose a reason for hiding this comment

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

similar to same questions, it's going to be handled below these lines

        const listItem = await lists.patchListItem({
          _version,
          id,
          meta,
          value,
        });
        if (listItem == null) {
          return siemResponse.error({
            body: `list item id: "${id}" not found`,
            statusCode: 404,
          });
        } else {

// needs to be migrated to data stream if index exists
if (!dataStreamExists) {
const indexExists = await lists.getListItemIndexExists();
if (indexExists) {
Copy link
Contributor

Choose a reason for hiding this comment

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

same here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@vitaliidm vitaliidm requested a review from e40pud August 22, 2023 09:38
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!

@dasansol92
Copy link
Contributor

For changes affecting exceptions items/lists, would be nice having this test passing in CI when it's enabled: #164473
Thanks!

@kibana-ci
Copy link
Collaborator

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] Defend Workflows Endpoint Cypress Tests #2 / Automated Response Actions From alerts "after all" hook for "should have generated endpoint and rule" "after all" hook for "should have generated endpoint and rule"
  • [job] [logs] Defend Workflows Endpoint Cypress Tests #2 / Automated Response Actions From alerts "before all" hook for "should have generated endpoint and rule" "before all" hook for "should have generated endpoint and rule"

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
lists 261 262 +1
securitySolution 4444 4451 +7
total +8

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/securitysolution-es-utils 62 76 +14
@kbn/securitysolution-io-ts-list-types 515 519 +4
lists 94 96 +2
total +20

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
lists 145.3KB 145.4KB +81.0B
securitySolution 15.7MB 15.7MB +89.0B
total +170.0B
Unknown metric groups

API count

id before after diff
@kbn/securitysolution-es-utils 68 87 +19
@kbn/securitysolution-io-ts-list-types 528 532 +4
lists 210 222 +12
total +35

Unreferenced deprecated APIs

id before after diff
lists 0 4 +4

History

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

cc @vitaliidm

@vitaliidm vitaliidm merged commit 505d826 into elastic:main Aug 23, 2023
@vitaliidm vitaliidm deleted the alerts_8_10/move-lists-to-ds branch March 4, 2024 17:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
8.11 candidate backport:skip This commit does not require backporting release_note:skip Skip the PR/issue when compiling release notes Team:Defend Workflows “EDR Workflows” sub-team of Security Solution Team:Detection Engine Security Solution Detection Engine Area Team:Detections and Resp Security Detection Response Team Team: SecuritySolution Security Solutions Team working on SIEM, Endpoint, Timeline, Resolver, etc. v8.11.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants