insightconnect-plugin-runtime 5.4.3__py3-none-any.whl → 5.4.4__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/server.py +7 -2
- {insightconnect_plugin_runtime-5.4.3.dist-info → insightconnect_plugin_runtime-5.4.4.dist-info}/METADATA +2 -2
- {insightconnect_plugin_runtime-5.4.3.dist-info → insightconnect_plugin_runtime-5.4.4.dist-info}/RECORD +7 -7
- tests/unit/test_server_cloud_plugins.py +27 -9
- tests/unit/utils.py +4 -4
- {insightconnect_plugin_runtime-5.4.3.dist-info → insightconnect_plugin_runtime-5.4.4.dist-info}/WHEEL +0 -0
- {insightconnect_plugin_runtime-5.4.3.dist-info → insightconnect_plugin_runtime-5.4.4.dist-info}/top_level.txt +0 -0
|
@@ -14,7 +14,7 @@ from gunicorn.arbiter import Arbiter
|
|
|
14
14
|
import structlog
|
|
15
15
|
from pythonjsonlogger.jsonlogger import JsonFormatter
|
|
16
16
|
from requests import get as request_get
|
|
17
|
-
from requests.exceptions import HTTPError, MissingSchema, Timeout, JSONDecodeError
|
|
17
|
+
from requests.exceptions import HTTPError, MissingSchema, Timeout, JSONDecodeError, ConnectionError
|
|
18
18
|
from time import sleep
|
|
19
19
|
from werkzeug.utils import secure_filename
|
|
20
20
|
|
|
@@ -194,7 +194,7 @@ class PluginServer(gunicorn.app.base.BaseApplication):
|
|
|
194
194
|
|
|
195
195
|
self.config_options = plugin_config
|
|
196
196
|
self.logger.info("Plugin configuration successfully retrieved...")
|
|
197
|
-
|
|
197
|
+
return
|
|
198
198
|
except MissingSchema as missing_schema:
|
|
199
199
|
self.logger.error(f"Invalid URL being requested: {CPS_ENDPOINT}, error={missing_schema}")
|
|
200
200
|
except Timeout as timeout:
|
|
@@ -203,9 +203,14 @@ class PluginServer(gunicorn.app.base.BaseApplication):
|
|
|
203
203
|
self.logger.error(f"Connection error when trying to reach CPS. CPS={CPS_ENDPOINT}, error={http_error}")
|
|
204
204
|
except JSONDecodeError as bad_json:
|
|
205
205
|
self.logger.error(f"Got bad JSON back. Response content={request_response.content}, error={bad_json}")
|
|
206
|
+
except ConnectionError as http_connection_pool_error:
|
|
207
|
+
self.logger.info(
|
|
208
|
+
"Connection refused when trying to reach CPS, retrying as the connection is still establishing."
|
|
209
|
+
)
|
|
206
210
|
except Exception as error:
|
|
207
211
|
self.logger.error(f"Hit an unexpected error when retrieving plugin custom configs, error={error}")
|
|
208
212
|
sleep(RETRY_SLEEP)
|
|
213
|
+
self.logger.error(f"Unable to reach CPS after {CPS_RETRY} attempts. CPS={CPS_ENDPOINT}")
|
|
209
214
|
|
|
210
215
|
def register_api_spec(self):
|
|
211
216
|
"""Register all swagger schema definitions and path objects"""
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: insightconnect-plugin-runtime
|
|
3
|
-
Version: 5.4.
|
|
3
|
+
Version: 5.4.4
|
|
4
4
|
Summary: InsightConnect Plugin Runtime
|
|
5
5
|
Home-page: https://github.com/rapid7/komand-plugin-sdk-python
|
|
6
6
|
Author: Rapid7 Integrations Alliance
|
|
@@ -211,7 +211,7 @@ contributed. Black is installed as a test dependency and the hook can be initial
|
|
|
211
211
|
after cloning this repository.
|
|
212
212
|
|
|
213
213
|
## Changelog
|
|
214
|
-
|
|
214
|
+
* 5.4.4 - Handling the 'Connection Refused' to cps (during startup) as an info instead of error log as this is an expected error.
|
|
215
215
|
* 5.4.3 - Updated dependencies to the latest versions | Fixed issue related to logger `StreamHandlers`
|
|
216
216
|
* 5.4.2 - Remove background scheduler to simplify when the server gets custom_config values | Revert to use `bullseye` for slim image.
|
|
217
217
|
* 5.4.1 - Retry logic added to get values from external API for custom_config values.
|
|
@@ -8,7 +8,7 @@ insightconnect_plugin_runtime/helper.py,sha256=m5PxN04-NPXM1X10S2wwjqmiLvnNntd6T
|
|
|
8
8
|
insightconnect_plugin_runtime/metrics.py,sha256=hf_Aoufip_s4k4o8Gtzz90ymZthkaT2e5sXh5B4LcF0,3186
|
|
9
9
|
insightconnect_plugin_runtime/plugin.py,sha256=0IcyhAxklL8lMX7qRXBJ0V6rCt56b5VyrqBG3RAOatU,23573
|
|
10
10
|
insightconnect_plugin_runtime/schema.py,sha256=jTNc6KAMqFpaDVWrAYhkVC6e8I63P3X7uVlJkAr1hiY,583
|
|
11
|
-
insightconnect_plugin_runtime/server.py,sha256=
|
|
11
|
+
insightconnect_plugin_runtime/server.py,sha256=Qf2LF4_6VDRK55xzNXpd5znwe78gA26wOWbvlmvp4Ro,12141
|
|
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
|
|
14
14
|
insightconnect_plugin_runtime/trigger.py,sha256=Zq3cy68N3QxAGbNZKCID6CZF05Zi7YD2sdy_qbedUY8,874
|
|
@@ -73,12 +73,12 @@ tests/unit/test_metrics.py,sha256=PjjTrB9w7uQ2Q5UN-893-SsH3EGJuBseOMHSD1I004s,79
|
|
|
73
73
|
tests/unit/test_oauth.py,sha256=nbFG0JH1x04ExXqSe-b5BGdt_hJs7DP17eUa6bQzcYI,2093
|
|
74
74
|
tests/unit/test_plugin.py,sha256=ZTNAZWwZhDIAbxkVuWhnz9FzmojbijgMmsLWM2mXQI0,4160
|
|
75
75
|
tests/unit/test_schema.py,sha256=swWZPRo_Q4M6VHte-srmxcV2wH-XS7pgmNRxpaL0Qrg,642
|
|
76
|
-
tests/unit/test_server_cloud_plugins.py,sha256=
|
|
76
|
+
tests/unit/test_server_cloud_plugins.py,sha256=PuMDHTz3af6lR9QK1BtPScr7_cRbWhetowADieVlXdo,5096
|
|
77
77
|
tests/unit/test_server_spec.py,sha256=je97BaktgK0Fiz3AwFPkcmHzYtOJJNqJV_Fw5hrvqX4,644
|
|
78
78
|
tests/unit/test_trigger.py,sha256=E53mAUoVyponWu_4IQZ0IC1gQ9lakBnTn_9vKN2IZfg,1692
|
|
79
79
|
tests/unit/test_variables.py,sha256=OUEOqGYZA3Nd5oKk5GVY3hcrWKHpZpxysBJcO_v5gzs,291
|
|
80
|
-
tests/unit/utils.py,sha256
|
|
81
|
-
insightconnect_plugin_runtime-5.4.
|
|
82
|
-
insightconnect_plugin_runtime-5.4.
|
|
83
|
-
insightconnect_plugin_runtime-5.4.
|
|
84
|
-
insightconnect_plugin_runtime-5.4.
|
|
80
|
+
tests/unit/utils.py,sha256=g_phxLH96rNwsdrry8Y7SjT9oZCps7ussI-ofc9K_xw,478
|
|
81
|
+
insightconnect_plugin_runtime-5.4.4.dist-info/METADATA,sha256=BpiS7DqRutG4tJTDJcr7y9LvoxJl597-4yFswMpo2b4,12702
|
|
82
|
+
insightconnect_plugin_runtime-5.4.4.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
83
|
+
insightconnect_plugin_runtime-5.4.4.dist-info/top_level.txt,sha256=AJtyJOpiFzHxsbHUICTcUKXyrGQ3tZxhrEHsPjJBvEA,36
|
|
84
|
+
insightconnect_plugin_runtime-5.4.4.dist-info/RECORD,,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from requests.exceptions import HTTPError, Timeout, TooManyRedirects
|
|
1
|
+
from requests.exceptions import HTTPError, Timeout, TooManyRedirects, ConnectionError
|
|
2
2
|
from parameterized import parameterized
|
|
3
3
|
from unittest import TestCase, skip
|
|
4
4
|
from unittest.mock import patch, MagicMock
|
|
@@ -46,11 +46,22 @@ class TestServerCloudPlugins(TestCase):
|
|
|
46
46
|
|
|
47
47
|
self.plugin.tasks = None # reset tasks value
|
|
48
48
|
|
|
49
|
-
@parameterized.expand(
|
|
49
|
+
@parameterized.expand(
|
|
50
|
+
[
|
|
51
|
+
["error", HTTPError],
|
|
52
|
+
["error", Timeout],
|
|
53
|
+
["unexpected", TooManyRedirects],
|
|
54
|
+
["Connection refused", ConnectionError],
|
|
55
|
+
]
|
|
56
|
+
)
|
|
50
57
|
@patch("insightconnect_plugin_runtime.server.request_get")
|
|
51
58
|
@patch("structlog.get_logger")
|
|
52
|
-
@patch(
|
|
53
|
-
|
|
59
|
+
@patch(
|
|
60
|
+
"insightconnect_plugin_runtime.server.CPS_RETRY", new=2
|
|
61
|
+
) # reduce retries in unit tests
|
|
62
|
+
@patch(
|
|
63
|
+
"insightconnect_plugin_runtime.server.RETRY_SLEEP", new=1
|
|
64
|
+
) # reduce sleep in unit tests
|
|
54
65
|
def test_cps_raises_an_error(self, test_cond, exception, log, mocked_req, _mock_cloud, _run):
|
|
55
66
|
log.return_value = Logger()
|
|
56
67
|
# If we have successfully got config and scheduler options, and later this call fails we should keep values
|
|
@@ -63,11 +74,18 @@ class TestServerCloudPlugins(TestCase):
|
|
|
63
74
|
|
|
64
75
|
self.assertDictEqual(plugin_server.config_options, PLUGIN_VALUE_2)
|
|
65
76
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
77
|
+
if test_cond == "Connection refused":
|
|
78
|
+
mocked_req.side_effect = ConnectionError("Connection Refused")
|
|
79
|
+
plugin_server.get_plugin_properties_from_cps()
|
|
80
|
+
# we log error as info log, as this is likely to be hit when the pod is just starting up
|
|
81
|
+
self.assertIn(test_cond, plugin_server.logger.last_info[-1])
|
|
82
|
+
|
|
83
|
+
else:
|
|
84
|
+
# First call has happened and now successful - force to hit specific handled and unexpected errors.
|
|
85
|
+
mocked_req.side_effect = exception("Warning HTTP error returned...")
|
|
86
|
+
plugin_server.get_plugin_properties_from_cps()
|
|
87
|
+
# we log error in all and `unexpected` in TooManyRedirects as there is no direct catch for this
|
|
88
|
+
self.assertIn(test_cond, plugin_server.logger.last_error[-2])
|
|
71
89
|
|
|
72
90
|
# Values should not have changed
|
|
73
91
|
self.assertDictEqual(plugin_server.config_options, PLUGIN_VALUE_2)
|
tests/unit/utils.py
CHANGED
|
@@ -10,11 +10,11 @@ class MockResponse:
|
|
|
10
10
|
class Logger:
|
|
11
11
|
"""Mocked logger to easily find last log triggered from SDK server."""
|
|
12
12
|
def __init__(self):
|
|
13
|
-
self.last_error =
|
|
14
|
-
self.last_info =
|
|
13
|
+
self.last_error = []
|
|
14
|
+
self.last_info = []
|
|
15
15
|
|
|
16
16
|
def info(self, log: str):
|
|
17
|
-
self.last_info
|
|
17
|
+
self.last_info.append(log)
|
|
18
18
|
|
|
19
19
|
def error(self, log: str):
|
|
20
|
-
self.last_error
|
|
20
|
+
self.last_error.append(log)
|
|
File without changes
|
|
File without changes
|