robusta-cli 0.10.25__tar.gz → 0.10.26a1__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 (259) hide show
  1. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/PKG-INFO +6 -5
  2. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/pyproject.toml +11 -8
  3. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/_version.py +1 -1
  4. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/discovery/discovery.py +1 -1
  5. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/cluster_status.py +11 -0
  6. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/env_vars.py +5 -0
  7. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/runner_config.py +4 -1
  8. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/common.py +1 -1
  9. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/container_playbook_utils.py +18 -6
  10. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/prometheus_enrichment_utils.py +90 -22
  11. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/reporting/base.py +2 -1
  12. robusta_cli-0.10.26a1/src/robusta/core/reporting/custom_rendering.py +76 -0
  13. robusta_cli-0.10.26a1/src/robusta/core/sinks/mail/mail_sink.py +18 -0
  14. robusta_cli-0.10.26a1/src/robusta/core/sinks/mail/mail_sink_params.py +23 -0
  15. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/opsgenie/opsgenie_sink.py +2 -1
  16. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/pagerduty/pagerduty_sink.py +2 -2
  17. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/robusta/dal/supabase_dal.py +116 -26
  18. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/robusta/robusta_sink.py +14 -7
  19. robusta_cli-0.10.26a1/src/robusta/core/sinks/robusta/rrm/account_resource_fetcher.py +21 -0
  20. robusta_cli-0.10.26a1/src/robusta/core/sinks/robusta/rrm/base_resource_manager.py +37 -0
  21. robusta_cli-0.10.26a1/src/robusta/core/sinks/robusta/rrm/prometheus_alert_resource_manager.py +288 -0
  22. robusta_cli-0.10.26a1/src/robusta/core/sinks/robusta/rrm/rrm.py +59 -0
  23. robusta_cli-0.10.26a1/src/robusta/core/sinks/robusta/rrm/types.py +107 -0
  24. robusta_cli-0.10.26a1/src/robusta/core/sinks/rocketchat/rocketchat_sink.py +19 -0
  25. robusta_cli-0.10.26a1/src/robusta/core/sinks/rocketchat/rocketchat_sink_params.py +23 -0
  26. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/sink_factory.py +7 -0
  27. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/transformer.py +45 -32
  28. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/webhook/webhook_sink.py +2 -2
  29. robusta_cli-0.10.26a1/src/robusta/integrations/mail/sender.py +202 -0
  30. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/mattermost/client.py +6 -1
  31. robusta_cli-0.10.26a1/src/robusta/integrations/rocketchat/__init__.py +0 -0
  32. robusta_cli-0.10.26a1/src/robusta/integrations/rocketchat/sender.py +366 -0
  33. robusta_cli-0.10.26a1/src/robusta/integrations/scheduled/__init__.py +0 -0
  34. robusta_cli-0.10.26a1/src/robusta/integrations/webex/__init__.py +0 -0
  35. robusta_cli-0.10.26a1/src/robusta/runner/__init__.py +0 -0
  36. robusta_cli-0.10.26a1/src/robusta/utils/__init__.py +0 -0
  37. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/common.py +7 -0
  38. robusta_cli-0.10.25/src/robusta/core/reporting/custom_rendering.py +0 -38
  39. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/LICENSE +0 -0
  40. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/__init__.py +0 -0
  41. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/api/__init__.py +0 -0
  42. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/__init__.py +0 -0
  43. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/auth.py +0 -0
  44. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/backend_profile.py +0 -0
  45. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/eula.py +0 -0
  46. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/integrations_cmd.py +0 -0
  47. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/main.py +0 -0
  48. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/playbooks_cmd.py +0 -0
  49. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/self_host.py +0 -0
  50. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/slack_feedback_message.py +0 -0
  51. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/slack_verification.py +0 -0
  52. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/cli/utils.py +0 -0
  53. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/__init__.py +0 -0
  54. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/discovery/__init__.py +0 -0
  55. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/discovery/resource_names.py +0 -0
  56. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/discovery/top_service_resolver.py +0 -0
  57. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/discovery/utils.py +0 -0
  58. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/exceptions.py +0 -0
  59. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/__init__.py +0 -0
  60. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/base_params.py +0 -0
  61. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/events.py +0 -0
  62. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/helm_release.py +0 -0
  63. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/jobs.py +0 -0
  64. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/k8s_operation_type.py +0 -0
  65. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/namespaces.py +0 -0
  66. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/nodes.py +0 -0
  67. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/pods.py +0 -0
  68. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/model/services.py +0 -0
  69. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/persistency/__init__.py +0 -0
  70. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/persistency/in_memory.py +0 -0
  71. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/persistency/scheduled_jobs_states_dal.py +0 -0
  72. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/__init__.py +0 -0
  73. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/actions_registry.py +0 -0
  74. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/base_trigger.py +0 -0
  75. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/generation.py +0 -0
  76. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/internal/discovery_events.py +0 -0
  77. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/job_utils.py +0 -0
  78. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/node_playbook_utils.py +0 -0
  79. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/playbook_utils.py +0 -0
  80. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/playbooks_event_handler.py +0 -0
  81. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/playbooks_event_handler_impl.py +0 -0
  82. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/pod_utils/crashloop_utils.py +0 -0
  83. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/pod_utils/imagepull_utils.py +0 -0
  84. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/pod_utils/pending_pod_utils.py +0 -0
  85. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/playbooks/trigger.py +0 -0
  86. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/reporting/__init__.py +0 -0
  87. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/reporting/action_requests.py +0 -0
  88. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/reporting/blocks.py +0 -0
  89. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/reporting/callbacks.py +0 -0
  90. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/reporting/consts.py +0 -0
  91. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/reporting/finding_subjects.py +0 -0
  92. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/reporting/utils.py +0 -0
  93. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/schedule/__init__.py +0 -0
  94. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/schedule/model.py +0 -0
  95. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/schedule/scheduler.py +0 -0
  96. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/__init__.py +0 -0
  97. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/datadog/__init__.py +0 -0
  98. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/datadog/datadog_sink.py +0 -0
  99. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/datadog/datadog_sink_params.py +0 -0
  100. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/discord/__init__.py +0 -0
  101. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/discord/discord_sink.py +0 -0
  102. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/discord/discord_sink_params.py +0 -0
  103. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/file/__init__.py +0 -0
  104. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/file/file_sink.py +0 -0
  105. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/file/file_sink_params.py +0 -0
  106. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/file/object_traverser.py +0 -0
  107. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/jira/__init__.py +0 -0
  108. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/jira/jira_sink.py +0 -0
  109. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/jira/jira_sink_params.py +0 -0
  110. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/kafka/__init__.py +0 -0
  111. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/kafka/kafka_sink.py +0 -0
  112. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/kafka/kafka_sink_params.py +0 -0
  113. {robusta_cli-0.10.25/src/robusta/core/sinks/robusta/dal → robusta_cli-0.10.26a1/src/robusta/core/sinks/mail}/__init__.py +0 -0
  114. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/mattermost/__init__.py +0 -0
  115. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/mattermost/mattermost_sink.py +0 -0
  116. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/mattermost/mattermost_sink_params.py +0 -0
  117. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/msteams/__init__.py +0 -0
  118. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/msteams/msteams_sink.py +0 -0
  119. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/msteams/msteams_sink_params.py +0 -0
  120. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/opsgenie/__init__.py +0 -0
  121. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/opsgenie/opsgenie_sink_params.py +0 -0
  122. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/pagerduty/__init__.py +0 -0
  123. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/pagerduty/pagerduty_sink_params.py +0 -0
  124. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/robusta/__init__.py +0 -0
  125. {robusta_cli-0.10.25/src/robusta/integrations → robusta_cli-0.10.26a1/src/robusta/core/sinks/robusta/dal}/__init__.py +0 -0
  126. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/robusta/dal/model_conversion.py +0 -0
  127. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/robusta/discovery_metrics.py +0 -0
  128. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/robusta/prometheus_health_checker.py +0 -0
  129. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/robusta/robusta_sink_params.py +0 -0
  130. {robusta_cli-0.10.25/src/robusta/integrations/common → robusta_cli-0.10.26a1/src/robusta/core/sinks/robusta/rrm}/__init__.py +0 -0
  131. {robusta_cli-0.10.25/src/robusta/integrations/discord → robusta_cli-0.10.26a1/src/robusta/core/sinks/rocketchat}/__init__.py +0 -0
  132. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/sink_base.py +0 -0
  133. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/sink_base_params.py +0 -0
  134. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/sink_config.py +0 -0
  135. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/slack/__init__.py +0 -0
  136. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/slack/slack_sink.py +0 -0
  137. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/slack/slack_sink_params.py +0 -0
  138. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/telegram/__init__.py +0 -0
  139. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/telegram/telegram_client.py +0 -0
  140. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/telegram/telegram_sink.py +0 -0
  141. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/telegram/telegram_sink_params.py +0 -0
  142. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/victorops/__init__.py +0 -0
  143. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/victorops/victorops_sink.py +0 -0
  144. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/victorops/victorops_sink_params.py +0 -0
  145. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/webex/__init__.py +0 -0
  146. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/webex/webex_sink.py +0 -0
  147. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/webex/webex_sink_params.py +0 -0
  148. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/webhook/__init__.py +0 -0
  149. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/webhook/webhook_sink_params.py +0 -0
  150. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/yamessenger/__init__.py +0 -0
  151. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/yamessenger/yamessenger_client.py +0 -0
  152. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/yamessenger/yamessenger_sink.py +0 -0
  153. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/sinks/yamessenger/yamessenger_sink_params.py +0 -0
  154. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/triggers/container_oom_killed_trigger.py +0 -0
  155. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/triggers/custom_triggers.py +0 -0
  156. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/triggers/error_event_trigger.py +0 -0
  157. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/triggers/helm_releases_triggers.py +0 -0
  158. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/triggers/job_failed_trigger.py +0 -0
  159. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/triggers/oom_killed_trigger_base.py +0 -0
  160. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/triggers/pod_crash_loop_trigger.py +0 -0
  161. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/triggers/pod_image_pull_backoff.py +0 -0
  162. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/core/triggers/pod_oom_killed_trigger.py +0 -0
  163. {robusta_cli-0.10.25/src/robusta/integrations/git → robusta_cli-0.10.26a1/src/robusta/integrations}/__init__.py +0 -0
  164. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/argocd/argocd_client.py +0 -0
  165. {robusta_cli-0.10.25/src/robusta/integrations/jira → robusta_cli-0.10.26a1/src/robusta/integrations/common}/__init__.py +0 -0
  166. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/common/requests.py +0 -0
  167. {robusta_cli-0.10.25/src/robusta/integrations/kubernetes → robusta_cli-0.10.26a1/src/robusta/integrations/discord}/__init__.py +0 -0
  168. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/discord/sender.py +0 -0
  169. {robusta_cli-0.10.25/src/robusta/integrations/kubernetes/autogenerated → robusta_cli-0.10.26a1/src/robusta/integrations/git}/__init__.py +0 -0
  170. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/git/git_repo.py +0 -0
  171. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/grafana.py +0 -0
  172. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/helper.py +0 -0
  173. {robusta_cli-0.10.25/src/robusta/integrations/kubernetes/autogenerated/v1 → robusta_cli-0.10.26a1/src/robusta/integrations/jira}/__init__.py +0 -0
  174. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/jira/client.py +0 -0
  175. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/jira/sender.py +0 -0
  176. {robusta_cli-0.10.25/src/robusta/integrations/mattermost → robusta_cli-0.10.26a1/src/robusta/integrations/kubernetes}/__init__.py +0 -0
  177. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/api_client_utils.py +0 -0
  178. {robusta_cli-0.10.25/src/robusta/integrations/msteams/msteams_elements → robusta_cli-0.10.26a1/src/robusta/integrations/kubernetes/autogenerated}/__init__.py +0 -0
  179. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/autogenerated/events.py +0 -0
  180. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/autogenerated/models.py +0 -0
  181. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/autogenerated/triggers.py +0 -0
  182. {robusta_cli-0.10.25/src/robusta/integrations/prometheus → robusta_cli-0.10.26a1/src/robusta/integrations/kubernetes/autogenerated/v1}/__init__.py +0 -0
  183. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/autogenerated/v1/models.py +0 -0
  184. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/base_event.py +0 -0
  185. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/base_triggers.py +0 -0
  186. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/custom_models.py +0 -0
  187. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/model_not_found_exception.py +0 -0
  188. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/process_utils.py +0 -0
  189. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/kubernetes/templates.py +0 -0
  190. {robusta_cli-0.10.25/src/robusta/integrations/resource_analysis → robusta_cli-0.10.26a1/src/robusta/integrations/mail}/__init__.py +0 -0
  191. {robusta_cli-0.10.25/src/robusta/integrations/scheduled → robusta_cli-0.10.26a1/src/robusta/integrations/mattermost}/__init__.py +0 -0
  192. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/mattermost/sender.py +0 -0
  193. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/__init__.py +0 -0
  194. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_adaptive_card_files.py +0 -0
  195. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_adaptive_card_files_image.py +0 -0
  196. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_adaptive_card_files_text.py +0 -0
  197. {robusta_cli-0.10.25/src/robusta/integrations/webex → robusta_cli-0.10.26a1/src/robusta/integrations/msteams/msteams_elements}/__init__.py +0 -0
  198. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_elements/msteams_action.py +0 -0
  199. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_elements/msteams_base.py +0 -0
  200. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_elements/msteams_card.py +0 -0
  201. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_elements/msteams_column.py +0 -0
  202. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_elements/msteams_container.py +0 -0
  203. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_elements/msteams_images.py +0 -0
  204. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_elements/msteams_table.py +0 -0
  205. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_elements/msteams_text_block.py +0 -0
  206. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_mark_down_fix_url.py +0 -0
  207. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/msteams_msg.py +0 -0
  208. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/msteams/sender.py +0 -0
  209. {robusta_cli-0.10.25/src/robusta/runner → robusta_cli-0.10.26a1/src/robusta/integrations/prometheus}/__init__.py +0 -0
  210. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/prometheus/models.py +0 -0
  211. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/prometheus/trigger.py +0 -0
  212. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/prometheus/utils.py +0 -0
  213. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/receiver.py +0 -0
  214. {robusta_cli-0.10.25/src/robusta/utils → robusta_cli-0.10.26a1/src/robusta/integrations/resource_analysis}/__init__.py +0 -0
  215. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/resource_analysis/cpu_analyzer.py +0 -0
  216. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/resource_analysis/memory_analyzer.py +0 -0
  217. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/resource_analysis/node_cpu_analyzer.py +0 -0
  218. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/resource_analysis/prometheus_analyzer.py +0 -0
  219. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/scheduled/event.py +0 -0
  220. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/scheduled/models.py +0 -0
  221. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/scheduled/playbook_scheduler.py +0 -0
  222. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/scheduled/playbook_scheduler_manager.py +0 -0
  223. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/scheduled/playbook_scheduler_manager_impl.py +0 -0
  224. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/scheduled/trigger.py +0 -0
  225. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/slack/__init__.py +0 -0
  226. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/slack/sender.py +0 -0
  227. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/integrations/webex/sender.py +0 -0
  228. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/model/alert_relabel_config.py +0 -0
  229. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/model/config.py +0 -0
  230. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/model/playbook_action.py +0 -0
  231. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/model/playbook_definition.py +0 -0
  232. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/patch/patch.py +0 -0
  233. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/config_loader.py +0 -0
  234. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/log_init.py +0 -0
  235. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/main.py +0 -0
  236. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/not_found_exception.py +0 -0
  237. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/object_updater.py +0 -0
  238. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/ssl_utils.py +0 -0
  239. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/telemetry.py +0 -0
  240. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/telemetry_service.py +0 -0
  241. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/web.py +0 -0
  242. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/runner/web_api.py +0 -0
  243. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/auth_provider.py +0 -0
  244. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/base64_utils.py +0 -0
  245. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/cluster_provider_discovery.py +0 -0
  246. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/decorators.py +0 -0
  247. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/docs.py +0 -0
  248. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/documented_pydantic.py +0 -0
  249. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/error_codes.py +0 -0
  250. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/file_system_watcher.py +0 -0
  251. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/function_hashes.py +0 -0
  252. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/json_schema.py +0 -0
  253. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/parsing.py +0 -0
  254. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/rate_limiter.py +0 -0
  255. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/server_start.py +0 -0
  256. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/service_discovery.py +0 -0
  257. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/silence_utils.py +0 -0
  258. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/stack_tracer.py +0 -0
  259. {robusta_cli-0.10.25 → robusta_cli-0.10.26a1}/src/robusta/utils/task_queue.py +0 -0
@@ -1,19 +1,19 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: robusta-cli
3
- Version: 0.10.25
3
+ Version: 0.10.26a1
4
4
  Summary:
5
5
  Author: Natan Yellin
6
6
  Author-email: aantn@users.noreply.github.com
7
- Requires-Python: >=3.8,<4.0
7
+ Requires-Python: >=3.8,<3.11
8
8
  Classifier: Programming Language :: Python :: 3
9
9
  Classifier: Programming Language :: Python :: 3.8
10
10
  Classifier: Programming Language :: Python :: 3.9
11
11
  Classifier: Programming Language :: Python :: 3.10
12
- Classifier: Programming Language :: Python :: 3.11
13
12
  Provides-Extra: all
14
13
  Requires-Dist: CairoSVG (>=2.5.2,<3.0.0) ; extra == "all"
15
- Requires-Dist: Flask (>=1.1.2,<2.0.0) ; extra == "all"
14
+ Requires-Dist: Flask (>=3.0.0,<4.0.0) ; extra == "all"
16
15
  Requires-Dist: PyJWT (==2.4.0)
16
+ Requires-Dist: apprise (>=1.5.0,<2.0.0)
17
17
  Requires-Dist: attrs (>=23.1.0,<24.0.0)
18
18
  Requires-Dist: better-exceptions (>=0.3.3,<0.4.0) ; extra == "all"
19
19
  Requires-Dist: bitmath (>=1.3.3.1,<2.0.0.0)
@@ -27,7 +27,7 @@ Requires-Dist: dpath (>=2.0.5,<3.0.0)
27
27
  Requires-Dist: dulwich (==0.20.28) ; extra == "all"
28
28
  Requires-Dist: fpdf2 (>=2.7.1,<3.0.0)
29
29
  Requires-Dist: grafana-api (>=1.0.3,<2.0.0) ; extra == "all"
30
- Requires-Dist: hikaru (>=1.0.1,<2.0.0)
30
+ Requires-Dist: hikaru-model-26 (>=1.1.1,<2.0.0)
31
31
  Requires-Dist: kafka-python (>=2.0.2,<3.0.0) ; extra == "all"
32
32
  Requires-Dist: kubernetes (>=26.1.0,<27.0.0)
33
33
  Requires-Dist: markdown2 (>=2.4.2,<3.0.0)
@@ -39,6 +39,7 @@ Requires-Dist: pydantic (>=1.8.1,<2.0.0)
39
39
  Requires-Dist: pymsteams (>=0.1.16,<0.2.0)
40
40
  Requires-Dist: pytz (>=2021.3,<2022.0)
41
41
  Requires-Dist: pyyaml (>=6.0,<7.0)
42
+ Requires-Dist: rocketchat-api (>=1.30.0,<2.0.0)
42
43
  Requires-Dist: sentry-sdk (>=1.5.2,<2.0.0) ; extra == "all"
43
44
  Requires-Dist: slack-sdk (>=3.7.0,<4.0.0)
44
45
  Requires-Dist: supabase (>=1.0.3,<2.0.0) ; extra == "all"
@@ -1,10 +1,10 @@
1
1
  [tool.poetry]
2
2
  name = "robusta-cli"
3
- version = "0.10.25"
3
+ version = "0.10.26-alpha1"
4
4
  description = ""
5
5
  authors = ["Natan Yellin <aantn@users.noreply.github.com>"]
6
6
  packages = [
7
- { include = "robusta", from = "src"},
7
+ { include = "robusta", from = "src" },
8
8
  ]
9
9
 
10
10
  [tool.black]
@@ -21,18 +21,20 @@ robusta = "robusta.cli.main:app"
21
21
 
22
22
 
23
23
  [tool.poetry.dependencies]
24
- python = "^3.8"
24
+ # Robusta CLI should work on 3.8, but the core code requires 3.9+. Both
25
+ # are known not to work on 3.11. Unfortunately this spec is shared between
26
+ # the CLI and core, so we have to specify 3.8+.
27
+ python = "^3.8, <3.11"
25
28
  typer = "^0.4.1"
26
29
  colorlog = "^5.0.1"
27
30
  pydantic = "^1.8.1"
28
31
  kubernetes = "^26.1.0"
29
- hikaru = "^1.0.1"
30
32
  click-spinner = "^0.1.10"
31
33
  pymsteams = "^0.1.16"
32
34
  supabase = { version = "^1.0.3", optional = true }
33
35
  tabulate = { version = "^0.8.10" }
34
36
  slack-sdk = { version = "^3.7.0" }
35
- Flask = { version = "^1.1.2", optional = true }
37
+ Flask = { version = "^3.0.0", optional = true }
36
38
  grafana-api = { version = "^1.0.3", optional = true }
37
39
  watchdog = { version = "^2.1.0", optional = true }
38
40
  better-exceptions = { version = "^0.3.3", optional = true }
@@ -64,6 +66,10 @@ PyJWT = "2.4.0"
64
66
  fpdf2 = "^2.7.1"
65
67
  attrs = "^23.1.0"
66
68
  prometrix = "0.1.10"
69
+ hikaru-model-26 = "^1.1.1"
70
+ apprise = "^1.5.0"
71
+ rocketchat-api = "^1.30.0"
72
+
67
73
  [tool.poetry.dev-dependencies]
68
74
  pre-commit = "^2.13.0"
69
75
  pytest = "^6.2.4"
@@ -103,9 +109,6 @@ types-click-spinner = "^0.1.10"
103
109
  types-toml = "^0.10.2"
104
110
  types-tabulate = "^0.8.10"
105
111
 
106
- # There is a bug in jinga2 and markupsafe (explicitly markupsafe 2.1.1)
107
- markupsafe = "2.0.1"
108
-
109
112
  [tool.poetry.extras]
110
113
  all = ["Flask", "grafana-api", "watchdog", "dulwich", "better-exceptions", "CairoSVG", "tabulate", "kafka-python", "prometheus-api-client", "supabase", "datadog-api-client", "pygal", "tinycss", "cssselect", "rsa", "sentry-sdk", "poetry-core"]
111
114
 
@@ -1,2 +1,2 @@
1
1
  # this is updated by .github/workflows/release.yaml
2
- __version__ = "0.10.25"
2
+ __version__ = "0.10.26-alpha1"
@@ -362,7 +362,7 @@ class Discovery:
362
362
  # we use map here to deduplicate and pick only the latest release data
363
363
  helm_releases_map[decoded_release_row.get_service_key()] = decoded_release_row
364
364
  except Exception as e:
365
- logging.error(f"an error occured while decoding helm releases: {e}")
365
+ logging.error(f"an error occurred while decoding helm releases: {e}")
366
366
 
367
367
  continue_ref = secrets.metadata._continue
368
368
  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):
@@ -29,3 +32,11 @@ class ClusterStatus(BaseModel):
29
32
  ttl_hours: int
30
33
  stats: ClusterStats
31
34
  activity_stats: ActivityStats
35
+
36
+
37
+ class Account(BaseModel):
38
+ id: str
39
+ account_type: int
40
+ is_test_account: bool
41
+ name: Optional[str]
42
+ creation_date: datetime
@@ -41,6 +41,7 @@ FLOAT_PRECISION_LIMIT = int(os.environ.get("FLOAT_PRECISION_LIMIT", 11))
41
41
 
42
42
  PROMETHEUS_REQUEST_TIMEOUT_SECONDS = float(os.environ.get("PROMETHEUS_REQUEST_TIMEOUT_SECONDS", 90.0))
43
43
  PROMETHEUS_ENABLED = os.environ.get("PROMETHEUS_ENABLED", "false").lower() == "true"
44
+ MANAGED_PROMETHEUS_ALERTS_ENABLED = os.environ.get("MANAGED_PROMETHEUS_ALERTS_ENABLED", "false").lower() == "true"
44
45
  PROMETHEUS_SSL_ENABLED = os.environ.get("PROMETHEUS_SSL_ENABLED", "false").lower() == "true"
45
46
 
46
47
  INCOMING_REQUEST_TIME_WINDOW_SECONDS = int(os.environ.get("INCOMING_REQUEST_TIME_WINDOW_SECONDS", 3600))
@@ -95,4 +96,8 @@ DISABLE_HELM_MONITORING = load_bool("DISABLE_HELM_MONITORING", False)
95
96
 
96
97
  PROMETHEUS_ERROR_LOG_PERIOD_SEC = int(os.environ.get("DISCOVERY_MAX_BATCHES", 14400))
97
98
 
99
+ RRM_PERIOD_SEC = int(os.environ.get("RRM_PERIOD_SEC", 90))
100
+
101
+ MAX_ALLOWED_RULES_PER_CRD_ALERT = int(os.environ.get("MAX_ALLOWED_RULES_PER_CRD_ALERT", 600))
102
+
98
103
  IMAGE_REGISTRY = os.environ.get("IMAGE_REGISTRY", "us-central1-docker.pkg.dev/genuine-flight-317411/devel")
@@ -14,7 +14,9 @@ from robusta.core.sinks.msteams.msteams_sink_params import MsTeamsSinkConfigWrap
14
14
  from robusta.core.sinks.opsgenie.opsgenie_sink_params import OpsGenieSinkConfigWrapper
15
15
  from robusta.core.sinks.pagerduty.pagerduty_sink_params import PagerdutyConfigWrapper
16
16
  from robusta.core.sinks.robusta.robusta_sink_params import RobustaSinkConfigWrapper
17
+ from robusta.core.sinks.rocketchat.rocketchat_sink_params import RocketchatSinkConfigWrapper
17
18
  from robusta.core.sinks.slack.slack_sink_params import SlackSinkConfigWrapper
19
+ from robusta.core.sinks.mail.mail_sink_params import MailSinkConfigWrapper
18
20
  from robusta.core.sinks.telegram.telegram_sink_params import TelegramSinkConfigWrapper
19
21
  from robusta.core.sinks.victorops.victorops_sink_params import VictoropsConfigWrapper
20
22
  from robusta.core.sinks.webex.webex_sink_params import WebexSinkConfigWrapper
@@ -42,6 +44,7 @@ class RunnerConfig(BaseModel):
42
44
  DataDogSinkConfigWrapper,
43
45
  KafkaSinkConfigWrapper,
44
46
  MsTeamsSinkConfigWrapper,
47
+ RocketchatSinkConfigWrapper,
45
48
  OpsGenieSinkConfigWrapper,
46
49
  TelegramSinkConfigWrapper,
47
50
  WebhookSinkConfigWrapper,
@@ -53,6 +56,7 @@ class RunnerConfig(BaseModel):
53
56
  YaMessengerSinkConfigWrapper,
54
57
  JiraSinkConfigWrapper,
55
58
  FileSinkConfigWrapper,
59
+ MailSinkConfigWrapper,
56
60
  ]
57
61
  ]
58
62
  ]
@@ -67,7 +71,6 @@ class RunnerConfig(BaseModel):
67
71
 
68
72
  @staticmethod
69
73
  def _replace_env_var_in_playbook_repo(playbook_repo: PlaybookRepo):
70
-
71
74
  url_env_var_replacement = get_env_replacement(playbook_repo.url)
72
75
  if url_env_var_replacement:
73
76
  playbook_repo.url = url_env_var_replacement
@@ -79,7 +79,7 @@ def get_resource_events_table(
79
79
  )
80
80
 
81
81
 
82
- def get_event_timestamp(event: Event):
82
+ def get_event_timestamp(event: Event) -> Optional[str]:
83
83
  if event.deprecatedLastTimestamp:
84
84
  return event.deprecatedLastTimestamp
85
85
  elif event.eventTime:
@@ -4,15 +4,19 @@ from hikaru.model.rel_1_26 import Container, Pod
4
4
 
5
5
  from robusta.core.model.base_params import ResourceChartItemType, ResourceChartResourceType, ResourceGraphEnricherParams
6
6
  from robusta.core.model.pods import PodContainer
7
- from robusta.core.playbooks.prometheus_enrichment_utils import XAxisLine, create_resource_enrichment
7
+ from robusta.core.playbooks.prometheus_enrichment_utils import XAxisLine, YAxisLine, create_resource_enrichment
8
+ from robusta.integrations.kubernetes.api_client_utils import parse_kubernetes_datetime
8
9
 
9
10
 
10
- def create_container_graph(params: ResourceGraphEnricherParams, pod: Pod, container: Container, show_limit=False):
11
+ def create_container_graph(params: ResourceGraphEnricherParams, pod: Pod, oomkilled_container: PodContainer, show_limit=False):
12
+ container = oomkilled_container.container
13
+ oom_killed_status = oomkilled_container.state
11
14
  labels = {
12
15
  "pod": pod.metadata.name,
13
16
  "container": container.name,
14
17
  "namespace": pod.metadata.namespace,
15
18
  }
19
+
16
20
  start_at = datetime.now()
17
21
  limit_lines = []
18
22
  if show_limit:
@@ -20,12 +24,12 @@ def create_container_graph(params: ResourceGraphEnricherParams, pod: Pod, contai
20
24
  requests, limits = PodContainer.get_memory_resources(container)
21
25
  if limits > 0:
22
26
  memory_limit_in_bytes = limits * 1024 * 1024
23
- limit_line = XAxisLine(label="Memory Limit", value=memory_limit_in_bytes)
27
+ limit_line = XAxisLine(label="Limit", value=memory_limit_in_bytes)
24
28
  limit_lines.append(limit_line)
25
29
 
26
30
  if requests > 0:
27
31
  request_limit_in_bytes = requests * 1024 * 1024
28
- limit_line = XAxisLine(label="Memory Request", value=request_limit_in_bytes)
32
+ limit_line = XAxisLine(label="Request", value=request_limit_in_bytes)
29
33
  limit_lines.append(limit_line)
30
34
 
31
35
  if params.resource_type == "CPU":
@@ -33,14 +37,22 @@ def create_container_graph(params: ResourceGraphEnricherParams, pod: Pod, contai
33
37
 
34
38
  if limits > 0:
35
39
  cpu_limit_in_bytes = limits * 1024 * 1024
36
- limit_line = XAxisLine(label="CPU Limit", value=cpu_limit_in_bytes)
40
+ limit_line = XAxisLine(label="Limit", value=cpu_limit_in_bytes)
37
41
  limit_lines.append(limit_line)
38
42
 
39
43
  if requests > 0:
40
44
  request_limit_in_bytes = requests * 1024 * 1024
41
- limit_line = XAxisLine(label="CPU Request", value=request_limit_in_bytes)
45
+ limit_line = XAxisLine(label="Request", value=request_limit_in_bytes)
42
46
  limit_lines.append(limit_line)
43
47
 
48
+ if oomkilled_container.state.terminated and \
49
+ oomkilled_container.state.terminated.reason == "OOMKilled" and \
50
+ oom_killed_status.terminated and \
51
+ oom_killed_status.terminated.finishedAt:
52
+ oom_killed_datetime = parse_kubernetes_datetime(oom_killed_status.terminated.finishedAt)
53
+ limit_line = YAxisLine(label="OOM Kill Time", value=oom_killed_datetime.timestamp())
54
+ limit_lines.append(limit_line)
55
+
44
56
  graph_enrichment = create_resource_enrichment(
45
57
  start_at,
46
58
  labels,
@@ -1,6 +1,6 @@
1
1
  import math
2
2
  from collections import defaultdict, namedtuple
3
- from datetime import datetime, timedelta
3
+ from datetime import timedelta
4
4
  from string import Template
5
5
  from typing import Any, Callable, Dict, List, Optional, Tuple, Union
6
6
 
@@ -18,7 +18,7 @@ from robusta.core.model.base_params import (
18
18
  )
19
19
  from robusta.core.model.env_vars import FLOAT_PRECISION_LIMIT, PROMETHEUS_REQUEST_TIMEOUT_SECONDS
20
20
  from robusta.core.reporting.blocks import FileBlock
21
- from robusta.core.reporting.custom_rendering import charts_style
21
+ from robusta.core.reporting.custom_rendering import charts_style, PlotCustomCSS
22
22
 
23
23
  ResourceKey = Tuple[ResourceChartResourceType, ResourceChartItemType]
24
24
  ChartLabelFactory = Callable[[int], str]
@@ -30,6 +30,27 @@ class XAxisLine(BaseModel):
30
30
  value: float
31
31
 
32
32
 
33
+ class YAxisLine(BaseModel):
34
+ label: str
35
+ value: float
36
+
37
+
38
+ class PlotData:
39
+ def __init__(self, plot: Tuple[str, List[Tuple]],
40
+ color: str,
41
+ stroke_style: Optional[Dict[str, Any]] = None,
42
+ stroke: Optional[bool] = True,
43
+ show_dots: bool = True,
44
+ dots_size: Optional[int] = None,
45
+ ):
46
+ self.plot = plot
47
+ self.color = color
48
+ self.stroke_style = stroke_style
49
+ self.stroke = stroke
50
+ self.show_dots = show_dots
51
+ self.dots_size = dots_size
52
+
53
+
33
54
  def __prepare_promql_query(provided_labels: Dict[Any, Any], promql_query_template: str) -> str:
34
55
  labels: Dict[Any, Any] = defaultdict(lambda: "<missing>")
35
56
  labels.update(provided_labels)
@@ -169,8 +190,8 @@ def create_chart_from_prometheus_query(
169
190
  max_time = 0
170
191
 
171
192
  # We use the [graph_plot_color_list] to map colors corresponding to matching line labels on [plot_list].
172
- plot_list: List[Tuple[str, List[Tuple]]] = []
173
- graph_plot_color_list: List[str] = []
193
+ plot_data_list: List[PlotData] = []
194
+ max_y_value = 0
174
195
  series_list_result = prometheus_query_result.series_list_result
175
196
  if filter_prom_jobs:
176
197
  series_list_result = filter_prom_jobs_results(series_list_result)
@@ -187,44 +208,84 @@ def create_chart_from_prometheus_query(
187
208
  timestamp = series.timestamps[index]
188
209
  value = round(float(series.values[index]), FLOAT_PRECISION_LIMIT)
189
210
  values.append((timestamp, value))
211
+ if value > max_y_value:
212
+ max_y_value = value
190
213
  min_time = min(min_time, min(series.timestamps))
191
214
  max_time = max(max_time, max(series.timestamps))
192
215
 
193
- plot_list.append((label, values))
194
- graph_plot_color_list.append("#9747FF")
216
+ plot_data = PlotData(plot=(label, values), color="#3F3F3F", show_dots=False,
217
+ stroke_style={'width': 8, 'dasharray': '8', 'linecap': 'round',
218
+ 'linejoin': 'round'},)
219
+ plot_data_list.append(plot_data)
220
+
221
+ for line in lines:
222
+ if isinstance(line, XAxisLine) and line.value > max_y_value:
223
+ max_y_value = line.value
195
224
 
196
225
  assert lines is not None
197
226
  for line in lines:
198
227
  value = [(min_time, line.value), (max_time, line.value)]
199
228
 
200
- if line.label == "Memory Limit" \
201
- or line.label == "CPU Limit":
202
- plot_list.append((line.label, value))
203
- graph_plot_color_list.append("#FF5959")
229
+ if "Limit" in line.label:
230
+ plot_data = PlotData(plot=(line.label, value), color="#FF5959")
204
231
 
205
- elif line.label == "Memory Request" \
206
- or line.label == "CPU Request":
207
- plot_list.append((line.label, value))
208
- graph_plot_color_list.append("#0DC291")
232
+ elif "Request" in line.label:
233
+ plot_data = PlotData(plot=(line.label, value), color="#0DC291")
234
+
235
+ elif line.label == "OOM Kill Time":
236
+ value = [(line.value, max_y_value), (line.value, 0)]
237
+
238
+ plot_data = PlotData(plot=(line.label, value), color="#FF5959", show_dots=False,
239
+ stroke_style={'width': 6, 'dasharray': '3, 6', 'linecap': 'round',
240
+ 'linejoin': 'round'})
209
241
 
210
242
  else:
211
- plot_list.append((line.label, value))
212
- graph_plot_color_list.append("#2a0065")
243
+ plot_data = PlotData(plot=(line.label, value), color="#2a0065")
213
244
 
245
+ plot_data_list.append(plot_data)
246
+
247
+ graph_plot_color_list = [plot_data.color for plot_data in plot_data_list]
214
248
  graph_plot_color_list.extend(["#1e0047", "#2a0065"])
249
+ config = pygal.Config()
250
+ custom_css = PlotCustomCSS().get_css_file_path()
251
+ config.css.append(f'file://{custom_css}')
215
252
  chart = pygal.XY(
253
+ config,
216
254
  show_dots=True,
217
255
  style=charts_style(graph_colors=tuple(graph_plot_color_list)),
218
256
  truncate_legend=15,
219
257
  include_x_axis=include_x_axis,
220
258
  width=1280,
221
- height=720,
259
+ height=500,
222
260
  )
223
261
 
262
+ y_axis_division = 5
263
+ # Calculate the maximum Y value with an added 20% padding
264
+ max_y_value_with_padding = max_y_value + (max_y_value*0.20)
265
+
266
+ # Calculate the interval between each Y-axis label
267
+ interval = max_y_value_with_padding / (y_axis_division - 1)
268
+
269
+ if values_format == ChartValuesFormat.Percentage:
270
+ # Calculate the Y-axis labels, shift to percentage, and round to the nearest whole number percentage
271
+ chart.y_labels = [round((i * interval) * 100) / 100 for i in range(y_axis_division)]
272
+ else:
273
+ # For non-percentage formats, round the Y-axis labels to the nearest whole number
274
+ chart.y_labels = [round(i * interval) for i in range(y_axis_division)]
275
+
276
+ chart.y_labels_major = chart.y_labels
277
+ chart.range = (0, max_y_value_with_padding)
278
+ chart.show_x_guides = True
279
+ chart.show_y_guides = True
280
+ chart.spacing = 20
281
+ chart.margin_top = 10
282
+ chart.margin_bottom = 50
224
283
  chart.x_label_rotation = 35
225
284
  chart.truncate_label = -1
226
285
  chart.x_value_formatter = lambda timestamp: datetime.fromtimestamp(timestamp).strftime("%b %-d %H:%M")
227
-
286
+ chart.legend_at_bottom = True
287
+ chart.legend_at_bottom_columns = 5
288
+ chart.legend_box_size = 8
228
289
  value_formatters = {
229
290
  ChartValuesFormat.Plain: lambda val: str(val),
230
291
  ChartValuesFormat.Bytes: lambda val: humanize.naturalsize(val, binary=True),
@@ -239,8 +300,15 @@ def create_chart_from_prometheus_query(
239
300
  else:
240
301
  chart.title = promql_query
241
302
 
242
- for plot in plot_list:
243
- chart.add(plot[0], plot[1])
303
+ for p in plot_data_list:
304
+ chart.add(
305
+ p.plot[0],
306
+ p.plot[1],
307
+ stroke_style=p.stroke_style,
308
+ show_dots=p.show_dots,
309
+ dots_size=p.dots_size,
310
+ stroke=p.stroke,
311
+ )
244
312
 
245
313
  return chart
246
314
 
@@ -338,7 +406,7 @@ def create_resource_enrichment(
338
406
  values_format=ChartValuesFormat.CPUUsage,
339
407
  ),
340
408
  (ResourceChartResourceType.Memory, ResourceChartItemType.Pod): ChartOptions(
341
- query='sum(container_memory_working_set_bytes{pod=~"$pod", container!="", image!=""}) by (pod, job)',
409
+ query='sum(container_memory_working_set_bytes{namespace="$namespace", pod=~"$pod", container!="", image!=""}) by (pod, job)',
342
410
  values_format=ChartValuesFormat.Bytes,
343
411
  ),
344
412
  (ResourceChartResourceType.Memory, ResourceChartItemType.Node): ChartOptions(
@@ -346,7 +414,7 @@ def create_resource_enrichment(
346
414
  values_format=ChartValuesFormat.Percentage,
347
415
  ),
348
416
  (ResourceChartResourceType.Memory, ResourceChartItemType.Container): ChartOptions(
349
- query='sum(container_memory_working_set_bytes{pod=~"$pod", container=~"$container", image!=""}) by (container, pod, job)',
417
+ query='sum(container_memory_working_set_bytes{namespace="$namespace", pod=~"$pod", container=~"$container", image!=""}) by (container, pod, job)',
350
418
  values_format=ChartValuesFormat.Bytes,
351
419
  ),
352
420
  (ResourceChartResourceType.Disk, ResourceChartItemType.Pod): None,
@@ -17,6 +17,7 @@ from robusta.core.reporting.consts import FindingSource, FindingSubjectType, Fin
17
17
 
18
18
  class BaseBlock(BaseModel):
19
19
  hidden: bool = False
20
+ html_class: str = None
20
21
 
21
22
 
22
23
  class Emojis(Enum):
@@ -51,7 +52,7 @@ class FindingSeverity(Enum):
51
52
  if self == FindingSeverity.DEBUG:
52
53
  return "🔵"
53
54
  elif self == FindingSeverity.INFO:
54
- return "🟢"
55
+ return "⚪️"
55
56
  elif self == FindingSeverity.LOW:
56
57
  return "🟡"
57
58
  elif self == FindingSeverity.MEDIUM:
@@ -0,0 +1,76 @@
1
+ import logging
2
+ from datetime import datetime
3
+ from typing import Tuple, Optional
4
+ import tempfile
5
+
6
+ from robusta.core.model.env_vars import DEFAULT_TIMEZONE
7
+
8
+
9
+ class RendererType:
10
+ DATETIME = "DATETIME"
11
+
12
+
13
+ def render_value(renderer: RendererType, value):
14
+ if renderer == RendererType.DATETIME:
15
+ date_value = datetime.fromtimestamp(value / 1000.0)
16
+ return date_value.astimezone(DEFAULT_TIMEZONE).strftime("%b %d, %Y, %I:%M:%S %p")
17
+ raise Exception(f"Unsupported renderer type {renderer}")
18
+
19
+
20
+ def charts_style(
21
+ graph_colors: Tuple = ("#9747FF", "#FF5959", "#0DC291", "#2a0065", "#1e0047"),
22
+ ):
23
+ from pygal.style import Style
24
+
25
+ return Style(
26
+ background="#FFFFFF",
27
+ plot_background="#FFFFFF",
28
+ value_background="rgba(229, 229, 229, 1)",
29
+ foreground="#607D8B",
30
+ foreground_strong="#607D8B",
31
+ foreground_subtle="#607D8B",
32
+ guide_stroke_dasharray="0,0",
33
+ major_guide_stroke_dasharray="0,0",
34
+ guide_stroke_color="#E7EBEB",
35
+ major_guide_stroke_color="#E7EBEB",
36
+ opacity=".6",
37
+ opacity_hover=".9",
38
+ transition="400ms ease-in",
39
+ colors=graph_colors,
40
+ )
41
+
42
+
43
+ class PlotCustomCSS:
44
+ _css_file_path = None
45
+
46
+ def __init__(self):
47
+ if PlotCustomCSS._css_file_path is None:
48
+ try:
49
+ custom_css = '''
50
+ {{ id }}.title {
51
+ fill: #11383A;
52
+ }
53
+
54
+ {{ id }}.legends .legend text {
55
+ fill: #3f3f3f;
56
+ }
57
+
58
+ {{ id }}.axis.y text {
59
+ fill: #3f3f3f;
60
+ }
61
+
62
+ {{ id }}.axis.x text {
63
+ fill: #3f3f3f;
64
+ }
65
+ '''
66
+
67
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.css') as f:
68
+ f.write(custom_css.encode('utf-8'))
69
+ f.flush()
70
+ PlotCustomCSS._css_file_path = f.name
71
+ except Exception as e:
72
+ logging.error(f"Error during initializing PlotCustomCSS: {e}", exc_info=True)
73
+ PlotCustomCSS._css_file_path = None
74
+
75
+ def get_css_file_path(self) -> Optional[str]:
76
+ return self._css_file_path
@@ -0,0 +1,18 @@
1
+ from robusta.core.reporting.base import Finding
2
+ from robusta.core.sinks.sink_base import SinkBase
3
+ from robusta.core.sinks.mail.mail_sink_params import MailSinkConfigWrapper
4
+ from robusta.integrations.mail.sender import MailSender
5
+
6
+
7
+ class MailSink(SinkBase):
8
+ def __init__(self, sink_config: MailSinkConfigWrapper, registry):
9
+ super().__init__(sink_config.mail_sink, registry)
10
+ self.sender = MailSender(
11
+ sink_config.mail_sink.mailto,
12
+ self.signing_key,
13
+ self.account_id,
14
+ self.cluster_name,
15
+ )
16
+
17
+ def write_finding(self, finding: Finding, platform_enabled: bool):
18
+ self.sender.send_finding_via_email(finding, platform_enabled)
@@ -0,0 +1,23 @@
1
+ from pydantic import validator
2
+
3
+ from robusta.core.sinks.sink_base_params import SinkBaseParams
4
+ from robusta.core.sinks.sink_config import SinkConfigBase
5
+
6
+
7
+ class MailSinkParams(SinkBaseParams):
8
+ mailto: str
9
+
10
+ @validator("mailto")
11
+ def validate_mailto(cls, mailto):
12
+ # Make sure we only handle emails and exclude other schemes provided by apprise
13
+ # (there is a lot of them).
14
+ if not (mailto.startswith("mailto://") or mailto.startswith("mailtos://")):
15
+ raise AttributeError(f"{mailto} is not a mailto(s) address")
16
+ return mailto
17
+
18
+
19
+ class MailSinkConfigWrapper(SinkConfigBase):
20
+ mail_sink: MailSinkParams
21
+
22
+ def get_params(self) -> SinkBaseParams:
23
+ return self.mail_sink
@@ -98,5 +98,6 @@ class OpsGenieSink(SinkBase):
98
98
 
99
99
  @classmethod
100
100
  def __enrichments_as_text(cls, enrichments: List[Enrichment]) -> str:
101
- text_arr = [Transformer.to_html(enrichment.blocks) for enrichment in enrichments]
101
+ transformer = Transformer()
102
+ text_arr = [transformer.to_html(enrichment.blocks) for enrichment in enrichments]
102
103
  return "---\n".join(text_arr)
@@ -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,