robusta-api 0.35.0__tar.gz → 0.36.0__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 (305) hide show
  1. {robusta_api-0.35.0 → robusta_api-0.36.0}/PKG-INFO +1 -1
  2. {robusta_api-0.35.0 → robusta_api-0.36.0}/pyproject.toml +1 -1
  3. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/_version.py +1 -1
  4. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/base_params.py +16 -0
  5. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/env_vars.py +1 -0
  6. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/internal/ai_integration.py +40 -0
  7. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/sink_base.py +13 -2
  8. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/sink_base_params.py +37 -0
  9. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/timing.py +26 -0
  10. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/slack/sender.py +12 -1
  11. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/config_loader.py +2 -0
  12. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/web.py +3 -1
  13. {robusta_api-0.35.0 → robusta_api-0.36.0}/LICENSE +0 -0
  14. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/__init__.py +0 -0
  15. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/api/__init__.py +0 -0
  16. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/clients/robusta_client.py +0 -0
  17. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/__init__.py +0 -0
  18. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/discovery/__init__.py +0 -0
  19. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/discovery/discovery.py +0 -0
  20. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/discovery/resource_names.py +0 -0
  21. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/discovery/top_service_resolver.py +0 -0
  22. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/discovery/utils.py +0 -0
  23. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/exceptions.py +0 -0
  24. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/__init__.py +0 -0
  25. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/cluster_status.py +0 -0
  26. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/events.py +0 -0
  27. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/helm_release.py +0 -0
  28. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/jobs.py +0 -0
  29. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/k8s_operation_type.py +0 -0
  30. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/namespaces.py +0 -0
  31. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/nodes.py +0 -0
  32. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/openshift_group.py +0 -0
  33. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/pods.py +0 -0
  34. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/runner_config.py +0 -0
  35. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/model/services.py +0 -0
  36. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/persistency/__init__.py +0 -0
  37. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/persistency/in_memory.py +0 -0
  38. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/persistency/scheduled_jobs_states_dal.py +0 -0
  39. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/__init__.py +0 -0
  40. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/actions_registry.py +0 -0
  41. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/base_trigger.py +0 -0
  42. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/common.py +0 -0
  43. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/container_playbook_utils.py +0 -0
  44. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/crash_reporter.py +0 -0
  45. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/generation.py +0 -0
  46. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/internal/CRD_API_DOCUMENTATION.md +0 -0
  47. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/internal/__init__.py +0 -0
  48. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/internal/crds.py +0 -0
  49. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/internal/discovery_events.py +0 -0
  50. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/job_utils.py +0 -0
  51. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/node_enrichment_utils.py +0 -0
  52. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/node_playbook_utils.py +0 -0
  53. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/oom_killer_utils.py +0 -0
  54. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/playbook_utils.py +0 -0
  55. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/playbooks_event_handler.py +0 -0
  56. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/playbooks_event_handler_impl.py +0 -0
  57. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/pod_utils/crashloop_utils.py +0 -0
  58. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/pod_utils/imagepull_utils.py +0 -0
  59. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/pod_utils/pending_pod_utils.py +0 -0
  60. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/prometheus_enrichment_utils.py +0 -0
  61. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/playbooks/trigger.py +0 -0
  62. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/pubsub/__init__.py +0 -0
  63. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/pubsub/event_emitter.py +0 -0
  64. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/pubsub/event_subscriber.py +0 -0
  65. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/pubsub/events_pubsub.py +0 -0
  66. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/__init__.py +0 -0
  67. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/action_requests.py +0 -0
  68. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/base.py +0 -0
  69. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/blocks.py +0 -0
  70. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/callbacks.py +0 -0
  71. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/consts.py +0 -0
  72. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/custom_rendering.py +0 -0
  73. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/finding_subjects.py +0 -0
  74. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/holmes.py +0 -0
  75. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/url_helpers.py +0 -0
  76. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/reporting/utils.py +0 -0
  77. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/schedule/__init__.py +0 -0
  78. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/schedule/model.py +0 -0
  79. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/schedule/scheduler.py +0 -0
  80. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/__init__.py +0 -0
  81. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/common/__init__.py +0 -0
  82. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/common/channel_transformer.py +0 -0
  83. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/common/html_tools.py +0 -0
  84. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/datadog/__init__.py +0 -0
  85. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/datadog/datadog_sink.py +0 -0
  86. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/datadog/datadog_sink_params.py +0 -0
  87. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/discord/__init__.py +0 -0
  88. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/discord/discord_sink.py +0 -0
  89. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/discord/discord_sink_params.py +0 -0
  90. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/file/__init__.py +0 -0
  91. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/file/file_sink.py +0 -0
  92. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/file/file_sink_params.py +0 -0
  93. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/file/object_traverser.py +0 -0
  94. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/google_chat/__init__.py +0 -0
  95. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/google_chat/google_chat.py +0 -0
  96. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/google_chat/google_chat_params.py +0 -0
  97. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/incidentio/__init__.py +0 -0
  98. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/incidentio/incidentio_api.py +0 -0
  99. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/incidentio/incidentio_client.py +0 -0
  100. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/incidentio/incidentio_sink.py +0 -0
  101. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/incidentio/incidentio_sink_params.py +0 -0
  102. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/jira/__init__.py +0 -0
  103. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/jira/jira_sink.py +0 -0
  104. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/jira/jira_sink_params.py +0 -0
  105. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/kafka/__init__.py +0 -0
  106. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/kafka/kafka_sink.py +0 -0
  107. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/kafka/kafka_sink_params.py +0 -0
  108. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/mail/__init__.py +0 -0
  109. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/mail/mail_sink.py +0 -0
  110. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/mail/mail_sink_params.py +0 -0
  111. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/mattermost/__init__.py +0 -0
  112. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/mattermost/mattermost_sink.py +0 -0
  113. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/mattermost/mattermost_sink_params.py +0 -0
  114. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/msteams/__init__.py +0 -0
  115. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/msteams/msteams_sink.py +0 -0
  116. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/msteams/msteams_sink_params.py +0 -0
  117. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/msteams/msteams_webhook_tranformer.py +0 -0
  118. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/opsgenie/__init__.py +0 -0
  119. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/opsgenie/opsgenie_sink.py +0 -0
  120. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/opsgenie/opsgenie_sink_params.py +0 -0
  121. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/pagerduty/__init__.py +0 -0
  122. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/pagerduty/pagerduty_sink.py +0 -0
  123. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/pagerduty/pagerduty_sink_params.py +0 -0
  124. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/pushover/__init__.py +0 -0
  125. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/pushover/pushover_client.py +0 -0
  126. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/pushover/pushover_sink.py +0 -0
  127. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/pushover/pushover_sink_params.py +0 -0
  128. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/__init__.py +0 -0
  129. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/dal/__init__.py +0 -0
  130. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/dal/model_conversion.py +0 -0
  131. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/dal/supabase_dal.py +0 -0
  132. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/discovery_metrics.py +0 -0
  133. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/prometheus_discovery_utils.py +0 -0
  134. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/robusta_sink.py +0 -0
  135. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/robusta_sink_params.py +0 -0
  136. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/rrm/__init__.py +0 -0
  137. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/rrm/account_resource_fetcher.py +0 -0
  138. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/rrm/base_resource_manager.py +0 -0
  139. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/rrm/prometheus_alert_resource_manager.py +0 -0
  140. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/rrm/rrm.py +0 -0
  141. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/robusta/rrm/types.py +0 -0
  142. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/rocketchat/__init__.py +0 -0
  143. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/rocketchat/rocketchat_sink.py +0 -0
  144. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/rocketchat/rocketchat_sink_params.py +0 -0
  145. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/servicenow/__init__.py +0 -0
  146. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/servicenow/servicenow_sink.py +0 -0
  147. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/servicenow/servicenow_sink_params.py +0 -0
  148. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/sink_config.py +0 -0
  149. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/sink_factory.py +0 -0
  150. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/slack/__init__.py +0 -0
  151. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/slack/preview/slack_sink_preview.py +0 -0
  152. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/slack/preview/slack_sink_preview_params.py +0 -0
  153. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/slack/slack_sink.py +0 -0
  154. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/slack/slack_sink_params.py +0 -0
  155. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/slack/templates/header.j2 +0 -0
  156. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/slack/templates/template_loader.py +0 -0
  157. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/telegram/__init__.py +0 -0
  158. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/telegram/telegram_client.py +0 -0
  159. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/telegram/telegram_sink.py +0 -0
  160. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/telegram/telegram_sink_params.py +0 -0
  161. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/transformer.py +0 -0
  162. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/victorops/__init__.py +0 -0
  163. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/victorops/victorops_sink.py +0 -0
  164. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/victorops/victorops_sink_params.py +0 -0
  165. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/webex/__init__.py +0 -0
  166. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/webex/webex_sink.py +0 -0
  167. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/webex/webex_sink_params.py +0 -0
  168. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/webhook/__init__.py +0 -0
  169. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/webhook/webhook_sink.py +0 -0
  170. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/webhook/webhook_sink_params.py +0 -0
  171. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/yamessenger/__init__.py +0 -0
  172. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/yamessenger/yamessenger_client.py +0 -0
  173. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/yamessenger/yamessenger_sink.py +0 -0
  174. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/yamessenger/yamessenger_sink_params.py +0 -0
  175. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/zulip/__init__.py +0 -0
  176. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/zulip/zulip_sink.py +0 -0
  177. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/sinks/zulip/zulip_sink_params.py +0 -0
  178. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/stream/utils.py +0 -0
  179. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/container_oom_killed_trigger.py +0 -0
  180. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/custom_triggers.py +0 -0
  181. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/error_event_trigger.py +0 -0
  182. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/helm_releases_triggers.py +0 -0
  183. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/job_failed_trigger.py +0 -0
  184. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/multi_resources_trigger.py +0 -0
  185. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/oom_killed_trigger_base.py +0 -0
  186. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/pod_crash_loop_trigger.py +0 -0
  187. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/pod_evicted_trigger.py +0 -0
  188. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/pod_image_pull_backoff.py +0 -0
  189. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/core/triggers/pod_oom_killed_trigger.py +0 -0
  190. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/__init__.py +0 -0
  191. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/argocd/argocd_client.py +0 -0
  192. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/common/__init__.py +0 -0
  193. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/common/requests.py +0 -0
  194. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/discord/__init__.py +0 -0
  195. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/discord/sender.py +0 -0
  196. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/git/__init__.py +0 -0
  197. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/git/git_repo.py +0 -0
  198. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/git/well_known_hosts.py +0 -0
  199. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/google_chat/__init__.py +0 -0
  200. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/google_chat/sender.py +0 -0
  201. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/grafana.py +0 -0
  202. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/helper.py +0 -0
  203. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/jira/__init__.py +0 -0
  204. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/jira/client.py +0 -0
  205. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/jira/sender.py +0 -0
  206. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/__init__.py +0 -0
  207. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/api_client_utils.py +0 -0
  208. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/autogenerated/__init__.py +0 -0
  209. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/autogenerated/events.py +0 -0
  210. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/autogenerated/models.py +0 -0
  211. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/autogenerated/triggers.py +0 -0
  212. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/autogenerated/v1/__init__.py +0 -0
  213. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/autogenerated/v1/models.py +0 -0
  214. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/base_event.py +0 -0
  215. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/base_triggers.py +0 -0
  216. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/custom_crds.py +0 -0
  217. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/custom_models.py +0 -0
  218. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/model_not_found_exception.py +0 -0
  219. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/process_utils.py +0 -0
  220. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/kubernetes/templates.py +0 -0
  221. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/mail/__init__.py +0 -0
  222. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/mail/sender.py +0 -0
  223. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/mattermost/__init__.py +0 -0
  224. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/mattermost/client.py +0 -0
  225. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/mattermost/sender.py +0 -0
  226. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/__init__.py +0 -0
  227. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_adaptive_card_files.py +0 -0
  228. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_adaptive_card_files_image.py +0 -0
  229. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_adaptive_card_files_text.py +0 -0
  230. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_elements/__init__.py +0 -0
  231. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_elements/msteams_action.py +0 -0
  232. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_elements/msteams_base.py +0 -0
  233. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_elements/msteams_card.py +0 -0
  234. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_elements/msteams_column.py +0 -0
  235. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_elements/msteams_container.py +0 -0
  236. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_elements/msteams_images.py +0 -0
  237. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_elements/msteams_table.py +0 -0
  238. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_elements/msteams_text_block.py +0 -0
  239. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_mark_down_fix_url.py +0 -0
  240. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/msteams_msg.py +0 -0
  241. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/msteams/sender.py +0 -0
  242. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/openshift/__init__.py +0 -0
  243. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/openshift/token.py +0 -0
  244. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/prometheus/__init__.py +0 -0
  245. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/prometheus/models.py +0 -0
  246. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/prometheus/trigger.py +0 -0
  247. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/prometheus/utils.py +0 -0
  248. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/receiver.py +0 -0
  249. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/resource_analysis/__init__.py +0 -0
  250. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/resource_analysis/cpu_analyzer.py +0 -0
  251. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/resource_analysis/memory_analyzer.py +0 -0
  252. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/resource_analysis/node_cpu_analyzer.py +0 -0
  253. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/resource_analysis/prometheus_analyzer.py +0 -0
  254. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/rocketchat/__init__.py +0 -0
  255. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/rocketchat/sender.py +0 -0
  256. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/scheduled/__init__.py +0 -0
  257. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/scheduled/event.py +0 -0
  258. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/scheduled/models.py +0 -0
  259. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/scheduled/playbook_scheduler.py +0 -0
  260. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/scheduled/playbook_scheduler_manager.py +0 -0
  261. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/scheduled/playbook_scheduler_manager_impl.py +0 -0
  262. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/scheduled/trigger.py +0 -0
  263. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/servicenow/__init__.py +0 -0
  264. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/servicenow/sender.py +0 -0
  265. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/slack/__init__.py +0 -0
  266. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/webex/__init__.py +0 -0
  267. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/webex/sender.py +0 -0
  268. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/zulip/__init__.py +0 -0
  269. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/integrations/zulip/sender.py +0 -0
  270. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/model/alert_relabel_config.py +0 -0
  271. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/model/config.py +0 -0
  272. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/model/playbook_action.py +0 -0
  273. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/model/playbook_definition.py +0 -0
  274. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/patch/patch.py +0 -0
  275. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/__init__.py +0 -0
  276. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/log_init.py +0 -0
  277. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/main.py +0 -0
  278. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/not_found_exception.py +0 -0
  279. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/object_updater.py +0 -0
  280. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/process_setup.py +0 -0
  281. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/ssl_utils.py +0 -0
  282. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/telemetry.py +0 -0
  283. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/telemetry_service.py +0 -0
  284. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/runner/web_api.py +0 -0
  285. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/__init__.py +0 -0
  286. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/auth_provider.py +0 -0
  287. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/base64_utils.py +0 -0
  288. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/cluster_provider_discovery.py +0 -0
  289. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/common.py +0 -0
  290. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/decorators.py +0 -0
  291. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/docs.py +0 -0
  292. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/documented_pydantic.py +0 -0
  293. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/error_codes.py +0 -0
  294. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/file_system_watcher.py +0 -0
  295. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/function_hashes.py +0 -0
  296. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/json_schema.py +0 -0
  297. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/parsing.py +0 -0
  298. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/rate_limiter.py +0 -0
  299. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/scope.py +0 -0
  300. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/server_start.py +0 -0
  301. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/service_discovery.py +0 -0
  302. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/silence_utils.py +0 -0
  303. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/stack_tracer.py +0 -0
  304. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/task_queue.py +0 -0
  305. {robusta_api-0.35.0 → robusta_api-0.36.0}/src/robusta/utils/time_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robusta-api
3
- Version: 0.35.0
3
+ Version: 0.36.0
4
4
  Summary:
5
5
  Author: Arik Alon
6
6
  Author-email: arikalon1@users.noreply.github.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "robusta-api"
3
- version = "0.35.0"
3
+ version = "0.36.0"
4
4
  description = ""
5
5
  authors = ["Arik Alon <arikalon1@users.noreply.github.com>"]
6
6
  packages = [
@@ -1,2 +1,2 @@
1
1
  # this is updated by .github/workflows/release.yaml
2
- __version__ = "0.35.0"
2
+ __version__ = "0.36.0"
@@ -188,6 +188,7 @@ class ToolApprovalDecision(BaseModel):
188
188
  tool_call_id: str
189
189
  approved: bool
190
190
  save_prefixes: Optional[List[str]] = None # Prefixes to remember for session
191
+ decision: Optional[Dict[str, Any]] = None # Structured decision data (e.g. OAuth callback params). Parsed by Holmes.
191
192
 
192
193
 
193
194
  class HolmesChatParams(HolmesParams):
@@ -216,6 +217,21 @@ class HolmesIssueChatParams(HolmesChatParams):
216
217
  context: HolmesIssueChatParamsContext
217
218
 
218
219
 
220
+ class HolmesOAuthParams(ActionParams):
221
+ """
222
+ Forwards OAuth callback data to Holmes.
223
+ Params are intentionally generic (extra=allow) — the actual contract
224
+ is defined by Holmes and can evolve without runner changes.
225
+
226
+ :var toolset_name: The MCP toolset to authenticate
227
+ """
228
+
229
+ toolset_name: str
230
+
231
+ class Config:
232
+ extra = "allow"
233
+
234
+
219
235
  class HolmesConversationParams(HolmesParams):
220
236
  """
221
237
  :var resource: The resource related to this investigation. A resource has a `name` and `kind`, and may have `namespace` and `node`
@@ -72,6 +72,7 @@ RUNNER_SERVICE_ACCOUNT = os.environ.get("RUNNER_SERVICE_ACCOUNT", f"{RELEASE_NAM
72
72
  TELEMETRY_PERIODIC_SEC = int(os.environ.get("TELEMETRY_PERIODIC_SEC", 60 * 60 * 24)) # 24H
73
73
 
74
74
  SLACK_REQUEST_TIMEOUT = int(os.environ.get("SLACK_REQUEST_TIMEOUT", 90))
75
+ SLACK_RATE_LIMIT_RETRIES = int(os.environ.get("SLACK_RATE_LIMIT_RETRIES", 2))
75
76
  SLACK_TABLE_COLUMNS_LIMIT = int(os.environ.get("SLACK_TABLE_COLUMNS_LIMIT", 3))
76
77
  SLACK_FORWARD_URL = os.environ.get("SLACK_FORWARD_URL") # forward endpoint "https://api.robusta.dev/slack/"
77
78
  DISCORD_TABLE_COLUMNS_LIMIT = int(os.environ.get("DISCORD_TABLE_COLUMNS_LIMIT", 4))
@@ -12,6 +12,7 @@ from robusta.core.model.base_params import (
12
12
  HolmesChatParams,
13
13
  HolmesConversationParams,
14
14
  HolmesIssueChatParams,
15
+ HolmesOAuthParams,
15
16
  ResourceInfo,
16
17
  )
17
18
  from robusta.core.model.events import ExecutionBaseEvent
@@ -385,6 +386,45 @@ def holmes_chat(event: ExecutionBaseEvent, params: HolmesChatParams):
385
386
  handle_holmes_error(e)
386
387
 
387
388
 
389
+ @action
390
+ def holmes_oauth(event: ExecutionBaseEvent, params: HolmesOAuthParams):
391
+ """
392
+ Forwards OAuth callback data to Holmes for token exchange and storage.
393
+
394
+ This action is a thin pass-through — the actual OAuth contract is defined
395
+ in Holmes. Params use extra=allow so Holmes can evolve the contract
396
+ (e.g. add new fields) without requiring runner changes.
397
+ """
398
+ holmes_url = HolmesDiscovery.find_holmes_url(params.holmes_url)
399
+ if not holmes_url:
400
+ raise ActionException(
401
+ ErrorCodes.HOLMES_DISCOVERY_FAILED,
402
+ "Robusta couldn't connect to the Holmes client.",
403
+ )
404
+
405
+ try:
406
+ result = requests.post(
407
+ f"{holmes_url}/api/oauth/callback",
408
+ json=params.dict(),
409
+ timeout=60,
410
+ )
411
+ result.raise_for_status()
412
+ response_data = result.json()
413
+
414
+ finding = Finding(
415
+ title="Holmes OAuth",
416
+ aggregation_key="HolmesOAuthResult",
417
+ subject=FindingSubject(subject_type=FindingSubjectType.TYPE_NONE),
418
+ finding_type=FindingType.AI_ANALYSIS,
419
+ failure=not response_data.get("success", False),
420
+ )
421
+ event.add_finding(finding)
422
+
423
+ except Exception as e:
424
+ logging.exception("Failed to complete Holmes OAuth callback")
425
+ handle_holmes_error(e)
426
+
427
+
388
428
  def stream_and_render_graphs(url, holmes_req, event):
389
429
  with requests.post(
390
430
  url,
@@ -8,8 +8,8 @@ from pydantic import BaseModel, Field
8
8
 
9
9
  from robusta.core.model.k8s_operation_type import K8sOperationType
10
10
  from robusta.core.reporting.base import Finding
11
- from robusta.core.sinks.sink_base_params import ActivityInterval, ActivityParams, SinkBaseParams
12
- from robusta.core.sinks.timing import TimeSlice, TimeSliceAlways
11
+ from robusta.core.sinks.sink_base_params import ActivityInterval, ActivityParams, MuteInterval, SinkBaseParams
12
+ from robusta.core.sinks.timing import MuteDateInterval, TimeSlice, TimeSliceAlways
13
13
 
14
14
 
15
15
  KeyT = Tuple[str, ...]
@@ -71,6 +71,7 @@ class SinkBase(ABC):
71
71
  self.signing_key = global_config.get("signing_key", "")
72
72
 
73
73
  self.time_slices = self._build_time_slices_from_params(self.params.activity)
74
+ self.mute_date_intervals = self._build_mute_intervals_from_params(self.params.mute_intervals)
74
75
 
75
76
  self.grouping_summary_mode = False
76
77
  self.grouping_enabled = False
@@ -151,6 +152,14 @@ class SinkBase(ABC):
151
152
  def _interval_to_time_slice(self, timezone: str, interval: ActivityInterval):
152
153
  return TimeSlice(interval.days, [(time.start, time.end) for time in interval.hours], timezone)
153
154
 
155
+ def _build_mute_intervals_from_params(self, params: Optional[List[MuteInterval]]):
156
+ if not params:
157
+ return []
158
+ return [
159
+ MuteDateInterval(interval.start_date, interval.end_date, interval.timezone)
160
+ for interval in params
161
+ ]
162
+
154
163
  def is_global_config_changed(self) -> bool:
155
164
  # registry global config can be updated without these stored values being changed
156
165
  global_config = self.registry.get_global_config()
@@ -163,6 +172,8 @@ class SinkBase(ABC):
163
172
  pass
164
173
 
165
174
  def accepts(self, finding: Finding) -> bool:
175
+ if any(mute.is_muted_now() for mute in self.mute_date_intervals):
176
+ return False
166
177
  return (
167
178
  finding.matches(self.params.match, self.params.scope)
168
179
  and any(time_slice.is_active_now() for time_slice in self.time_slices)
@@ -57,6 +57,42 @@ class ActivityParams(BaseModel):
57
57
  return intervals
58
58
 
59
59
 
60
+ DATE_TIME_RE = re.compile(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$")
61
+
62
+
63
+ def check_date_time_format(value: str) -> str:
64
+ if not DATE_TIME_RE.match(value):
65
+ raise ValueError(f"invalid date-time: {value}. Expected format: YYYY-MM-DD HH:MM")
66
+ date_part, time_part = value.split(" ", 1)
67
+ year, month, day = date_part.split("-")
68
+ hour, minute = time_part.split(":")
69
+ year, month, day, hour, minute = int(year), int(month), int(day), int(hour), int(minute)
70
+ if not (1 <= month <= 12):
71
+ raise ValueError(f"invalid month: {month}")
72
+ if not (1 <= day <= 31):
73
+ raise ValueError(f"invalid day: {day}")
74
+ if not (0 <= hour <= 23):
75
+ raise ValueError(f"invalid hour: {hour}")
76
+ if not (0 <= minute <= 59):
77
+ raise ValueError(f"invalid minute: {minute}")
78
+ return value
79
+
80
+
81
+ class MuteInterval(BaseModel):
82
+ start_date: str # YYYY-MM-DD HH:MM
83
+ end_date: str # YYYY-MM-DD HH:MM
84
+ timezone: str = "UTC"
85
+
86
+ _validator_start = validator("start_date", allow_reuse=True)(check_date_time_format)
87
+ _validator_end = validator("end_date", allow_reuse=True)(check_date_time_format)
88
+
89
+ @validator("timezone")
90
+ def check_timezone(cls, timezone: str):
91
+ if timezone not in pytz.all_timezones:
92
+ raise ValueError(f"unknown timezone {timezone}")
93
+ return timezone
94
+
95
+
60
96
  class RegularNotificationModeParams(BaseModel):
61
97
  # This is mandatory because using the regular mode without setting it
62
98
  # would make no sense - all the notifications would just pass through
@@ -108,6 +144,7 @@ class SinkBaseParams(ABC, BaseModel):
108
144
  match: dict = {}
109
145
  scope: Optional[ScopeParams]
110
146
  activity: Optional[ActivityParams]
147
+ mute_intervals: Optional[List[MuteInterval]]
111
148
  grouping: Optional[GroupingParams]
112
149
  stop: bool = False # Stop processing if this sink has been matched
113
150
 
@@ -65,3 +65,29 @@ class TimeSlice(TimeSliceBase):
65
65
  class TimeSliceAlways(TimeSliceBase):
66
66
  def is_active_now(self) -> bool:
67
67
  return True
68
+
69
+
70
+ class MuteDateInterval:
71
+ """Checks if the current date/time falls within a mute interval.
72
+
73
+ start_date and end_date are in YYYY-MM-DD HH:MM format.
74
+ """
75
+
76
+ def __init__(self, start_date: str, end_date: str, timezone: str = "UTC"):
77
+ self.start = self._parse(start_date)
78
+ self.end = self._parse(end_date)
79
+ try:
80
+ self.timezone = pytz.timezone(timezone)
81
+ except pytz.exceptions.UnknownTimeZoneError:
82
+ raise ValueError(f"Unknown time zone {timezone}")
83
+
84
+ def _parse(self, date_str: str) -> Tuple[int, int, int, int, int]:
85
+ date_part, time_part = date_str.strip().split(" ")
86
+ year, month, day = date_part.split("-")
87
+ hour, minute = time_part.split(":")
88
+ return int(year), int(month), int(day), int(hour), int(minute)
89
+
90
+ def is_muted_now(self) -> bool:
91
+ now = datetime.now(self.timezone)
92
+ current = (now.year, now.month, now.day, now.hour, now.minute)
93
+ return self.start <= current <= self.end
@@ -12,12 +12,14 @@ from dateutil import tz
12
12
  from slack_sdk import WebClient
13
13
  from slack_sdk.errors import SlackApiError
14
14
  from slack_sdk.http_retry import all_builtin_retry_handlers
15
+ from slack_sdk.http_retry.builtin_handlers import RateLimitErrorRetryHandler
15
16
  from robusta.core.sinks.slack.templates.template_loader import template_loader
16
17
 
17
18
  from robusta.core.model.env_vars import (
18
19
  ADDITIONAL_CERTIFICATE,
19
20
  HOLMES_ASK_SLACK_BUTTON_ENABLED,
20
21
  HOLMES_ENABLED,
22
+ SLACK_RATE_LIMIT_RETRIES,
21
23
  SLACK_REQUEST_TIMEOUT,
22
24
  SLACK_TABLE_COLUMNS_LIMIT,
23
25
  SLACK_FORWARD_URL,
@@ -57,6 +59,15 @@ MAX_BLOCK_CHARS = 3000
57
59
  MENTION_PATTERN = re.compile(r"<[^>]+>")
58
60
 
59
61
 
62
+ def _build_retry_handlers():
63
+ handlers = all_builtin_retry_handlers()
64
+ return [
65
+ RateLimitErrorRetryHandler(max_retry_count=SLACK_RATE_LIMIT_RETRIES)
66
+ if isinstance(h, RateLimitErrorRetryHandler) else h
67
+ for h in handlers
68
+ ]
69
+
70
+
60
71
  class SlackSender:
61
72
  verified_api_tokens: Set[str] = set()
62
73
  channel_name_to_id = {}
@@ -77,7 +88,7 @@ class SlackSender:
77
88
  token=slack_token,
78
89
  ssl=ssl_context,
79
90
  timeout=SLACK_REQUEST_TIMEOUT,
80
- retry_handlers=all_builtin_retry_handlers(),
91
+ retry_handlers=_build_retry_handlers(),
81
92
  base_url=SLACK_FORWARD_URL or WebClient.BASE_URL
82
93
  )
83
94
  if SLACK_FORWARD_URL:
@@ -184,6 +184,8 @@ class ConfigLoader:
184
184
  @classmethod
185
185
  def __import_playbooks_package(cls, actions_registry: ActionsRegistry, package_name: str):
186
186
  logging.info(f"Importing actions package {package_name}")
187
+ # Clear stale FileFinder caches so walk_packages discovers new .py files
188
+ importlib.invalidate_caches()
187
189
  # Reload is required for modules that are already loaded
188
190
  pkg = importlib.reload(importlib.import_module(package_name))
189
191
  playbooks_modules = [name for _, name, _ in pkgutil.walk_packages(path=pkg.__path__)]
@@ -11,7 +11,7 @@ from werkzeug.middleware.dispatcher import DispatcherMiddleware
11
11
 
12
12
  from robusta.clients.robusta_client import fetch_runner_info
13
13
  from robusta.core.model.env_vars import NUM_EVENT_THREADS, PORT, TRACE_INCOMING_ALERTS, TRACE_INCOMING_REQUESTS, \
14
- PROCESSED_ALERTS_CACHE_TTL, PROCESSED_ALERTS_CACHE_MAX_SIZE, RUNNER_VERSION, RUNNER_BIND_ADDR
14
+ PROCESSED_ALERTS_CACHE_TTL, PROCESSED_ALERTS_CACHE_MAX_SIZE, RUNNER_VERSION, RUNNER_BIND_ADDR, ENABLE_TELEMETRY
15
15
  from robusta.core.playbooks.playbooks_event_handler import PlaybooksEventHandler
16
16
  from robusta.core.triggers.helm_releases_triggers import HelmReleasesTriggerEvent, IncomingHelmReleasesEventPayload
17
17
  from robusta.integrations.kubernetes.base_triggers import IncomingK8sEventPayload, K8sTriggerEvent
@@ -46,6 +46,8 @@ class Web:
46
46
 
47
47
  @staticmethod
48
48
  def _check_version():
49
+ if not ENABLE_TELEMETRY:
50
+ return None
49
51
  runner_info = fetch_runner_info()
50
52
  if not runner_info or not runner_info.latest_version:
51
53
  # we couldn't fetch the latest version.
File without changes