166 lines
7.6 KiB
Text
166 lines
7.6 KiB
Text
#!/usr/bin/env nu
|
|
# Thin entry for cluster commands.
|
|
# Loads only cluster-deploy.nu + discover + workspace (~140ms vs ~49s for the full entry).
|
|
|
|
export-env {
|
|
let lib_dirs_raw = ($env.NU_LIB_DIRS? | default "")
|
|
let current_lib_dirs = if ($lib_dirs_raw | type) == "string" {
|
|
if ($lib_dirs_raw | is-empty) { [] } else { ($lib_dirs_raw | split row ":") }
|
|
} else {
|
|
$lib_dirs_raw
|
|
}
|
|
let dynamic = ($env.PROVISIONING? | default "" | path join "core" "nulib")
|
|
$env.NU_LIB_DIRS = ([
|
|
"/opt/provisioning/core/nulib"
|
|
"/usr/local/provisioning/core/nulib"
|
|
] | append $current_lib_dirs | append (if ($dynamic | is-not-empty) { [$dynamic] } else { [] }))
|
|
}
|
|
|
|
use domain/workspace/mod.nu *
|
|
use platform/user/config.nu [get-workspace-path, get-active-workspace-details]
|
|
use platform/config/accessor.nu [config-get]
|
|
use orchestration/cluster_deploy.nu *
|
|
use orchestration/clusters/discover.nu [discover-clusters, get-cluster-info]
|
|
use cli/components.nu ["main component list", "main cluster top", "main cluster label-nodes", "main cluster plan", "main cluster capacity", "main cluster services"]
|
|
|
|
def main [
|
|
...args: string
|
|
--workspace (-w): string = ""
|
|
--dry-run (-n)
|
|
--kubeconfig (-k): string = ""
|
|
--secrets-file (-s): string = ""
|
|
--out (-o): string = ""
|
|
--debug (-x)
|
|
--notitles
|
|
]: nothing -> nothing {
|
|
if $debug { $env.PROVISIONING_DEBUG = true }
|
|
|
|
let rest = if (($args | length) > 0) and (($args | first) in ["cluster", "cl"]) {
|
|
$args | skip 1
|
|
} else {
|
|
$args
|
|
}
|
|
let sub = ($rest | get 0? | default "")
|
|
let arg1 = ($rest | get 1? | default "")
|
|
let arg2 = ($rest | get 2? | default "")
|
|
|
|
let help_text = {
|
|
print "Cluster Management"
|
|
print "=================="
|
|
print ""
|
|
print "Usage: prvng cluster <subcommand> [options]"
|
|
print ""
|
|
print "Subcommands:"
|
|
print " list List cluster-mode components in active workspace (alias: ls, l)"
|
|
print " show <name> Show a cluster-mode component's full config (alias: sh, info)"
|
|
print " top [pods] [-o json|yaml] Live node usage via kubectl top; (alias: t)"
|
|
print " 'top pods' appends heaviest pods by memory"
|
|
print " '-o json|yaml' emits structured output + legend on req%/lim%/no-req"
|
|
print " services [-n <ns>] [-o json|yaml] List all Kubernetes services in the cluster (alias: svc, svcs)"
|
|
print " label-nodes [--apply] Reconcile declared node labels/node_class (alias: labels, ln)"
|
|
print " onto live nodes (dry-run unless --apply)"
|
|
print " plan <service> [-o json|yaml] Simulate a (re)deploy: projected req%/ws% (alias: p, sim)"
|
|
print " per eligible node + fit recommendation"
|
|
print " capacity [--add-worker] [--resize <n>] Per-node load by category (movable/pinned/ (alias: cap)"
|
|
print " infra) + horizontal-vs-vertical what-if"
|
|
print " deploy <layer> <cluster> [options] Deploy a cluster (layer: platform|apps) (alias: d)"
|
|
print ""
|
|
print "Flags for deploy:"
|
|
print " --workspace (-w) <name> Workspace name (defaults to active)"
|
|
print " --dry-run (-n) Print execution plan without running scripts"
|
|
print " --kubeconfig (-k) <path> Override KUBECONFIG path"
|
|
print " --secrets-file (-s) <path> SOPS-encrypted dotenv with install secrets"
|
|
print ""
|
|
print "Examples:"
|
|
print " prvng cl l"
|
|
print " prvng cluster show sgoyol"
|
|
print " prvng cl deploy platform sgoyol --dry-run"
|
|
print " prvng cluster deploy apps wuji -w libre-daoshi"
|
|
}
|
|
|
|
match $sub {
|
|
"" | "help" | "h" | "-h" | "--help" => { do $help_text }
|
|
"list" | "ls" | "l" => {
|
|
let rows = if ($workspace | is-not-empty) {
|
|
main component list --workspace $workspace --mode "cluster"
|
|
} else {
|
|
main component list --mode "cluster"
|
|
}
|
|
if ($rows | is-empty) {
|
|
print "No cluster-mode components declared in the active workspace."
|
|
return
|
|
}
|
|
$rows | reject pod_selector
|
|
}
|
|
"show" | "info" | "sh" => {
|
|
if ($arg1 | is-empty) {
|
|
print "Error: cluster show requires a name"
|
|
print "Usage: prvng cluster show <name>"
|
|
return
|
|
}
|
|
let rows = if ($workspace | is-not-empty) {
|
|
main component list --workspace $workspace --mode "cluster"
|
|
} else {
|
|
main component list --mode "cluster"
|
|
}
|
|
let found = ($rows | where name == $arg1 | get 0?)
|
|
if ($found | is-empty) {
|
|
print $"Error: cluster component '($arg1)' not found in active workspace"
|
|
print $"Available: ($rows | get name | str join ', ')"
|
|
return
|
|
}
|
|
$found | reject pod_selector live_check
|
|
}
|
|
"services" | "svc" | "svcs" => {
|
|
let ns_arg = if ($arg1 | is-not-empty) and ($arg1 | str starts-with "-") == false { $arg1 } else { "" }
|
|
let out_val = if ($arg1 == "-o") { $arg2 } else if ($arg2 == "-o") { "" } else { $out }
|
|
let ws_flag = if ($workspace | is-not-empty) { [$workspace] } else { [] }
|
|
if ($ns_arg | is-not-empty) {
|
|
main cluster services --workspace ($ws_flag | get 0? | default "") --namespace $ns_arg --out $out_val
|
|
} else {
|
|
main cluster services --workspace ($ws_flag | get 0? | default "") --out $out_val
|
|
}
|
|
}
|
|
"top" | "t" => {
|
|
main cluster top $arg1 --workspace $workspace --out $out
|
|
}
|
|
"label-nodes" | "labels" | "ln" => {
|
|
let apply = ($arg1 in ["apply", "--apply", "-a"])
|
|
if $apply {
|
|
main cluster label-nodes --workspace $workspace --apply
|
|
} else {
|
|
main cluster label-nodes --workspace $workspace
|
|
}
|
|
}
|
|
"plan" | "p" | "sim" => {
|
|
if ($arg1 | is-empty) {
|
|
print "Usage: prvng cluster plan <service> [-o json|yaml]"
|
|
return
|
|
}
|
|
main cluster plan $arg1 --workspace $workspace --out $out
|
|
}
|
|
"capacity" | "cap" => {
|
|
main cluster capacity --workspace $workspace --out $out
|
|
}
|
|
"deploy" | "d" => {
|
|
let layer = $arg1
|
|
let cluster = $arg2
|
|
if ($layer | is-empty) or ($cluster | is-empty) {
|
|
print "Usage: prvng cluster deploy <layer> <cluster> [--workspace <name>]"
|
|
print " layer: platform | apps"
|
|
print " cluster: sgoyol | wuji | ..."
|
|
exit 1
|
|
}
|
|
if ($workspace | is-not-empty) {
|
|
main cluster deploy $layer $cluster --workspace $workspace --dry-run=$dry_run --kubeconfig $kubeconfig --secrets-file $secrets_file
|
|
} else {
|
|
main cluster deploy $layer $cluster --dry-run=$dry_run --kubeconfig $kubeconfig --secrets-file $secrets_file
|
|
}
|
|
}
|
|
_ => {
|
|
print $"Unknown cluster subcommand: ($sub)"
|
|
print ""
|
|
do $help_text
|
|
}
|
|
}
|
|
}
|