insightconnect-plugin-runtime 5.2.4__tar.gz → 5.3.1__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 (84) hide show
  1. {insightconnect-plugin-runtime-5.2.4/insightconnect_plugin_runtime.egg-info → insightconnect-plugin-runtime-5.3.1}/PKG-INFO +58 -12
  2. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/README.md +54 -8
  3. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect-plugin-swagger.json +55 -55
  4. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/api/endpoints.py +2 -0
  5. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/exceptions.py +10 -0
  6. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1/insightconnect_plugin_runtime.egg-info}/PKG-INFO +58 -12
  7. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime.egg-info/requires.txt +3 -3
  8. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/setup.py +4 -4
  9. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/__init__.py +15 -8
  10. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/hello_trigger/trigger.py +7 -1
  11. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/throw_exception_trigger/trigger.py +2 -2
  12. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/MANIFEST.in +0 -0
  13. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/__init__.py +0 -0
  14. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/action.py +0 -0
  15. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/api/__init__.py +0 -0
  16. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/api/schemas.py +0 -0
  17. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/cli.py +0 -0
  18. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/clients/__init__.py +0 -0
  19. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/clients/aws_client.py +0 -0
  20. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/clients/oauth.py +0 -0
  21. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/connection.py +0 -0
  22. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/data/input_message_schema.json +0 -0
  23. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/data/output_message_schema.json +0 -0
  24. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/dispatcher.py +0 -0
  25. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/helper.py +0 -0
  26. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/metrics.py +0 -0
  27. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/plugin.py +0 -0
  28. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/schema.py +0 -0
  29. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/server.py +0 -0
  30. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/step.py +0 -0
  31. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/task.py +0 -0
  32. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/trigger.py +0 -0
  33. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/util.py +0 -0
  34. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime/variables.py +0 -0
  35. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime.egg-info/SOURCES.txt +0 -0
  36. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime.egg-info/dependency_links.txt +0 -0
  37. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/insightconnect_plugin_runtime.egg-info/top_level.txt +0 -0
  38. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/setup.cfg +0 -0
  39. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/__init__.py +0 -0
  40. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/__init__.py +0 -0
  41. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/__init__.py +0 -0
  42. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/__init__.py +0 -0
  43. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/__init__.py +0 -0
  44. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/hello/__init__.py +0 -0
  45. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/hello/action.py +0 -0
  46. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/hello/schema.py +0 -0
  47. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/return_bad_json/__init__.py +0 -0
  48. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/return_bad_json/action.py +0 -0
  49. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/return_bad_json/schema.py +0 -0
  50. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/throw_exception/__init__.py +0 -0
  51. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/throw_exception/action.py +0 -0
  52. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/throw_exception/schema.py +0 -0
  53. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/connection/__init__.py +0 -0
  54. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/connection/connection.py +0 -0
  55. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/connection/schema.py +0 -0
  56. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/__init__.py +0 -0
  57. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/hello_trigger/__init__.py +0 -0
  58. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/hello_trigger/schema.py +0 -0
  59. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/return_bad_json_trigger/__init__.py +0 -0
  60. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/return_bad_json_trigger/schema.py +0 -0
  61. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/return_bad_json_trigger/trigger.py +0 -0
  62. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/throw_exception_trigger/__init__.py +0 -0
  63. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/throw_exception_trigger/schema.py +0 -0
  64. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/komand_hello_world/util/__init__.py +0 -0
  65. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/hello_world/setup.py +0 -0
  66. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/tests/__init__.py +0 -0
  67. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/tests/conftest.py +0 -0
  68. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/tests/test_cli.py +0 -0
  69. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/tests/test_hello_world.py +0 -0
  70. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/plugin/hello_world/tests/test_server.py +0 -0
  71. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/__init__.py +0 -0
  72. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_action.py +0 -0
  73. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_aws_action.py +0 -0
  74. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_custom_encoder.py +0 -0
  75. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_endpoints.py +0 -0
  76. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_exceptions.py +0 -0
  77. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_helpers.py +0 -0
  78. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_metrics.py +0 -0
  79. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_oauth.py +0 -0
  80. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_plugin.py +0 -0
  81. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_schema.py +0 -0
  82. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_server_spec.py +0 -0
  83. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_trigger.py +0 -0
  84. {insightconnect-plugin-runtime-5.2.4 → insightconnect-plugin-runtime-5.3.1}/tests/unit/test_variables.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: insightconnect-plugin-runtime
3
- Version: 5.2.4
3
+ Version: 5.3.1
4
4
  Summary: InsightConnect Plugin Runtime
5
5
  Home-page: https://github.com/rapid7/komand-plugin-sdk-python
6
6
  Author: Rapid7 Integrations Alliance
@@ -15,11 +15,11 @@ Description-Content-Type: text/markdown
15
15
  Requires-Dist: requests==2.31.0
16
16
  Requires-Dist: python_jsonschema_objects==0.3.12
17
17
  Requires-Dist: jsonschema==3.2.0
18
- Requires-Dist: certifi==2022.12.7
18
+ Requires-Dist: certifi==2023.7.22
19
19
  Requires-Dist: Flask==2.3.2
20
20
  Requires-Dist: gunicorn==20.0.4
21
- Requires-Dist: greenlet<=1.1.2,>=0.4.17
22
- Requires-Dist: gevent==20.9.0
21
+ Requires-Dist: greenlet==3.0.1
22
+ Requires-Dist: gevent==23.9.1
23
23
  Requires-Dist: marshmallow==3.4.0
24
24
  Requires-Dist: apispec==3.2.0
25
25
  Requires-Dist: apispec-webframeworks==0.5.2
@@ -48,10 +48,10 @@ to get started.
48
48
 
49
49
  ## Development of the InsightConnect Plugin Runtime
50
50
 
51
- The Python Runtime codebase is built to support Python 3.8+ as of version 4.0.0. The following dependencies will need
51
+ The Python Runtime codebase is built to support Python 3.9.18 as of version 5.3.0. The following dependencies will need
52
52
  to be installed when developing or testing the Plugin Runtime:
53
53
 
54
- - Python 3.8
54
+ - Python 3.9.18
55
55
  - Docker
56
56
  - make
57
57
  - tox
@@ -67,19 +67,51 @@ version and activate it. Then build, install, and confirm the package has been i
67
67
  > source venv/bin/activate
68
68
  > pip install -e ./
69
69
  > pip list | grep insightconnect-plugin-runtime
70
- insightconnect-plugin-runtime 4.0.0
70
+ insightconnect-plugin-runtime 5.2.2
71
71
  ```
72
72
 
73
73
  #### Building the InsightConnect Plugin Runtime Docker Images
74
74
 
75
- Currently the `3-38` dockerfile is used by default when building the docker image. If you want to specify another
76
- dockerfile for testing purposes, such as `3-38-slim`, you can pass it as an argument.
75
+ Currently the `python-3` dockerfile is used by default when building the docker image. If you want to specify another
76
+ dockerfile for testing purposes, such as `python-3-slim`, you can pass it as an argument.
77
77
 
78
78
  ```
79
- make build-image DOCKERFILE=3-38-slim
79
+ make build-image DOCKERFILE=python-3-slim
80
80
  ```
81
81
 
82
- This will overwrite the default `3-38`, provided that it exists in the `dockerfiles` directory.
82
+ This will overwrite the default `python-3`, provided that it exists in the `dockerfiles` directory.
83
+
84
+ #### Building/troubleshooting local images (Mac M1)
85
+
86
+ Our images are built with OS/ARCH:linux/amd64 due to our ci.yml file specifying linux. Historically this has
87
+ not caused any issues but with an M1 Mac, docker will now use arm64. This is because docker builds the image to match the
88
+ distribution of the OS running the command. To ensure that building locally and on GH produces an image of the same
89
+ architecture the `--platform` specifier is passed in the dockerfile.
90
+
91
+ If you build a plugin locally we can see further issues that:
92
+ - the local image does match the current OS distro so docker continues to look remotely..
93
+ - docker can not find this (newly created) image remotely on docker registry (dev images should not be pushed to registry)
94
+
95
+ To overcome this we need to specify `platform=linux/amd64` in the plugin docker file. E.g. if building plugins/html then
96
+ this file should be updated `plugins/html/Dockerfile`.
97
+ *Note*: building this arch on mac M1 will cause the build to be slower.
98
+
99
+
100
+ Example error of local image not matching OS distro without passing the `--platform` flag:
101
+ ```
102
+ => ERROR [internal] load metadata for docker.io/rapid7/insightconnect-python-3-slim-plugin:latest 1.4s
103
+ ------
104
+ > [internal] load metadata for docker.io/rapid7/insightconnect-python-3-slim-plugin:latest:
105
+ ------
106
+ Dockerfile:1
107
+ --------------------
108
+ 1 | >>> FROM rapid7/insightconnect-python-3-slim-plugin
109
+ 2 | LABEL organization=rapid7
110
+ 3 | LABEL sdk=python
111
+ --------------------
112
+ ERROR: failed to solve: rapid7/insightconnect-python-3-slim-plugin: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
113
+ make: *** [image] Error 1
114
+ ```
83
115
 
84
116
  ### Testing Sample Plugin
85
117
  The easiest way to test changes to the runtime is by running it locally against one of the [sample plugins](./samples)
@@ -145,9 +177,21 @@ Running all tests:
145
177
 
146
178
  Running a specific test file:
147
179
  ```
148
- > tox -e py38 -- tests/plugin/hello_world/tests/test_cli.py
180
+ > tox -e py39 -- tests/plugin/hello_world/tests/test_cli.py
149
181
  ```
150
182
 
183
+ ## Plugin vs Slim Plugin Comparison
184
+
185
+ | | Plugin | Slim Plugin |
186
+ |:------------------|:-------:|:-----------:|
187
+ | Python Version | 3.9.18 | 3.9.18 |
188
+ | OS | Alpine | Bullseye |
189
+ | Package installer | apk | apt |
190
+ | Shell | /bin/sh | /bin/bash |
191
+ | Image Size | ~350MB | ~180MB |
192
+
193
+ Note that for the plugin image, we run `apk update` and `apk add ..` which leads to a longer build time.
194
+
151
195
  ## Release
152
196
 
153
197
  To release a new version of the InsightConnect Python Plugin Runtime, the below steps must be followed:
@@ -168,6 +212,8 @@ after cloning this repository.
168
212
 
169
213
  ## Changelog
170
214
 
215
+ * 5.3.1 - New logging added to the beginning and end of a task | New logging when an exception is instantiated.
216
+ * 5.3.0 - Update base images to pull Python 3.9.18 | python packages bump | rename image to drop python minor version.
171
217
  * 5.2.4 - Extended logging with OrgID and IntID
172
218
  * 5.2.3 - Extended logging in AWSClient
173
219
  * 5.2.2 - Fix longstanding bug where some error responses from a plugin could be in HTML format instead of JSON
@@ -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.8+ as of version 4.0.0. The following dependencies will need
22
+ The Python Runtime codebase is built to support Python 3.9.18 as of version 5.3.0. The following dependencies will need
23
23
  to be installed when developing or testing the Plugin Runtime:
24
24
 
25
- - Python 3.8
25
+ - Python 3.9.18
26
26
  - Docker
27
27
  - make
28
28
  - tox
@@ -38,19 +38,51 @@ 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 4.0.0
41
+ insightconnect-plugin-runtime 5.2.2
42
42
  ```
43
43
 
44
44
  #### Building the InsightConnect Plugin Runtime Docker Images
45
45
 
46
- Currently the `3-38` dockerfile is used by default when building the docker image. If you want to specify another
47
- dockerfile for testing purposes, such as `3-38-slim`, you can pass it as an argument.
46
+ Currently the `python-3` dockerfile is used by default when building the docker image. If you want to specify another
47
+ dockerfile for testing purposes, such as `python-3-slim`, you can pass it as an argument.
48
48
 
49
49
  ```
50
- make build-image DOCKERFILE=3-38-slim
50
+ make build-image DOCKERFILE=python-3-slim
51
51
  ```
52
52
 
53
- This will overwrite the default `3-38`, provided that it exists in the `dockerfiles` directory.
53
+ This will overwrite the default `python-3`, provided that it exists in the `dockerfiles` directory.
54
+
55
+ #### Building/troubleshooting local images (Mac M1)
56
+
57
+ Our images are built with OS/ARCH:linux/amd64 due to our ci.yml file specifying linux. Historically this has
58
+ not caused any issues but with an M1 Mac, docker will now use arm64. This is because docker builds the image to match the
59
+ distribution of the OS running the command. To ensure that building locally and on GH produces an image of the same
60
+ architecture the `--platform` specifier is passed in the dockerfile.
61
+
62
+ If you build a plugin locally we can see further issues that:
63
+ - the local image does match the current OS distro so docker continues to look remotely..
64
+ - docker can not find this (newly created) image remotely on docker registry (dev images should not be pushed to registry)
65
+
66
+ To overcome this we need to specify `platform=linux/amd64` in the plugin docker file. E.g. if building plugins/html then
67
+ this file should be updated `plugins/html/Dockerfile`.
68
+ *Note*: building this arch on mac M1 will cause the build to be slower.
69
+
70
+
71
+ Example error of local image not matching OS distro without passing the `--platform` flag:
72
+ ```
73
+ => ERROR [internal] load metadata for docker.io/rapid7/insightconnect-python-3-slim-plugin:latest 1.4s
74
+ ------
75
+ > [internal] load metadata for docker.io/rapid7/insightconnect-python-3-slim-plugin:latest:
76
+ ------
77
+ Dockerfile:1
78
+ --------------------
79
+ 1 | >>> FROM rapid7/insightconnect-python-3-slim-plugin
80
+ 2 | LABEL organization=rapid7
81
+ 3 | LABEL sdk=python
82
+ --------------------
83
+ ERROR: failed to solve: rapid7/insightconnect-python-3-slim-plugin: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
84
+ make: *** [image] Error 1
85
+ ```
54
86
 
55
87
  ### Testing Sample Plugin
56
88
  The easiest way to test changes to the runtime is by running it locally against one of the [sample plugins](./samples)
@@ -116,9 +148,21 @@ Running all tests:
116
148
 
117
149
  Running a specific test file:
118
150
  ```
119
- > tox -e py38 -- tests/plugin/hello_world/tests/test_cli.py
151
+ > tox -e py39 -- tests/plugin/hello_world/tests/test_cli.py
120
152
  ```
121
153
 
154
+ ## Plugin vs Slim Plugin Comparison
155
+
156
+ | | Plugin | Slim Plugin |
157
+ |:------------------|:-------:|:-----------:|
158
+ | Python Version | 3.9.18 | 3.9.18 |
159
+ | OS | Alpine | Bullseye |
160
+ | Package installer | apk | apt |
161
+ | Shell | /bin/sh | /bin/bash |
162
+ | Image Size | ~350MB | ~180MB |
163
+
164
+ Note that for the plugin image, we run `apk update` and `apk add ..` which leads to a longer build time.
165
+
122
166
  ## Release
123
167
 
124
168
  To release a new version of the InsightConnect Python Plugin Runtime, the below steps must be followed:
@@ -139,6 +183,8 @@ after cloning this repository.
139
183
 
140
184
  ## Changelog
141
185
 
186
+ * 5.3.1 - New logging added to the beginning and end of a task | New logging when an exception is instantiated.
187
+ * 5.3.0 - Update base images to pull Python 3.9.18 | python packages bump | rename image to drop python minor version.
142
188
  * 5.2.4 - Extended logging with OrgID and IntID
143
189
  * 5.2.3 - Extended logging in AWSClient
144
190
  * 5.2.2 - Fix longstanding bug where some error responses from a plugin could be in HTML format instead of JSON
@@ -451,32 +451,36 @@
451
451
  "PluginInfo": {
452
452
  "type": "object",
453
453
  "properties": {
454
- "enable_cache": {
455
- "type": "boolean"
454
+ "sdk_version": {
455
+ "type": "string"
456
456
  },
457
- "threads": {
457
+ "title": {
458
+ "type": "string"
459
+ },
460
+ "number_of_workers": {
458
461
  "type": "integer",
459
462
  "format": "int32"
460
463
  },
461
- "plugin_spec_version": {
462
- "type": "string"
463
- },
464
- "name": {
464
+ "version": {
465
465
  "type": "string"
466
466
  },
467
- "sdk_version": {
467
+ "vendor": {
468
468
  "type": "string"
469
469
  },
470
- "support": {
471
- "type": "string"
470
+ "threads": {
471
+ "type": "integer",
472
+ "format": "int32"
472
473
  },
473
474
  "description": {
474
475
  "type": "string"
475
476
  },
476
- "title": {
477
+ "name": {
477
478
  "type": "string"
478
479
  },
479
- "vendor": {
480
+ "enable_cache": {
481
+ "type": "boolean"
482
+ },
483
+ "support": {
480
484
  "type": "string"
481
485
  },
482
486
  "tags": {
@@ -485,11 +489,7 @@
485
489
  "type": "string"
486
490
  }
487
491
  },
488
- "number_of_workers": {
489
- "type": "integer",
490
- "format": "int32"
491
- },
492
- "version": {
492
+ "plugin_spec_version": {
493
493
  "type": "string"
494
494
  }
495
495
  }
@@ -520,9 +520,6 @@
520
520
  "ActionTriggerOutput": {
521
521
  "type": "object",
522
522
  "properties": {
523
- "body": {
524
- "$ref": "#/definitions/ActionTriggerOutputBody"
525
- },
526
523
  "type": {
527
524
  "type": "string",
528
525
  "enum": [
@@ -532,6 +529,9 @@
532
529
  },
533
530
  "version": {
534
531
  "type": "string"
532
+ },
533
+ "body": {
534
+ "$ref": "#/definitions/ActionTriggerOutputBody"
535
535
  }
536
536
  },
537
537
  "required": [
@@ -546,16 +546,16 @@
546
546
  "status": {
547
547
  "type": "string"
548
548
  },
549
- "state": {
550
- "type": "object"
551
- },
552
- "meta": {
549
+ "output": {
553
550
  "type": "object"
554
551
  },
555
552
  "log": {
556
553
  "type": "string"
557
554
  },
558
- "output": {
555
+ "meta": {
556
+ "type": "object"
557
+ },
558
+ "state": {
559
559
  "type": "object"
560
560
  }
561
561
  },
@@ -570,9 +570,6 @@
570
570
  "TaskOutput": {
571
571
  "type": "object",
572
572
  "properties": {
573
- "body": {
574
- "$ref": "#/definitions/TaskOutputBody"
575
- },
576
573
  "type": {
577
574
  "type": "string",
578
575
  "enum": [
@@ -581,6 +578,9 @@
581
578
  },
582
579
  "version": {
583
580
  "type": "string"
581
+ },
582
+ "body": {
583
+ "$ref": "#/definitions/TaskOutputBody"
584
584
  }
585
585
  },
586
586
  "required": [
@@ -592,14 +592,14 @@
592
592
  "ActionTriggerInputBody": {
593
593
  "type": "object",
594
594
  "properties": {
595
- "action": {
596
- "type": "string"
597
- },
598
595
  "connection": {
599
596
  "type": "object"
600
597
  },
601
598
  "input": {
602
599
  "type": "object"
600
+ },
601
+ "action": {
602
+ "type": "string"
603
603
  }
604
604
  },
605
605
  "required": [
@@ -611,9 +611,6 @@
611
611
  "ActionTriggerInput": {
612
612
  "type": "object",
613
613
  "properties": {
614
- "body": {
615
- "$ref": "#/definitions/ActionTriggerInputBody"
616
- },
617
614
  "type": {
618
615
  "type": "string",
619
616
  "enum": [
@@ -623,6 +620,9 @@
623
620
  },
624
621
  "version": {
625
622
  "type": "string"
623
+ },
624
+ "body": {
625
+ "$ref": "#/definitions/ActionTriggerInputBody"
626
626
  }
627
627
  },
628
628
  "required": [
@@ -634,7 +634,7 @@
634
634
  "TaskInputBody": {
635
635
  "type": "object",
636
636
  "properties": {
637
- "input": {
637
+ "state": {
638
638
  "type": "object"
639
639
  },
640
640
  "connection": {
@@ -643,7 +643,7 @@
643
643
  "task": {
644
644
  "type": "string"
645
645
  },
646
- "state": {
646
+ "input": {
647
647
  "type": "object"
648
648
  }
649
649
  },
@@ -657,9 +657,6 @@
657
657
  "TaskInput": {
658
658
  "type": "object",
659
659
  "properties": {
660
- "body": {
661
- "$ref": "#/definitions/TaskInputBody"
662
- },
663
660
  "type": {
664
661
  "type": "string",
665
662
  "enum": [
@@ -668,6 +665,9 @@
668
665
  },
669
666
  "version": {
670
667
  "type": "string"
668
+ },
669
+ "body": {
670
+ "$ref": "#/definitions/TaskInputBody"
671
671
  }
672
672
  },
673
673
  "required": [
@@ -679,15 +679,15 @@
679
679
  "ActionTriggerDetails": {
680
680
  "type": "object",
681
681
  "properties": {
682
+ "input": {
683
+ "type": "object"
684
+ },
682
685
  "output": {
683
686
  "type": "object"
684
687
  },
685
688
  "title": {
686
689
  "type": "string"
687
690
  },
688
- "input": {
689
- "type": "object"
690
- },
691
691
  "description": {
692
692
  "type": "string"
693
693
  }
@@ -696,6 +696,12 @@
696
696
  "ConnectionDetails": {
697
697
  "type": "object",
698
698
  "properties": {
699
+ "type": {
700
+ "type": "string"
701
+ },
702
+ "title": {
703
+ "type": "string"
704
+ },
699
705
  "required": {
700
706
  "type": "array",
701
707
  "items": {
@@ -704,12 +710,6 @@
704
710
  },
705
711
  "properties": {
706
712
  "type": "object"
707
- },
708
- "type": {
709
- "type": "string"
710
- },
711
- "title": {
712
- "type": "string"
713
713
  }
714
714
  }
715
715
  },
@@ -724,23 +724,23 @@
724
724
  "TaskDetails": {
725
725
  "type": "object",
726
726
  "properties": {
727
- "schedule": {
728
- "type": "object"
729
- },
730
727
  "state": {
731
728
  "type": "object"
732
729
  },
733
- "description": {
734
- "type": "string"
735
- },
736
730
  "title": {
737
731
  "type": "string"
738
732
  },
739
- "input": {
733
+ "schedule": {
740
734
  "type": "object"
741
735
  },
736
+ "description": {
737
+ "type": "string"
738
+ },
742
739
  "output": {
743
740
  "type": "object"
741
+ },
742
+ "input": {
743
+ "type": "object"
744
744
  }
745
745
  }
746
746
  }
@@ -157,11 +157,13 @@ class Endpoints:
157
157
  500:
158
158
  description: Unexpected error
159
159
  """
160
+ self.logger.info("Plugin task beginning execution...")
160
161
  input_message = request.get_json(force=True)
161
162
  self.logger.debug("Request input: %s", input_message)
162
163
  Endpoints.validate_action_trigger_task_empty_input(input_message)
163
164
  Endpoints.validate_action_trigger_task_name(input_message, name, "task")
164
165
  output = self.run_action_trigger_task(input_message)
166
+ self.logger.info("Plugin task finished execution...")
165
167
  return output
166
168
 
167
169
  @legacy.route("/triggers/<string:name>/test", methods=["POST"])
@@ -1,4 +1,8 @@
1
1
  # -*- coding: utf-8 -*-
2
+ import structlog
3
+ logger = structlog.get_logger("plugin")
4
+
5
+
2
6
  class ClientException(Exception):
3
7
  """
4
8
  An exception which marks an error made by the plugin invoker.
@@ -120,6 +124,12 @@ class ConnectionTestException(Exception):
120
124
 
121
125
  self.data = str(data) if data else ""
122
126
 
127
+ # Safeguard to ensure the exception is logged across all plugins even if the plugin
128
+ # itself does not call `self.logger.error(<error info>)`
129
+ params = ["cause", "assistance", "data", "preset"]
130
+ info_log = ", ".join([f"{atr}='{getattr(self, atr)}'" for atr in params if getattr(self, atr)])
131
+ logger.error(f"Plugin exception instantiated. {info_log}")
132
+
123
133
  def __str__(self):
124
134
  if self.data:
125
135
  return "Connection test failed!\n\n{cause} {assistance} Response was: {data}".format(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: insightconnect-plugin-runtime
3
- Version: 5.2.4
3
+ Version: 5.3.1
4
4
  Summary: InsightConnect Plugin Runtime
5
5
  Home-page: https://github.com/rapid7/komand-plugin-sdk-python
6
6
  Author: Rapid7 Integrations Alliance
@@ -15,11 +15,11 @@ Description-Content-Type: text/markdown
15
15
  Requires-Dist: requests==2.31.0
16
16
  Requires-Dist: python_jsonschema_objects==0.3.12
17
17
  Requires-Dist: jsonschema==3.2.0
18
- Requires-Dist: certifi==2022.12.7
18
+ Requires-Dist: certifi==2023.7.22
19
19
  Requires-Dist: Flask==2.3.2
20
20
  Requires-Dist: gunicorn==20.0.4
21
- Requires-Dist: greenlet<=1.1.2,>=0.4.17
22
- Requires-Dist: gevent==20.9.0
21
+ Requires-Dist: greenlet==3.0.1
22
+ Requires-Dist: gevent==23.9.1
23
23
  Requires-Dist: marshmallow==3.4.0
24
24
  Requires-Dist: apispec==3.2.0
25
25
  Requires-Dist: apispec-webframeworks==0.5.2
@@ -48,10 +48,10 @@ to get started.
48
48
 
49
49
  ## Development of the InsightConnect Plugin Runtime
50
50
 
51
- The Python Runtime codebase is built to support Python 3.8+ as of version 4.0.0. The following dependencies will need
51
+ The Python Runtime codebase is built to support Python 3.9.18 as of version 5.3.0. The following dependencies will need
52
52
  to be installed when developing or testing the Plugin Runtime:
53
53
 
54
- - Python 3.8
54
+ - Python 3.9.18
55
55
  - Docker
56
56
  - make
57
57
  - tox
@@ -67,19 +67,51 @@ version and activate it. Then build, install, and confirm the package has been i
67
67
  > source venv/bin/activate
68
68
  > pip install -e ./
69
69
  > pip list | grep insightconnect-plugin-runtime
70
- insightconnect-plugin-runtime 4.0.0
70
+ insightconnect-plugin-runtime 5.2.2
71
71
  ```
72
72
 
73
73
  #### Building the InsightConnect Plugin Runtime Docker Images
74
74
 
75
- Currently the `3-38` dockerfile is used by default when building the docker image. If you want to specify another
76
- dockerfile for testing purposes, such as `3-38-slim`, you can pass it as an argument.
75
+ Currently the `python-3` dockerfile is used by default when building the docker image. If you want to specify another
76
+ dockerfile for testing purposes, such as `python-3-slim`, you can pass it as an argument.
77
77
 
78
78
  ```
79
- make build-image DOCKERFILE=3-38-slim
79
+ make build-image DOCKERFILE=python-3-slim
80
80
  ```
81
81
 
82
- This will overwrite the default `3-38`, provided that it exists in the `dockerfiles` directory.
82
+ This will overwrite the default `python-3`, provided that it exists in the `dockerfiles` directory.
83
+
84
+ #### Building/troubleshooting local images (Mac M1)
85
+
86
+ Our images are built with OS/ARCH:linux/amd64 due to our ci.yml file specifying linux. Historically this has
87
+ not caused any issues but with an M1 Mac, docker will now use arm64. This is because docker builds the image to match the
88
+ distribution of the OS running the command. To ensure that building locally and on GH produces an image of the same
89
+ architecture the `--platform` specifier is passed in the dockerfile.
90
+
91
+ If you build a plugin locally we can see further issues that:
92
+ - the local image does match the current OS distro so docker continues to look remotely..
93
+ - docker can not find this (newly created) image remotely on docker registry (dev images should not be pushed to registry)
94
+
95
+ To overcome this we need to specify `platform=linux/amd64` in the plugin docker file. E.g. if building plugins/html then
96
+ this file should be updated `plugins/html/Dockerfile`.
97
+ *Note*: building this arch on mac M1 will cause the build to be slower.
98
+
99
+
100
+ Example error of local image not matching OS distro without passing the `--platform` flag:
101
+ ```
102
+ => ERROR [internal] load metadata for docker.io/rapid7/insightconnect-python-3-slim-plugin:latest 1.4s
103
+ ------
104
+ > [internal] load metadata for docker.io/rapid7/insightconnect-python-3-slim-plugin:latest:
105
+ ------
106
+ Dockerfile:1
107
+ --------------------
108
+ 1 | >>> FROM rapid7/insightconnect-python-3-slim-plugin
109
+ 2 | LABEL organization=rapid7
110
+ 3 | LABEL sdk=python
111
+ --------------------
112
+ ERROR: failed to solve: rapid7/insightconnect-python-3-slim-plugin: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
113
+ make: *** [image] Error 1
114
+ ```
83
115
 
84
116
  ### Testing Sample Plugin
85
117
  The easiest way to test changes to the runtime is by running it locally against one of the [sample plugins](./samples)
@@ -145,9 +177,21 @@ Running all tests:
145
177
 
146
178
  Running a specific test file:
147
179
  ```
148
- > tox -e py38 -- tests/plugin/hello_world/tests/test_cli.py
180
+ > tox -e py39 -- tests/plugin/hello_world/tests/test_cli.py
149
181
  ```
150
182
 
183
+ ## Plugin vs Slim Plugin Comparison
184
+
185
+ | | Plugin | Slim Plugin |
186
+ |:------------------|:-------:|:-----------:|
187
+ | Python Version | 3.9.18 | 3.9.18 |
188
+ | OS | Alpine | Bullseye |
189
+ | Package installer | apk | apt |
190
+ | Shell | /bin/sh | /bin/bash |
191
+ | Image Size | ~350MB | ~180MB |
192
+
193
+ Note that for the plugin image, we run `apk update` and `apk add ..` which leads to a longer build time.
194
+
151
195
  ## Release
152
196
 
153
197
  To release a new version of the InsightConnect Python Plugin Runtime, the below steps must be followed:
@@ -168,6 +212,8 @@ after cloning this repository.
168
212
 
169
213
  ## Changelog
170
214
 
215
+ * 5.3.1 - New logging added to the beginning and end of a task | New logging when an exception is instantiated.
216
+ * 5.3.0 - Update base images to pull Python 3.9.18 | python packages bump | rename image to drop python minor version.
171
217
  * 5.2.4 - Extended logging with OrgID and IntID
172
218
  * 5.2.3 - Extended logging in AWSClient
173
219
  * 5.2.2 - Fix longstanding bug where some error responses from a plugin could be in HTML format instead of JSON
@@ -1,11 +1,11 @@
1
1
  requests==2.31.0
2
2
  python_jsonschema_objects==0.3.12
3
3
  jsonschema==3.2.0
4
- certifi==2022.12.7
4
+ certifi==2023.7.22
5
5
  Flask==2.3.2
6
6
  gunicorn==20.0.4
7
- greenlet<=1.1.2,>=0.4.17
8
- gevent==20.9.0
7
+ greenlet==3.0.1
8
+ gevent==23.9.1
9
9
  marshmallow==3.4.0
10
10
  apispec==3.2.0
11
11
  apispec-webframeworks==0.5.2
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setup(
7
7
  name="insightconnect-plugin-runtime",
8
- version="5.2.4",
8
+ version="5.3.1",
9
9
  description="InsightConnect Plugin Runtime",
10
10
  long_description=long_description,
11
11
  long_description_content_type="text/markdown",
@@ -17,11 +17,11 @@ setup(
17
17
  "requests==2.31.0",
18
18
  "python_jsonschema_objects==0.3.12",
19
19
  "jsonschema==3.2.0",
20
- "certifi==2022.12.7",
20
+ "certifi==2023.7.22",
21
21
  "Flask==2.3.2",
22
22
  "gunicorn==20.0.4",
23
- "greenlet>=0.4.17, <=1.1.2",
24
- "gevent==20.9.0",
23
+ "greenlet==3.0.1",
24
+ "gevent==23.9.1",
25
25
  "marshmallow==3.4.0",
26
26
  "apispec==3.2.0",
27
27
  "apispec-webframeworks==0.5.2",
@@ -55,10 +55,16 @@ def run_trigger(input_file, output_file, plugin, expect_timeout=False):
55
55
  plugin.triggers[trigger_name].dispatcher = capture
56
56
 
57
57
  executor = thread.ThreadPoolExecutor()
58
- executor.submit(plugin.handle_step, input_message)
59
- future = executor.submit(capture.wait_for_caught_message)
60
- out = futures.wait([future], timeout=10)
61
- done = out.done
58
+
59
+ if expect_timeout:
60
+ future = executor.submit(plugin.handle_step, input_message)
61
+ future_ans = future.exception()
62
+ done = future_ans.output
63
+ else:
64
+ executor.submit(plugin.handle_step, input_message)
65
+ future = executor.submit(capture.wait_for_caught_message)
66
+ out = futures.wait([future], timeout=10)
67
+ done = out.done
62
68
 
63
69
  # Non-graceful shutdown
64
70
  executor._threads.clear()
@@ -69,7 +75,8 @@ def run_trigger(input_file, output_file, plugin, expect_timeout=False):
69
75
  return
70
76
  raise Exception("Timeout")
71
77
 
72
- output = capture.caught_message
78
+ # output = capture.caught_message
79
+ output = done if expect_timeout else capture.caught_message
73
80
 
74
81
  if "body" in output and "log" in output["body"]:
75
82
  output["body"]["log"] = ""
@@ -79,7 +86,7 @@ def run_trigger(input_file, output_file, plugin, expect_timeout=False):
79
86
 
80
87
  if output != expected_output:
81
88
  raise Exception(
82
- "Actual output differs from expected output.{} != {}".format(
83
- output, expected_output
84
- )
89
+ f"Actual output differs from expected output/ \n"
90
+ f"Actual output: {output} \n"
91
+ f"Expected output: {expected_output}"
85
92
  )
@@ -18,8 +18,14 @@ class HelloTrigger(insightconnect_plugin_runtime.Trigger):
18
18
  """Run the trigger"""
19
19
  while True:
20
20
  self.logger.info("I am the log")
21
- self.send({"message": self.connection.greeting.format(params["name"])})
21
+ resp = {"message": self.connection.greeting.format(params["name"])}
22
+ self.send(resp)
22
23
  time.sleep(10)
24
+ # because this is a test we need to return otherwise the thread runs indefinitely to match how
25
+ # triggers run in production. Check using params 'test' so that if we build image of this plugin and
26
+ # test we will enter the loop as usual.
27
+ if params["test"]:
28
+ return resp
23
29
 
24
30
  def test(self):
25
31
  self.logger.info("This is a test")
@@ -15,7 +15,7 @@ class ThrowExceptionTrigger(insightconnect_plugin_runtime.Trigger):
15
15
  )
16
16
 
17
17
  def run(self, params={}):
18
- raise Exception("because I can")
18
+ raise Exception("Forced exception test")
19
19
 
20
20
  def test(self, params={}):
21
- raise Exception("because I can")
21
+ raise Exception("Forced exception test")