insightconnect-plugin-runtime 5.4.2__tar.gz → 5.4.4__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-5.4.2/insightconnect_plugin_runtime.egg-info → insightconnect-plugin-runtime-5.4.4}/PKG-INFO +9 -8
  2. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/README.md +2 -1
  3. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/plugin.py +19 -9
  4. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/server.py +7 -2
  5. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/util.py +15 -0
  6. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4/insightconnect_plugin_runtime.egg-info}/PKG-INFO +9 -8
  7. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime.egg-info/requires.txt +6 -6
  8. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/setup.py +7 -7
  9. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/__init__.py +0 -1
  10. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_server_cloud_plugins.py +27 -9
  11. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/utils.py +4 -4
  12. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/MANIFEST.in +0 -0
  13. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect-plugin-swagger.json +0 -0
  14. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/__init__.py +0 -0
  15. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/action.py +0 -0
  16. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/api/__init__.py +0 -0
  17. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/api/endpoints.py +0 -0
  18. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/api/schemas.py +0 -0
  19. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/cli.py +0 -0
  20. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/clients/__init__.py +0 -0
  21. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/clients/aws_client.py +0 -0
  22. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/clients/oauth.py +0 -0
  23. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/connection.py +0 -0
  24. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/data/input_message_schema.json +0 -0
  25. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/data/output_message_schema.json +0 -0
  26. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/dispatcher.py +0 -0
  27. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/exceptions.py +0 -0
  28. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/helper.py +0 -0
  29. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/metrics.py +0 -0
  30. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/schema.py +0 -0
  31. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/step.py +0 -0
  32. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/task.py +0 -0
  33. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/trigger.py +0 -0
  34. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime/variables.py +0 -0
  35. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime.egg-info/SOURCES.txt +0 -0
  36. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime.egg-info/dependency_links.txt +0 -0
  37. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/insightconnect_plugin_runtime.egg-info/top_level.txt +0 -0
  38. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/setup.cfg +0 -0
  39. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/__init__.py +0 -0
  40. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/__init__.py +0 -0
  41. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/__init__.py +0 -0
  42. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/__init__.py +0 -0
  43. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/__init__.py +0 -0
  44. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/hello/__init__.py +0 -0
  45. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/hello/action.py +0 -0
  46. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/hello/schema.py +0 -0
  47. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/return_bad_json/__init__.py +0 -0
  48. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/return_bad_json/action.py +0 -0
  49. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/return_bad_json/schema.py +0 -0
  50. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/throw_exception/__init__.py +0 -0
  51. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/throw_exception/action.py +0 -0
  52. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/actions/throw_exception/schema.py +0 -0
  53. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/connection/__init__.py +0 -0
  54. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/connection/connection.py +0 -0
  55. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/connection/schema.py +0 -0
  56. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/tasks/__init__.py +0 -0
  57. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/tasks/monitor_events/__init__.py +0 -0
  58. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/tasks/monitor_events/schema.py +0 -0
  59. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/tasks/monitor_events/task.py +0 -0
  60. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/__init__.py +0 -0
  61. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/hello_trigger/__init__.py +0 -0
  62. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/hello_trigger/schema.py +0 -0
  63. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/hello_trigger/trigger.py +0 -0
  64. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/return_bad_json_trigger/__init__.py +0 -0
  65. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/return_bad_json_trigger/schema.py +0 -0
  66. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/return_bad_json_trigger/trigger.py +0 -0
  67. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/throw_exception_trigger/__init__.py +0 -0
  68. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/throw_exception_trigger/schema.py +0 -0
  69. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/triggers/throw_exception_trigger/trigger.py +0 -0
  70. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/komand_hello_world/util/__init__.py +0 -0
  71. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/hello_world/setup.py +0 -0
  72. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/tests/__init__.py +0 -0
  73. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/tests/conftest.py +0 -0
  74. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/tests/test_cli.py +0 -0
  75. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/tests/test_hello_world.py +0 -0
  76. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/plugin/hello_world/tests/test_server.py +0 -0
  77. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/__init__.py +0 -0
  78. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_action.py +0 -0
  79. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_api.py +0 -0
  80. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_aws_action.py +0 -0
  81. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_custom_encoder.py +0 -0
  82. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_endpoints.py +0 -0
  83. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_exceptions.py +0 -0
  84. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_helpers.py +0 -0
  85. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_metrics.py +0 -0
  86. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_oauth.py +0 -0
  87. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_plugin.py +0 -0
  88. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_schema.py +0 -0
  89. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_server_spec.py +0 -0
  90. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/tests/unit/test_trigger.py +0 -0
  91. {insightconnect-plugin-runtime-5.4.2 → insightconnect-plugin-runtime-5.4.4}/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.4.2
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
@@ -14,14 +14,14 @@ Classifier: Topic :: Software Development :: Build Tools
14
14
  Description-Content-Type: text/markdown
15
15
  Requires-Dist: requests==2.31.0
16
16
  Requires-Dist: python_jsonschema_objects==0.5.2
17
- Requires-Dist: jsonschema==4.21.0
18
- Requires-Dist: certifi==2023.11.17
19
- Requires-Dist: Flask==3.0.0
17
+ Requires-Dist: jsonschema==4.21.1
18
+ Requires-Dist: certifi==2024.2.2
19
+ Requires-Dist: Flask==3.0.2
20
20
  Requires-Dist: gunicorn==21.2.0
21
21
  Requires-Dist: greenlet==3.0.3
22
- Requires-Dist: gevent==23.9.1
23
- Requires-Dist: marshmallow==3.20.2
24
- Requires-Dist: apispec==6.4.0
22
+ Requires-Dist: gevent==24.2.1
23
+ Requires-Dist: marshmallow==3.21.0
24
+ Requires-Dist: apispec==6.5.0
25
25
  Requires-Dist: apispec-webframeworks==1.0.0
26
26
  Requires-Dist: blinker==1.7.0
27
27
  Requires-Dist: structlog==24.1.0
@@ -211,7 +211,8 @@ 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
+ * 5.4.3 - Updated dependencies to the latest versions | Fixed issue related to logger `StreamHandlers`
215
216
  * 5.4.2 - Remove background scheduler to simplify when the server gets custom_config values | Revert to use `bullseye` for slim image.
216
217
  * 5.4.1 - Retry logic added to get values from external API for custom_config values.
217
218
  * 5.4.0 - Implementation of custom_config parameter for plugin tasks | Alpine image updated OpenSSL and expat | Use `bookworm` for slim image.
@@ -182,7 +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
-
185
+ * 5.4.4 - Handling the 'Connection Refused' to cps (during startup) as an info instead of error log as this is an expected error.
186
+ * 5.4.3 - Updated dependencies to the latest versions | Fixed issue related to logger `StreamHandlers`
186
187
  * 5.4.2 - Remove background scheduler to simplify when the server gets custom_config values | Revert to use `bullseye` for slim image.
187
188
  * 5.4.1 - Retry logic added to get values from external API for custom_config values.
188
189
  * 5.4.0 - Implementation of custom_config parameter for plugin tasks | Alpine image updated OpenSSL and expat | Use `bookworm` for slim image.
@@ -18,7 +18,7 @@ from insightconnect_plugin_runtime.exceptions import (
18
18
  PluginException,
19
19
  )
20
20
  from insightconnect_plugin_runtime.metrics import MetricsBuilder
21
- from insightconnect_plugin_runtime.util import is_running_in_cloud
21
+ from insightconnect_plugin_runtime.util import is_running_in_cloud, flush_logging_handlers
22
22
 
23
23
  message_output_type = {
24
24
  "action_start": "action_event",
@@ -374,8 +374,12 @@ class Plugin(object):
374
374
  log_stream = io.StringIO()
375
375
  stream_handler = logging.StreamHandler(log_stream)
376
376
  stream_handler.setLevel(logging.DEBUG if is_debug else logging.INFO)
377
- logging.getLogger("plugin").addHandler(stream_handler)
378
- logger = structlog.get_logger("plugin")
377
+
378
+ # Getting logger instances, struct_logger is formatted and mainly used in actions, triggers, and tasks
379
+ # while plugin_logger is the same instance that is used to add/remove and flush handlers during step execution
380
+ struct_logger = structlog.get_logger("plugin")
381
+ plugin_logger = logging.getLogger("plugin")
382
+ plugin_logger.addHandler(stream_handler)
379
383
 
380
384
  success = True
381
385
  caught_exception = None
@@ -409,7 +413,7 @@ class Plugin(object):
409
413
  output = self.start_step(
410
414
  input_message["body"],
411
415
  "action",
412
- logger,
416
+ struct_logger,
413
417
  log_stream,
414
418
  is_test,
415
419
  is_debug,
@@ -419,7 +423,7 @@ class Plugin(object):
419
423
  output = self.start_step(
420
424
  input_message["body"],
421
425
  "trigger",
422
- logger,
426
+ struct_logger,
423
427
  log_stream,
424
428
  is_test,
425
429
  is_debug,
@@ -431,7 +435,7 @@ class Plugin(object):
431
435
  output = self.start_step(
432
436
  input_message["body"],
433
437
  "task",
434
- logger,
438
+ struct_logger,
435
439
  log_stream,
436
440
  is_test,
437
441
  is_debug,
@@ -440,7 +444,7 @@ class Plugin(object):
440
444
  output, state, has_more_pages, status_code, error_object = self.start_step(
441
445
  input_message["body"],
442
446
  "task",
443
- logger,
447
+ struct_logger,
444
448
  log_stream,
445
449
  is_test,
446
450
  is_debug,
@@ -450,7 +454,7 @@ class Plugin(object):
450
454
  output = self.start_step(
451
455
  input_message["body"],
452
456
  "connection_test",
453
- logger,
457
+ struct_logger,
454
458
  log_stream,
455
459
  is_test,
456
460
  is_debug,
@@ -459,7 +463,7 @@ class Plugin(object):
459
463
  except (ClientException, ServerException, PluginException, Exception) as e:
460
464
  success = False
461
465
  caught_exception = e
462
- logger.exception(e)
466
+ struct_logger.exception(e)
463
467
  finally:
464
468
  output = self.envelope(
465
469
  out_type,
@@ -475,6 +479,11 @@ class Plugin(object):
475
479
  caught_exception,
476
480
  is_test,
477
481
  )
482
+
483
+ # Flush all the handlers and remove the one that was previously created
484
+ flush_logging_handlers(plugin_logger)
485
+ plugin_logger.removeHandler(stream_handler)
486
+
478
487
  if not success:
479
488
  raise LoggedException(caught_exception, output)
480
489
  return output
@@ -497,6 +506,7 @@ class Plugin(object):
497
506
  :param log_stream the raw stream for the log
498
507
  :param is_test: True if the action's test method should execute
499
508
  :param is_debug: True if debug is enabled
509
+ :param is_connection_test: True if connection test is running
500
510
  :return: An action_event message
501
511
  """
502
512
  connection = self.connection_cache.get(message_body["connection"], logger)
@@ -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
- break
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"""
@@ -139,6 +139,21 @@ class OutputMasker:
139
139
  return masked_response
140
140
 
141
141
 
142
+ def flush_logging_handlers(logger: logging.Logger) -> None:
143
+ """
144
+ Flush all the logging handlers attached to the logger.
145
+
146
+ :param logger: The logger object to flush the handlers for.
147
+ :type: logging.Logger
148
+
149
+ :return: None
150
+ :rtype: None
151
+ """
152
+
153
+ for handler in logger.handlers:
154
+ handler.flush()
155
+
156
+
142
157
  def default_for_object(obj, defs):
143
158
  defaults = {}
144
159
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: insightconnect-plugin-runtime
3
- Version: 5.4.2
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
@@ -14,14 +14,14 @@ Classifier: Topic :: Software Development :: Build Tools
14
14
  Description-Content-Type: text/markdown
15
15
  Requires-Dist: requests==2.31.0
16
16
  Requires-Dist: python_jsonschema_objects==0.5.2
17
- Requires-Dist: jsonschema==4.21.0
18
- Requires-Dist: certifi==2023.11.17
19
- Requires-Dist: Flask==3.0.0
17
+ Requires-Dist: jsonschema==4.21.1
18
+ Requires-Dist: certifi==2024.2.2
19
+ Requires-Dist: Flask==3.0.2
20
20
  Requires-Dist: gunicorn==21.2.0
21
21
  Requires-Dist: greenlet==3.0.3
22
- Requires-Dist: gevent==23.9.1
23
- Requires-Dist: marshmallow==3.20.2
24
- Requires-Dist: apispec==6.4.0
22
+ Requires-Dist: gevent==24.2.1
23
+ Requires-Dist: marshmallow==3.21.0
24
+ Requires-Dist: apispec==6.5.0
25
25
  Requires-Dist: apispec-webframeworks==1.0.0
26
26
  Requires-Dist: blinker==1.7.0
27
27
  Requires-Dist: structlog==24.1.0
@@ -211,7 +211,8 @@ 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
+ * 5.4.3 - Updated dependencies to the latest versions | Fixed issue related to logger `StreamHandlers`
215
216
  * 5.4.2 - Remove background scheduler to simplify when the server gets custom_config values | Revert to use `bullseye` for slim image.
216
217
  * 5.4.1 - Retry logic added to get values from external API for custom_config values.
217
218
  * 5.4.0 - Implementation of custom_config parameter for plugin tasks | Alpine image updated OpenSSL and expat | Use `bookworm` for slim image.
@@ -1,13 +1,13 @@
1
1
  requests==2.31.0
2
2
  python_jsonschema_objects==0.5.2
3
- jsonschema==4.21.0
4
- certifi==2023.11.17
5
- Flask==3.0.0
3
+ jsonschema==4.21.1
4
+ certifi==2024.2.2
5
+ Flask==3.0.2
6
6
  gunicorn==21.2.0
7
7
  greenlet==3.0.3
8
- gevent==23.9.1
9
- marshmallow==3.20.2
10
- apispec==6.4.0
8
+ gevent==24.2.1
9
+ marshmallow==3.21.0
10
+ apispec==6.5.0
11
11
  apispec-webframeworks==1.0.0
12
12
  blinker==1.7.0
13
13
  structlog==24.1.0
@@ -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.4.2",
8
+ version="5.4.4",
9
9
  description="InsightConnect Plugin Runtime",
10
10
  long_description=long_description,
11
11
  long_description_content_type="text/markdown",
@@ -16,14 +16,14 @@ setup(
16
16
  install_requires=[
17
17
  "requests==2.31.0",
18
18
  "python_jsonschema_objects==0.5.2",
19
- "jsonschema==4.21.0",
20
- "certifi==2023.11.17",
21
- "Flask==3.0.0",
19
+ "jsonschema==4.21.1",
20
+ "certifi==2024.2.2",
21
+ "Flask==3.0.2",
22
22
  "gunicorn==21.2.0",
23
23
  "greenlet==3.0.3",
24
- "gevent==23.9.1",
25
- "marshmallow==3.20.2",
26
- "apispec==6.4.0",
24
+ "gevent==24.2.1",
25
+ "marshmallow==3.21.0",
26
+ "apispec==6.5.0",
27
27
  "apispec-webframeworks==1.0.0",
28
28
  "blinker==1.7.0",
29
29
  "structlog==24.1.0",
@@ -46,7 +46,6 @@ def run_action(input_file, output_file, handler, expect_fail=False):
46
46
 
47
47
 
48
48
  def run_trigger(input_file, output_file, plugin, expect_timeout=False):
49
-
50
49
  input_message = json.load(open(input_file))
51
50
  expected_output = json.load(open(output_file))
52
51
 
@@ -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([["error", HTTPError], ["error", Timeout], ["unexpected", TooManyRedirects]])
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("insightconnect_plugin_runtime.server.CPS_RETRY", new=2) # reduce retries in unit tests
53
- @patch("insightconnect_plugin_runtime.server.RETRY_SLEEP", new=1) # reduce sleep in unit tests
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
- # First call has happened and now successful - force to hit specific handled and unexpected errors.
67
- mocked_req.side_effect = exception("Warning HTTP error returned...")
68
- plugin_server.get_plugin_properties_from_cps()
69
- # we log error in all and `unexpected` in TooManyRedirects as there is no direct catch for this
70
- self.assertIn(test_cond, plugin_server.logger.last_error)
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)
@@ -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 = None
14
- self.last_info = None
13
+ self.last_error = []
14
+ self.last_info = []
15
15
 
16
16
  def info(self, log: str):
17
- self.last_info = log
17
+ self.last_info.append(log)
18
18
 
19
19
  def error(self, log: str):
20
- self.last_error = log
20
+ self.last_error.append(log)