From 5fff45ec93ab74419cd3fe92acec8553c3593149 Mon Sep 17 00:00:00 2001 From: Aaron Jewitt Date: Mon, 26 Jan 2026 11:00:45 +0100 Subject: [PATCH] Added logic to main.py to use the created_at and updated_at values if they exist (#5444) * Added logic to main.py to use the created_at and updated_at values from the ndjson file if they exist. * Add comment for parsing created_at and updated_at fields to metadata * updated the date metadata code based on PR feedback * Add --dates-import option to rule import command Introduce a new option `--dates-import` to parse `created_at` and `updated_at` fields from rule content. This allows users to import date metadata while preventing conflicts with existing date options. * Update version to 1.5.23 for release preparation This update increments the version number in the project metadata to reflect the upcoming release. No other changes were made. * Update date metadata logic to include timezone information Modified the handling of creation and updated dates to ensure that the datetime objects are timezone-aware by replacing the timezone info with UTC. This change improves the accuracy of date metadata in the rules. * Updated format of main.py using ruff * Update project version to 1.5.29 * updating pyproject version --------- Co-authored-by: Sergey Polzunov --- detection_rules/main.py | 20 ++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/detection_rules/main.py b/detection_rules/main.py index b2e5d1a7a..4636fa018 100644 --- a/detection_rules/main.py +++ b/detection_rules/main.py @@ -169,6 +169,7 @@ def generate_rules_index( @click.option("--strip-none-values", "-snv", is_flag=True, help="Strip None values from the rule") @click.option("--local-creation-date", "-lc", is_flag=True, help="Preserve the local creation date of the rule") @click.option("--local-updated-date", "-lu", is_flag=True, help="Preserve the local updated date of the rule") +@click.option("--dates-import", "-di", is_flag=True, help="Parse created_at and updated_at from the rule content") @click.option( "--load-rule-loading", "-lr", @@ -189,11 +190,16 @@ def import_rules_into_repo( # noqa: PLR0912, PLR0913, PLR0915 strip_none_values: bool, local_creation_date: bool, local_updated_date: bool, + dates_import: bool, load_rule_loading: bool, ) -> None: """Import rules from json, toml, or yaml files containing Kibana exported rule(s).""" errors: list[str] = [] + if dates_import and (local_creation_date or local_updated_date): + click.echo("Error: --dates-import cannot be used with --local-creation-date or --local-updated-date.") + return + rule_files: list[Path] = [] if directory: rule_files = list(directory.glob("**/*.*")) @@ -252,6 +258,20 @@ def import_rules_into_repo( # noqa: PLR0912, PLR0913, PLR0915 if isinstance(contents["author"], str): contents["author"] = [contents["author"]] + # Parse created_at and updated_at to creation_date and updated_date if they exist in contents + if dates_import: + now = datetime.now(UTC).strftime("%Y-%m-%dT%H:%M:%S.%fZ") + contents["creation_date"] = ( + datetime.strptime(contents.get("created_at", now), "%Y-%m-%dT%H:%M:%S.%fZ") + .replace(tzinfo=UTC) + .strftime("%Y/%m/%d") + ) + contents["updated_date"] = ( + datetime.strptime(contents.get("updated_at", now), "%Y-%m-%dT%H:%M:%S.%fZ") + .replace(tzinfo=UTC) + .strftime("%Y/%m/%d") + ) + contents.update( update_metadata_from_file( rule_path, {"creation_date": local_creation_date, "updated_date": local_updated_date} diff --git a/pyproject.toml b/pyproject.toml index 14ff5d8c2..a28439ef4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "detection_rules" -version = "1.5.29" +version = "1.5.30" description = "Detection Rules is the home for rules used by Elastic Security. This repository is used for the development, maintenance, testing, validation, and release of rules for Elastic Security’s Detection Engine." readme = "README.md" requires-python = ">=3.12"