Drain sicuro in scale-in, alert Ops su overflow e controlli admin senza abilitare il deploy in produzione. Co-authored-by: Cursor <cursoragent@cursor.com>
84 lines
3.6 KiB
ERB
84 lines
3.6 KiB
ERB
<% content_for :body_class, "admin-body" %>
|
|
<h2><%= t("admin.stream_nodes.title") %></h2>
|
|
<p class="admin-muted">
|
|
<%= t("admin.stream_nodes.providers", cloud: @cloud_provider, dns: @dns_provider) %>
|
|
</p>
|
|
|
|
<p class="admin-muted">
|
|
<%= t(
|
|
"admin.stream_nodes.autoscale",
|
|
enabled: (@autoscale_metrics[:enabled] ? "ON" : "OFF"),
|
|
free: @autoscale_metrics[:free_slots],
|
|
soft: @autoscale_metrics[:soft_free_slots],
|
|
spare: @autoscale_metrics[:spare_ready],
|
|
warm: @autoscale_metrics[:warm_spare_min],
|
|
overflow: @autoscale_metrics[:overflow_nodes],
|
|
max: @autoscale_metrics[:max_overflow_nodes],
|
|
kind: @autoscale_metrics[:kind]
|
|
) %>
|
|
· <%= t(
|
|
"admin.stream_nodes.autoscale_budget",
|
|
eur: @autoscale_metrics[:estimated_monthly_eur],
|
|
budget: @autoscale_metrics[:monthly_budget_eur],
|
|
ok: (@autoscale_metrics[:within_budget] ? "OK" : "OVER")
|
|
) %>
|
|
<% if @autoscale_metrics[:kill_switch] %>
|
|
· <strong><%= t("admin.stream_nodes.kill_switch_active") %></strong>
|
|
<% end %>
|
|
</p>
|
|
|
|
<p>
|
|
<%= button_to t("admin.stream_nodes.provision_lab"), admin_stream_nodes_path, method: :post, params: { kind: "lab" }, class: "admin-btn" %>
|
|
<% if @hetzner_configured %>
|
|
<%= button_to t("admin.stream_nodes.provision_cloud"), admin_stream_nodes_path, method: :post, params: { kind: "cloud" }, class: "admin-btn",
|
|
form: { data: { confirm: t("admin.stream_nodes.provision_cloud_confirm") } } %>
|
|
<% else %>
|
|
<span class="admin-muted"><%= t("admin.stream_nodes.hetzner_token_missing") %></span>
|
|
<% end %>
|
|
<% if @autoscale_metrics[:kill_switch] %>
|
|
<%= button_to t("admin.stream_nodes.clear_kill_switch"), clear_kill_switch_admin_stream_nodes_path, method: :delete, class: "admin-btn admin-btn-secondary" %>
|
|
<% else %>
|
|
<%= button_to t("admin.stream_nodes.engage_kill_switch"), kill_switch_admin_stream_nodes_path, method: :post, class: "admin-btn admin-btn-danger",
|
|
form: { data: { confirm: t("admin.stream_nodes.kill_switch_confirm") } } %>
|
|
<% end %>
|
|
</p>
|
|
|
|
<table class="admin-table">
|
|
<thead>
|
|
<tr>
|
|
<th><%= t("admin.stream_nodes.col.slug") %></th>
|
|
<th><%= t("admin.stream_nodes.col.role") %></th>
|
|
<th><%= t("admin.stream_nodes.col.status") %></th>
|
|
<th><%= t("admin.stream_nodes.col.slots") %></th>
|
|
<th><%= t("admin.stream_nodes.col.hostname") %></th>
|
|
<th><%= t("admin.stream_nodes.col.provider") %></th>
|
|
<th></th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<% @nodes.each do |node| %>
|
|
<tr>
|
|
<td><code><%= node.slug %></code></td>
|
|
<td><%= node.role %></td>
|
|
<td><%= node.status %></td>
|
|
<td><%= node.active_publishers %> / <%= node.max_publishers %> (free <%= node.free_slots %>)</td>
|
|
<td><code><%= node.hostname %></code></td>
|
|
<td><%= node.provider %><% if node.provider_instance_id.present? %> · <%= node.provider_instance_id %><% end %></td>
|
|
<td class="admin-actions">
|
|
<% if node.slug != "home" %>
|
|
<% if node.status == "ready" %>
|
|
<%= button_to t("admin.stream_nodes.drain"), drain_admin_stream_node_path(node), method: :post, class: "admin-btn admin-btn-secondary" %>
|
|
<% end %>
|
|
<%= button_to t("admin.stream_nodes.destroy"), admin_stream_node_path(node), method: :delete, class: "admin-btn admin-btn-danger", form: { data: { confirm: t("admin.stream_nodes.destroy_confirm", slug: node.slug) } } %>
|
|
<% end %>
|
|
</td>
|
|
</tr>
|
|
<% end %>
|
|
</tbody>
|
|
</table>
|
|
|
|
<% if @lab_hosts.present? %>
|
|
<h3><%= t("admin.stream_nodes.hosts_title") %></h3>
|
|
<pre class="admin-pre"><%= @lab_hosts %></pre>
|
|
<% end %>
|