robusta-cli 0.10.26a4__tar.gz → 0.10.27__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 (264) hide show
  1. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/PKG-INFO +1 -1
  2. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/pyproject.toml +2 -1
  3. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/_version.py +1 -1
  4. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/main.py +2 -1
  5. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/discovery/discovery.py +1 -1
  6. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/cluster_status.py +3 -0
  7. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/env_vars.py +5 -1
  8. robusta_cli-0.10.27/src/robusta/core/playbooks/base_trigger.py +36 -0
  9. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/internal/discovery_events.py +2 -2
  10. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/playbooks_event_handler_impl.py +10 -4
  11. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/schedule/scheduler.py +1 -1
  12. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/pagerduty/pagerduty_sink.py +2 -2
  13. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/robusta/dal/supabase_dal.py +127 -25
  14. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/robusta/prometheus_health_checker.py +1 -1
  15. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/robusta/robusta_sink.py +14 -10
  16. robusta_cli-0.10.27/src/robusta/core/sinks/robusta/rrm/account_resource_fetcher.py +22 -0
  17. robusta_cli-0.10.27/src/robusta/core/sinks/robusta/rrm/base_resource_manager.py +13 -0
  18. robusta_cli-0.10.27/src/robusta/core/sinks/robusta/rrm/prometheus_alert_resource_manager.py +202 -0
  19. robusta_cli-0.10.27/src/robusta/core/sinks/robusta/rrm/rrm.py +81 -0
  20. robusta_cli-0.10.27/src/robusta/core/sinks/robusta/rrm/types.py +62 -0
  21. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/sink_base.py +15 -2
  22. robusta_cli-0.10.27/src/robusta/core/sinks/sink_base_params.py +96 -0
  23. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/slack/slack_sink_params.py +32 -8
  24. robusta_cli-0.10.27/src/robusta/core/sinks/timing.py +67 -0
  25. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/transformer.py +1 -1
  26. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/triggers/custom_triggers.py +2 -0
  27. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/triggers/error_event_trigger.py +7 -7
  28. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/triggers/helm_releases_triggers.py +5 -5
  29. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/triggers/job_failed_trigger.py +5 -3
  30. robusta_cli-0.10.27/src/robusta/core/triggers/multi_resources_trigger.py +55 -0
  31. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/triggers/oom_killed_trigger_base.py +4 -4
  32. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/triggers/pod_crash_loop_trigger.py +5 -3
  33. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/triggers/pod_image_pull_backoff.py +4 -3
  34. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/base_triggers.py +14 -4
  35. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/mail/sender.py +9 -5
  36. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/prometheus/trigger.py +10 -5
  37. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/slack/sender.py +1 -1
  38. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/model/config.py +21 -26
  39. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/config_loader.py +13 -4
  40. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/main.py +2 -0
  41. robusta_cli-0.10.27/src/robusta/runner/process_setup.py +18 -0
  42. robusta_cli-0.10.27/src/robusta/utils/__init__.py +0 -0
  43. robusta_cli-0.10.26a4/src/robusta/core/playbooks/base_trigger.py +0 -54
  44. robusta_cli-0.10.26a4/src/robusta/core/sinks/sink_base_params.py +0 -46
  45. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/LICENSE +0 -0
  46. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/__init__.py +0 -0
  47. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/api/__init__.py +0 -0
  48. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/__init__.py +0 -0
  49. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/auth.py +0 -0
  50. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/backend_profile.py +0 -0
  51. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/eula.py +0 -0
  52. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/integrations_cmd.py +0 -0
  53. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/playbooks_cmd.py +0 -0
  54. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/self_host.py +0 -0
  55. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/slack_feedback_message.py +0 -0
  56. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/slack_verification.py +0 -0
  57. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/cli/utils.py +0 -0
  58. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/__init__.py +0 -0
  59. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/discovery/__init__.py +0 -0
  60. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/discovery/resource_names.py +0 -0
  61. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/discovery/top_service_resolver.py +0 -0
  62. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/discovery/utils.py +0 -0
  63. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/exceptions.py +0 -0
  64. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/__init__.py +0 -0
  65. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/base_params.py +0 -0
  66. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/events.py +0 -0
  67. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/helm_release.py +0 -0
  68. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/jobs.py +0 -0
  69. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/k8s_operation_type.py +0 -0
  70. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/namespaces.py +0 -0
  71. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/nodes.py +0 -0
  72. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/pods.py +0 -0
  73. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/runner_config.py +0 -0
  74. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/model/services.py +0 -0
  75. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/persistency/__init__.py +0 -0
  76. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/persistency/in_memory.py +0 -0
  77. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/persistency/scheduled_jobs_states_dal.py +0 -0
  78. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/__init__.py +0 -0
  79. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/actions_registry.py +0 -0
  80. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/common.py +0 -0
  81. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/container_playbook_utils.py +0 -0
  82. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/generation.py +0 -0
  83. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/job_utils.py +0 -0
  84. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/node_playbook_utils.py +0 -0
  85. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/oom_killer_utils.py +0 -0
  86. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/playbook_utils.py +0 -0
  87. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/playbooks_event_handler.py +0 -0
  88. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/pod_utils/crashloop_utils.py +0 -0
  89. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/pod_utils/imagepull_utils.py +0 -0
  90. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/pod_utils/pending_pod_utils.py +0 -0
  91. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/prometheus_enrichment_utils.py +0 -0
  92. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/playbooks/trigger.py +0 -0
  93. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/reporting/__init__.py +0 -0
  94. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/reporting/action_requests.py +0 -0
  95. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/reporting/base.py +0 -0
  96. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/reporting/blocks.py +0 -0
  97. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/reporting/callbacks.py +0 -0
  98. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/reporting/consts.py +0 -0
  99. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/reporting/custom_rendering.py +0 -0
  100. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/reporting/finding_subjects.py +0 -0
  101. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/reporting/utils.py +0 -0
  102. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/schedule/__init__.py +0 -0
  103. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/schedule/model.py +0 -0
  104. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/__init__.py +0 -0
  105. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/datadog/__init__.py +0 -0
  106. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/datadog/datadog_sink.py +0 -0
  107. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/datadog/datadog_sink_params.py +0 -0
  108. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/discord/__init__.py +0 -0
  109. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/discord/discord_sink.py +0 -0
  110. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/discord/discord_sink_params.py +0 -0
  111. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/file/__init__.py +0 -0
  112. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/file/file_sink.py +0 -0
  113. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/file/file_sink_params.py +0 -0
  114. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/file/object_traverser.py +0 -0
  115. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/jira/__init__.py +0 -0
  116. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/jira/jira_sink.py +0 -0
  117. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/jira/jira_sink_params.py +0 -0
  118. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/kafka/__init__.py +0 -0
  119. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/kafka/kafka_sink.py +0 -0
  120. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/kafka/kafka_sink_params.py +0 -0
  121. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/mail/__init__.py +0 -0
  122. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/mail/mail_sink.py +0 -0
  123. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/mail/mail_sink_params.py +0 -0
  124. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/mattermost/__init__.py +0 -0
  125. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/mattermost/mattermost_sink.py +0 -0
  126. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/mattermost/mattermost_sink_params.py +0 -0
  127. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/msteams/__init__.py +0 -0
  128. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/msteams/msteams_sink.py +0 -0
  129. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/msteams/msteams_sink_params.py +0 -0
  130. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/opsgenie/__init__.py +0 -0
  131. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/opsgenie/opsgenie_sink.py +0 -0
  132. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/opsgenie/opsgenie_sink_params.py +0 -0
  133. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/pagerduty/__init__.py +0 -0
  134. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/pagerduty/pagerduty_sink_params.py +0 -0
  135. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/robusta/__init__.py +0 -0
  136. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/robusta/dal/__init__.py +0 -0
  137. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/robusta/dal/model_conversion.py +0 -0
  138. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/robusta/discovery_metrics.py +0 -0
  139. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/robusta/robusta_sink_params.py +0 -0
  140. {robusta_cli-0.10.26a4/src/robusta/core/sinks/rocketchat → robusta_cli-0.10.27/src/robusta/core/sinks/robusta/rrm}/__init__.py +0 -0
  141. {robusta_cli-0.10.26a4/src/robusta/integrations → robusta_cli-0.10.27/src/robusta/core/sinks/rocketchat}/__init__.py +0 -0
  142. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/rocketchat/rocketchat_sink.py +0 -0
  143. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/rocketchat/rocketchat_sink_params.py +0 -0
  144. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/sink_config.py +0 -0
  145. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/sink_factory.py +0 -0
  146. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/slack/__init__.py +0 -0
  147. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/slack/slack_sink.py +0 -0
  148. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/telegram/__init__.py +0 -0
  149. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/telegram/telegram_client.py +0 -0
  150. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/telegram/telegram_sink.py +0 -0
  151. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/telegram/telegram_sink_params.py +0 -0
  152. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/victorops/__init__.py +0 -0
  153. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/victorops/victorops_sink.py +0 -0
  154. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/victorops/victorops_sink_params.py +0 -0
  155. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/webex/__init__.py +0 -0
  156. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/webex/webex_sink.py +0 -0
  157. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/webex/webex_sink_params.py +0 -0
  158. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/webhook/__init__.py +0 -0
  159. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/webhook/webhook_sink.py +0 -0
  160. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/webhook/webhook_sink_params.py +0 -0
  161. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/yamessenger/__init__.py +0 -0
  162. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/yamessenger/yamessenger_client.py +0 -0
  163. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/yamessenger/yamessenger_sink.py +0 -0
  164. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/sinks/yamessenger/yamessenger_sink_params.py +0 -0
  165. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/triggers/container_oom_killed_trigger.py +0 -0
  166. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/core/triggers/pod_oom_killed_trigger.py +0 -0
  167. {robusta_cli-0.10.26a4/src/robusta/integrations/common → robusta_cli-0.10.27/src/robusta/integrations}/__init__.py +0 -0
  168. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/argocd/argocd_client.py +0 -0
  169. {robusta_cli-0.10.26a4/src/robusta/integrations/discord → robusta_cli-0.10.27/src/robusta/integrations/common}/__init__.py +0 -0
  170. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/common/requests.py +0 -0
  171. {robusta_cli-0.10.26a4/src/robusta/integrations/git → robusta_cli-0.10.27/src/robusta/integrations/discord}/__init__.py +0 -0
  172. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/discord/sender.py +0 -0
  173. {robusta_cli-0.10.26a4/src/robusta/integrations/jira → robusta_cli-0.10.27/src/robusta/integrations/git}/__init__.py +0 -0
  174. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/git/git_repo.py +0 -0
  175. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/grafana.py +0 -0
  176. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/helper.py +0 -0
  177. {robusta_cli-0.10.26a4/src/robusta/integrations/kubernetes → robusta_cli-0.10.27/src/robusta/integrations/jira}/__init__.py +0 -0
  178. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/jira/client.py +0 -0
  179. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/jira/sender.py +0 -0
  180. {robusta_cli-0.10.26a4/src/robusta/integrations/kubernetes/autogenerated → robusta_cli-0.10.27/src/robusta/integrations/kubernetes}/__init__.py +0 -0
  181. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/api_client_utils.py +0 -0
  182. {robusta_cli-0.10.26a4/src/robusta/integrations/kubernetes/autogenerated/v1 → robusta_cli-0.10.27/src/robusta/integrations/kubernetes/autogenerated}/__init__.py +0 -0
  183. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/autogenerated/events.py +0 -0
  184. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/autogenerated/models.py +0 -0
  185. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/autogenerated/triggers.py +0 -0
  186. {robusta_cli-0.10.26a4/src/robusta/integrations/mail → robusta_cli-0.10.27/src/robusta/integrations/kubernetes/autogenerated/v1}/__init__.py +0 -0
  187. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/autogenerated/v1/models.py +0 -0
  188. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/base_event.py +0 -0
  189. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/custom_models.py +0 -0
  190. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/model_not_found_exception.py +0 -0
  191. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/process_utils.py +0 -0
  192. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/kubernetes/templates.py +0 -0
  193. {robusta_cli-0.10.26a4/src/robusta/integrations/mattermost → robusta_cli-0.10.27/src/robusta/integrations/mail}/__init__.py +0 -0
  194. {robusta_cli-0.10.26a4/src/robusta/integrations/msteams/msteams_elements → robusta_cli-0.10.27/src/robusta/integrations/mattermost}/__init__.py +0 -0
  195. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/mattermost/client.py +0 -0
  196. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/mattermost/sender.py +0 -0
  197. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/__init__.py +0 -0
  198. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_adaptive_card_files.py +0 -0
  199. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_adaptive_card_files_image.py +0 -0
  200. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_adaptive_card_files_text.py +0 -0
  201. {robusta_cli-0.10.26a4/src/robusta/integrations/prometheus → robusta_cli-0.10.27/src/robusta/integrations/msteams/msteams_elements}/__init__.py +0 -0
  202. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_elements/msteams_action.py +0 -0
  203. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_elements/msteams_base.py +0 -0
  204. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_elements/msteams_card.py +0 -0
  205. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_elements/msteams_column.py +0 -0
  206. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_elements/msteams_container.py +0 -0
  207. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_elements/msteams_images.py +0 -0
  208. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_elements/msteams_table.py +0 -0
  209. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_elements/msteams_text_block.py +0 -0
  210. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_mark_down_fix_url.py +0 -0
  211. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/msteams_msg.py +0 -0
  212. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/msteams/sender.py +0 -0
  213. {robusta_cli-0.10.26a4/src/robusta/integrations/resource_analysis → robusta_cli-0.10.27/src/robusta/integrations/prometheus}/__init__.py +0 -0
  214. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/prometheus/models.py +0 -0
  215. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/prometheus/utils.py +0 -0
  216. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/receiver.py +0 -0
  217. {robusta_cli-0.10.26a4/src/robusta/integrations/rocketchat → robusta_cli-0.10.27/src/robusta/integrations/resource_analysis}/__init__.py +0 -0
  218. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/resource_analysis/cpu_analyzer.py +0 -0
  219. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/resource_analysis/memory_analyzer.py +0 -0
  220. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/resource_analysis/node_cpu_analyzer.py +0 -0
  221. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/resource_analysis/prometheus_analyzer.py +0 -0
  222. {robusta_cli-0.10.26a4/src/robusta/integrations/scheduled → robusta_cli-0.10.27/src/robusta/integrations/rocketchat}/__init__.py +0 -0
  223. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/rocketchat/sender.py +0 -0
  224. {robusta_cli-0.10.26a4/src/robusta/integrations/webex → robusta_cli-0.10.27/src/robusta/integrations/scheduled}/__init__.py +0 -0
  225. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/scheduled/event.py +0 -0
  226. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/scheduled/models.py +0 -0
  227. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/scheduled/playbook_scheduler.py +0 -0
  228. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/scheduled/playbook_scheduler_manager.py +0 -0
  229. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/scheduled/playbook_scheduler_manager_impl.py +0 -0
  230. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/scheduled/trigger.py +0 -0
  231. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/slack/__init__.py +0 -0
  232. {robusta_cli-0.10.26a4/src/robusta/runner → robusta_cli-0.10.27/src/robusta/integrations/webex}/__init__.py +0 -0
  233. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/integrations/webex/sender.py +0 -0
  234. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/model/alert_relabel_config.py +0 -0
  235. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/model/playbook_action.py +0 -0
  236. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/model/playbook_definition.py +0 -0
  237. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/patch/patch.py +0 -0
  238. {robusta_cli-0.10.26a4/src/robusta/utils → robusta_cli-0.10.27/src/robusta/runner}/__init__.py +0 -0
  239. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/log_init.py +0 -0
  240. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/not_found_exception.py +0 -0
  241. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/object_updater.py +0 -0
  242. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/ssl_utils.py +0 -0
  243. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/telemetry.py +0 -0
  244. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/telemetry_service.py +0 -0
  245. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/web.py +0 -0
  246. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/runner/web_api.py +0 -0
  247. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/auth_provider.py +0 -0
  248. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/base64_utils.py +0 -0
  249. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/cluster_provider_discovery.py +0 -0
  250. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/common.py +0 -0
  251. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/decorators.py +0 -0
  252. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/docs.py +0 -0
  253. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/documented_pydantic.py +0 -0
  254. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/error_codes.py +0 -0
  255. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/file_system_watcher.py +0 -0
  256. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/function_hashes.py +0 -0
  257. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/json_schema.py +0 -0
  258. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/parsing.py +0 -0
  259. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/rate_limiter.py +0 -0
  260. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/server_start.py +0 -0
  261. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/service_discovery.py +0 -0
  262. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/silence_utils.py +0 -0
  263. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/stack_tracer.py +0 -0
  264. {robusta_cli-0.10.26a4 → robusta_cli-0.10.27}/src/robusta/utils/task_queue.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robusta-cli
3
- Version: 0.10.26a4
3
+ Version: 0.10.27
4
4
  Summary:
5
5
  Author: Natan Yellin
6
6
  Author-email: aantn@users.noreply.github.com
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "robusta-cli"
3
- version = "0.10.26-alpha4"
3
+ version = "0.10.27"
4
4
  description = ""
5
5
  authors = ["Natan Yellin <aantn@users.noreply.github.com>"]
6
6
  packages = [
@@ -115,6 +115,7 @@ all = ["Flask", "grafana-api", "watchdog", "dulwich", "better-exceptions", "Cair
115
115
  [tool.poetry.group.dev.dependencies]
116
116
  sphinx-jinja = { git = "https://github.com/robusta-dev/sphinx-jinja.git" }
117
117
  sphinx-reredirects = "^0.1.1"
118
+ freezegun = "^1.4.0"
118
119
 
119
120
  [build-system]
120
121
  requires = ["poetry-core>=1.0.0"]
@@ -1,2 +1,2 @@
1
1
  # this is updated by .github/workflows/release.yaml
2
- __version__ = "0.10.26-alpha4"
2
+ __version__ = "0.10.27"
@@ -11,7 +11,7 @@ from typing import Dict, List, Optional, Union
11
11
  import certifi
12
12
  import typer
13
13
  import yaml
14
- from hikaru.model.rel_1_26 import Container, Job, JobSpec, ObjectMeta, PodSpec, PodTemplateSpec
14
+ from hikaru.model.rel_1_26 import Container, Job, JobSpec, ObjectMeta, PodSpec, PodTemplateSpec, SecurityContext
15
15
  from kubernetes import client, config
16
16
  from pydantic import BaseModel, Extra
17
17
 
@@ -501,6 +501,7 @@ def demo_alert(
501
501
  name="alert-curl",
502
502
  image=image,
503
503
  command=command,
504
+ securityContext=SecurityContext(runAsUser=2000),
504
505
  )
505
506
  ],
506
507
  restartPolicy="Never",
@@ -364,7 +364,7 @@ class Discovery:
364
364
  # we use map here to deduplicate and pick only the latest release data
365
365
  helm_releases_map[decoded_release_row.get_service_key()] = decoded_release_row
366
366
  except Exception as e:
367
- logging.error(f"an error occured while decoding helm releases: {e}")
367
+ logging.error(f"an error occurred while decoding helm releases: {e}")
368
368
 
369
369
  continue_ref = secrets.metadata._continue
370
370
  if not continue_ref:
@@ -1,3 +1,5 @@
1
+ from datetime import datetime
2
+
1
3
  from pydantic.main import BaseModel, List, Optional
2
4
 
3
5
 
@@ -18,6 +20,7 @@ class ActivityStats(BaseModel):
18
20
  alertManagerConnection: bool
19
21
  prometheusConnection: bool
20
22
  prometheusRetentionTime: str
23
+ managedPrometheusAlerts: bool
21
24
 
22
25
 
23
26
  class ClusterStatus(BaseModel):
@@ -34,12 +34,12 @@ INTERNAL_PLAYBOOKS_ROOT = os.environ.get("INTERNAL_PLAYBOOKS_ROOT", "/app/src/ro
34
34
  DEFAULT_TIMEZONE = pytz.timezone(os.environ.get("DEFAULT_TIMEZONE", "UTC"))
35
35
  NUM_EVENT_THREADS = int(os.environ.get("NUM_EVENT_THREADS", 20))
36
36
  INCOMING_EVENTS_QUEUE_MAX_SIZE = int(os.environ.get("INCOMING_EVENTS_QUEUE_MAX_SIZE", 500))
37
- EVENT_PARSING_WORKERS = int(os.environ.get("EVENT_PARSING_WORKERS", 1))
38
37
 
39
38
  FLOAT_PRECISION_LIMIT = int(os.environ.get("FLOAT_PRECISION_LIMIT", 11))
40
39
 
41
40
  PROMETHEUS_REQUEST_TIMEOUT_SECONDS = float(os.environ.get("PROMETHEUS_REQUEST_TIMEOUT_SECONDS", 90.0))
42
41
  PROMETHEUS_ENABLED = os.environ.get("PROMETHEUS_ENABLED", "false").lower() == "true"
42
+ MANAGED_CONFIGURATION_ENABLED = os.environ.get("MANAGED_CONFIGURATION_ENABLED", "false").lower() == "true"
43
43
  PROMETHEUS_SSL_ENABLED = os.environ.get("PROMETHEUS_SSL_ENABLED", "false").lower() == "true"
44
44
 
45
45
  INCOMING_REQUEST_TIME_WINDOW_SECONDS = int(os.environ.get("INCOMING_REQUEST_TIME_WINDOW_SECONDS", 3600))
@@ -94,6 +94,10 @@ DISABLE_HELM_MONITORING = load_bool("DISABLE_HELM_MONITORING", False)
94
94
 
95
95
  PROMETHEUS_ERROR_LOG_PERIOD_SEC = int(os.environ.get("DISCOVERY_MAX_BATCHES", 14400))
96
96
 
97
+ RRM_PERIOD_SEC = int(os.environ.get("RRM_PERIOD_SEC", 90))
98
+
99
+ MAX_ALLOWED_RULES_PER_CRD_ALERT = int(os.environ.get("MAX_ALLOWED_RULES_PER_CRD_ALERT", 600))
100
+
97
101
  IMAGE_REGISTRY = os.environ.get("IMAGE_REGISTRY", "us-central1-docker.pkg.dev/genuine-flight-317411/devel")
98
102
 
99
103
  CLUSTER_DOMAIN = os.environ.get("CLUSTER_DOMAIN", "cluster.local")
@@ -0,0 +1,36 @@
1
+ import abc
2
+ from typing import Any, Dict, List, Optional, Type
3
+
4
+ from pydantic import BaseModel
5
+
6
+ from robusta.core.model.events import ExecutionBaseEvent
7
+ from robusta.core.reporting.base import Finding
8
+ from robusta.utils.documented_pydantic import DocumentedModel
9
+
10
+
11
+ class TriggerEvent(BaseModel):
12
+ @abc.abstractmethod
13
+ def get_event_name(self) -> str:
14
+ """Return trigger event name"""
15
+ return ""
16
+
17
+ def get_event_description(self) -> str:
18
+ """Returns a description of the concrete event"""
19
+ return "NA"
20
+
21
+
22
+ class BaseTrigger(DocumentedModel):
23
+ def get_trigger_event(self) -> str:
24
+ pass
25
+
26
+ def should_fire(self, event: TriggerEvent, playbook_id: str, build_context: Dict[str, Any]):
27
+ return True
28
+
29
+ def build_execution_event(
30
+ self, event: TriggerEvent, sink_findings: Dict[str, List[Finding]], build_context: Dict[str, Any]
31
+ ) -> Optional[ExecutionBaseEvent]:
32
+ pass
33
+
34
+ @staticmethod
35
+ def get_execution_event_type() -> Type[ExecutionBaseEvent]:
36
+ pass
@@ -63,7 +63,7 @@ def create_debug_event_finding(event: Event):
63
63
  Create finding based on the kubernetes event
64
64
  """
65
65
  k8s_obj = event.regarding
66
-
66
+ subject_type = FindingSubjectType.from_kind(k8s_obj.kind.lower()) if k8s_obj.kind else FindingSubjectType.TYPE_NONE
67
67
  finding = Finding(
68
68
  title=f"{event.reason} {event.type} for {k8s_obj.kind} {k8s_obj.namespace}/{k8s_obj.name}",
69
69
  description=event.note,
@@ -73,7 +73,7 @@ def create_debug_event_finding(event: Event):
73
73
  aggregation_key=f"Kubernetes {event.type} Event",
74
74
  subject=FindingSubject(
75
75
  k8s_obj.name,
76
- FindingSubjectType.from_kind(k8s_obj.kind.lower()),
76
+ subject_type,
77
77
  k8s_obj.namespace,
78
78
  ),
79
79
  creation_date=get_event_timestamp(event),
@@ -17,7 +17,6 @@ from robusta.core.playbooks.trigger import Trigger
17
17
  from robusta.core.reporting import MarkdownBlock
18
18
  from robusta.core.reporting.base import Finding
19
19
  from robusta.core.reporting.consts import SYNC_RESPONSE_SINK
20
- from robusta.core.sinks.robusta import RobustaSink
21
20
  from robusta.core.sinks.robusta.dal.model_conversion import ModelConversion
22
21
  from robusta.model.alert_relabel_config import AlertRelabel
23
22
  from robusta.model.config import Registry
@@ -46,12 +45,13 @@ class PlaybooksEventHandlerImpl(PlaybooksEventHandler):
46
45
  execution_response = None
47
46
  execution_event: Optional[ExecutionBaseEvent] = None
48
47
  sink_findings: Dict[str, List[Finding]] = defaultdict(list)
48
+ build_context: Dict[str, Any] = {}
49
49
  for playbook in playbooks:
50
- fired_trigger = self.__get_fired_trigger(trigger_event, playbook.triggers, playbook.get_id())
50
+ fired_trigger = self.__get_fired_trigger(trigger_event, playbook.triggers, playbook.get_id(), build_context)
51
51
  if fired_trigger:
52
52
  execution_event = None
53
53
  try:
54
- execution_event = fired_trigger.build_execution_event(trigger_event, sink_findings)
54
+ execution_event = fired_trigger.build_execution_event(trigger_event, sink_findings, build_context)
55
55
  # sink_findings needs to be shared between playbooks.
56
56
  # build_execution_event returns a different instance because it's running in a child process
57
57
  execution_event.sink_findings = sink_findings
@@ -281,9 +281,10 @@ class PlaybooksEventHandlerImpl(PlaybooksEventHandler):
281
281
  trigger_event: TriggerEvent,
282
282
  playbook_triggers: List[Trigger],
283
283
  playbook_id: str,
284
+ build_context: Dict[str, Any],
284
285
  ) -> Optional[BaseTrigger]:
285
286
  for trigger in playbook_triggers:
286
- if trigger.get().should_fire(trigger_event, playbook_id):
287
+ if trigger.get().should_fire(trigger_event, playbook_id, build_context):
287
288
  return trigger.get()
288
289
  return None
289
290
 
@@ -307,6 +308,11 @@ class PlaybooksEventHandlerImpl(PlaybooksEventHandler):
307
308
  # Each sink has a different findings, but enrichments are shared
308
309
  finding_copy = copy.deepcopy(finding)
309
310
  sink.write_finding(finding_copy, self.registry.get_sinks().platform_enabled)
311
+
312
+ sink_info = sinks_info[sink_name]
313
+ sink_info.type = sink.__class__.__name__
314
+ sink_info.findings_count += 1
315
+
310
316
  if sink.params.stop:
311
317
  return
312
318
 
@@ -14,7 +14,7 @@ from robusta.core.schedule.model import DynamicDelayRepeat, JobStatus, Scheduled
14
14
  # for a short time there are two runners running (old+new version) and they both
15
15
  # see the new scheduled playbook. we add a delay so that only the new runner ends up
16
16
  # running the scheduled playbook
17
- INITIAL_SCHEDULE_DELAY_SEC = os.environ.get("INITIAL_SCHEDULE_DELAY_SEC", 120)
17
+ INITIAL_SCHEDULE_DELAY_SEC = int(os.environ.get("INITIAL_SCHEDULE_DELAY_SEC", 120))
18
18
 
19
19
 
20
20
  class Scheduler:
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Dict, Any, Optional
2
+ from typing import Dict, Any, Optional, List
3
3
 
4
4
  import requests
5
5
 
@@ -233,7 +233,7 @@ class PagerdutySink(SinkBase):
233
233
  return ""
234
234
 
235
235
  @staticmethod
236
- def __to_unformatted_text_for_changes(block: KubernetesDiffBlock) -> Optional[list[str]]:
236
+ def __to_unformatted_text_for_changes(block: KubernetesDiffBlock) -> Optional[List[str]]:
237
237
  return list(map(
238
238
  lambda diff: diff.formatted_path,
239
239
  block.diffs,
@@ -1,9 +1,12 @@
1
1
  import json
2
2
  import logging
3
3
  import time
4
- from typing import Any, Dict, List
5
-
4
+ from collections import defaultdict
5
+ from datetime import datetime
6
+ from typing import Any, Dict, List, Optional
6
7
  import requests
8
+ from postgrest.base_request_builder import BaseFilterRequestBuilder
9
+ from postgrest.utils import sanitize_param
7
10
  from postgrest.types import ReturnMethod
8
11
  from supabase import create_client
9
12
  from supabase.lib.client_options import ClientOptions
@@ -19,8 +22,10 @@ from robusta.core.reporting import Enrichment
19
22
  from robusta.core.reporting.base import Finding
20
23
  from robusta.core.reporting.blocks import EventsBlock, EventsRef, ScanReportBlock, ScanReportRow
21
24
  from robusta.core.reporting.consts import EnrichmentAnnotation
22
- from robusta.core.sinks.robusta import RobustaSinkParams
23
25
  from robusta.core.sinks.robusta.dal.model_conversion import ModelConversion
26
+ from robusta.core.sinks.robusta.rrm.account_resource_fetcher import AccountResourceFetcher
27
+ from robusta.core.sinks.robusta.rrm.types import AccountResource, ResourceKind, \
28
+ AccountResourceStatusType, AccountResourceStatusInfo
24
29
 
25
30
  SERVICES_TABLE = "Services"
26
31
  NODES_TABLE = "Nodes"
@@ -33,19 +38,22 @@ NAMESPACES_TABLE = "Namespaces"
33
38
  UPDATE_CLUSTER_NODE_COUNT = "update_cluster_node_count"
34
39
  SCANS_RESULT_TABLE = "ScansResults"
35
40
  RESOURCE_EVENTS = "ResourceEvents"
41
+ ACCOUNT_RESOURCE_TABLE = "AccountResource"
42
+ ACCOUNT_RESOURCE_STATUS_TABLE = "AccountResourceStatus"
36
43
 
37
44
 
38
- class SupabaseDal:
45
+ class SupabaseDal(AccountResourceFetcher):
39
46
  def __init__(
40
- self,
41
- url: str,
42
- key: str,
43
- account_id: str,
44
- email: str,
45
- password: str,
46
- sink_params: RobustaSinkParams,
47
- cluster_name: str,
48
- signing_key: str,
47
+ self,
48
+ url: str,
49
+ key: str,
50
+ account_id: str,
51
+ email: str,
52
+ password: str,
53
+ sink_name: str,
54
+ persist_events: bool,
55
+ cluster_name: str,
56
+ signing_key: str,
49
57
  ):
50
58
  httpx_logger = logging.getLogger("httpx")
51
59
  if httpx_logger:
@@ -62,7 +70,8 @@ class SupabaseDal:
62
70
  self.sign_in_time = 0
63
71
  self.sign_in()
64
72
  self.client.auth.on_auth_state_change(self.__update_token_patch)
65
- self.sink_params = sink_params
73
+ self.sink_name = sink_name
74
+ self.persist_events = persist_events
66
75
  self.signing_key = signing_key
67
76
 
68
77
  def __to_db_scanResult(self, scanResult: ScanReportRow) -> Dict[Any, Any]:
@@ -115,7 +124,7 @@ class SupabaseDal:
115
124
  evidence = ModelConversion.to_evidence_json(
116
125
  account_id=self.account_id,
117
126
  cluster_id=self.cluster,
118
- sink_name=self.sink_params.name,
127
+ sink_name=self.sink_name,
119
128
  signing_key=self.signing_key,
120
129
  finding_id=finding.id,
121
130
  enrichment=enrichment,
@@ -176,15 +185,8 @@ class SupabaseDal:
176
185
  res = (
177
186
  self.client.table(SERVICES_TABLE)
178
187
  .select(
179
- "name",
180
- "type",
181
- "namespace",
182
- "classification",
183
- "config",
184
- "ready_pods",
185
- "total_pods",
186
- "is_helm_release",
187
- )
188
+ "name", "type", "namespace", "classification", "config", "ready_pods", "total_pods",
189
+ "is_helm_release")
188
190
  .filter("account_id", "eq", self.account_id)
189
191
  .filter("cluster", "eq", self.cluster)
190
192
  .filter("deleted", "eq", False)
@@ -284,6 +286,14 @@ class SupabaseDal:
284
286
  self.handle_supabase_error()
285
287
  raise
286
288
 
289
+ @staticmethod
290
+ def custom_filter_request_builder(frq: BaseFilterRequestBuilder, operator: str,
291
+ criteria: str) -> BaseFilterRequestBuilder:
292
+ key, val = sanitize_param(operator), f"{criteria}"
293
+ frq.params = frq.params.set(key, val)
294
+
295
+ return frq
296
+
287
297
  def get_active_jobs(self) -> List[JobInfo]:
288
298
  try:
289
299
  res = (
@@ -499,13 +509,105 @@ class SupabaseDal:
499
509
  def persist_platform_blocks(self, enrichment: Enrichment, finding_id):
500
510
  blocks = enrichment.blocks
501
511
  for i, block in enumerate(blocks):
502
- if isinstance(block, EventsBlock) and self.sink_params.persist_events and block.events:
512
+ if isinstance(block, EventsBlock) and self.persist_events and block.events:
503
513
  self.persist_events_block(block)
504
514
  event = block.events[0]
505
515
  blocks[i] = EventsRef(name=event.name, namespace=event.namespace, kind=event.kind.lower())
506
516
  if isinstance(block, ScanReportBlock):
507
517
  self.persist_scan(block)
508
518
 
519
+ def get_account_resources(
520
+ self,
521
+ resource_kind: Optional[ResourceKind] = None,
522
+ latest_revision: Optional[datetime] = None,
523
+ ) -> Dict[ResourceKind, List[AccountResource]]:
524
+ try:
525
+ query_builder = (
526
+ self.client.table(ACCOUNT_RESOURCE_TABLE)
527
+ .select("entity_id", "resource_kind", "clusters_target_set", "resource_state", "deleted", "enabled",
528
+ "updated_at")
529
+ .eq("account_id", self.account_id)
530
+ )
531
+
532
+ if resource_kind:
533
+ query_builder.eq("resource_kind", resource_kind)
534
+
535
+ if latest_revision:
536
+ query_builder.gt("updated_at", latest_revision.isoformat())
537
+ else:
538
+ # in the initial db fetch don't include the deleted records.
539
+ # in the subsequent db fetch allow even the deleted records so that they can be removed from the cluster
540
+ query_builder.eq("deleted", False)
541
+ query_builder.eq("enabled", True)
542
+
543
+ query_builder = SupabaseDal.custom_filter_request_builder(
544
+ query_builder,
545
+ operator="or",
546
+ criteria=f'(clusters_target_set.cs.["*"], clusters_target_set.cs.["{self.cluster}"])',
547
+ )
548
+ query_builder = query_builder.order(column="updated_at", desc=False)
549
+
550
+ res = query_builder.execute()
551
+ except Exception as e:
552
+ msg = f"Failed to get existing account resources (supabase) error"
553
+ logging.error(msg, exc_info=True)
554
+ self.handle_supabase_error()
555
+ raise e
556
+
557
+ account_resources_map: Dict[ResourceKind, List[AccountResource]] = defaultdict(list)
558
+
559
+ for data in res.data:
560
+ resource = AccountResource(
561
+ entity_id=data["entity_id"],
562
+ resource_kind=data["resource_kind"],
563
+ clusters_target_set=data["clusters_target_set"],
564
+ resource_state=data["resource_state"],
565
+ deleted=data["deleted"],
566
+ enabled=data["enabled"],
567
+ updated_at=data["updated_at"],
568
+ )
569
+
570
+ account_resources_map[resource.resource_kind].append(resource)
571
+
572
+ return account_resources_map
573
+
574
+ def __to_db_account_resource_status(
575
+ self,
576
+ status_type: AccountResourceStatusType,
577
+ latest_revision: datetime,
578
+ info: Optional[AccountResourceStatusInfo] = None,
579
+ ) -> Dict[Any, Any]:
580
+ latest_revision_iso = latest_revision.isoformat()
581
+ data = {
582
+ "account_id": self.account_id,
583
+ "cluster_id": self.cluster,
584
+ "status": status_type,
585
+ "info": info.dict() if info else None,
586
+ "updated_at": "now()",
587
+ "latest_revision": latest_revision_iso,
588
+ }
589
+
590
+ if status_type != AccountResourceStatusType.error:
591
+ data["synced_revision"] = latest_revision_iso
592
+
593
+ return data
594
+
595
+ def set_account_resource_status(
596
+ self,
597
+ status_type: AccountResourceStatusType,
598
+ info: Optional[AccountResourceStatusInfo],
599
+ latest_revision: datetime
600
+ ):
601
+ try:
602
+ data = self.__to_db_account_resource_status(status_type=status_type, info=info,
603
+ latest_revision=latest_revision)
604
+
605
+ self.client.table(ACCOUNT_RESOURCE_STATUS_TABLE).upsert(data).execute()
606
+ except Exception as e:
607
+ logging.error(f"Failed to set account resource status to {status_type}", exc_info=True)
608
+ self.handle_supabase_error()
609
+ raise
610
+
509
611
  def __rpc_patch(self, func_name: str, params: dict) -> Dict[str, Any]:
510
612
  """
511
613
  Supabase client is async. Sync impl of rpc call
@@ -31,7 +31,7 @@ class PrometheusHealthChecker:
31
31
 
32
32
  self.__last_alertmanager_error_log_time = 0
33
33
  self.__last_prometheus_error_log_time = 0
34
- self.__check_prometheus_flags = True
34
+ self.__check_prometheus_flags = global_config.get("check_prometheus_flags", True)
35
35
 
36
36
  self.__thread = threading.Thread(target=self.__run_checks)
37
37
  self.__thread.start()
@@ -11,13 +11,12 @@ from kubernetes.client import V1Node, V1NodeCondition, V1NodeList, V1Taint
11
11
 
12
12
  from robusta.core.discovery.discovery import DISCOVERY_STACKTRACE_TIMEOUT_S, Discovery, DiscoveryResults
13
13
  from robusta.core.discovery.top_service_resolver import TopLevelResource, TopServiceResolver
14
- from robusta.core.model.cluster_status import ActivityStats, ClusterStats, ClusterStatus
15
14
  from robusta.core.model.env_vars import (
16
- CLUSTER_STATUS_PERIOD_SEC,
17
- DISCOVERY_CHECK_THRESHOLD_SEC,
18
- DISCOVERY_PERIOD_SEC,
19
15
  DISCOVERY_WATCHDOG_CHECK_SEC,
20
16
  )
17
+ from robusta.core.model.cluster_status import ActivityStats, ClusterStats, ClusterStatus
18
+ from robusta.core.model.env_vars import CLUSTER_STATUS_PERIOD_SEC, DISCOVERY_CHECK_THRESHOLD_SEC, DISCOVERY_PERIOD_SEC, \
19
+ MANAGED_CONFIGURATION_ENABLED
21
20
  from robusta.core.model.helm_release import HelmRelease
22
21
  from robusta.core.model.jobs import JobInfo
23
22
  from robusta.core.model.k8s_operation_type import K8sOperationType
@@ -29,6 +28,7 @@ from robusta.core.reporting.base import Finding
29
28
  from robusta.core.sinks.robusta.discovery_metrics import DiscoveryMetrics
30
29
  from robusta.core.sinks.robusta.prometheus_health_checker import PrometheusHealthChecker
31
30
  from robusta.core.sinks.robusta.robusta_sink_params import RobustaSinkConfigWrapper, RobustaToken
31
+ from robusta.core.sinks.robusta.rrm.rrm import RRM
32
32
  from robusta.core.sinks.sink_base import SinkBase
33
33
  from robusta.integrations.receiver import ActionRequestReceiver
34
34
  from robusta.runner.web_api import WebApi
@@ -62,7 +62,8 @@ class RobustaSink(SinkBase):
62
62
  robusta_token.account_id,
63
63
  robusta_token.email,
64
64
  robusta_token.password,
65
- sink_config.robusta_sink,
65
+ sink_config.robusta_sink.name,
66
+ sink_config.robusta_sink.persist_events,
66
67
  self.cluster_name,
67
68
  self.signing_key,
68
69
  )
@@ -71,9 +72,11 @@ class RobustaSink(SinkBase):
71
72
  self.last_send_time = 0
72
73
  self.__discovery_period_sec = DISCOVERY_PERIOD_SEC
73
74
 
75
+ global_config = self.get_global_config()
74
76
  self.__prometheus_health_checker = PrometheusHealthChecker(
75
- discovery_period_sec=self.__discovery_period_sec, global_config=self.get_global_config()
77
+ discovery_period_sec=self.__discovery_period_sec, global_config=global_config
76
78
  )
79
+ self.__rrm_checker = RRM(dal=self.dal, cluster=self.cluster_name, account_id=self.account_id)
77
80
  self.__pods_running_count: int = 0
78
81
  self.__update_cluster_status() # send runner version initially, then force prometheus alert time periodically.
79
82
 
@@ -215,7 +218,7 @@ class RobustaSink(SinkBase):
215
218
 
216
219
  except Exception as e:
217
220
  logging.error(
218
- f"An error occured while publishing single service: name - {new_service.name}, namespace - {new_service.namespace} service type: {new_service.service_type} | {e}"
221
+ f"An error occurred while publishing single service: name - {new_service.name}, namespace - {new_service.namespace} service type: {new_service.service_type} | {e}"
219
222
  )
220
223
 
221
224
  def __publish_new_services(self, active_services: List[ServiceInfo]):
@@ -277,11 +280,11 @@ class RobustaSink(SinkBase):
277
280
  timeout_delay=30,
278
281
  )
279
282
  if response != 200:
280
- logging.error("Error occured while sending `helm release trigger event`")
283
+ logging.error("Error occurred while sending `helm release trigger event`")
281
284
  else:
282
285
  logging.debug("Sent `helm release` trigger event.")
283
286
  except Exception:
284
- logging.error("Error occured while sending `helm release` trigger event", exc_info=True)
287
+ logging.error("Error occurred while sending `helm release` trigger event", exc_info=True)
285
288
 
286
289
  def __discover_resources(self) -> DiscoveryResults:
287
290
  # discovery is using the k8s python API and not Hikaru, since it's performance is 10 times better
@@ -463,7 +466,7 @@ class RobustaSink(SinkBase):
463
466
  for helm_release_key in curr_helm_releases.keys():
464
467
  current_helm_release = curr_helm_releases[helm_release_key]
465
468
  if (
466
- self.__helm_releases_cache.get(helm_release_key) != current_helm_release
469
+ self.__helm_releases_cache.get(helm_release_key) != current_helm_release
467
470
  ): # helm_release not in the cache, or changed
468
471
  helm_releases.append(current_helm_release)
469
472
  self.__helm_releases_cache[helm_release_key] = current_helm_release
@@ -478,6 +481,7 @@ class RobustaSink(SinkBase):
478
481
  alertManagerConnection=prometheus_health_checker_status.alertmanager,
479
482
  prometheusConnection=prometheus_health_checker_status.prometheus,
480
483
  prometheusRetentionTime=prometheus_health_checker_status.prometheus_retention_time,
484
+ managedPrometheusAlerts=MANAGED_CONFIGURATION_ENABLED
481
485
  )
482
486
 
483
487
  # checking the status of relay connection
@@ -0,0 +1,22 @@
1
+ from abc import ABC, abstractmethod
2
+ from datetime import datetime
3
+ from typing import List, Optional, Dict
4
+
5
+ from robusta.core.sinks.robusta.rrm.types import AccountResource, ResourceKind, AccountResourceStatusType, \
6
+ AccountResourceStatusInfo
7
+
8
+
9
+ class AccountResourceFetcher(ABC):
10
+ @abstractmethod
11
+ def get_account_resources(
12
+ self, resource_kind: Optional[ResourceKind] = None, latest_revision: Optional[datetime] = None,
13
+ ) -> Dict[ResourceKind, List[AccountResource]]:
14
+ pass
15
+
16
+ @abstractmethod
17
+ def set_account_resource_status(
18
+ self, status_type: AccountResourceStatusType,
19
+ info: Optional[AccountResourceStatusInfo],
20
+ latest_revision: datetime
21
+ ):
22
+ pass
@@ -0,0 +1,13 @@
1
+ from typing import Optional, List
2
+
3
+ from robusta.core.sinks.robusta.rrm.types import ResourceKind, AccountResource
4
+
5
+
6
+ class BaseResourceHandler:
7
+ def __init__(self, resource_kind: ResourceKind, cluster: str):
8
+ self.__latest_revision = None
9
+ self._resource_kind = resource_kind
10
+ self.cluster = cluster
11
+
12
+ def handle_resources(self, resources: List[AccountResource]) -> Optional[str]:
13
+ pass