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 Solutions] Adds security detection rule actions as importable and exportable #115243

Merged

Conversation

FrankHassanabad
Copy link
Contributor

@FrankHassanabad FrankHassanabad commented Oct 15, 2021

Summary

Adds the security detection rule actions as being exportable and importable.

  • Adds exportable actions for legacy notification system
  • Adds exportable actions for the new throttle notification system
  • Adds importable but only imports into the new throttle notification system.
  • Updates unit tests

In your ndjson file when you have actions exported you will see them like so:

"actions": [
    {
      "group": "default",
      "id": "b55117e0-2df9-11ec-b789-7f03e3cdd668",
      "params": {
        "message": "Rule {{context.rule.name}} generated {{state.signals_count}} alerts"
      },
      "action_type_id": ".slack"
    }
  ]

where before it was actions: [] and was not provided.

Caveats

If you delete your connector and have an invalid connector then the rule(s) that were referring to that invalid connector will not import and you will get an error like this:

Screen Shot 2021-10-15 at 2 47 10 PM

This does not export your connectors at this point in time. You have to export your connector through the Saved Object Management separate like so:
Screen Shot 2021-10-15 at 2 58 03 PM

However, if remove everything and import your connector without changing its saved object ID and then go to import the rules everything should import ok and you will get your actions working.

Manual Testing:

  • You can create normal actions on an alert and then do exports and you should see the actions in your ndjson file
  • You can create legacy notifications from 7.14.0 and then upgrade and export and you should see the actions in your ndjson file
  • You can manually create legacy notifications by:

By getting an alert id first and ensuring that your legacy_notifications/one_action.json contains a valid action then running this command:

./post_legacy_notification.sh 3403c0d0-2d44-11ec-b147-3b0c6d563a60
  • You can export your connector and remove everything and then do an import and you will have everything imported and working with your actions and connector wired up correctly.

Checklist

@kibanamachine
Copy link
Contributor

⏳ Build in-progress, with failures

Failed CI Steps

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

@FrankHassanabad
Copy link
Contributor Author

@elasticmachine merge upstream

@FrankHassanabad FrankHassanabad self-assigned this Oct 15, 2021
@FrankHassanabad FrankHassanabad changed the title Make actions exportable [Security Solutions] Adds security detection rule actions as being exportable Oct 15, 2021
@FrankHassanabad FrankHassanabad marked this pull request as ready for review October 15, 2021 20:00
@FrankHassanabad FrankHassanabad requested a review from a team as a code owner October 15, 2021 20:00
@FrankHassanabad FrankHassanabad changed the title [Security Solutions] Adds security detection rule actions as being exportable [Security Solutions] Adds security detection rule actions as exportable items Oct 15, 2021
@FrankHassanabad FrankHassanabad changed the title [Security Solutions] Adds security detection rule actions as exportable items [Security Solutions] Adds security detection rule actions as importable and exportable Oct 15, 2021
isRuleRegistryEnabled: boolean
): Promise<{
rulesNdjson: string;
exportDetails: string;
}> => {
const ruleAlertTypes = await getNonPackagedRules({ rulesClient, isRuleRegistryEnabled });
const rules = transformAlertsToRules(ruleAlertTypes);
const alertIds = ruleAlertTypes.map((rule) => rule.id);
const legacyActions = await legacyGetBulkRuleActionsSavedObject({
Copy link
Contributor

Choose a reason for hiding this comment

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

@rylnd I think this is similar to what we need to do for the telemetry query to get existing legacy SOs.

Copy link
Contributor

@yctercero yctercero left a comment

Choose a reason for hiding this comment

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

LGTM! Feels good to have a way forward with exporting/importing actions 🚀

@FrankHassanabad
Copy link
Contributor Author

@elasticmachine merge upstream

@FrankHassanabad
Copy link
Contributor Author

@elasticmachine merge upstream

@kevinlog
Copy link
Contributor

@elasticmachine merge upstream

@FrankHassanabad FrankHassanabad enabled auto-merge (squash) October 19, 2021 03:05
@yctercero
Copy link
Contributor

@elasticmachine merge upstream

@dhurley14
Copy link
Contributor

@elasticmachine merge upstream

@kibanamachine
Copy link
Contributor

merge conflict between base and head

@kibanamachine
Copy link
Contributor

💛 Build succeeded, but was flaky


Test Failures

Kibana Pipeline / general / X-Pack API Integration Tests.x-pack/test/api_integration/apis/ml/jobs/categorization_field_examples·ts.apis Machine Learning jobs Categorization example endpoint - partially valid, more than 75% are null

Link to Jenkins

Standard Out

Failed Tests Reporter:
  - Test has not failed recently on tracked branches

[00:00:00]     │
[00:00:00]       └-: apis
[00:00:00]         └-> "before all" hook in "apis"
[00:11:29]         └-: Machine Learning
[00:11:29]           └-> "before all" hook in "Machine Learning"
[00:11:29]           └-> "before all" hook in "Machine Learning"
[00:11:29]             │ debg creating role ft_ml_source
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_source]
[00:11:29]             │ debg creating role ft_ml_source_readonly
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_source_readonly]
[00:11:29]             │ debg creating role ft_ml_dest
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_dest]
[00:11:29]             │ debg creating role ft_ml_dest_readonly
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_dest_readonly]
[00:11:29]             │ debg creating role ft_ml_ui_extras
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_ml_ui_extras]
[00:11:29]             │ debg creating role ft_default_space_ml_all
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space_ml_all]
[00:11:29]             │ debg creating role ft_default_space1_ml_all
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space1_ml_all]
[00:11:29]             │ debg creating role ft_all_spaces_ml_all
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_all_spaces_ml_all]
[00:11:29]             │ debg creating role ft_default_space_ml_read
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space_ml_read]
[00:11:29]             │ debg creating role ft_default_space1_ml_read
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space1_ml_read]
[00:11:29]             │ debg creating role ft_all_spaces_ml_read
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_all_spaces_ml_read]
[00:11:29]             │ debg creating role ft_default_space_ml_none
[00:11:29]             │ info [o.e.x.s.a.r.TransportPutRoleAction] [node-01] added role [ft_default_space_ml_none]
[00:11:29]             │ debg creating user ft_ml_poweruser
[00:11:29]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_poweruser]
[00:11:29]             │ debg created user ft_ml_poweruser
[00:11:29]             │ debg creating user ft_ml_poweruser_spaces
[00:11:29]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_poweruser_spaces]
[00:11:29]             │ debg created user ft_ml_poweruser_spaces
[00:11:29]             │ debg creating user ft_ml_poweruser_space1
[00:11:29]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_poweruser_space1]
[00:11:29]             │ debg created user ft_ml_poweruser_space1
[00:11:29]             │ debg creating user ft_ml_poweruser_all_spaces
[00:11:29]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_poweruser_all_spaces]
[00:11:29]             │ debg created user ft_ml_poweruser_all_spaces
[00:11:29]             │ debg creating user ft_ml_viewer
[00:11:30]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_viewer]
[00:11:30]             │ debg created user ft_ml_viewer
[00:11:30]             │ debg creating user ft_ml_viewer_spaces
[00:11:30]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_viewer_spaces]
[00:11:30]             │ debg created user ft_ml_viewer_spaces
[00:11:30]             │ debg creating user ft_ml_viewer_space1
[00:11:30]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_viewer_space1]
[00:11:30]             │ debg created user ft_ml_viewer_space1
[00:11:30]             │ debg creating user ft_ml_viewer_all_spaces
[00:11:30]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_viewer_all_spaces]
[00:11:30]             │ debg created user ft_ml_viewer_all_spaces
[00:11:30]             │ debg creating user ft_ml_unauthorized
[00:11:30]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_unauthorized]
[00:11:30]             │ debg created user ft_ml_unauthorized
[00:11:30]             │ debg creating user ft_ml_unauthorized_spaces
[00:11:30]             │ info [o.e.x.s.a.u.TransportPutUserAction] [node-01] added user [ft_ml_unauthorized_spaces]
[00:11:30]             │ debg created user ft_ml_unauthorized_spaces
[00:15:33]           └-: jobs
[00:15:33]             └-> "before all" hook in "jobs"
[00:15:33]             └-: Categorization example endpoint - 
[00:15:33]               └-> "before all" hook for "valid with good number of tokens"
[00:15:33]               └-> "before all" hook for "valid with good number of tokens"
[00:15:33]                 │ info [x-pack/test/functional/es_archives/ml/categorization] Loading "mappings.json"
[00:15:33]                 │ info [x-pack/test/functional/es_archives/ml/categorization] Loading "data.json.gz"
[00:15:33]                 │ info [o.e.c.m.MetadataCreateIndexService] [node-01] [ft_categorization] creating index, cause [api], templates [], shards [1]/[0]
[00:15:33]                 │ info [x-pack/test/functional/es_archives/ml/categorization] Created index "ft_categorization"
[00:15:33]                 │ debg [x-pack/test/functional/es_archives/ml/categorization] "ft_categorization" settings {"index":{"number_of_replicas":"0","number_of_shards":"1"}}
[00:15:34]                 │ info [x-pack/test/functional/es_archives/ml/categorization] Indexed 1501 docs into "ft_categorization"
[00:15:34]                 │ debg applying update to kibana config: {"dateFormat:tz":"UTC"}
[00:15:34]               └-> valid with good number of tokens
[00:15:34]                 └-> "before each" hook: global before each for "valid with good number of tokens"
[00:15:35]                 └- ✓ pass  (184ms)
[00:15:35]               └-> invalid, too many tokens.
[00:15:35]                 └-> "before each" hook: global before each for "invalid, too many tokens."
[00:15:35]                 │ info [r.suppressed] [node-01] path: /_analyze, params: {}
[00:15:35]                 │      org.elasticsearch.transport.RemoteTransportException: [node-01][127.0.0.1:63151][indices:admin/analyze[s]]
[00:15:35]                 │      Caused by: java.lang.IllegalStateException: The number of tokens produced by calling _analyze has exceeded the allowed maximum of [10000]. This limit can be set by changing the [index.analyze.max_token_count] index level setting.
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction$TokenCounter.increment(TransportAnalyzeAction.java:397) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.simpleAnalyze(TransportAnalyzeAction.java:229) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.analyze(TransportAnalyzeAction.java:204) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.analyze(TransportAnalyzeAction.java:122) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.shardOperation(TransportAnalyzeAction.java:110) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.shardOperation(TransportAnalyzeAction.java:62) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.support.single.shard.TransportSingleShardAction.lambda$asyncShardOperation$0(TransportSingleShardAction.java:99) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.ActionRunnable.lambda$supply$0(ActionRunnable.java:47) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.ActionRunnable$2.doRun(ActionRunnable.java:62) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:737) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:26) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
[00:15:35]                 │      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
[00:15:35]                 │      	at java.lang.Thread.run(Thread.java:833) [?:?]
[00:15:35]                 │ info [r.suppressed] [node-01] path: /_analyze, params: {}
[00:15:35]                 │      org.elasticsearch.transport.RemoteTransportException: [node-01][127.0.0.1:63151][indices:admin/analyze[s]]
[00:15:35]                 │      Caused by: java.lang.IllegalStateException: The number of tokens produced by calling _analyze has exceeded the allowed maximum of [10000]. This limit can be set by changing the [index.analyze.max_token_count] index level setting.
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction$TokenCounter.increment(TransportAnalyzeAction.java:397) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.simpleAnalyze(TransportAnalyzeAction.java:229) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.analyze(TransportAnalyzeAction.java:204) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.analyze(TransportAnalyzeAction.java:122) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.shardOperation(TransportAnalyzeAction.java:110) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.admin.indices.analyze.TransportAnalyzeAction.shardOperation(TransportAnalyzeAction.java:62) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.support.single.shard.TransportSingleShardAction.lambda$asyncShardOperation$0(TransportSingleShardAction.java:99) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.ActionRunnable.lambda$supply$0(ActionRunnable.java:47) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.action.ActionRunnable$2.doRun(ActionRunnable.java:62) ~[elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:737) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:26) [elasticsearch-8.0.0-SNAPSHOT.jar:8.0.0-SNAPSHOT]
[00:15:35]                 │      	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
[00:15:35]                 │      	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
[00:15:35]                 │      	at java.lang.Thread.run(Thread.java:833) [?:?]
[00:15:35]                 └- ✓ pass  (199ms)
[00:15:35]               └-> partially valid, more than 75% are null
[00:15:35]                 └-> "before each" hook: global before each for "partially valid, more than 75% are null"
[00:15:35]                 └- ✖ fail: apis Machine Learning jobs Categorization example endpoint -  partially valid, more than 75% are null
[00:15:35]                 │       Error: expected 249 to sort of equal 250
[00:15:35]                 │       + expected - actual
[00:15:35]                 │ 
[00:15:35]                 │       -249
[00:15:35]                 │       +250
[00:15:35]                 │       
[00:15:35]                 │       at Assertion.assert (/dev/shm/workspace/parallel/15/kibana/node_modules/@kbn/expect/expect.js:100:11)
[00:15:35]                 │       at Assertion.eql (/dev/shm/workspace/parallel/15/kibana/node_modules/@kbn/expect/expect.js:244:8)
[00:15:35]                 │       at Context.<anonymous> (test/api_integration/apis/ml/jobs/categorization_field_examples.ts:303:36)
[00:15:35]                 │       at runMicrotasks (<anonymous>)
[00:15:35]                 │       at processTicksAndRejections (node:internal/process/task_queues:96:5)
[00:15:35]                 │       at Object.apply (/dev/shm/workspace/parallel/15/kibana/node_modules/@kbn/test/target_node/functional_test_runner/lib/mocha/wrap_function.js:87:16)
[00:15:35]                 │ 
[00:15:35]                 │ 

Stack Trace

Error: expected 249 to sort of equal 250
    at Assertion.assert (/dev/shm/workspace/parallel/15/kibana/node_modules/@kbn/expect/expect.js:100:11)
    at Assertion.eql (/dev/shm/workspace/parallel/15/kibana/node_modules/@kbn/expect/expect.js:244:8)
    at Context.<anonymous> (test/api_integration/apis/ml/jobs/categorization_field_examples.ts:303:36)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at Object.apply (/dev/shm/workspace/parallel/15/kibana/node_modules/@kbn/test/target_node/functional_test_runner/lib/mocha/wrap_function.js:87:16) {
  actual: '249',
  expected: '250',
  showDiff: true
}

Metrics [docs]

✅ unchanged

History

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

cc @FrankHassanabad

@FrankHassanabad FrankHassanabad merged commit c2c08be into elastic:master Oct 19, 2021
@FrankHassanabad FrankHassanabad added the auto-backport Deprecated - use backport:version if exact versions are needed label Oct 19, 2021
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Oct 19, 2021
…le and exportable (elastic#115243)

## Summary

Adds the security detection rule actions as being exportable and importable.
* Adds exportable actions for legacy notification system
* Adds exportable actions for the new throttle notification system
* Adds importable but only imports into the new throttle notification system.
* Updates unit tests

In your `ndjson` file when you have actions exported you will see them like so:

```json
"actions": [
    {
      "group": "default",
      "id": "b55117e0-2df9-11ec-b789-7f03e3cdd668",
      "params": {
        "message": "Rule {{context.rule.name}} generated {{state.signals_count}} alerts"
      },
      "action_type_id": ".slack"
    }
  ]
```

where before it was `actions: []` and was not provided.

**Caveats**

If you delete your connector and have an invalid connector then the rule(s) that were referring to that invalid connector will not import and you will get an error like this:

<img width="802" alt="Screen Shot 2021-10-15 at 2 47 10 PM" src="https://user-images.githubusercontent.com/1151048/137554991-b3984be9-d2ad-488e-a309-29da656ca4ea.png">

This does _not_ export your connectors at this point in time. You have to export your connector through the Saved Object Management separate like so:
<img width="1545" alt="Screen Shot 2021-10-15 at 2 58 03 PM" src="https://user-images.githubusercontent.com/1151048/137555135-3f0bfd63-5d67-496b-8d5b-bdef01d6122f.png">

However, if remove everything and import your connector without changing its saved object ID and then go to import the rules everything should import ok and you will get your actions working.

**Manual Testing**:

* You can create normal actions on an alert and then do exports and you should see the actions in your ndjson file 
* You can create legacy notifications from 7.14.0 and then upgrade and export and you should see the actions in your ndjson file
* You can manually create legacy notifications by:

By getting an alert id first and ensuring that your `legacy_notifications/one_action.json` contains a valid action then running this command:
```ts
./post_legacy_notification.sh 3403c0d0-2d44-11ec-b147-3b0c6d563a60
```

* You can export your connector and remove everything and then do an import and you will have everything imported and working with your actions and connector wired up correctly.

### Checklist

- [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added
@kibanamachine
Copy link
Contributor

💚 Backport successful

Status Branch Result
7.x

This backport PR will be merged automatically after passing CI.

jloleysens added a commit to jloleysens/kibana that referenced this pull request Oct 19, 2021
…-link-to-kibana-app

* 'master' of github.com:elastic/kibana: (30 commits)
  Fix potential error from undefined (elastic#115562)
  [App Search, Crawler] Fix validation step panel padding/whitespace (elastic#115542)
  [Cases][Connectors] ServiceNow ITOM: MVP (elastic#114125)
  Change default session idle timeout to 8 hours. (elastic#115565)
  Upgrade EUI to v39.1.1 (elastic#114732)
  [App Search] Wired up organic results on Curation Suggestions view (elastic#114717)
  [i18n] remove i18n html extractor (elastic#115004)
  [Logs/Metrics UI] Add deprecated field configuration to Deprecations API (elastic#115103)
  [Transform] Add alerting rules management to Transform UI (elastic#115363)
  Update UI links to Fleet and Agent docs (elastic#115295)
  [ML] Adding ability to change data view in advanced job wizard (elastic#115191)
  Change deleteByNamespace to include legacy URL aliases (elastic#115459)
  [Unified Integrations] Remove and cleanup add data views (elastic#115424)
  [Discover] Show ignored field values (elastic#115040)
  [ML] Stop reading the ml.max_open_jobs node attribute (elastic#115524)
  [Discover] Improve doc viewer code in Discover (elastic#114759)
  [Security Solutions] Adds security detection rule actions as importable and exportable (elastic#115243)
  [Security Solution] [Platform] Migrate legacy actions whenever user interacts with the rule (elastic#115101)
  [Fleet] Add telemetry for integration cards (elastic#115413)
  🐛 Fix single percentile case when ES is returning no buckets (elastic#115214)
  ...

# Conflicts:
#	x-pack/plugins/reporting/public/management/__snapshots__/report_listing.test.tsx.snap
kibanamachine added a commit that referenced this pull request Oct 19, 2021
…le and exportable (#115243) (#115579)

## Summary

Adds the security detection rule actions as being exportable and importable.
* Adds exportable actions for legacy notification system
* Adds exportable actions for the new throttle notification system
* Adds importable but only imports into the new throttle notification system.
* Updates unit tests

In your `ndjson` file when you have actions exported you will see them like so:

```json
"actions": [
    {
      "group": "default",
      "id": "b55117e0-2df9-11ec-b789-7f03e3cdd668",
      "params": {
        "message": "Rule {{context.rule.name}} generated {{state.signals_count}} alerts"
      },
      "action_type_id": ".slack"
    }
  ]
```

where before it was `actions: []` and was not provided.

**Caveats**

If you delete your connector and have an invalid connector then the rule(s) that were referring to that invalid connector will not import and you will get an error like this:

<img width="802" alt="Screen Shot 2021-10-15 at 2 47 10 PM" src="https://user-images.githubusercontent.com/1151048/137554991-b3984be9-d2ad-488e-a309-29da656ca4ea.png">

This does _not_ export your connectors at this point in time. You have to export your connector through the Saved Object Management separate like so:
<img width="1545" alt="Screen Shot 2021-10-15 at 2 58 03 PM" src="https://user-images.githubusercontent.com/1151048/137555135-3f0bfd63-5d67-496b-8d5b-bdef01d6122f.png">

However, if remove everything and import your connector without changing its saved object ID and then go to import the rules everything should import ok and you will get your actions working.

**Manual Testing**:

* You can create normal actions on an alert and then do exports and you should see the actions in your ndjson file 
* You can create legacy notifications from 7.14.0 and then upgrade and export and you should see the actions in your ndjson file
* You can manually create legacy notifications by:

By getting an alert id first and ensuring that your `legacy_notifications/one_action.json` contains a valid action then running this command:
```ts
./post_legacy_notification.sh 3403c0d0-2d44-11ec-b147-3b0c6d563a60
```

* You can export your connector and remove everything and then do an import and you will have everything imported and working with your actions and connector wired up correctly.

### Checklist

- [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added

Co-authored-by: Frank Hassanabad <frank.hassanabad@elastic.co>
@FrankHassanabad FrankHassanabad deleted the make-actions-exportable branch October 20, 2021 22:12
@KOTungseth KOTungseth added the Feature:Detection Alerts Security Solution Detection Alerts Feature label Nov 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
auto-backport Deprecated - use backport:version if exact versions are needed Feature:Detection Alerts Security Solution Detection Alerts Feature release_note:enhancement Team:Security Solution Platform Security Solution Platform Team v7.16.0 v8.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants