Skip to content

Commit 2110ad5

Browse files
authored
[FR] Support new_terms schema import/export w/custom format (#3890)
* [FR] Support new_terms schema import/export w/custom format * fix formatter for filters * handle both rule formats when parsing data view
1 parent bd345d4 commit 2110ad5

File tree

3 files changed

+31
-2
lines changed

3 files changed

+31
-2
lines changed

detection_rules/main.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,10 @@ def import_rules_into_repo(input_file, required_only, directory):
111111
base_path = contents.get('name') or contents.get('rule', {}).get('name')
112112
base_path = rulename_to_filename(base_path) if base_path else base_path
113113
rule_path = os.path.join(RULES_DIR, base_path) if base_path else None
114-
additional = ['index'] if not contents.get('data_view_id') else ['data_view_id']
114+
115+
# handle both rule json formats loaded from kibana and toml
116+
data_view_id = contents.get("data_view_id") or contents.get("rule", {}).get("data_view_id")
117+
additional = ["index"] if not data_view_id else ["data_view_id"]
115118
rule_prompt(rule_path, required_only=required_only, save=True, verbose=True,
116119
additional_required=additional, **contents)
117120

detection_rules/rule.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from semver import Version
2222
from marko.block import Document as MarkoDocument
2323
from marko.ext.gfm import gfm
24-
from marshmallow import ValidationError, validates_schema
24+
from marshmallow import ValidationError, validates_schema, pre_load
2525

2626
import kql
2727

@@ -768,6 +768,27 @@ class HistoryWindowStart:
768768
type: Literal["new_terms"]
769769
new_terms: NewTermsMapping
770770

771+
@pre_load
772+
def preload_data(self, data: dict, **kwargs) -> dict:
773+
"""Preloads and formats the data to match the required schema."""
774+
if "new_terms_fields" in data and "history_window_start" in data:
775+
new_terms_mapping = {
776+
"field": "new_terms_fields",
777+
"value": data["new_terms_fields"],
778+
"history_window_start": [
779+
{
780+
"field": "history_window_start",
781+
"value": data["history_window_start"]
782+
}
783+
]
784+
}
785+
data["new_terms"] = new_terms_mapping
786+
787+
# cleanup original fields after building into our toml format
788+
data.pop("new_terms_fields")
789+
data.pop("history_window_start")
790+
return data
791+
771792
def transform(self, obj: dict) -> dict:
772793
"""Transforms new terms data to API format for Kibana."""
773794
obj[obj["new_terms"].get("field")] = obj["new_terms"].get("value")

detection_rules/rule_formatter.py

+5
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ def _do_write(_data, _contents):
216216
preserved_fields = ["params.message"]
217217
v = [preserve_formatting_for_fields(action, preserved_fields) for action in v]
218218

219+
if k == 'filters':
220+
# explicitly preserve formatting for value field in filters
221+
preserved_fields = ["meta.value"]
222+
v = [preserve_formatting_for_fields(meta, preserved_fields) for meta in v]
223+
219224
if k == 'note' and isinstance(v, str):
220225
# Transform instances of \ to \\ as calling write will convert \\ to \.
221226
# This will ensure that the output file has the correct number of backslashes.

0 commit comments

Comments
 (0)