use lib_provisioning * use utils.nu * use ../lib_provisioning/config/accessor.nu * use ../../../extensions/providers/hetzner/nulib/hetzner/api.nu [hetzner_api_server_info] # Show detailed server information export def "main info" [ name?: string # Server hostname or index (all servers if omitted) --infra (-i): string # Infra directory --settings (-s): string # Settings path --notitles # Not titles --helpinfo (-h) # For more details use options "help" (no dashes) --out: string # Output format: json, yaml, text (default) ] { if ($out | is-not-empty) { set-provisioning-out $out set-provisioning-no-terminal true } provisioning_init $helpinfo "servers info" [] let curr_settings = (find_get_settings --infra $infra --settings $settings) let servers = if ($curr_settings | get data? | is-not-empty) { $curr_settings.data | get servers? | default [] } else { $curr_settings | get servers? | default [] } if ($servers | is-empty) { _print "No servers configured" return } let target = if ($name | is-not-empty) { let found = (find_server $name $servers ($out | default "")) if ($found | is-empty) { _print $"🛑 Server not found: ($name)" exit 1 } [$found] } else { $servers } let ws_root = ($curr_settings | get -o infra_path | default "" | path dirname) let infra_dir = ($curr_settings | get -o infra_path | default "" | path join ($curr_settings | get -o infra | default "")) let fsm_states = (read_fsm_states $ws_root) let ts_states = (read_infra_taskserv_states $infra_dir) # Use $out directly — get-provisioning-out env mutation doesn't propagate back to this scope match ($out | default "") { "json" => { print ($target | to json) } "yaml" => { print ($target | to yaml) } "" => { $target | each {|s| _print $"\n(ansi cyan_bold)($s.hostname)(ansi reset)" _print ($s | reject hostname | table -e -i false) # FSM state + live protection let dim_id = (server_fsm_dimension $s.hostname) let fsm_entry = if ($dim_id | is-not-empty) { $fsm_states | get -o $dim_id | default null } else { null } let live_prot = (do -i { hetzner_api_server_info $s.hostname | get -o protection } | default null) let fsm_line = if $fsm_entry != null { $" FSM ($dim_id): (ansi yellow)($fsm_entry.current)(ansi reset) → (ansi green)($fsm_entry.desired)(ansi reset)" } else { "" } let prot_line = $" Protection: (ansi cyan)(format_protection $live_prot)(ansi reset)" if ($fsm_line | is-not-empty) { _print $fsm_line } _print $prot_line # Taskserv runtime states let ts = ($ts_states | get -o $s.hostname | default []) if ($ts | is-not-empty) { _print $"\n (ansi default_dimmed)taskserv states(ansi reset)" _print ($ts | each {|t| let state_color = match $t.state { "completed" => (ansi green) "failed" => (ansi red) "running" => (ansi yellow) _ => (ansi default_dimmed) } { taskserv: $t.name state: $"($state_color)($t.state)(ansi reset)" operation: $t.operation } } | table -i false) } } | ignore } _ => { print ($target | to json) } } if not $notitles and not (is-debug-enabled) { end_run "" } }