insightconnect-plugin-runtime 6.2.1__py3-none-any.whl → 6.2.3__py3-none-any.whl
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.
- insightconnect_plugin_runtime/api/endpoints.py +14 -15
- insightconnect_plugin_runtime/helper.py +69 -32
- insightconnect_plugin_runtime/schema.py +6 -9
- {insightconnect_plugin_runtime-6.2.1.dist-info → insightconnect_plugin_runtime-6.2.3.dist-info}/METADATA +25 -15
- {insightconnect_plugin_runtime-6.2.1.dist-info → insightconnect_plugin_runtime-6.2.3.dist-info}/RECORD +8 -8
- {insightconnect_plugin_runtime-6.2.1.dist-info → insightconnect_plugin_runtime-6.2.3.dist-info}/WHEEL +1 -1
- tests/unit/test_helpers.py +43 -17
- {insightconnect_plugin_runtime-6.2.1.dist-info → insightconnect_plugin_runtime-6.2.3.dist-info}/top_level.txt +0 -0
|
@@ -1,27 +1,27 @@
|
|
|
1
|
+
import importlib.metadata as importlib_metadata
|
|
1
2
|
import json
|
|
2
|
-
import subprocess
|
|
3
|
-
import yaml
|
|
4
3
|
import os
|
|
5
|
-
import pkg_resources
|
|
6
4
|
import signal
|
|
7
|
-
|
|
8
|
-
from werkzeug.exceptions import InternalServerError, HTTPException
|
|
5
|
+
import subprocess
|
|
9
6
|
from typing import Any, Dict
|
|
10
7
|
|
|
11
8
|
import structlog
|
|
9
|
+
import yaml
|
|
10
|
+
from flask import Blueprint, abort, jsonify, make_response, request
|
|
11
|
+
from werkzeug.exceptions import HTTPException, InternalServerError
|
|
12
12
|
|
|
13
|
+
from insightconnect_plugin_runtime.api.schemas import (
|
|
14
|
+
ActionTriggerDetailsSchema,
|
|
15
|
+
ConnectionDetailsSchema,
|
|
16
|
+
PluginInfoSchema,
|
|
17
|
+
TaskDetailsSchema,
|
|
18
|
+
)
|
|
13
19
|
from insightconnect_plugin_runtime.exceptions import (
|
|
14
20
|
ClientException,
|
|
15
|
-
ServerException,
|
|
16
|
-
LoggedException,
|
|
17
21
|
ConnectionTestException,
|
|
22
|
+
LoggedException,
|
|
18
23
|
PluginException,
|
|
19
|
-
|
|
20
|
-
from insightconnect_plugin_runtime.api.schemas import (
|
|
21
|
-
PluginInfoSchema,
|
|
22
|
-
ActionTriggerDetailsSchema,
|
|
23
|
-
TaskDetailsSchema,
|
|
24
|
-
ConnectionDetailsSchema,
|
|
24
|
+
ServerException,
|
|
25
25
|
)
|
|
26
26
|
from insightconnect_plugin_runtime.util import OutputMasker
|
|
27
27
|
|
|
@@ -780,11 +780,10 @@ class Endpoints:
|
|
|
780
780
|
|
|
781
781
|
def get_plugin_sdk_version(self):
|
|
782
782
|
try:
|
|
783
|
-
version =
|
|
783
|
+
version = importlib_metadata.version("insightconnect-plugin-runtime")
|
|
784
784
|
except Exception:
|
|
785
785
|
self.logger.warn("Unable to get SDK version")
|
|
786
786
|
version = "0.0.0"
|
|
787
|
-
|
|
788
787
|
return version
|
|
789
788
|
|
|
790
789
|
def add_plugin_custom_config(
|
|
@@ -10,7 +10,7 @@ import subprocess
|
|
|
10
10
|
import time
|
|
11
11
|
from datetime import datetime, timedelta
|
|
12
12
|
from io import IOBase
|
|
13
|
-
from typing import Any, Callable, Dict, List, Union, Tuple
|
|
13
|
+
from typing import Any, Callable, Dict, List, Union, Tuple, Optional
|
|
14
14
|
from urllib import request
|
|
15
15
|
from hashlib import sha1
|
|
16
16
|
from json import JSONDecodeError
|
|
@@ -33,17 +33,45 @@ DEFAULTS_HOURS_AGO = 24
|
|
|
33
33
|
logger = logging.getLogger()
|
|
34
34
|
|
|
35
35
|
|
|
36
|
-
def hash_sha1(log: Dict) -> str:
|
|
36
|
+
def hash_sha1(log: Dict[str, Any], keys: Optional[List[str]] = None) -> str:
|
|
37
37
|
"""
|
|
38
38
|
Iterate through a dictionary and hash each value.
|
|
39
|
+
Optionally only hash certain keys in the dictionary.
|
|
40
|
+
|
|
39
41
|
:param log: Dictionary to be hashed.
|
|
40
|
-
:
|
|
42
|
+
:param keys: Optional list of keys to hash on if provided
|
|
43
|
+
|
|
41
44
|
:return: Hex digest of hash.
|
|
42
|
-
:rtype: str
|
|
43
45
|
"""
|
|
46
|
+
|
|
44
47
|
hash_ = sha1() # nosec B303
|
|
45
|
-
|
|
48
|
+
|
|
49
|
+
# Leaving no room for developer error and ensuring they know exactly where it went wrong
|
|
50
|
+
# if they provide a key not in list format
|
|
51
|
+
if keys is not None and not isinstance(keys, list):
|
|
52
|
+
raise TypeError(
|
|
53
|
+
f"The 'keys' parameter must be a list or None in the 'hash_sha1' function, not {type(keys).__name__}"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
# Hash all key-value pairs if no keys provided
|
|
57
|
+
if keys is None:
|
|
58
|
+
items_to_hash = log.items()
|
|
59
|
+
|
|
60
|
+
# Otherwise, only include specified keys
|
|
61
|
+
else:
|
|
62
|
+
items_to_hash = []
|
|
63
|
+
for key in keys:
|
|
64
|
+
if key in log:
|
|
65
|
+
items_to_hash.append((key, log[key]))
|
|
66
|
+
|
|
67
|
+
# Alert if the key is not found in the log
|
|
68
|
+
else:
|
|
69
|
+
raise KeyError(f"Key '{key}' not found in the provided log.")
|
|
70
|
+
|
|
71
|
+
# Iterate through items to hash and hash
|
|
72
|
+
for key, value in items_to_hash:
|
|
46
73
|
hash_.update(f"{key}{value}".encode(ENCODE_TYPE))
|
|
74
|
+
|
|
47
75
|
return hash_.hexdigest()
|
|
48
76
|
|
|
49
77
|
|
|
@@ -137,7 +165,12 @@ def make_request(
|
|
|
137
165
|
raise PluginException(
|
|
138
166
|
preset=PluginException.Preset.UNKNOWN, data=str(exception)
|
|
139
167
|
)
|
|
140
|
-
response_handler(
|
|
168
|
+
response_handler(
|
|
169
|
+
response,
|
|
170
|
+
exception_custom_configs,
|
|
171
|
+
exception_data_location,
|
|
172
|
+
allowed_status_codes,
|
|
173
|
+
)
|
|
141
174
|
return response
|
|
142
175
|
|
|
143
176
|
|
|
@@ -192,7 +225,7 @@ def request_error_handling(
|
|
|
192
225
|
exception.response,
|
|
193
226
|
data_location=exception_data_location,
|
|
194
227
|
custom_configs=custom_configs,
|
|
195
|
-
allowed_status_codes=allowed_status_codes
|
|
228
|
+
allowed_status_codes=allowed_status_codes,
|
|
196
229
|
)
|
|
197
230
|
else:
|
|
198
231
|
raise PluginException(
|
|
@@ -443,15 +476,19 @@ def convert_dict_to_snake_case(
|
|
|
443
476
|
|
|
444
477
|
if isinstance(input_dict, list):
|
|
445
478
|
return [
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
479
|
+
(
|
|
480
|
+
convert_dict_to_snake_case(element)
|
|
481
|
+
if isinstance(element, (dict, list))
|
|
482
|
+
else element
|
|
483
|
+
)
|
|
449
484
|
for element in input_dict
|
|
450
485
|
]
|
|
451
486
|
return {
|
|
452
|
-
convert_to_snake_case(key):
|
|
453
|
-
|
|
454
|
-
|
|
487
|
+
convert_to_snake_case(key): (
|
|
488
|
+
convert_dict_to_snake_case(value)
|
|
489
|
+
if isinstance(value, (dict, list))
|
|
490
|
+
else value
|
|
491
|
+
)
|
|
455
492
|
for key, value in input_dict.items()
|
|
456
493
|
}
|
|
457
494
|
|
|
@@ -665,7 +702,7 @@ def open_cachefile(cache_file, append=False):
|
|
|
665
702
|
logger.info("OpenCacheFile: %s created", cache_file)
|
|
666
703
|
f = open(cache_file, "a+" if append else "r+")
|
|
667
704
|
return f
|
|
668
|
-
|
|
705
|
+
logger.error("OpenCacheFile: %s directory or does not exist", cache_dir)
|
|
669
706
|
|
|
670
707
|
|
|
671
708
|
def remove_cachefile(cache_file):
|
|
@@ -748,11 +785,11 @@ def open_url(url, timeout=None, verify=True, **kwargs):
|
|
|
748
785
|
urlobj = request.urlopen(req, timeout=timeout, context=ctx)
|
|
749
786
|
return urlobj
|
|
750
787
|
except request.HTTPError as e:
|
|
751
|
-
|
|
788
|
+
logger.error("HTTPError: %s for %s", str(e.code), url)
|
|
752
789
|
if e.code == 304:
|
|
753
790
|
return None
|
|
754
791
|
except request.URLError as e:
|
|
755
|
-
|
|
792
|
+
logger.error("URLError: %s for %s", str(e.reason), url)
|
|
756
793
|
raise Exception("GetURL Failed")
|
|
757
794
|
|
|
758
795
|
|
|
@@ -780,17 +817,17 @@ def check_url(url):
|
|
|
780
817
|
return True
|
|
781
818
|
|
|
782
819
|
except requests.exceptions.HTTPError:
|
|
783
|
-
|
|
820
|
+
logger.error(
|
|
784
821
|
"Requests: HTTPError: status code %s for %s",
|
|
785
822
|
str(resp.status_code) if resp else None,
|
|
786
823
|
url,
|
|
787
824
|
)
|
|
788
825
|
except requests.exceptions.Timeout:
|
|
789
|
-
|
|
826
|
+
logger.error("Requests: Timeout for %s", url)
|
|
790
827
|
except requests.exceptions.TooManyRedirects:
|
|
791
|
-
|
|
828
|
+
logger.error("Requests: TooManyRedirects for %s", url)
|
|
792
829
|
except requests.ConnectionError:
|
|
793
|
-
|
|
830
|
+
logger.error("Requests: ConnectionError for %s", url)
|
|
794
831
|
return False
|
|
795
832
|
|
|
796
833
|
|
|
@@ -810,7 +847,7 @@ def exec_command(command):
|
|
|
810
847
|
rcode = p.poll()
|
|
811
848
|
return {"stdout": stdout, "stderr": stderr, "rcode": rcode}
|
|
812
849
|
except OSError as e:
|
|
813
|
-
|
|
850
|
+
logger.error(
|
|
814
851
|
"SubprocessError: %s %s: %s", str(e.filename), str(e.strerror), str(e.errno)
|
|
815
852
|
)
|
|
816
853
|
raise Exception("ExecCommand")
|
|
@@ -836,7 +873,7 @@ def encode_file(file_path):
|
|
|
836
873
|
return efile
|
|
837
874
|
return None
|
|
838
875
|
except (IOError, OSError) as e:
|
|
839
|
-
|
|
876
|
+
logger.error("EncodeFile: Failed to open file: %s", e.strerror)
|
|
840
877
|
raise Exception("EncodeFile")
|
|
841
878
|
finally:
|
|
842
879
|
if isinstance(f, IOBase):
|
|
@@ -859,17 +896,17 @@ def check_url_modified(url):
|
|
|
859
896
|
if resp.status_code == 200:
|
|
860
897
|
return True
|
|
861
898
|
except requests.exceptions.HTTPError:
|
|
862
|
-
|
|
899
|
+
logger.error(
|
|
863
900
|
"Requests: HTTPError: status code %s for %s",
|
|
864
901
|
str(resp.status_code) if resp else None,
|
|
865
902
|
url,
|
|
866
903
|
)
|
|
867
904
|
except requests.exceptions.Timeout:
|
|
868
|
-
|
|
905
|
+
logger.error("Requests: Timeout for %s", url)
|
|
869
906
|
except requests.exceptions.TooManyRedirects:
|
|
870
|
-
|
|
907
|
+
logger.error("Requests: TooManyRedirects for %s", url)
|
|
871
908
|
except requests.ConnectionError:
|
|
872
|
-
|
|
909
|
+
logger.error("Requests: ConnectionError for %s", url)
|
|
873
910
|
return False
|
|
874
911
|
|
|
875
912
|
|
|
@@ -895,7 +932,7 @@ def get_url_path_filename(url):
|
|
|
895
932
|
if name[n].endswith("."):
|
|
896
933
|
return name
|
|
897
934
|
except IndexError:
|
|
898
|
-
|
|
935
|
+
logger.error("Range: IndexError: URL basename is short: %s of %s", name, url)
|
|
899
936
|
return None
|
|
900
937
|
return None
|
|
901
938
|
|
|
@@ -915,16 +952,16 @@ def get_url_filename(url):
|
|
|
915
952
|
return name
|
|
916
953
|
return None
|
|
917
954
|
except requests.exceptions.MissingSchema:
|
|
918
|
-
|
|
955
|
+
logger.error("Requests: MissingSchema: Requires ftp|http(s):// for %s", url)
|
|
919
956
|
except requests.exceptions.HTTPError:
|
|
920
|
-
|
|
957
|
+
logger.error(
|
|
921
958
|
"Requests: HTTPError: status code %s for %s",
|
|
922
959
|
str(resp.status_code) if resp else None,
|
|
923
960
|
url,
|
|
924
961
|
)
|
|
925
962
|
except requests.exceptions.Timeout:
|
|
926
|
-
|
|
963
|
+
logger.error("Requests: Timeout for %s", url)
|
|
927
964
|
except requests.exceptions.TooManyRedirects:
|
|
928
|
-
|
|
965
|
+
logger.error("Requests: TooManyRedirects for %s", url)
|
|
929
966
|
except requests.ConnectionError:
|
|
930
|
-
|
|
967
|
+
logger.error("Requests: ConnectionError for %s", url)
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import json
|
|
2
|
+
from pathlib import Path
|
|
2
3
|
|
|
3
|
-
import pkg_resources
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
def load_schema(file_name):
|
|
5
|
+
def load_schema(file_name: str) -> dict:
|
|
7
6
|
"""
|
|
8
7
|
Loads a json schema from the packages data folder.
|
|
9
8
|
:param file_name: name of the file
|
|
10
9
|
:return: JSON object as a dictionary
|
|
11
10
|
"""
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
schema = json.loads(schema)
|
|
18
|
-
return schema
|
|
12
|
+
with open(
|
|
13
|
+
Path(__file__).parent / "data" / file_name, "r", encoding="utf-8"
|
|
14
|
+
) as schema_file:
|
|
15
|
+
return json.loads(schema_file.read())
|
|
19
16
|
|
|
20
17
|
|
|
21
18
|
input_message_schema = load_schema("input_message_schema.json")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
2
|
Name: insightconnect-plugin-runtime
|
|
3
|
-
Version: 6.2.
|
|
3
|
+
Version: 6.2.3
|
|
4
4
|
Summary: InsightConnect Plugin Runtime
|
|
5
5
|
Home-page: https://github.com/rapid7/komand-plugin-sdk-python
|
|
6
6
|
Author: Rapid7 Integrations Alliance
|
|
@@ -12,20 +12,28 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
12
12
|
Classifier: Natural Language :: English
|
|
13
13
|
Classifier: Topic :: Software Development :: Build Tools
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
|
-
Requires-Dist: requests==2.32.
|
|
15
|
+
Requires-Dist: requests==2.32.3
|
|
16
16
|
Requires-Dist: python_jsonschema_objects==0.5.2
|
|
17
|
-
Requires-Dist: jsonschema==4.
|
|
18
|
-
Requires-Dist: certifi==2024.
|
|
19
|
-
Requires-Dist: Flask==3.0
|
|
20
|
-
Requires-Dist: gunicorn==
|
|
17
|
+
Requires-Dist: jsonschema==4.22.0
|
|
18
|
+
Requires-Dist: certifi==2024.12.14
|
|
19
|
+
Requires-Dist: Flask==3.1.0
|
|
20
|
+
Requires-Dist: gunicorn==23.0.0
|
|
21
21
|
Requires-Dist: greenlet==3.1.1
|
|
22
|
-
Requires-Dist: gevent==24.
|
|
22
|
+
Requires-Dist: gevent==24.11.1
|
|
23
23
|
Requires-Dist: marshmallow==3.21.0
|
|
24
24
|
Requires-Dist: apispec==6.5.0
|
|
25
25
|
Requires-Dist: apispec-webframeworks==1.0.0
|
|
26
|
-
Requires-Dist: blinker==1.
|
|
27
|
-
Requires-Dist: structlog==24.
|
|
26
|
+
Requires-Dist: blinker==1.9.0
|
|
27
|
+
Requires-Dist: structlog==24.4.0
|
|
28
28
|
Requires-Dist: python-json-logger==2.0.7
|
|
29
|
+
Dynamic: author
|
|
30
|
+
Dynamic: author-email
|
|
31
|
+
Dynamic: classifier
|
|
32
|
+
Dynamic: description
|
|
33
|
+
Dynamic: description-content-type
|
|
34
|
+
Dynamic: home-page
|
|
35
|
+
Dynamic: requires-dist
|
|
36
|
+
Dynamic: summary
|
|
29
37
|
|
|
30
38
|
|
|
31
39
|
# InsightConnect Python Plugin Runtime 
|
|
@@ -48,10 +56,10 @@ to get started.
|
|
|
48
56
|
|
|
49
57
|
## Development of the InsightConnect Plugin Runtime
|
|
50
58
|
|
|
51
|
-
The Python Runtime codebase is built to support Python 3.11.
|
|
59
|
+
The Python Runtime codebase is built to support Python 3.11.11 as of version 6.2.3. The following dependencies will need
|
|
52
60
|
to be installed when developing or testing the Plugin Runtime:
|
|
53
61
|
|
|
54
|
-
- Python 3.11.
|
|
62
|
+
- Python 3.11.11
|
|
55
63
|
- Docker
|
|
56
64
|
- make
|
|
57
65
|
- tox
|
|
@@ -67,7 +75,7 @@ version and activate it. Then build, install, and confirm the package has been i
|
|
|
67
75
|
> source venv/bin/activate
|
|
68
76
|
> pip install -e ./
|
|
69
77
|
> pip list | grep insightconnect-plugin-runtime
|
|
70
|
-
insightconnect-plugin-runtime
|
|
78
|
+
insightconnect-plugin-runtime 6.2.3
|
|
71
79
|
```
|
|
72
80
|
|
|
73
81
|
#### Building the InsightConnect Plugin Runtime Docker Images
|
|
@@ -123,7 +131,7 @@ name as a parameter:
|
|
|
123
131
|
|
|
124
132
|
The plugin will be started in `http` mode and listening at `http:0.0.0.0:10001`:
|
|
125
133
|
```
|
|
126
|
-
[2020-02-13 23:21:13 -0500] [56567] [INFO] Starting gunicorn
|
|
134
|
+
[2020-02-13 23:21:13 -0500] [56567] [INFO] Starting gunicorn 23.0.0
|
|
127
135
|
[2020-02-13 23:21:13 -0500] [56567] [INFO] Listening at: http://0.0.0.0:10001 (56567)
|
|
128
136
|
[2020-02-13 23:21:13 -0500] [56567] [INFO] Using worker: threads
|
|
129
137
|
[2020-02-13 23:21:13 -0500] [56571] [INFO] Booting worker with pid: 56571
|
|
@@ -184,7 +192,7 @@ Running a specific test file:
|
|
|
184
192
|
|
|
185
193
|
| | Plugin | Slim Plugin |
|
|
186
194
|
|:------------------|:-------:|:-----------:|
|
|
187
|
-
| Python Version | 3.11.
|
|
195
|
+
| Python Version | 3.11.11 | 3.11.11 |
|
|
188
196
|
| OS | Alpine | Bullseye |
|
|
189
197
|
| Package installer | apk | apt |
|
|
190
198
|
| Shell | /bin/sh | /bin/bash |
|
|
@@ -211,6 +219,8 @@ contributed. Black is installed as a test dependency and the hook can be initial
|
|
|
211
219
|
after cloning this repository.
|
|
212
220
|
|
|
213
221
|
## Changelog
|
|
222
|
+
* 6.2.3 - Updated dockerfiles for both `slim` and `full` SDK types to use Python 3.11.11 | Updated dependencies | Removed `pkg_resources` usage due to deprecation
|
|
223
|
+
* 6.2.2 - Fix instances where logging errors would lead to duplicate entries being output | Add option to hash only on provided keys for `hash_sha1` function
|
|
214
224
|
* 6.2.1 - Fix instances where logging would lead to duplicate entries being output
|
|
215
225
|
* 6.2.0 - Update base images to pull Python 3.11.10 | changed the pep-8 check in tox to `pycodestyle`
|
|
216
226
|
* 6.1.4 - Address vulnerabilities within local development requirements.txt and vulnerabilities in slim image.
|
|
@@ -4,10 +4,10 @@ insightconnect_plugin_runtime/cli.py,sha256=Pb-Janu-XfRlSXxPHh30OIquljWptrhhS51C
|
|
|
4
4
|
insightconnect_plugin_runtime/connection.py,sha256=4bHHV2B0UFGsAtvLu1fiYQRwx7fissUakHPUyjLQO0E,2340
|
|
5
5
|
insightconnect_plugin_runtime/dispatcher.py,sha256=ru7njnyyWE1-oD-VbZJ-Z8tELwvDf69rM7Iezs4rbnw,1774
|
|
6
6
|
insightconnect_plugin_runtime/exceptions.py,sha256=Pvcdkx81o6qC2qU661x-DzNjuIMP82x52nPMSEqEo4s,8491
|
|
7
|
-
insightconnect_plugin_runtime/helper.py,sha256=
|
|
7
|
+
insightconnect_plugin_runtime/helper.py,sha256=WiCFu4S33BL8wugBmyFH-06inkcXPmdC5cv0UGlSHfA,32646
|
|
8
8
|
insightconnect_plugin_runtime/metrics.py,sha256=hf_Aoufip_s4k4o8Gtzz90ymZthkaT2e5sXh5B4LcF0,3186
|
|
9
9
|
insightconnect_plugin_runtime/plugin.py,sha256=Yf4LNczykDVc31F9G8uuJ9gxEsgmxmAr0n4pcZzichM,26393
|
|
10
|
-
insightconnect_plugin_runtime/schema.py,sha256=
|
|
10
|
+
insightconnect_plugin_runtime/schema.py,sha256=6MVw5hqGATU1VLgwfOWfPsP3hy1OnsugCTsgX8sknes,521
|
|
11
11
|
insightconnect_plugin_runtime/server.py,sha256=09fxsbKf2ZZvSqRP2Bv9e9-fspDyEFR8_YgIFeMnXqQ,12578
|
|
12
12
|
insightconnect_plugin_runtime/step.py,sha256=KdERg-789-s99IEKN61DR08naz-YPxyinPT0C_T81C4,855
|
|
13
13
|
insightconnect_plugin_runtime/task.py,sha256=d-H1EAzVnmSdDEJtXyIK5JySprxpF9cetVoFGtWlHrg,123
|
|
@@ -15,7 +15,7 @@ insightconnect_plugin_runtime/trigger.py,sha256=Zq3cy68N3QxAGbNZKCID6CZF05Zi7YD2
|
|
|
15
15
|
insightconnect_plugin_runtime/util.py,sha256=qPkZ3LA55nYuNYdansEbnCnBccQkpzIpp9NA1B64Kvw,8444
|
|
16
16
|
insightconnect_plugin_runtime/variables.py,sha256=7FjJGnU7KUR7m9o-_tRq7Q3KiaB1Pp0Apj1NGgOwrJk,3056
|
|
17
17
|
insightconnect_plugin_runtime/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
insightconnect_plugin_runtime/api/endpoints.py,sha256=
|
|
18
|
+
insightconnect_plugin_runtime/api/endpoints.py,sha256=8QQrxzW8jmQIkalud8fqYwB05uUw8sTiDNgO5ZekOCA,33353
|
|
19
19
|
insightconnect_plugin_runtime/api/schemas.py,sha256=jRmDrwLJTBl-iQOnyZkSwyJlCWg4eNjAnKfD9Eko4z0,2754
|
|
20
20
|
insightconnect_plugin_runtime/clients/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
21
|
insightconnect_plugin_runtime/clients/aws_client.py,sha256=bgSK3Txr1YonDiUN5JFEZ5cAyCXFM14JjfMus6lRV8o,23017
|
|
@@ -68,7 +68,7 @@ tests/unit/test_aws_action.py,sha256=pBE23Qn4aXKJqPmwiHMcEU5zPdyvbKO-eK-6jUlrsQw
|
|
|
68
68
|
tests/unit/test_custom_encoder.py,sha256=KLYyVOTq9MEkZXyhVHqjm5LVSW6uJS4Davgghsw9DGk,2207
|
|
69
69
|
tests/unit/test_endpoints.py,sha256=LuXOfLBu47rDjGa5YEsOwTZBEdvQdl_C6-r46oxWZA8,6401
|
|
70
70
|
tests/unit/test_exceptions.py,sha256=Y4F-ij8WkEJkUU3mPvxlEchqE9NCdxDvR8bJzPVVNao,5328
|
|
71
|
-
tests/unit/test_helpers.py,sha256=
|
|
71
|
+
tests/unit/test_helpers.py,sha256=9Y5N5cUBtesfr289oOZFekMJb84VYuFjucqQ9VEk3WQ,17431
|
|
72
72
|
tests/unit/test_metrics.py,sha256=PjjTrB9w7uQ2Q5UN-893-SsH3EGJuBseOMHSD1I004s,7979
|
|
73
73
|
tests/unit/test_oauth.py,sha256=nbFG0JH1x04ExXqSe-b5BGdt_hJs7DP17eUa6bQzcYI,2093
|
|
74
74
|
tests/unit/test_plugin.py,sha256=ZTNAZWwZhDIAbxkVuWhnz9FzmojbijgMmsLWM2mXQI0,4160
|
|
@@ -78,7 +78,7 @@ tests/unit/test_server_spec.py,sha256=je97BaktgK0Fiz3AwFPkcmHzYtOJJNqJV_Fw5hrvqX
|
|
|
78
78
|
tests/unit/test_trigger.py,sha256=E53mAUoVyponWu_4IQZ0IC1gQ9lakBnTn_9vKN2IZfg,1692
|
|
79
79
|
tests/unit/test_variables.py,sha256=OUEOqGYZA3Nd5oKk5GVY3hcrWKHpZpxysBJcO_v5gzs,291
|
|
80
80
|
tests/unit/utils.py,sha256=VooVmfpIgxmglNdtmT32AkEDFxHxyRHLK8RsCWjjYRY,2153
|
|
81
|
-
insightconnect_plugin_runtime-6.2.
|
|
82
|
-
insightconnect_plugin_runtime-6.2.
|
|
83
|
-
insightconnect_plugin_runtime-6.2.
|
|
84
|
-
insightconnect_plugin_runtime-6.2.
|
|
81
|
+
insightconnect_plugin_runtime-6.2.3.dist-info/METADATA,sha256=m0fZClkhAwEVwvC34tDdEfursS7-CuHs5bhYZJNJab8,15610
|
|
82
|
+
insightconnect_plugin_runtime-6.2.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
83
|
+
insightconnect_plugin_runtime-6.2.3.dist-info/top_level.txt,sha256=AJtyJOpiFzHxsbHUICTcUKXyrGQ3tZxhrEHsPjJBvEA,36
|
|
84
|
+
insightconnect_plugin_runtime-6.2.3.dist-info/RECORD,,
|
tests/unit/test_helpers.py
CHANGED
|
@@ -510,20 +510,46 @@ class TestRequestsHelpers(TestCase):
|
|
|
510
510
|
)
|
|
511
511
|
|
|
512
512
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
513
|
+
class TestHashing(TestCase):
|
|
514
|
+
def setUp(self) -> None:
|
|
515
|
+
self.log = {"example": "value", "sample": "value"}
|
|
516
|
+
|
|
517
|
+
def test_hash_sha1_no_keys(self):
|
|
518
|
+
# Test hash with no keys provided
|
|
519
|
+
expected_hash = "2e1ccc1a95e9b2044f13546c25fe380bbd039293"
|
|
520
|
+
self.assertEqual(helper.hash_sha1(self.log), expected_hash)
|
|
521
|
+
|
|
522
|
+
def test_hash_sha1_keys(self):
|
|
523
|
+
# Test hash with valid key provided
|
|
524
|
+
expected_hash = "61c908e52d66a763ceed0798b8e5f4b7f0328a21"
|
|
525
|
+
self.assertEqual(helper.hash_sha1(self.log, keys=["example"]), expected_hash)
|
|
526
|
+
|
|
527
|
+
def test_hash_sha1_keys_wrong_type(self):
|
|
528
|
+
# Test hash with wrong type for keys
|
|
529
|
+
with self.assertRaises(TypeError) as context:
|
|
530
|
+
helper.hash_sha1(self.log, keys="test")
|
|
531
|
+
|
|
532
|
+
self.assertEqual(
|
|
533
|
+
str(context.exception),
|
|
534
|
+
"The 'keys' parameter must be a list or None in the 'hash_sha1' function, not str"
|
|
535
|
+
)
|
|
536
|
+
|
|
537
|
+
def test_hash_sha1_keys_not_found(self):
|
|
538
|
+
# Test hash with key not found
|
|
539
|
+
with self.assertRaises(KeyError) as context:
|
|
540
|
+
helper.hash_sha1(self.log, keys=["example", "test"])
|
|
541
|
+
|
|
542
|
+
self.assertEqual(str(context.exception), "\"Key 'test' not found in the provided log.\"")
|
|
543
|
+
|
|
544
|
+
def test_compare_and_dedupe_hashes(self):
|
|
545
|
+
hashes = ["2e1ccc1a95e9b2044f13546c25fe380bbd039293"]
|
|
546
|
+
logs = [
|
|
547
|
+
{
|
|
548
|
+
"example": "value",
|
|
549
|
+
"sample": "value",
|
|
550
|
+
},
|
|
551
|
+
{"specimen": "new_value"},
|
|
552
|
+
]
|
|
553
|
+
assert [{"specimen": "new_value"}], [
|
|
554
|
+
"ad6ae80c0356e02b1561cb58408ee678eb1070bb"
|
|
555
|
+
] == helper.compare_and_dedupe_hashes(hashes, logs)
|
|
File without changes
|