robusta-api 0.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (295) hide show
  1. robusta/__init__.py +0 -0
  2. robusta/_version.py +2 -0
  3. robusta/api/__init__.py +330 -0
  4. robusta/cli/__init__.py +0 -0
  5. robusta/cli/auth.py +166 -0
  6. robusta/cli/backend_profile.py +54 -0
  7. robusta/cli/eula.py +27 -0
  8. robusta/cli/integrations_cmd.py +154 -0
  9. robusta/cli/main.py +517 -0
  10. robusta/cli/playbooks_cmd.py +386 -0
  11. robusta/cli/self_host.py +238 -0
  12. robusta/cli/slack_feedback_message.py +86 -0
  13. robusta/cli/slack_verification.py +104 -0
  14. robusta/cli/utils.py +146 -0
  15. robusta/core/__init__.py +0 -0
  16. robusta/core/discovery/__init__.py +0 -0
  17. robusta/core/discovery/discovery.py +818 -0
  18. robusta/core/discovery/resource_names.py +88 -0
  19. robusta/core/discovery/top_service_resolver.py +76 -0
  20. robusta/core/discovery/utils.py +45 -0
  21. robusta/core/exceptions.py +16 -0
  22. robusta/core/model/__init__.py +0 -0
  23. robusta/core/model/base_params.py +346 -0
  24. robusta/core/model/cluster_status.py +34 -0
  25. robusta/core/model/env_vars.py +124 -0
  26. robusta/core/model/events.py +168 -0
  27. robusta/core/model/helm_release.py +67 -0
  28. robusta/core/model/jobs.py +182 -0
  29. robusta/core/model/k8s_operation_type.py +7 -0
  30. robusta/core/model/namespaces.py +20 -0
  31. robusta/core/model/nodes.py +51 -0
  32. robusta/core/model/pods.py +264 -0
  33. robusta/core/model/runner_config.py +102 -0
  34. robusta/core/model/services.py +127 -0
  35. robusta/core/persistency/__init__.py +0 -0
  36. robusta/core/persistency/in_memory.py +20 -0
  37. robusta/core/persistency/scheduled_jobs_states_dal.py +66 -0
  38. robusta/core/playbooks/__init__.py +0 -0
  39. robusta/core/playbooks/actions_registry.py +109 -0
  40. robusta/core/playbooks/base_trigger.py +36 -0
  41. robusta/core/playbooks/common.py +121 -0
  42. robusta/core/playbooks/container_playbook_utils.py +69 -0
  43. robusta/core/playbooks/crash_reporter.py +65 -0
  44. robusta/core/playbooks/generation.py +131 -0
  45. robusta/core/playbooks/internal/discovery_events.py +87 -0
  46. robusta/core/playbooks/job_utils.py +47 -0
  47. robusta/core/playbooks/node_playbook_utils.py +28 -0
  48. robusta/core/playbooks/oom_killer_utils.py +95 -0
  49. robusta/core/playbooks/playbook_utils.py +67 -0
  50. robusta/core/playbooks/playbooks_event_handler.py +76 -0
  51. robusta/core/playbooks/playbooks_event_handler_impl.py +365 -0
  52. robusta/core/playbooks/pod_utils/crashloop_utils.py +62 -0
  53. robusta/core/playbooks/pod_utils/imagepull_utils.py +229 -0
  54. robusta/core/playbooks/pod_utils/pending_pod_utils.py +162 -0
  55. robusta/core/playbooks/prometheus_enrichment_utils.py +542 -0
  56. robusta/core/playbooks/trigger.py +27 -0
  57. robusta/core/pubsub/__init__.py +0 -0
  58. robusta/core/pubsub/event_emitter.py +7 -0
  59. robusta/core/pubsub/event_subscriber.py +17 -0
  60. robusta/core/pubsub/events_pubsub.py +20 -0
  61. robusta/core/reporting/__init__.py +67 -0
  62. robusta/core/reporting/action_requests.py +57 -0
  63. robusta/core/reporting/base.py +383 -0
  64. robusta/core/reporting/blocks.py +820 -0
  65. robusta/core/reporting/callbacks.py +49 -0
  66. robusta/core/reporting/consts.py +96 -0
  67. robusta/core/reporting/custom_rendering.py +76 -0
  68. robusta/core/reporting/finding_subjects.py +52 -0
  69. robusta/core/reporting/utils.py +46 -0
  70. robusta/core/schedule/__init__.py +0 -0
  71. robusta/core/schedule/model.py +47 -0
  72. robusta/core/schedule/scheduler.py +153 -0
  73. robusta/core/sinks/__init__.py +3 -0
  74. robusta/core/sinks/common/__init__.py +1 -0
  75. robusta/core/sinks/common/channel_transformer.py +106 -0
  76. robusta/core/sinks/common/html_tools.py +108 -0
  77. robusta/core/sinks/datadog/__init__.py +2 -0
  78. robusta/core/sinks/datadog/datadog_sink.py +127 -0
  79. robusta/core/sinks/datadog/datadog_sink_params.py +17 -0
  80. robusta/core/sinks/discord/__init__.py +2 -0
  81. robusta/core/sinks/discord/discord_sink.py +15 -0
  82. robusta/core/sinks/discord/discord_sink_params.py +17 -0
  83. robusta/core/sinks/file/__init__.py +0 -0
  84. robusta/core/sinks/file/file_sink.py +33 -0
  85. robusta/core/sinks/file/file_sink_params.py +19 -0
  86. robusta/core/sinks/file/object_traverser.py +90 -0
  87. robusta/core/sinks/google_chat/__init__.py +0 -0
  88. robusta/core/sinks/google_chat/google_chat.py +19 -0
  89. robusta/core/sinks/google_chat/google_chat_params.py +19 -0
  90. robusta/core/sinks/jira/__init__.py +2 -0
  91. robusta/core/sinks/jira/jira_sink.py +15 -0
  92. robusta/core/sinks/jira/jira_sink_params.py +31 -0
  93. robusta/core/sinks/kafka/__init__.py +2 -0
  94. robusta/core/sinks/kafka/kafka_sink.py +80 -0
  95. robusta/core/sinks/kafka/kafka_sink_params.py +19 -0
  96. robusta/core/sinks/mail/__init__.py +0 -0
  97. robusta/core/sinks/mail/mail_sink.py +18 -0
  98. robusta/core/sinks/mail/mail_sink_params.py +27 -0
  99. robusta/core/sinks/mattermost/__init__.py +2 -0
  100. robusta/core/sinks/mattermost/mattermost_sink.py +26 -0
  101. robusta/core/sinks/mattermost/mattermost_sink_params.py +35 -0
  102. robusta/core/sinks/msteams/__init__.py +2 -0
  103. robusta/core/sinks/msteams/msteams_sink.py +15 -0
  104. robusta/core/sinks/msteams/msteams_sink_params.py +17 -0
  105. robusta/core/sinks/opsgenie/__init__.py +2 -0
  106. robusta/core/sinks/opsgenie/opsgenie_sink.py +103 -0
  107. robusta/core/sinks/opsgenie/opsgenie_sink_params.py +22 -0
  108. robusta/core/sinks/pagerduty/__init__.py +2 -0
  109. robusta/core/sinks/pagerduty/pagerduty_sink.py +254 -0
  110. robusta/core/sinks/pagerduty/pagerduty_sink_params.py +17 -0
  111. robusta/core/sinks/pushover/__init__.py +2 -0
  112. robusta/core/sinks/pushover/pushover_client.py +60 -0
  113. robusta/core/sinks/pushover/pushover_sink.py +123 -0
  114. robusta/core/sinks/pushover/pushover_sink_params.py +22 -0
  115. robusta/core/sinks/robusta/__init__.py +2 -0
  116. robusta/core/sinks/robusta/dal/__init__.py +0 -0
  117. robusta/core/sinks/robusta/dal/model_conversion.py +203 -0
  118. robusta/core/sinks/robusta/dal/supabase_dal.py +712 -0
  119. robusta/core/sinks/robusta/discovery_metrics.py +30 -0
  120. robusta/core/sinks/robusta/prometheus_health_checker.py +108 -0
  121. robusta/core/sinks/robusta/robusta_sink.py +675 -0
  122. robusta/core/sinks/robusta/robusta_sink_params.py +29 -0
  123. robusta/core/sinks/robusta/rrm/__init__.py +0 -0
  124. robusta/core/sinks/robusta/rrm/account_resource_fetcher.py +22 -0
  125. robusta/core/sinks/robusta/rrm/base_resource_manager.py +13 -0
  126. robusta/core/sinks/robusta/rrm/prometheus_alert_resource_manager.py +202 -0
  127. robusta/core/sinks/robusta/rrm/rrm.py +85 -0
  128. robusta/core/sinks/robusta/rrm/types.py +62 -0
  129. robusta/core/sinks/rocketchat/__init__.py +0 -0
  130. robusta/core/sinks/rocketchat/rocketchat_sink.py +19 -0
  131. robusta/core/sinks/rocketchat/rocketchat_sink_params.py +27 -0
  132. robusta/core/sinks/servicenow/__init__.py +0 -0
  133. robusta/core/sinks/servicenow/servicenow_sink.py +15 -0
  134. robusta/core/sinks/servicenow/servicenow_sink_params.py +24 -0
  135. robusta/core/sinks/sink_base.py +185 -0
  136. robusta/core/sinks/sink_base_params.py +158 -0
  137. robusta/core/sinks/sink_config.py +15 -0
  138. robusta/core/sinks/sink_factory.py +64 -0
  139. robusta/core/sinks/slack/__init__.py +2 -0
  140. robusta/core/sinks/slack/slack_sink.py +80 -0
  141. robusta/core/sinks/slack/slack_sink_params.py +32 -0
  142. robusta/core/sinks/telegram/__init__.py +2 -0
  143. robusta/core/sinks/telegram/telegram_client.py +47 -0
  144. robusta/core/sinks/telegram/telegram_sink.py +93 -0
  145. robusta/core/sinks/telegram/telegram_sink_params.py +22 -0
  146. robusta/core/sinks/timing.py +67 -0
  147. robusta/core/sinks/transformer.py +262 -0
  148. robusta/core/sinks/victorops/__init__.py +2 -0
  149. robusta/core/sinks/victorops/victorops_sink.py +82 -0
  150. robusta/core/sinks/victorops/victorops_sink_params.py +17 -0
  151. robusta/core/sinks/webex/__init__.py +2 -0
  152. robusta/core/sinks/webex/webex_sink.py +20 -0
  153. robusta/core/sinks/webex/webex_sink_params.py +18 -0
  154. robusta/core/sinks/webhook/__init__.py +2 -0
  155. robusta/core/sinks/webhook/webhook_sink.py +140 -0
  156. robusta/core/sinks/webhook/webhook_sink_params.py +23 -0
  157. robusta/core/sinks/yamessenger/__init__.py +2 -0
  158. robusta/core/sinks/yamessenger/yamessenger_client.py +84 -0
  159. robusta/core/sinks/yamessenger/yamessenger_sink.py +96 -0
  160. robusta/core/sinks/yamessenger/yamessenger_sink_params.py +30 -0
  161. robusta/core/sinks/zulip/__init__.py +2 -0
  162. robusta/core/sinks/zulip/zulip_sink.py +32 -0
  163. robusta/core/sinks/zulip/zulip_sink_params.py +28 -0
  164. robusta/core/triggers/container_oom_killed_trigger.py +32 -0
  165. robusta/core/triggers/custom_triggers.py +31 -0
  166. robusta/core/triggers/error_event_trigger.py +150 -0
  167. robusta/core/triggers/helm_releases_triggers.py +176 -0
  168. robusta/core/triggers/job_failed_trigger.py +53 -0
  169. robusta/core/triggers/multi_resources_trigger.py +59 -0
  170. robusta/core/triggers/oom_killed_trigger_base.py +110 -0
  171. robusta/core/triggers/pod_crash_loop_trigger.py +75 -0
  172. robusta/core/triggers/pod_evicted_trigger.py +55 -0
  173. robusta/core/triggers/pod_image_pull_backoff.py +83 -0
  174. robusta/core/triggers/pod_oom_killed_trigger.py +32 -0
  175. robusta/integrations/__init__.py +0 -0
  176. robusta/integrations/argocd/argocd_client.py +25 -0
  177. robusta/integrations/common/__init__.py +0 -0
  178. robusta/integrations/common/requests.py +72 -0
  179. robusta/integrations/discord/__init__.py +0 -0
  180. robusta/integrations/discord/sender.py +300 -0
  181. robusta/integrations/git/__init__.py +0 -0
  182. robusta/integrations/git/git_repo.py +296 -0
  183. robusta/integrations/git/well_known_hosts.py +16 -0
  184. robusta/integrations/google_chat/__init__.py +0 -0
  185. robusta/integrations/google_chat/sender.py +143 -0
  186. robusta/integrations/grafana.py +118 -0
  187. robusta/integrations/helper.py +16 -0
  188. robusta/integrations/jira/__init__.py +0 -0
  189. robusta/integrations/jira/client.py +294 -0
  190. robusta/integrations/jira/sender.py +252 -0
  191. robusta/integrations/kubernetes/__init__.py +0 -0
  192. robusta/integrations/kubernetes/api_client_utils.py +288 -0
  193. robusta/integrations/kubernetes/autogenerated/__init__.py +0 -0
  194. robusta/integrations/kubernetes/autogenerated/events.py +1219 -0
  195. robusta/integrations/kubernetes/autogenerated/models.py +12 -0
  196. robusta/integrations/kubernetes/autogenerated/triggers.py +2035 -0
  197. robusta/integrations/kubernetes/autogenerated/v1/__init__.py +0 -0
  198. robusta/integrations/kubernetes/autogenerated/v1/models.py +27 -0
  199. robusta/integrations/kubernetes/base_event.py +33 -0
  200. robusta/integrations/kubernetes/base_triggers.py +282 -0
  201. robusta/integrations/kubernetes/custom_models.py +775 -0
  202. robusta/integrations/kubernetes/model_not_found_exception.py +4 -0
  203. robusta/integrations/kubernetes/process_utils.py +125 -0
  204. robusta/integrations/kubernetes/templates.py +31 -0
  205. robusta/integrations/mail/__init__.py +0 -0
  206. robusta/integrations/mail/sender.py +109 -0
  207. robusta/integrations/mattermost/__init__.py +0 -0
  208. robusta/integrations/mattermost/client.py +167 -0
  209. robusta/integrations/mattermost/sender.py +169 -0
  210. robusta/integrations/msteams/__init__.py +1 -0
  211. robusta/integrations/msteams/msteams_adaptive_card_files.py +27 -0
  212. robusta/integrations/msteams/msteams_adaptive_card_files_image.py +69 -0
  213. robusta/integrations/msteams/msteams_adaptive_card_files_text.py +170 -0
  214. robusta/integrations/msteams/msteams_elements/__init__.py +0 -0
  215. robusta/integrations/msteams/msteams_elements/msteams_action.py +28 -0
  216. robusta/integrations/msteams/msteams_elements/msteams_base.py +6 -0
  217. robusta/integrations/msteams/msteams_elements/msteams_card.py +20 -0
  218. robusta/integrations/msteams/msteams_elements/msteams_column.py +38 -0
  219. robusta/integrations/msteams/msteams_elements/msteams_container.py +24 -0
  220. robusta/integrations/msteams/msteams_elements/msteams_images.py +22 -0
  221. robusta/integrations/msteams/msteams_elements/msteams_table.py +24 -0
  222. robusta/integrations/msteams/msteams_elements/msteams_text_block.py +74 -0
  223. robusta/integrations/msteams/msteams_mark_down_fix_url.py +22 -0
  224. robusta/integrations/msteams/msteams_msg.py +184 -0
  225. robusta/integrations/msteams/sender.py +66 -0
  226. robusta/integrations/openshift/__init__.py +1 -0
  227. robusta/integrations/openshift/token.py +17 -0
  228. robusta/integrations/prometheus/__init__.py +0 -0
  229. robusta/integrations/prometheus/models.py +235 -0
  230. robusta/integrations/prometheus/trigger.py +207 -0
  231. robusta/integrations/prometheus/utils.py +178 -0
  232. robusta/integrations/receiver.py +346 -0
  233. robusta/integrations/resource_analysis/__init__.py +0 -0
  234. robusta/integrations/resource_analysis/cpu_analyzer.py +28 -0
  235. robusta/integrations/resource_analysis/memory_analyzer.py +138 -0
  236. robusta/integrations/resource_analysis/node_cpu_analyzer.py +96 -0
  237. robusta/integrations/resource_analysis/prometheus_analyzer.py +49 -0
  238. robusta/integrations/rocketchat/__init__.py +0 -0
  239. robusta/integrations/rocketchat/sender.py +371 -0
  240. robusta/integrations/scheduled/__init__.py +0 -0
  241. robusta/integrations/scheduled/event.py +19 -0
  242. robusta/integrations/scheduled/models.py +7 -0
  243. robusta/integrations/scheduled/playbook_scheduler.py +19 -0
  244. robusta/integrations/scheduled/playbook_scheduler_manager.py +10 -0
  245. robusta/integrations/scheduled/playbook_scheduler_manager_impl.py +127 -0
  246. robusta/integrations/scheduled/trigger.py +55 -0
  247. robusta/integrations/servicenow/__init__.py +0 -0
  248. robusta/integrations/servicenow/sender.py +138 -0
  249. robusta/integrations/slack/__init__.py +1 -0
  250. robusta/integrations/slack/sender.py +519 -0
  251. robusta/integrations/webex/__init__.py +0 -0
  252. robusta/integrations/webex/sender.py +193 -0
  253. robusta/integrations/zulip/__init__.py +1 -0
  254. robusta/integrations/zulip/sender.py +171 -0
  255. robusta/model/alert_relabel_config.py +14 -0
  256. robusta/model/config.py +223 -0
  257. robusta/model/playbook_action.py +23 -0
  258. robusta/model/playbook_definition.py +44 -0
  259. robusta/patch/patch.py +167 -0
  260. robusta/runner/__init__.py +0 -0
  261. robusta/runner/config_loader.py +286 -0
  262. robusta/runner/log_init.py +21 -0
  263. robusta/runner/main.py +53 -0
  264. robusta/runner/not_found_exception.py +5 -0
  265. robusta/runner/object_updater.py +14 -0
  266. robusta/runner/process_setup.py +21 -0
  267. robusta/runner/ssl_utils.py +40 -0
  268. robusta/runner/telemetry.py +21 -0
  269. robusta/runner/telemetry_service.py +64 -0
  270. robusta/runner/web.py +166 -0
  271. robusta/runner/web_api.py +84 -0
  272. robusta/utils/__init__.py +0 -0
  273. robusta/utils/auth_provider.py +54 -0
  274. robusta/utils/base64_utils.py +9 -0
  275. robusta/utils/cluster_provider_discovery.py +111 -0
  276. robusta/utils/common.py +43 -0
  277. robusta/utils/decorators.py +22 -0
  278. robusta/utils/docs.py +52 -0
  279. robusta/utils/documented_pydantic.py +61 -0
  280. robusta/utils/error_codes.py +41 -0
  281. robusta/utils/file_system_watcher.py +49 -0
  282. robusta/utils/function_hashes.py +24 -0
  283. robusta/utils/json_schema.py +162 -0
  284. robusta/utils/parsing.py +23 -0
  285. robusta/utils/rate_limiter.py +29 -0
  286. robusta/utils/scope.py +95 -0
  287. robusta/utils/server_start.py +15 -0
  288. robusta/utils/service_discovery.py +25 -0
  289. robusta/utils/silence_utils.py +170 -0
  290. robusta/utils/stack_tracer.py +25 -0
  291. robusta/utils/task_queue.py +73 -0
  292. robusta_api-0.0.0.dist-info/LICENSE +21 -0
  293. robusta_api-0.0.0.dist-info/METADATA +60 -0
  294. robusta_api-0.0.0.dist-info/RECORD +295 -0
  295. robusta_api-0.0.0.dist-info/WHEEL +4 -0
robusta/__init__.py ADDED
File without changes
robusta/_version.py ADDED
@@ -0,0 +1,2 @@
1
+ # this is updated by .github/workflows/release.yaml
2
+ __version__ = "0.0.0"
@@ -0,0 +1,330 @@
1
+ from hikaru.model.rel_1_26 import Container, DaemonSet, Deployment, Pod, ReplicaSet, StatefulSet, Volume
2
+
3
+ from robusta.core.discovery.discovery import (
4
+ extract_containers_k8,
5
+ extract_ready_pods,
6
+ extract_total_pods,
7
+ extract_volumes_k8,
8
+ is_pod_finished,
9
+ is_release_managed_by_helm,
10
+ should_report_pod,
11
+ )
12
+ from robusta.core.discovery.resource_names import ResourceNameLister
13
+ from robusta.core.model.base_params import (
14
+ ActionParams,
15
+ AlertResourceGraphEnricherParams,
16
+ BashParams,
17
+ ChartValuesFormat,
18
+ CustomGraphEnricherParams,
19
+ EventEnricherParams,
20
+ FindingKeyParams,
21
+ GrafanaAnnotationParams,
22
+ GrafanaParams,
23
+ LogEnricherParams,
24
+ NamedRegexPattern,
25
+ PodResourceGraphEnricherParams,
26
+ PodRunningParams,
27
+ ProcessParams,
28
+ PrometheusDateRange,
29
+ PrometheusDuration,
30
+ PrometheusParams,
31
+ PrometheusQueryParams,
32
+ RateLimitParams,
33
+ ResourceChartItemType,
34
+ ResourceChartResourceType,
35
+ ResourceGraphEnricherParams,
36
+ OOMGraphEnricherParams,
37
+ OomKillParams,
38
+ TimedPrometheusParams,
39
+ VideoEnricherParams,
40
+ )
41
+ from robusta.core.model.env_vars import (
42
+ CLUSTER_DOMAIN,
43
+ CLUSTER_STATUS_PERIOD_SEC,
44
+ CUSTOM_PLAYBOOKS_ROOT,
45
+ DEFAULT_PLAYBOOKS_PIP_INSTALL,
46
+ DEFAULT_PLAYBOOKS_ROOT,
47
+ DEFAULT_TIMEZONE,
48
+ DISCORD_TABLE_COLUMNS_LIMIT,
49
+ DISCOVERY_PERIOD_SEC,
50
+ ENABLE_TELEMETRY,
51
+ FLOAT_PRECISION_LIMIT,
52
+ GIT_MAX_RETRIES,
53
+ GRAFANA_READ_TIMEOUT,
54
+ GRAFANA_RENDERER_URL,
55
+ IMAGE_REGISTRY,
56
+ INCOMING_EVENTS_QUEUE_MAX_SIZE,
57
+ INCOMING_REQUEST_TIME_WINDOW_SECONDS,
58
+ INSTALLATION_NAMESPACE,
59
+ INTERNAL_PLAYBOOKS_ROOT,
60
+ NUM_EVENT_THREADS,
61
+ PLAYBOOKS_CONFIG_FILE_PATH,
62
+ PLAYBOOKS_ROOT,
63
+ PORT,
64
+ PRINTED_TABLE_MAX_WIDTH,
65
+ PROMETHEUS_ENABLED,
66
+ PROMETHEUS_REQUEST_TIMEOUT_SECONDS,
67
+ RELAY_EXTERNAL_ACTIONS_URL,
68
+ RELEASE_NAME,
69
+ RESOURCE_UPDATES_CACHE_TTL_SEC,
70
+ ROBUSTA_LOGO_URL,
71
+ ROBUSTA_TELEMETRY_ENDPOINT,
72
+ ROBUSTA_UI_DOMAIN,
73
+ RUNNER_SERVICE_ACCOUNT,
74
+ RUNNER_VERSION,
75
+ SEND_ADDITIONAL_TELEMETRY,
76
+ SERVICE_CACHE_MAX_SIZE,
77
+ SERVICE_CACHE_TTL_SEC,
78
+ SLACK_TABLE_COLUMNS_LIMIT,
79
+ TEAMS_IMAGE_WIDTH,
80
+ TELEMETRY_PERIODIC_SEC,
81
+ TRACE_INCOMING_REQUESTS,
82
+ WEBSOCKET_PING_INTERVAL,
83
+ WEBSOCKET_PING_TIMEOUT,
84
+ )
85
+ from robusta.core.model.events import ExecutionBaseEvent
86
+ from robusta.core.model.k8s_operation_type import K8sOperationType
87
+ from robusta.core.model.pods import (
88
+ ContainerResources,
89
+ PodContainer,
90
+ PodResources,
91
+ ResourceAttributes,
92
+ find_most_recent_oom_killed_container,
93
+ format_unit,
94
+ get_oom_kill_time,
95
+ get_oom_killed_container,
96
+ is_state_in_oom_status,
97
+ k8s_memory_factors,
98
+ pod_limits,
99
+ pod_most_recent_oom_killed_container,
100
+ pod_other_requests,
101
+ pod_requests,
102
+ pod_resources,
103
+ pod_restarts,
104
+ )
105
+ from robusta.core.model.services import ContainerInfo, EnvVar, Resources, ServiceConfig, ServiceInfo, VolumeInfo
106
+ from robusta.core.persistency.in_memory import get_persistent_data
107
+ from robusta.core.playbooks.actions_registry import Action, action
108
+ from robusta.core.playbooks.common import get_event_timestamp, get_resource_events, get_resource_events_table
109
+ from robusta.core.playbooks.container_playbook_utils import create_container_graph
110
+ from robusta.core.playbooks.job_utils import CONTROLLER_UID, get_job_all_pods, get_job_latest_pod, get_job_selector
111
+ from robusta.core.playbooks.node_playbook_utils import create_node_graph_enrichment
112
+ from robusta.core.playbooks.pod_utils.crashloop_utils import get_crash_report_enrichments
113
+ from robusta.core.playbooks.pod_utils.imagepull_utils import (
114
+ get_image_pull_backoff_enrichment,
115
+ get_image_pull_backoff_container_statuses,
116
+ )
117
+ from robusta.core.playbooks.pod_utils.pending_pod_utils import get_pending_pod_enrichment
118
+ from robusta.core.playbooks.crash_reporter import send_crash_report
119
+ from robusta.core.playbooks.prometheus_enrichment_utils import (
120
+ XAxisLine,
121
+ create_chart_from_prometheus_query,
122
+ create_graph_enrichment,
123
+ create_resource_enrichment,
124
+ get_node_internal_ip,
125
+ run_prometheus_query,
126
+ run_prometheus_query_range,
127
+ )
128
+ from robusta.core.playbooks.trigger import (
129
+ BaseTrigger,
130
+ CustomTriggers,
131
+ K8sTriggers,
132
+ PrometheusAlertTriggers,
133
+ ScheduledTriggers,
134
+ Trigger,
135
+ )
136
+ from robusta.core.reporting import (
137
+ BaseBlock,
138
+ CallbackBlock,
139
+ CallbackChoice,
140
+ DividerBlock,
141
+ Emojis,
142
+ Enrichment,
143
+ FileBlock,
144
+ EmptyFileBlock,
145
+ Filterable,
146
+ Finding,
147
+ FindingSeverity,
148
+ FindingStatus,
149
+ FindingSubject,
150
+ HeaderBlock,
151
+ JsonBlock,
152
+ KubernetesDiffBlock,
153
+ KubernetesFieldsBlock,
154
+ ListBlock,
155
+ MarkdownBlock,
156
+ PrometheusBlock,
157
+ ScanReportBlock,
158
+ PopeyeScanReportBlock,
159
+ KRRScanReportBlock,
160
+ ScanReportRow,
161
+ TableBlock,
162
+ VideoLink,
163
+ )
164
+
165
+ from robusta.core.reporting.base import EnrichmentType
166
+ from robusta.core.reporting.blocks import GraphBlock
167
+ from robusta.core.reporting.action_requests import (
168
+ ActionRequestBody,
169
+ ExternalActionRequest,
170
+ OutgoingActionRequest,
171
+ PartialAuth,
172
+ sign_action_request,
173
+ )
174
+ from robusta.core.reporting.callbacks import ExternalActionRequestBuilder
175
+ from robusta.core.reporting.consts import (
176
+ EnrichmentAnnotation,
177
+ FindingAggregationKey,
178
+ FindingSource,
179
+ FindingSubjectType,
180
+ FindingType,
181
+ ScanType,
182
+ SlackAnnotations,
183
+ )
184
+ from robusta.core.reporting.custom_rendering import RendererType, charts_style, render_value
185
+ from robusta.core.reporting.finding_subjects import KubeObjFindingSubject, PodFindingSubject
186
+ from robusta.core.schedule.model import (
187
+ DynamicDelayRepeat,
188
+ FixedDelayRepeat,
189
+ JobState,
190
+ JobStatus,
191
+ ScheduledJob,
192
+ SchedulingInfo,
193
+ )
194
+ from robusta.core.playbooks.node_playbook_utils import create_node_graph_enrichment
195
+ from robusta.core.sinks import SinkBase, SinkBaseParams, SinkConfigBase
196
+ from robusta.core.sinks.kafka import KafkaSink, KafkaSinkConfigWrapper, KafkaSinkParams
197
+ from robusta.core.triggers.helm_releases_triggers import HelmReleasesEvent, HelmReleasesTriggerEvent
198
+ from robusta.integrations.argocd.argocd_client import ArgoCDClient
199
+ from robusta.integrations.git.git_repo import ClusterChanges, GitRepo, GitRepoManager, SingleChange
200
+ from robusta.integrations.grafana import Grafana
201
+ from robusta.integrations.kubernetes.api_client_utils import (
202
+ exec_commands,
203
+ exec_shell_command,
204
+ get_pod_logs,
205
+ list_available_services,
206
+ parse_kubernetes_datetime,
207
+ parse_kubernetes_datetime_to_ms,
208
+ parse_kubernetes_datetime_with_ms,
209
+ prepare_pod_command,
210
+ to_kubernetes_name,
211
+ upload_file,
212
+ wait_for_pod_status,
213
+ wait_until,
214
+ wait_until_job_complete,
215
+ )
216
+ from robusta.integrations.kubernetes.autogenerated.events import (
217
+ KIND_TO_EVENT_CLASS,
218
+ LOADERS_MAPPINGS,
219
+ ClusterRoleAttributes,
220
+ ClusterRoleBindingAttributes,
221
+ ClusterRoleBindingChangeEvent,
222
+ ClusterRoleBindingEvent,
223
+ ClusterRoleChangeEvent,
224
+ ClusterRoleEvent,
225
+ ConfigMapAttributes,
226
+ ConfigMapChangeEvent,
227
+ ConfigMapEvent,
228
+ DaemonSetAttributes,
229
+ DaemonSetChangeEvent,
230
+ DaemonSetEvent,
231
+ DeploymentAttributes,
232
+ DeploymentChangeEvent,
233
+ DeploymentEvent,
234
+ EventAttributes,
235
+ EventChangeEvent,
236
+ EventEvent,
237
+ HorizontalPodAutoscalerAttributes,
238
+ HorizontalPodAutoscalerChangeEvent,
239
+ HorizontalPodAutoscalerEvent,
240
+ JobAttributes,
241
+ JobChangeEvent,
242
+ JobEvent,
243
+ KubernetesAnyChangeEvent,
244
+ KubernetesResourceEvent,
245
+ NamespaceAttributes,
246
+ NamespaceChangeEvent,
247
+ NamespaceEvent,
248
+ NodeAttributes,
249
+ NodeChangeEvent,
250
+ NodeEvent,
251
+ PersistentVolumeAttributes,
252
+ PersistentVolumeChangeEvent,
253
+ PersistentVolumeEvent,
254
+ PodAttributes,
255
+ PodChangeEvent,
256
+ PodEvent,
257
+ ReplicaSetAttributes,
258
+ ReplicaSetChangeEvent,
259
+ ReplicaSetEvent,
260
+ ResourceAttributes,
261
+ ResourceLoader,
262
+ ServiceAccountAttributes,
263
+ ServiceAccountChangeEvent,
264
+ ServiceAccountEvent,
265
+ ServiceAttributes,
266
+ ServiceChangeEvent,
267
+ ServiceEvent,
268
+ StatefulSetAttributes,
269
+ StatefulSetChangeEvent,
270
+ StatefulSetEvent,
271
+ )
272
+ from robusta.integrations.kubernetes.autogenerated.models import VERSION_KIND_TO_MODEL_CLASS, get_api_version
273
+ from robusta.integrations.kubernetes.custom_models import (
274
+ JobSecret,
275
+ Process,
276
+ ProcessList,
277
+ RegexReplacementStyle,
278
+ RobustaDeployment,
279
+ RobustaEvent,
280
+ RobustaJob,
281
+ RobustaPod,
282
+ build_selector_query,
283
+ does_daemonset_have_toleration,
284
+ does_node_have_taint,
285
+ extract_image_list,
286
+ extract_images,
287
+ get_images,
288
+ list_pods_using_selector,
289
+ )
290
+ from robusta.integrations.kubernetes.process_utils import ProcessFinder, ProcessType
291
+ from robusta.integrations.prometheus.models import (
292
+ SEVERITY_MAP,
293
+ AlertManagerEvent,
294
+ PrometheusAlert,
295
+ PrometheusKubernetesAlert,
296
+ )
297
+ from robusta.integrations.prometheus.utils import (
298
+ AlertManagerDiscovery,
299
+ PrometheusDiscovery,
300
+ ServiceDiscovery,
301
+ get_prometheus_connect,
302
+ )
303
+ from robusta.integrations.resource_analysis.cpu_analyzer import CpuAnalyzer
304
+ from robusta.integrations.resource_analysis.memory_analyzer import MemoryAnalyzer, pretty_size
305
+ from robusta.integrations.resource_analysis.node_cpu_analyzer import NodeCpuAnalyzer
306
+ from robusta.integrations.scheduled.event import ScheduledExecutionEvent
307
+ from robusta.integrations.scheduled.playbook_scheduler_manager_impl import (
308
+ PlaybooksSchedulerManagerImpl,
309
+ ScheduledIntegrationParams,
310
+ )
311
+ from robusta.integrations.scheduled.trigger import DynamicDelayRepeatTrigger, FixedDelayRepeatTrigger
312
+ from robusta.integrations.slack.sender import SlackSender
313
+ from robusta.runner.object_updater import update_item_attr
314
+ from robusta.utils.base64_utils import is_base64_encoded
315
+ from robusta.utils.cluster_provider_discovery import cluster_provider
316
+ from robusta.utils.common import duplicate_without_fields, is_matching_diff
317
+ from robusta.utils.error_codes import ActionException, ErrorCodes
318
+ from robusta.utils.function_hashes import action_hash
319
+ from robusta.utils.parsing import load_json
320
+ from robusta.utils.rate_limiter import RateLimiter
321
+ from robusta.utils.silence_utils import (
322
+ AddSilenceParams,
323
+ AlertManagerParams,
324
+ DeleteSilenceParams,
325
+ Silence,
326
+ SilenceOperation,
327
+ gen_alertmanager_headers,
328
+ get_alertmanager_url,
329
+ get_alertmanager_url_path,
330
+ )
File without changes
robusta/cli/auth.py ADDED
@@ -0,0 +1,166 @@
1
+ import base64
2
+ import re
3
+ import subprocess
4
+ import traceback
5
+ import uuid
6
+ from typing import Optional
7
+
8
+ import click_spinner
9
+ import requests
10
+ import typer
11
+ import yaml
12
+ from cryptography.hazmat.primitives.asymmetric import rsa
13
+ from cryptography.hazmat.primitives.serialization import Encoding, NoEncryption, PrivateFormat, PublicFormat
14
+ from dpath.util import get
15
+ from pydantic import BaseModel
16
+
17
+ from robusta.cli.backend_profile import backend_profile
18
+ from robusta.cli.playbooks_cmd import NAMESPACE_EXPLANATION, get_playbooks_config
19
+ from robusta.cli.utils import exec_in_robusta_runner_output, namespace_to_kubectl
20
+
21
+ AUTH_SECRET_NAME = "robusta-auth-config-secret"
22
+ app = typer.Typer(add_completion=False)
23
+
24
+
25
+ class RSAKeyPair(BaseModel):
26
+ prv: str = None
27
+ pub: str = None
28
+ private: str = None
29
+ public: str = None
30
+
31
+
32
+ def gen_rsa_pair() -> RSAKeyPair:
33
+ # generate private/public key pair
34
+ key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
35
+
36
+ # get public key in OpenSSH format
37
+ public_key = key.public_key().public_bytes(Encoding.PEM, PublicFormat.SubjectPublicKeyInfo)
38
+
39
+ # get private key in PEM container format
40
+ pem = key.private_bytes(
41
+ encoding=Encoding.PEM, format=PrivateFormat.TraditionalOpenSSL, encryption_algorithm=NoEncryption()
42
+ )
43
+
44
+ return RSAKeyPair(public=base64.b64encode(public_key), private=base64.b64encode(pem))
45
+
46
+
47
+ def get_existing_auth_config(namespace: str) -> Optional[RSAKeyPair]:
48
+ try:
49
+ secret_content = subprocess.check_output(
50
+ f"kubectl get secret {namespace_to_kubectl(namespace)} {AUTH_SECRET_NAME} -o yaml",
51
+ shell=True,
52
+ )
53
+ except Exception:
54
+ return None
55
+
56
+ auth_secret = yaml.safe_load(secret_content)
57
+ return RSAKeyPair(
58
+ prv=base64.b64decode(auth_secret["data"]["prv"]).decode(),
59
+ pub=base64.b64decode(auth_secret["data"]["pub"]).decode(),
60
+ )
61
+
62
+
63
+ class TokenDetails(BaseModel):
64
+ pub: str
65
+ account_id: str
66
+ user_id: str
67
+ session_token: str
68
+ enc_key: str
69
+ key_id: str
70
+
71
+
72
+ def store_server_token(token_details: TokenDetails, debug: bool = False) -> bool:
73
+ try:
74
+ response = requests.post(backend_profile.robusta_store_token_url, json=token_details.dict())
75
+ if debug and response.status_code != 201:
76
+ typer.secho(f"Failed to store server token. status-code {response.status_code} text {response.text}")
77
+
78
+ return response.status_code == 201
79
+ except Exception:
80
+ if debug:
81
+ typer.secho(f"Error trying to store server token. {traceback.format_exc()}")
82
+ return False
83
+
84
+
85
+ def _get_signing_key_from_env_variable(namespace: Optional[str], env_var_name: str) -> str:
86
+ return str(exec_in_robusta_runner_output(f'echo "${env_var_name}"', namespace), "utf-8").strip()
87
+
88
+
89
+ @app.command(name="web-connect")
90
+ @app.command()
91
+ def gen_token(
92
+ account_id: str = typer.Option(
93
+ ...,
94
+ help="Robusta account id",
95
+ ),
96
+ user_id: str = typer.Option(..., help="User id for which the token is created"),
97
+ session_token: str = typer.Option(
98
+ ...,
99
+ help="User session token. Created for an authenticated user via the Robusta UI",
100
+ ),
101
+ namespace: str = typer.Option(
102
+ None,
103
+ help=NAMESPACE_EXPLANATION,
104
+ ),
105
+ debug: bool = typer.Option(False),
106
+ ):
107
+ """Generate token required to run actions manually in Robusta UI"""
108
+ typer.echo("connecting to cluster...")
109
+ with click_spinner.spinner():
110
+ auth_config = get_existing_auth_config(namespace)
111
+
112
+ if not auth_config:
113
+ typer.secho(
114
+ "\nRSA auth isn't configured. "
115
+ "Please update Robusta and run `robusta update-config` to configure it. Aborting!",
116
+ fg="red",
117
+ )
118
+ return
119
+
120
+ playbooks_config = get_playbooks_config(namespace)
121
+ active_playbooks_file = playbooks_config["data"]["active_playbooks.yaml"]
122
+ playbooks_config_yaml = yaml.safe_load(active_playbooks_file)
123
+ signing_key = get(playbooks_config_yaml, "global_config/signing_key", default=None)
124
+ if not signing_key:
125
+ typer.secho("signing_key is not defined. Please update Robusta and run `robusta update-config`", fg="red")
126
+ return
127
+
128
+ try:
129
+ env_match = re.fullmatch(r"\{\{\s*env\.(\S+)\s*}}", signing_key)
130
+ if env_match:
131
+ env_var_name = env_match.group(1)
132
+ typer.secho(f"Fetching secret key from an env var named: {env_var_name}")
133
+ signing_key = _get_signing_key_from_env_variable(namespace, env_var_name)
134
+ if not signing_key:
135
+ typer.secho(f"Could not find an env var named {env_var_name}", fg="red")
136
+ return
137
+ signing_key_uuid = uuid.UUID(signing_key)
138
+ except Exception:
139
+ typer.secho(
140
+ "Bad format for signing_key. Please run `robusta update-config` to generate a new valid"
141
+ " signing_key for your account.",
142
+ fg="red",
143
+ )
144
+ return
145
+
146
+ client_enc_key = uuid.uuid4()
147
+ server_enc_key = uuid.UUID(int=(signing_key_uuid.int ^ client_enc_key.int))
148
+ key_id = str(uuid.uuid4())
149
+
150
+ token_response = TokenDetails(
151
+ pub=auth_config.pub,
152
+ account_id=account_id,
153
+ user_id=user_id,
154
+ session_token=session_token,
155
+ enc_key=str(server_enc_key),
156
+ key_id=key_id,
157
+ )
158
+ if not store_server_token(token_response, debug):
159
+ typer.secho("Failed to store server token. Aborting!", fg="red")
160
+ return
161
+
162
+ # client response is the same, only with a different enc_key
163
+ token_response.enc_key = str(client_enc_key)
164
+
165
+ typer.secho("Token created successfully. Submit it in the Robusta UI", fg="green")
166
+ typer.secho(base64.b64encode(token_response.json(exclude={"session_token"}).encode("utf-8")).decode())
@@ -0,0 +1,54 @@
1
+ import os
2
+ import sys
3
+
4
+ import typer
5
+ from pydantic.main import BaseModel
6
+
7
+ from robusta.cli.utils import host_for_params
8
+
9
+ ROBUSTA_BACKEND_PROFILE = os.environ.get("ROBUSTA_BACKEND_PROFILE", "")
10
+
11
+
12
+ class BackendProfile(BaseModel):
13
+ robusta_cloud_api_host: str = ""
14
+ robusta_ui_domain: str = ""
15
+ robusta_relay_ws_address: str = ""
16
+ robusta_relay_external_actions_url: str = ""
17
+ robusta_telemetry_endpoint: str = ""
18
+ robusta_store_token_url: str = ""
19
+ custom_profile: bool = False
20
+
21
+ @classmethod
22
+ def fromDomainProvider(
23
+ cls, domain: str, api_endpoint_prefix: str, platform_endpoint_prefix: str, relay_endpoint_prefix: str
24
+ ):
25
+ return cls(
26
+ robusta_cloud_api_host=host_for_params(api_endpoint_prefix, domain),
27
+ robusta_ui_domain=host_for_params(platform_endpoint_prefix, domain),
28
+ robusta_relay_ws_address=host_for_params(relay_endpoint_prefix, domain, "wss"),
29
+ robusta_relay_external_actions_url=f"{host_for_params(api_endpoint_prefix, domain)}/integrations/generic/actions",
30
+ robusta_telemetry_endpoint=f"{host_for_params(api_endpoint_prefix, domain)}/telemetry",
31
+ robusta_store_token_url=f"{host_for_params(api_endpoint_prefix, domain)}/auth/server/tokens",
32
+ )
33
+
34
+
35
+ # default values
36
+ backend_profile = BackendProfile(
37
+ robusta_cloud_api_host="https://api.robusta.dev",
38
+ robusta_ui_domain="https://platform.robusta.dev",
39
+ robusta_store_token_url="https://api.robusta.dev/auth/server/tokens",
40
+ )
41
+
42
+ if ROBUSTA_BACKEND_PROFILE:
43
+ typer.secho(
44
+ f"Using Robusta backend profile: {ROBUSTA_BACKEND_PROFILE}",
45
+ color="blue",
46
+ )
47
+ backend_profile = BackendProfile.parse_file(ROBUSTA_BACKEND_PROFILE)
48
+ backend_profile.custom_profile = True
49
+
50
+ profile_dict = backend_profile.dict()
51
+ for attribute, val in profile_dict.items():
52
+ if not profile_dict.get(attribute):
53
+ typer.secho(f"Illegal profile. Missing {attribute}. Aborting!")
54
+ sys.exit(1)
robusta/cli/eula.py ADDED
@@ -0,0 +1,27 @@
1
+ import requests
2
+ import typer
3
+
4
+ from robusta.cli.backend_profile import backend_profile
5
+
6
+
7
+ def handle_eula(account_id, robusta_api_key, cloud_routing_enabled):
8
+ require_eula = robusta_api_key or cloud_routing_enabled
9
+ if not require_eula:
10
+ return
11
+
12
+ while True:
13
+ eula_url = f"{backend_profile.robusta_cloud_api_host}/eula.html"
14
+ typer.echo(f"Please read and approve our End User License Agreement: {eula_url}")
15
+ eula_approved = typer.confirm("Do you accept our End User License Agreement?")
16
+
17
+ if eula_approved:
18
+ try:
19
+ requests.get(f"{eula_url}?account_id={account_id}")
20
+ except Exception:
21
+ typer.echo(f"\nEula approval failed: {eula_url}")
22
+ return
23
+
24
+ typer.secho(
25
+ "End User License Agreement rejected. Sorry, you must either accept or restart the installation and disable the UI and cloud features",
26
+ fg="red",
27
+ )