insightconnect-plugin-runtime 6.2.1__tar.gz → 6.2.3__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.
Files changed (91) hide show
  1. {insightconnect_plugin_runtime-6.2.1/insightconnect_plugin_runtime.egg-info → insightconnect_plugin_runtime-6.2.3}/PKG-INFO +25 -15
  2. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/README.md +7 -5
  3. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/api/endpoints.py +14 -15
  4. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/helper.py +69 -32
  5. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/schema.py +6 -9
  6. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3/insightconnect_plugin_runtime.egg-info}/PKG-INFO +25 -15
  7. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime.egg-info/requires.txt +8 -8
  8. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/setup.py +9 -9
  9. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_helpers.py +43 -17
  10. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/MANIFEST.in +0 -0
  11. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect-plugin-swagger.json +0 -0
  12. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/__init__.py +0 -0
  13. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/action.py +0 -0
  14. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/api/__init__.py +0 -0
  15. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/api/schemas.py +0 -0
  16. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/cli.py +0 -0
  17. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/clients/__init__.py +0 -0
  18. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/clients/aws_client.py +0 -0
  19. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/clients/oauth.py +0 -0
  20. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/connection.py +0 -0
  21. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/data/input_message_schema.json +0 -0
  22. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/data/output_message_schema.json +0 -0
  23. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/dispatcher.py +0 -0
  24. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/exceptions.py +0 -0
  25. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/metrics.py +0 -0
  26. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/plugin.py +0 -0
  27. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/server.py +0 -0
  28. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/step.py +0 -0
  29. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/task.py +0 -0
  30. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/trigger.py +0 -0
  31. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/util.py +0 -0
  32. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime/variables.py +0 -0
  33. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime.egg-info/SOURCES.txt +0 -0
  34. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime.egg-info/dependency_links.txt +0 -0
  35. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/insightconnect_plugin_runtime.egg-info/top_level.txt +0 -0
  36. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/setup.cfg +0 -0
  37. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/__init__.py +0 -0
  38. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/__init__.py +0 -0
  39. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/__init__.py +0 -0
  40. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/__init__.py +0 -0
  41. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/__init__.py +0 -0
  42. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/__init__.py +0 -0
  43. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/hello/__init__.py +0 -0
  44. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/hello/action.py +0 -0
  45. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/hello/schema.py +0 -0
  46. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/return_bad_json/__init__.py +0 -0
  47. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/return_bad_json/action.py +0 -0
  48. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/return_bad_json/schema.py +0 -0
  49. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/throw_exception/__init__.py +0 -0
  50. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/throw_exception/action.py +0 -0
  51. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/throw_exception/schema.py +0 -0
  52. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/connection/__init__.py +0 -0
  53. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/connection/connection.py +0 -0
  54. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/connection/schema.py +0 -0
  55. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/tasks/__init__.py +0 -0
  56. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/tasks/monitor_events/__init__.py +0 -0
  57. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/tasks/monitor_events/schema.py +0 -0
  58. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/tasks/monitor_events/task.py +0 -0
  59. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/__init__.py +0 -0
  60. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/hello_trigger/__init__.py +0 -0
  61. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/hello_trigger/schema.py +0 -0
  62. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/hello_trigger/trigger.py +0 -0
  63. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/return_bad_json_trigger/__init__.py +0 -0
  64. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/return_bad_json_trigger/schema.py +0 -0
  65. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/return_bad_json_trigger/trigger.py +0 -0
  66. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/throw_exception_trigger/__init__.py +0 -0
  67. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/throw_exception_trigger/schema.py +0 -0
  68. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/throw_exception_trigger/trigger.py +0 -0
  69. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/komand_hello_world/util/__init__.py +0 -0
  70. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/hello_world/setup.py +0 -0
  71. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/tests/__init__.py +0 -0
  72. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/tests/conftest.py +0 -0
  73. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/tests/test_cli.py +0 -0
  74. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/tests/test_hello_world.py +0 -0
  75. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/plugin/hello_world/tests/test_server.py +0 -0
  76. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/__init__.py +0 -0
  77. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_action.py +0 -0
  78. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_api.py +0 -0
  79. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_aws_action.py +0 -0
  80. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_custom_encoder.py +0 -0
  81. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_endpoints.py +0 -0
  82. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_exceptions.py +0 -0
  83. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_metrics.py +0 -0
  84. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_oauth.py +0 -0
  85. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_plugin.py +0 -0
  86. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_schema.py +0 -0
  87. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_server_cloud_plugins.py +0 -0
  88. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_server_spec.py +0 -0
  89. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_trigger.py +0 -0
  90. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/test_variables.py +0 -0
  91. {insightconnect_plugin_runtime-6.2.1 → insightconnect_plugin_runtime-6.2.3}/tests/unit/utils.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: insightconnect-plugin-runtime
3
- Version: 6.2.1
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.2
15
+ Requires-Dist: requests==2.32.3
16
16
  Requires-Dist: python_jsonschema_objects==0.5.2
17
- Requires-Dist: jsonschema==4.21.1
18
- Requires-Dist: certifi==2024.07.04
19
- Requires-Dist: Flask==3.0.2
20
- Requires-Dist: gunicorn==22.0.0
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.10.1
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.7.0
27
- Requires-Dist: structlog==24.1.0
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 ![Build Status](https://github.com/rapid7/komand-plugin-sdk-python/workflows/Continuous%20Integration/badge.svg)
@@ -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.10 as of version 6.2.0. The following dependencies will need
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.10
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 5.2.2
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 19.7.1
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.10 | 3.11.10 |
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.
@@ -19,10 +19,10 @@ to get started.
19
19
 
20
20
  ## Development of the InsightConnect Plugin Runtime
21
21
 
22
- The Python Runtime codebase is built to support Python 3.11.10 as of version 6.2.0. The following dependencies will need
22
+ The Python Runtime codebase is built to support Python 3.11.11 as of version 6.2.3. The following dependencies will need
23
23
  to be installed when developing or testing the Plugin Runtime:
24
24
 
25
- - Python 3.11.10
25
+ - Python 3.11.11
26
26
  - Docker
27
27
  - make
28
28
  - tox
@@ -38,7 +38,7 @@ version and activate it. Then build, install, and confirm the package has been i
38
38
  > source venv/bin/activate
39
39
  > pip install -e ./
40
40
  > pip list | grep insightconnect-plugin-runtime
41
- insightconnect-plugin-runtime 5.2.2
41
+ insightconnect-plugin-runtime 6.2.3
42
42
  ```
43
43
 
44
44
  #### Building the InsightConnect Plugin Runtime Docker Images
@@ -94,7 +94,7 @@ name as a parameter:
94
94
 
95
95
  The plugin will be started in `http` mode and listening at `http:0.0.0.0:10001`:
96
96
  ```
97
- [2020-02-13 23:21:13 -0500] [56567] [INFO] Starting gunicorn 19.7.1
97
+ [2020-02-13 23:21:13 -0500] [56567] [INFO] Starting gunicorn 23.0.0
98
98
  [2020-02-13 23:21:13 -0500] [56567] [INFO] Listening at: http://0.0.0.0:10001 (56567)
99
99
  [2020-02-13 23:21:13 -0500] [56567] [INFO] Using worker: threads
100
100
  [2020-02-13 23:21:13 -0500] [56571] [INFO] Booting worker with pid: 56571
@@ -155,7 +155,7 @@ Running a specific test file:
155
155
 
156
156
  | | Plugin | Slim Plugin |
157
157
  |:------------------|:-------:|:-----------:|
158
- | Python Version | 3.11.10 | 3.11.10 |
158
+ | Python Version | 3.11.11 | 3.11.11 |
159
159
  | OS | Alpine | Bullseye |
160
160
  | Package installer | apk | apt |
161
161
  | Shell | /bin/sh | /bin/bash |
@@ -182,6 +182,8 @@ contributed. Black is installed as a test dependency and the hook can be initial
182
182
  after cloning this repository.
183
183
 
184
184
  ## Changelog
185
+ * 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
186
+ * 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
185
187
  * 6.2.1 - Fix instances where logging would lead to duplicate entries being output
186
188
  * 6.2.0 - Update base images to pull Python 3.11.10 | changed the pep-8 check in tox to `pycodestyle`
187
189
  * 6.1.4 - Address vulnerabilities within local development requirements.txt and vulnerabilities in slim image.
@@ -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
- from flask import jsonify, request, abort, make_response, Blueprint
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 = pkg_resources.require("insightconnect-plugin-runtime")[0].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
- :type Dict:
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
- for key, value in log.items():
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(response, exception_custom_configs, exception_data_location, allowed_status_codes)
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
- convert_dict_to_snake_case(element)
447
- if isinstance(element, (dict, list))
448
- else element
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): convert_dict_to_snake_case(value)
453
- if isinstance(value, (dict, list))
454
- else value
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
- logging.error("OpenCacheFile: %s directory or does not exist", cache_dir)
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
- logging.error("HTTPError: %s for %s", str(e.code), url)
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
- logging.error("URLError: %s for %s", str(e.reason), url)
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
- logging.error(
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
- logging.error("Requests: Timeout for %s", url)
826
+ logger.error("Requests: Timeout for %s", url)
790
827
  except requests.exceptions.TooManyRedirects:
791
- logging.error("Requests: TooManyRedirects for %s", url)
828
+ logger.error("Requests: TooManyRedirects for %s", url)
792
829
  except requests.ConnectionError:
793
- logging.error("Requests: ConnectionError for %s", url)
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
- logging.error(
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
- logging.error("EncodeFile: Failed to open file: %s", e.strerror)
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
- logging.error(
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
- logging.error("Requests: Timeout for %s", url)
905
+ logger.error("Requests: Timeout for %s", url)
869
906
  except requests.exceptions.TooManyRedirects:
870
- logging.error("Requests: TooManyRedirects for %s", url)
907
+ logger.error("Requests: TooManyRedirects for %s", url)
871
908
  except requests.ConnectionError:
872
- logging.error("Requests: ConnectionError for %s", url)
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
- logging.error("Range: IndexError: URL basename is short: %s of %s", name, url)
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
- logging.error("Requests: MissingSchema: Requires ftp|http(s):// for %s", url)
955
+ logger.error("Requests: MissingSchema: Requires ftp|http(s):// for %s", url)
919
956
  except requests.exceptions.HTTPError:
920
- logging.error(
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
- logging.error("Requests: Timeout for %s", url)
963
+ logger.error("Requests: Timeout for %s", url)
927
964
  except requests.exceptions.TooManyRedirects:
928
- logging.error("Requests: TooManyRedirects for %s", url)
965
+ logger.error("Requests: TooManyRedirects for %s", url)
929
966
  except requests.ConnectionError:
930
- logging.error("Requests: ConnectionError for %s", url)
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
- schema = pkg_resources.resource_stream(__name__, "/".join(("data", file_name)))
14
- schema = schema.read()
15
- if isinstance(schema, bytes):
16
- schema = schema.decode("utf-8")
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
1
+ Metadata-Version: 2.2
2
2
  Name: insightconnect-plugin-runtime
3
- Version: 6.2.1
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.2
15
+ Requires-Dist: requests==2.32.3
16
16
  Requires-Dist: python_jsonschema_objects==0.5.2
17
- Requires-Dist: jsonschema==4.21.1
18
- Requires-Dist: certifi==2024.07.04
19
- Requires-Dist: Flask==3.0.2
20
- Requires-Dist: gunicorn==22.0.0
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.10.1
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.7.0
27
- Requires-Dist: structlog==24.1.0
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 ![Build Status](https://github.com/rapid7/komand-plugin-sdk-python/workflows/Continuous%20Integration/badge.svg)
@@ -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.10 as of version 6.2.0. The following dependencies will need
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.10
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 5.2.2
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 19.7.1
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.10 | 3.11.10 |
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.
@@ -1,14 +1,14 @@
1
- requests==2.32.2
1
+ requests==2.32.3
2
2
  python_jsonschema_objects==0.5.2
3
- jsonschema==4.21.1
4
- certifi==2024.07.04
5
- Flask==3.0.2
6
- gunicorn==22.0.0
3
+ jsonschema==4.22.0
4
+ certifi==2024.12.14
5
+ Flask==3.1.0
6
+ gunicorn==23.0.0
7
7
  greenlet==3.1.1
8
- gevent==24.10.1
8
+ gevent==24.11.1
9
9
  marshmallow==3.21.0
10
10
  apispec==6.5.0
11
11
  apispec-webframeworks==1.0.0
12
- blinker==1.7.0
13
- structlog==24.1.0
12
+ blinker==1.9.0
13
+ structlog==24.4.0
14
14
  python-json-logger==2.0.7
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name="insightconnect-plugin-runtime",
8
- version="6.2.1",
8
+ version="6.2.3",
9
9
  description="InsightConnect Plugin Runtime",
10
10
  long_description=long_description,
11
11
  long_description_content_type="text/markdown",
@@ -14,19 +14,19 @@ setup(
14
14
  url="https://github.com/rapid7/komand-plugin-sdk-python",
15
15
  packages=find_packages(),
16
16
  install_requires=[
17
- "requests==2.32.2",
17
+ "requests==2.32.3",
18
18
  "python_jsonschema_objects==0.5.2",
19
- "jsonschema==4.21.1",
20
- "certifi==2024.07.04",
21
- "Flask==3.0.2",
22
- "gunicorn==22.0.0",
19
+ "jsonschema==4.22.0",
20
+ "certifi==2024.12.14",
21
+ "Flask==3.1.0",
22
+ "gunicorn==23.0.0",
23
23
  "greenlet==3.1.1",
24
- "gevent==24.10.1",
24
+ "gevent==24.11.1",
25
25
  "marshmallow==3.21.0",
26
26
  "apispec==6.5.0",
27
27
  "apispec-webframeworks==1.0.0",
28
- "blinker==1.7.0",
29
- "structlog==24.1.0",
28
+ "blinker==1.9.0",
29
+ "structlog==24.4.0",
30
30
  "python-json-logger==2.0.7"
31
31
  ],
32
32
  tests_require=[
@@ -510,20 +510,46 @@ class TestRequestsHelpers(TestCase):
510
510
  )
511
511
 
512
512
 
513
- def test_hash_sha1():
514
- log = {"example": "value", "sample": "value"}
515
- assert "2e1ccc1a95e9b2044f13546c25fe380bbd039293" == helper.hash_sha1(log)
516
-
517
-
518
- def test_compare_and_dedupe_hashes():
519
- hashes = ["2e1ccc1a95e9b2044f13546c25fe380bbd039293"]
520
- logs = [
521
- {
522
- "example": "value",
523
- "sample": "value",
524
- },
525
- {"specimen": "new_value"},
526
- ]
527
- assert [{"specimen": "new_value"}], [
528
- "ad6ae80c0356e02b1561cb58408ee678eb1070bb"
529
- ] == helper.compare_and_dedupe_hashes(hashes, logs)
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)