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
Add target-diff #664
base: main
Are you sure you want to change the base?
Add target-diff #664
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not review the whole PR, just added some small flow.record
quality of life suggestions since the merge of fox-it/flow.record#115
Available in flow.record==3.15
.
@@ -34,7 +34,7 @@ dependencies = [ | |||
"dissect.regf>=3.3.dev,<4.0.dev", | |||
"dissect.util>=3.0.dev,<4.0.dev", | |||
"dissect.volume>=3.0.dev,<4.0.dev", | |||
"flow.record~=3.14.0", | |||
"flow.record~=3.15.dev10 ", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"flow.record~=3.15.dev10 ", | |
"flow.record~=3.15.0", |
from flow.record import ( | ||
IGNORE_FIELDS_FOR_COMPARISON, | ||
Record, | ||
RecordOutput, | ||
set_ignored_fields_for_comparison, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can now use the ignore_fields_for_comparison
context manager.
from flow.record import ( | |
IGNORE_FIELDS_FOR_COMPARISON, | |
Record, | |
RecordOutput, | |
set_ignored_fields_for_comparison, | |
) | |
from flow.record import ( | |
ignore_fields_for_comparison, | |
Record, | |
RecordOutput, | |
) |
old_ignored_values = IGNORE_FIELDS_FOR_COMPARISON | ||
set_ignored_fields_for_comparison(["_generated", "_source", "hostname", "domain"]) | ||
|
||
src_records = set(get_plugin_output_records(plugin_name, plugin_arg_parts, self.src_target)) | ||
src_records_seen = set() | ||
|
||
for dst_record in get_plugin_output_records(plugin_name, plugin_arg_parts, self.dst_target): | ||
if dst_record in src_records: | ||
src_records_seen.add(dst_record) | ||
yield RecordUnchangedRecord( | ||
src_target=self.src_target.path, dst_target=self.dst_target.path, record=dst_record | ||
) | ||
else: | ||
yield RecordCreatedRecord( | ||
src_target=self.src_target.path, dst_target=self.dst_target.path, record=dst_record | ||
) | ||
for record in src_records - src_records_seen: | ||
yield RecordDeletedRecord(src_target=self.src_target.path, dst_target=self.dst_target.path, record=record) | ||
|
||
set_ignored_fields_for_comparison(old_ignored_values) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can now be wrapped in with ignore_fields_for_comparison([..]):
block
This PR adds the command
target-diff
, which can be used to compare two or more targets against one another:fs
mode outputs records denoting filesystem changes from one target to the other:Using
query
mode, you can compare plugin outputs from one target to the other:In
shell
mode, you can browse the target filesystems like intarget-shell
, where directory listings will show which files / directories have been changed, added or deleted. Using theplugin
command, plugin outputs can be compared from within the shell context.target-diff
depends on fox-it/flow.record#107. To allow tests to run for this PR we've temporarily bumped flow.record to3.15.dev10
inpyproject.toml
When three or more targets are provided, you can choose between treating every target as a 'delta' or compare every target against one 'absolute' target. Treating targets as 'deltas' is useful if you have multiple snapshots of the same target from different points in time. Treating targets as 'absolutes' can be useful in situations where you have a 'golden image' that you want to compare different targets against.
To keep code duplication low between
tools/diff.py
andtools/shell.py
, this PR adds a superclassExtendedCmd
toshell.py
that contains most of the functionality that is shared between the two. BothTargetCmd
andDifferentialCli
inherit from this class.