Skip to content

Commit 63e91c2

Browse files
Back-porting Version Trimming (#3704)
1 parent 2c3dbfc commit 63e91c2

File tree

1,016 files changed

+11960
-11214
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,016 files changed

+11960
-11214
lines changed

.github/workflows/lock-versions.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
description: 'List of branches to lock versions (ordered, comma separated)'
77
required: true
88
# 7.17 was intentionally skipped because it was added late and was bug fix only
9-
default: '8.3,8.4,8.5,8.6,8.7,8.8,8.9,8.10,8.11,8.12,8.13,8.14'
9+
default: '8.9,8.10,8.11,8.12,8.13,8.14'
1010

1111
jobs:
1212
pr:

detection_rules/devtools.py

+57-14
Original file line numberDiff line numberDiff line change
@@ -812,45 +812,88 @@ def raw_permalink(raw_link):
812812

813813
@dev_group.command('trim-version-lock')
814814
@click.argument('stack_version')
815+
@click.option('--skip-rule-updates', is_flag=True, help='Skip updating the rules')
815816
@click.option('--dry-run', is_flag=True, help='Print the changes rather than saving the file')
816-
def trim_version_lock(stack_version: str, dry_run: bool):
817+
def trim_version_lock(stack_version: str, skip_rule_updates: bool, dry_run: bool):
817818
"""Trim all previous entries within the version lock file which are lower than the min_version."""
818819
stack_versions = get_stack_versions()
819820
assert stack_version in stack_versions, \
820821
f'Unknown min_version ({stack_version}), expected: {", ".join(stack_versions)}'
821822

822823
min_version = Version.parse(stack_version)
823824
version_lock_dict = default_version_lock.version_lock.to_dict()
824-
removed = {}
825+
removed = defaultdict(list)
826+
rule_msv_drops = []
827+
828+
today = time.strftime('%Y/%m/%d')
829+
rc: RuleCollection | None = None
830+
if dry_run:
831+
rc = RuleCollection()
832+
else:
833+
if not skip_rule_updates:
834+
click.echo('Loading rules ...')
835+
rc = RuleCollection.default()
825836

826837
for rule_id, lock in version_lock_dict.items():
838+
file_min_stack: Version | None = None
839+
if 'min_stack_version' in lock:
840+
file_min_stack = Version.parse((lock['min_stack_version']), optional_minor_and_patch=True)
841+
if file_min_stack <= min_version:
842+
removed[rule_id].append(
843+
f'locked min_stack_version <= {min_version} - {"will remove" if dry_run else "removing"}!'
844+
)
845+
rule_msv_drops.append(rule_id)
846+
file_min_stack = None
847+
848+
if not dry_run:
849+
lock.pop('min_stack_version')
850+
if not skip_rule_updates:
851+
# remove the min_stack_version and min_stack_comments from rules as well (and update date)
852+
rule = rc.id_map.get(rule_id)
853+
if rule:
854+
new_meta = dataclasses.replace(
855+
rule.contents.metadata,
856+
updated_date=today,
857+
min_stack_version=None,
858+
min_stack_comments=None
859+
)
860+
contents = dataclasses.replace(rule.contents, metadata=new_meta)
861+
new_rule = TOMLRule(contents=contents, path=rule.path)
862+
new_rule.save_toml()
863+
removed[rule_id].append('rule min_stack_version dropped')
864+
else:
865+
removed[rule_id].append('rule not found to update!')
866+
827867
if 'previous' in lock:
828868
prev_vers = [Version.parse(v, optional_minor_and_patch=True) for v in list(lock['previous'])]
829-
outdated_vers = [f"{v.major}.{v.minor}" for v in prev_vers if v < min_version]
869+
outdated_vers = [v for v in prev_vers if v < min_version]
830870

831871
if not outdated_vers:
832872
continue
833873

834874
# we want to remove all "old" versions, but save the latest that is >= the min version supplied as the new
835875
# stack_version.
876+
latest_version = max(outdated_vers)
836877

837-
if dry_run:
838-
outdated_minus_current = [str(v) for v in outdated_vers if v < stack_version]
839-
if outdated_minus_current:
840-
removed[rule_id] = outdated_minus_current
841878
for outdated in outdated_vers:
842-
popped = lock['previous'].pop(str(outdated))
843-
if outdated >= stack_version:
844-
lock['previous'][str(Version(stack_version[:2]))] = popped
879+
short_outdated = f"{outdated.major}.{outdated.minor}"
880+
popped = lock['previous'].pop(str(short_outdated))
881+
# the core of the update - we only need to keep previous entries that are newer than the min supported
882+
# version (from stack-schema-map and stack-version parameter) and older than the locked
883+
# min_stack_version for a given rule, if one exists
884+
if file_min_stack and outdated == latest_version and outdated < file_min_stack:
885+
lock['previous'][f'{min_version.major}.{min_version.minor}'] = popped
886+
removed[rule_id].append(f'{short_outdated} updated to: {min_version.major}.{min_version.minor}')
887+
else:
888+
removed[rule_id].append(f'{outdated} dropped')
845889

846890
# remove the whole previous entry if it is now blank
847891
if not lock['previous']:
848892
lock.pop('previous')
849893

850-
if dry_run:
851-
click.echo(f'The following versions would be collapsed to {stack_version}:' if removed else 'No changes')
852-
click.echo('\n'.join(f'{k}: {", ".join(v)}' for k, v in removed.items()))
853-
else:
894+
click.echo(f'Changes {"that will be " if dry_run else ""} applied:' if removed else 'No changes')
895+
click.echo('\n'.join(f'{k}: {", ".join(v)}' for k, v in removed.items()))
896+
if not dry_run:
854897
new_lock = VersionLockFile.from_dict(dict(data=version_lock_dict))
855898
new_lock.save_to_file()
856899

detection_rules/etc/stack-schema-map.yaml

+29-30
Original file line numberDiff line numberDiff line change
@@ -42,39 +42,38 @@
4242
# beats: "8.2.1"
4343
# ecs: "8.2.1"
4444
# endgame: "1.9.0"
45+
# "8.3.0":
46+
# beats: "8.3.3"
47+
# ecs: "8.3.1"
48+
# endgame: "1.9.0"
49+
50+
# "8.4.0":
51+
# beats: "8.4.3"
52+
# ecs: "8.4.0"
53+
# endgame: "8.4.0"
54+
55+
# "8.5.0":
56+
# beats: "8.5.3"
57+
# ecs: "8.5.2"
58+
# endgame: "8.4.0"
59+
60+
# "8.6.0":
61+
# beats: "8.6.1"
62+
# ecs: "8.6.1"
63+
# endgame: "8.4.0"
64+
65+
# "8.7.0":
66+
# beats: "8.7.0"
67+
# ecs: "8.7.0"
68+
# endgame: "8.4.0"
69+
70+
# "8.8.0":
71+
# beats: "8.8.2"
72+
# ecs: "8.8.0"
73+
# endgame: "8.4.0"
4574

4675
## Supported
4776

48-
"8.3.0":
49-
beats: "8.3.3"
50-
ecs: "8.3.1"
51-
endgame: "1.9.0"
52-
53-
"8.4.0":
54-
beats: "8.4.3"
55-
ecs: "8.4.0"
56-
endgame: "8.4.0"
57-
58-
"8.5.0":
59-
beats: "8.5.3"
60-
ecs: "8.5.2"
61-
endgame: "8.4.0"
62-
63-
"8.6.0":
64-
beats: "8.6.1"
65-
ecs: "8.6.1"
66-
endgame: "8.4.0"
67-
68-
"8.7.0":
69-
beats: "8.7.0"
70-
ecs: "8.7.0"
71-
endgame: "8.4.0"
72-
73-
"8.8.0":
74-
beats: "8.8.2"
75-
ecs: "8.8.0"
76-
endgame: "8.4.0"
77-
7877
"8.9.0":
7978
beats: "8.9.0"
8079
ecs: "8.9.0"

0 commit comments

Comments
 (0)