flow.record 3.15.dev9__tar.gz → 3.15.dev12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {flow.record-3.15.dev9/flow.record.egg-info → flow.record-3.15.dev12}/PKG-INFO +1 -1
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/base.py +12 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/version.py +2 -2
- {flow.record-3.15.dev9 → flow.record-3.15.dev12/flow.record.egg-info}/PKG-INFO +1 -1
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/pyproject.toml +1 -1
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_record.py +66 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/COPYRIGHT +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/LICENSE +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/MANIFEST.in +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/README.md +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/examples/filesystem.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/examples/passivedns.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/examples/records.json +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/examples/tcpconn.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/__init__.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/__init__.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/archive.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/avro.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/broker.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/csvfile.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/duckdb.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/elastic.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/jsonfile.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/line.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/mongo.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/split.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/splunk.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/sqlite.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/stream.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/text.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/adapter/xlsx.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/exceptions.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/__init__.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/credential.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/__init__.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/ip.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/ipv4.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/tcp.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/fieldtypes/net/udp.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/jsonpacker.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/packer.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/selector.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/stream.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/tools/__init__.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/tools/geoip.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/tools/rdump.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/utils.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow/record/whitelist.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/SOURCES.txt +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/dependency_links.txt +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/entry_points.txt +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/requires.txt +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/flow.record.egg-info/top_level.txt +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/setup.cfg +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/__init__.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/_utils.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/docs/Makefile +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/docs/conf.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/docs/index.rst +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/selector_explain_example.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/standalone_test.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_avro.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_avro_adapter.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_compiled_selector.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_csv_adapter.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_deprecations.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_fieldtype_ip.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_fieldtypes.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_json_packer.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_json_record_adapter.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_multi_timestamp.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_packer.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_rdump.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_record_adapter.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_record_descriptor.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_regression.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_selector.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_splunk_adapter.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/test_sqlite_duckdb_adapter.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tests/utils_inspect.py +0 -0
- {flow.record-3.15.dev9 → flow.record-3.15.dev12}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flow.record
|
|
3
|
-
Version: 3.15.
|
|
3
|
+
Version: 3.15.dev12
|
|
4
4
|
Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
@@ -12,6 +12,7 @@ import os
|
|
|
12
12
|
import re
|
|
13
13
|
import sys
|
|
14
14
|
import warnings
|
|
15
|
+
from contextlib import contextmanager
|
|
15
16
|
from datetime import datetime, timezone
|
|
16
17
|
from itertools import zip_longest
|
|
17
18
|
from pathlib import Path
|
|
@@ -118,6 +119,17 @@ def set_ignored_fields_for_comparison(ignored_fields: Iterable[str]) -> None:
|
|
|
118
119
|
IGNORE_FIELDS_FOR_COMPARISON = set(ignored_fields)
|
|
119
120
|
|
|
120
121
|
|
|
122
|
+
@contextmanager
|
|
123
|
+
def ignore_fields_for_comparison(ignored_fields: Iterable[str]):
|
|
124
|
+
"""Context manager to temporarily ignore fields for comparison."""
|
|
125
|
+
original_ignored_fields = IGNORE_FIELDS_FOR_COMPARISON
|
|
126
|
+
try:
|
|
127
|
+
set_ignored_fields_for_comparison(ignored_fields)
|
|
128
|
+
yield
|
|
129
|
+
finally:
|
|
130
|
+
set_ignored_fields_for_comparison(original_ignored_fields)
|
|
131
|
+
|
|
132
|
+
|
|
121
133
|
class FieldType:
|
|
122
134
|
def _typename(self):
|
|
123
135
|
t = type(self)
|
|
@@ -12,5 +12,5 @@ __version__: str
|
|
|
12
12
|
__version_tuple__: VERSION_TUPLE
|
|
13
13
|
version_tuple: VERSION_TUPLE
|
|
14
14
|
|
|
15
|
-
__version__ = version = '3.15.
|
|
16
|
-
__version_tuple__ = version_tuple = (3, 15, '
|
|
15
|
+
__version__ = version = '3.15.dev12'
|
|
16
|
+
__version_tuple__ = version_tuple = (3, 15, 'dev12')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: flow.record
|
|
3
|
-
Version: 3.15.
|
|
3
|
+
Version: 3.15.dev12
|
|
4
4
|
Summary: A library for defining and creating structured data (called records) that can be streamed to disk or piped to other tools that use flow.record
|
|
5
5
|
Author-email: Dissect Team <dissect@fox-it.com>
|
|
6
6
|
License: Affero General Public License v3
|
|
@@ -19,6 +19,7 @@ from flow.record import (
|
|
|
19
19
|
record_stream,
|
|
20
20
|
)
|
|
21
21
|
from flow.record.base import (
|
|
22
|
+
ignore_fields_for_comparison,
|
|
22
23
|
merge_record_descriptors,
|
|
23
24
|
normalize_fieldname,
|
|
24
25
|
set_ignored_fields_for_comparison,
|
|
@@ -856,3 +857,68 @@ def test_compare_environment_variable():
|
|
|
856
857
|
assert same_same == but_still_same
|
|
857
858
|
assert same_same != but_different
|
|
858
859
|
assert len(set(records)) == 2
|
|
860
|
+
|
|
861
|
+
|
|
862
|
+
def test_ignore_fields_for_comparision_contextmanager():
|
|
863
|
+
TestRecord = RecordDescriptor(
|
|
864
|
+
"test/record",
|
|
865
|
+
[
|
|
866
|
+
("string", "firstname"),
|
|
867
|
+
("string", "lastname"),
|
|
868
|
+
("string", "movie"),
|
|
869
|
+
],
|
|
870
|
+
)
|
|
871
|
+
records = [
|
|
872
|
+
TestRecord("John", "Rambo", "First Blood"),
|
|
873
|
+
TestRecord("John", "Rambo", "Rambo: First Blood Part II"),
|
|
874
|
+
TestRecord("John", "Rambo", "Rambo III"),
|
|
875
|
+
TestRecord("John", "Rambo", "Rambo"),
|
|
876
|
+
TestRecord("John", "Rambo", "Rambo: Last Blood"),
|
|
877
|
+
TestRecord("Johnny", "English", "Johnny English"),
|
|
878
|
+
TestRecord("Johnny", "English", "Johnny English Strikes Again"),
|
|
879
|
+
TestRecord("John", "McClane", "Die Hard"),
|
|
880
|
+
TestRecord("John", "McClane", "Die Hard 2"),
|
|
881
|
+
TestRecord("John", "McClane", "Die Hard with a Vengeance"),
|
|
882
|
+
TestRecord("John", "McClane", "Live Free or Die Hard"),
|
|
883
|
+
TestRecord("John", "McClane", "A Good Day to Die Hard"),
|
|
884
|
+
TestRecord("John", "Wick", "John Wick"),
|
|
885
|
+
TestRecord("John", "Wick", "John Wick: Chapter 2"),
|
|
886
|
+
TestRecord("John", "Wick", "John Wick: Chapter 3 - Parabellum"),
|
|
887
|
+
]
|
|
888
|
+
|
|
889
|
+
with ignore_fields_for_comparison({"_generated", "lastname", "movie"}):
|
|
890
|
+
# unique by firstname
|
|
891
|
+
first_name_records = set(records)
|
|
892
|
+
firstnames = [first_name.firstname for first_name in first_name_records]
|
|
893
|
+
assert len(first_name_records) == 2
|
|
894
|
+
assert firstnames.count("John") == 1
|
|
895
|
+
assert firstnames.count("Johnny") == 1
|
|
896
|
+
assert records[0] == records[1]
|
|
897
|
+
|
|
898
|
+
# test nested context manager
|
|
899
|
+
with ignore_fields_for_comparison({"_generated", "firstname", "movie"}):
|
|
900
|
+
# unique by lastname
|
|
901
|
+
last_name_records = set(records)
|
|
902
|
+
lastnames = [last_name.lastname for last_name in last_name_records]
|
|
903
|
+
assert len(lastnames) == 4
|
|
904
|
+
assert lastnames.count("Rambo") == 1
|
|
905
|
+
assert lastnames.count("English") == 1
|
|
906
|
+
assert lastnames.count("McClane") == 1
|
|
907
|
+
assert lastnames.count("Wick") == 1
|
|
908
|
+
assert records[0] == records[1]
|
|
909
|
+
|
|
910
|
+
# test if the contextmanager properly resets the ignored fields
|
|
911
|
+
with ignore_fields_for_comparison({"_generated", "movie"}):
|
|
912
|
+
# unique by firstname + lastname
|
|
913
|
+
main_character_records = set(records)
|
|
914
|
+
main_characters = [f"{r.firstname} {r.lastname}" for r in main_character_records]
|
|
915
|
+
assert len(main_characters) == 4
|
|
916
|
+
assert main_characters.count("John Rambo") == 1
|
|
917
|
+
assert main_characters.count("Johnny English") == 1
|
|
918
|
+
assert main_characters.count("John McClane") == 1
|
|
919
|
+
assert main_characters.count("John Wick") == 1
|
|
920
|
+
assert records[0] == records[1]
|
|
921
|
+
|
|
922
|
+
# test reset again
|
|
923
|
+
assert len(set(records)) == len(records)
|
|
924
|
+
assert records[0] != records[1]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|