66 lines
3.8 KiB
Text
66 lines
3.8 KiB
Text
|
|
# Cluster kube-apiserver access resolution — extracted from cli/components.nu (ADR-026 slice 2a-iii).
|
||
|
|
use tools/nickel/process.nu [comp-ncl-export]
|
||
|
|
use domain/workspace/resolve.nu [comp-state-server comp-ws-path comp-ws-infra]
|
||
|
|
use platform/clients/ssh.nu [comp-server-ssh-info comp-ssh-run]
|
||
|
|
|
||
|
|
# Resolve how to reach the cluster's kube-apiserver for an infra.
|
||
|
|
# provisioning NEVER runs kubectl locally: the API server is reachable only from
|
||
|
|
# the control-plane node. The SSH host and remote kubectl invocation are declared
|
||
|
|
# in settings.cluster_access (ssh_host + remote_kubectl). When unset, fall back to
|
||
|
|
# the first server present in the state file and `k0s kubectl`.
|
||
|
|
export def comp-kubectl-access [ws_root: string, infra: string]: nothing -> record {
|
||
|
|
let raw = (comp-ncl-export $ws_root $"infra/($infra)/settings.ncl")
|
||
|
|
let s = ($raw | get -o settings | default {})
|
||
|
|
let ca = ($s | get -o cluster_access | default {})
|
||
|
|
# Operator-delegated workspaces (adr-002) own no cluster — they deploy onto a
|
||
|
|
# target cluster. With no local cluster_access, resolve the target workspace's
|
||
|
|
# access so kubectl reads hit the operator cluster's control-plane, not a CP
|
||
|
|
# this workspace does not have. Guarded: a failed cross-workspace resolve
|
||
|
|
# falls through to the local default rather than aborting the caller.
|
||
|
|
let target_ws = ($s | get -o deployment_target | default {}
|
||
|
|
| get -o target_cluster | default {} | get -o workspace | default "")
|
||
|
|
if ($ca | is-empty) and ($target_ws | is-not-empty) {
|
||
|
|
let delegated = (try {
|
||
|
|
let tgt_root = (comp-ws-path $target_ws)
|
||
|
|
if ($tgt_root | is-not-empty) and ($tgt_root != $ws_root) and ($tgt_root | path exists) {
|
||
|
|
comp-kubectl-access $tgt_root (comp-ws-infra $tgt_root)
|
||
|
|
} else { null }
|
||
|
|
} catch { null })
|
||
|
|
if ($delegated != null) { return $delegated }
|
||
|
|
}
|
||
|
|
let host = ($ca | get -o ssh_host | default "")
|
||
|
|
let kc = ($ca | get -o remote_kubectl | default "k0s kubectl")
|
||
|
|
let resolved_host = if ($host | is-not-empty) { $host } else {
|
||
|
|
let state_root = if (($ws_root | path join "infra" $infra ".provisioning-state.ncl") | path exists) {
|
||
|
|
$ws_root | path join "infra" $infra
|
||
|
|
} else { $ws_root }
|
||
|
|
comp-state-server $state_root
|
||
|
|
}
|
||
|
|
# ws_root/infra identify the workspace that OWNS the resolved host, so callers
|
||
|
|
# resolve SSH connection details (ip/user/key) from the right servers.ncl even
|
||
|
|
# when access was delegated from an operator-delegated workspace.
|
||
|
|
{ host: $resolved_host, kubectl: $kc, ws_root: $ws_root, infra: $infra }
|
||
|
|
}
|
||
|
|
|
||
|
|
# Run a remote kubectl command via SSH using the infra's declared cluster_access.
|
||
|
|
# Hard-bounded so it can never hang: ConnectTimeout caps the connect phase,
|
||
|
|
# ServerAlive kills a half-dead session, and a remote `timeout` caps the kubectl
|
||
|
|
# call itself. Returns the {exit_code, stdout, stderr} record from `complete`.
|
||
|
|
export def comp-kubectl-ssh [
|
||
|
|
ws_root: string,
|
||
|
|
infra: string,
|
||
|
|
kargs: string, # kubectl arguments, e.g. "get pods -A -o json"
|
||
|
|
--cmd-timeout: int = 20, # remote wall-clock cap on the kubectl invocation
|
||
|
|
]: nothing -> record {
|
||
|
|
let access = (comp-kubectl-access $ws_root $infra)
|
||
|
|
if ($access.host | is-empty) {
|
||
|
|
return { exit_code: 1, stdout: "", stderr: "cluster_access.ssh_host unset and no server in state file" }
|
||
|
|
}
|
||
|
|
# Resolve SSH details from the workspace that owns the host (the operator
|
||
|
|
# cluster when access was delegated), not necessarily the calling workspace.
|
||
|
|
let info = (comp-server-ssh-info $access.ws_root $access.infra $access.host)
|
||
|
|
let remote = $"export PATH=/usr/local/bin:/usr/bin:/bin:$PATH; timeout ($cmd_timeout) ($access.kubectl) ($kargs)"
|
||
|
|
comp-ssh-run $info.user $info.key $info.host $remote
|
||
|
|
}
|
||
|
|
|