mirror of
https://github.com/skoelle/kctl-tui.git
synced 2026-09-17 20:10:24 +00:00
Add kctl-tui doctor command for health checks
This commit is contained in:
@@ -205,6 +205,7 @@ ln -s /mnt/c/Users/<your-windows-username>/.kube/config ~/.kube/config
|
|||||||
kctl-tui # start the TUI (full navigation mode)
|
kctl-tui # start the TUI (full navigation mode)
|
||||||
kctl-tui --version # print version
|
kctl-tui --version # print version
|
||||||
kctl-tui --verbose # enable debug logging to stderr
|
kctl-tui --verbose # enable debug logging to stderr
|
||||||
|
kctl-tui doctor # check if all tools, config and connections are OK
|
||||||
kctl-tui config check # validate ~/.kctl-tui/config.yaml
|
kctl-tui config check # validate ~/.kctl-tui/config.yaml
|
||||||
kctl-tui panel --context=... --ns=... --team=... # internal (called by tmux)
|
kctl-tui panel --context=... --ns=... --team=... # internal (called by tmux)
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -48,6 +48,12 @@ func main() {
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
case "doctor":
|
||||||
|
if err := runDoctor(); err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "kctl-tui doctor error:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,3 +116,112 @@ func runConfig(args []string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func runDoctor() error {
|
||||||
|
pass := "ok"
|
||||||
|
fail := "FAIL"
|
||||||
|
warn := "WARN"
|
||||||
|
status := pass
|
||||||
|
errs := 0
|
||||||
|
|
||||||
|
check := func(label string, err error) {
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf(" [%s] %s: %v\n", fail, label, err)
|
||||||
|
status = fail
|
||||||
|
errs++
|
||||||
|
} else {
|
||||||
|
fmt.Printf(" [%s] %s\n", pass, label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
warnCheck := func(label string, err error) {
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf(" [%s] %s: %v\n", warn, label, err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf(" [%s] %s\n", pass, label)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Tools ---
|
||||||
|
fmt.Println("\nTools:")
|
||||||
|
check("kubectl", kubeexec.CheckTool("kubectl"))
|
||||||
|
check("tmux/psmux", kubeexec.CheckTool("tmux"))
|
||||||
|
check("k9s", kubeexec.CheckTool("k9s"))
|
||||||
|
warnCheck("aws CLI (optional)", kubeexec.CheckTool("aws"))
|
||||||
|
|
||||||
|
// --- Config ---
|
||||||
|
fmt.Println("\nConfig:")
|
||||||
|
cfgPath, err := config.DefaultPath()
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf(" [%s] config path: %v\n", fail, err)
|
||||||
|
errs++
|
||||||
|
status = fail
|
||||||
|
} else {
|
||||||
|
cfg, err := config.Load(cfgPath)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf(" [%s] load config: %v\n", fail, err)
|
||||||
|
errs++
|
||||||
|
status = fail
|
||||||
|
} else {
|
||||||
|
check("config file exists", nil)
|
||||||
|
if len(cfg.Contexts) == 0 {
|
||||||
|
fmt.Printf(" [%s] contexts configured\n", fail)
|
||||||
|
errs++
|
||||||
|
status = fail
|
||||||
|
} else {
|
||||||
|
fmt.Printf(" [%s] contexts configured (%d)\n", pass, len(cfg.Contexts))
|
||||||
|
}
|
||||||
|
if len(cfg.Envs) == 0 {
|
||||||
|
fmt.Printf(" [%s] envs configured\n", fail)
|
||||||
|
errs++
|
||||||
|
status = fail
|
||||||
|
} else {
|
||||||
|
fmt.Printf(" [%s] envs configured (%d)\n", pass, len(cfg.Envs))
|
||||||
|
}
|
||||||
|
if cfg.ContextTemplate != "" {
|
||||||
|
ctx := cfg.ResolveContext(cfg.Envs[0], cfg.Contexts[0])
|
||||||
|
fmt.Printf(" [%s] context_template resolves to: %s\n", pass, ctx)
|
||||||
|
} else {
|
||||||
|
fmt.Printf(" [%s] context_template is empty\n", fail)
|
||||||
|
errs++
|
||||||
|
status = fail
|
||||||
|
}
|
||||||
|
if cfg.SecretNameTemplate != "" && len(cfg.Envs) > 0 {
|
||||||
|
secret := cfg.ResolveSecretName("example-ns", cfg.Envs[0])
|
||||||
|
fmt.Printf(" [%s] secret_name_template resolves to: %s\n", pass, secret)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Connections ---
|
||||||
|
fmt.Println("\nConnections:")
|
||||||
|
if kubeexec.CheckTool("kubectl") == nil {
|
||||||
|
err := kubeexec.CheckAWSAuth()
|
||||||
|
if err == nil {
|
||||||
|
fmt.Printf(" [%s] kubectl cluster reachable\n", pass)
|
||||||
|
} else {
|
||||||
|
// Not fatal — cluster might be unreachable from this machine
|
||||||
|
fmt.Printf(" [%s] kubectl cluster: %v\n", warn, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if kubeexec.CheckTool("aws") == nil {
|
||||||
|
err := kubeexec.CheckAWSAuth()
|
||||||
|
if err == nil {
|
||||||
|
fmt.Printf(" [%s] AWS credentials valid\n", pass)
|
||||||
|
} else {
|
||||||
|
fmt.Printf(" [%s] AWS credentials: %v\n", warn, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf(" [%s] AWS credentials (aws CLI not installed)\n", warn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Summary ---
|
||||||
|
fmt.Println()
|
||||||
|
if status == pass {
|
||||||
|
fmt.Println("All checks passed. kctl-tui is ready to use.")
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%d error(s) found. Fix the issues above and re-run: kctl-tui doctor\n", errs)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user