mirror of
https://github.com/skoelle/kctl-tui.git
synced 2026-09-17 20:10:24 +00:00
Add README, PLAN.md, and SPEC.md
This commit is contained in:
@@ -0,0 +1,80 @@
|
|||||||
|
# PLAN.md — Implementation Roadmap
|
||||||
|
|
||||||
|
This document tracks how kctl-tui is being built, phase by phase, and what
|
||||||
|
is still open. For the full requirements, see [SPEC.md](SPEC.md).
|
||||||
|
|
||||||
|
## Phase 0 — Repository setup (done)
|
||||||
|
|
||||||
|
- [x] Go module (`github.com/skoelle/kctl-tui`), `.gitignore`, MIT `LICENSE`.
|
||||||
|
- [x] GitHub Actions workflow: `go vet` + `go test` on every push/PR, plus a
|
||||||
|
cross-platform build matrix (linux/darwin/windows x amd64/arm64) that
|
||||||
|
attaches binaries to GitHub Releases on version tags.
|
||||||
|
- [x] `install.sh` for Linux/macOS/WSL, downloading the latest release
|
||||||
|
asset.
|
||||||
|
- [x] `README.md`, `config.example.yaml`.
|
||||||
|
|
||||||
|
## Phase 1 — Core logic + navigation (done, initial version)
|
||||||
|
|
||||||
|
- [x] `internal/kctl`: pure, unit-tested logic —
|
||||||
|
context-pair matching (`FindNextContext`) and namespace/label
|
||||||
|
filtering (`DistinctLabelValues`, `NamespacesForLabelValue`).
|
||||||
|
- [x] `internal/config`: YAML config loading (`context_pairs`,
|
||||||
|
`team_label_key`), with safe defaults when no config file exists yet.
|
||||||
|
- [x] `internal/kubeexec`: thin wrappers around `kubectl`/`aws` CLI calls
|
||||||
|
(contexts, namespaces, deployments, rollout restart/status, secret
|
||||||
|
read, ExternalSecret annotation).
|
||||||
|
- [x] `cmd/kctl-tui` "full" mode: Bubble Tea navigation for
|
||||||
|
context -> team -> namespace, with `Esc` correctly popping back one
|
||||||
|
level at a time, defaults pre-selected from the currently active
|
||||||
|
context/namespace.
|
||||||
|
- [x] On confirming a namespace, "full" mode launches the 3-pane `tmux`
|
||||||
|
session (control pane + two `k9s` panes) via `tea.ExecProcess` and
|
||||||
|
resumes at the namespace screen once the session ends.
|
||||||
|
- [x] `cmd/kctl-tui` "panel" mode: menu for Redeploy and the AWS/Kubernetes
|
||||||
|
secrets diff + force-sync wizard, with `Esc` closing the whole tmux
|
||||||
|
session (`tmux kill-session`).
|
||||||
|
|
||||||
|
## Phase 2 — Hardening (open)
|
||||||
|
|
||||||
|
- [ ] Replace the hand-rolled AWS secret JSON parsing/`fmt.Sprintf` value
|
||||||
|
formatting with a proper typed decode, and handle secrets that are
|
||||||
|
plain strings rather than JSON.
|
||||||
|
- [ ] Add integration-style tests against a local `kind`/`k3d` cluster in
|
||||||
|
CI for the `kubeexec` wrappers currently excluded from automated
|
||||||
|
testing.
|
||||||
|
- [ ] Input validation for the free-text steps in "panel" mode (empty
|
||||||
|
secret ID/region/name, invalid characters).
|
||||||
|
- [ ] Graceful handling when `tmux`, `k9s`, or `aws` are not installed
|
||||||
|
(currently surfaces the raw exec error).
|
||||||
|
- [ ] Structured logging / `--verbose` flag for troubleshooting failed
|
||||||
|
`kubectl` calls.
|
||||||
|
|
||||||
|
## Phase 3 — Windows-native support (open, secondary priority)
|
||||||
|
|
||||||
|
- [ ] Detect OS at runtime; on native Windows (no WSL), fall back to
|
||||||
|
`wt.exe split-pane` instead of `tmux` for the status panes.
|
||||||
|
- [ ] Document/implement that `Tab`-based context switching and
|
||||||
|
`Esc`-triggered session close are **not** available in the native
|
||||||
|
Windows fallback, per SPEC.md 3.6 — the panes must be closed
|
||||||
|
manually there.
|
||||||
|
|
||||||
|
## Phase 4 — Nice-to-haves (open, not committed)
|
||||||
|
|
||||||
|
- [ ] Optional direct use of `client-go` instead of shelling out to
|
||||||
|
`kubectl`, for faster context/namespace/label queries.
|
||||||
|
- [ ] Config validation command (`kctl-tui config check`) that reports
|
||||||
|
unknown label keys or context names not present in the current
|
||||||
|
kubeconfig.
|
||||||
|
- [ ] Homebrew tap / `scoop` manifest as additional install options
|
||||||
|
alongside `install.sh`.
|
||||||
|
|
||||||
|
## Notes for contributors
|
||||||
|
|
||||||
|
- Keep any real organization-specific context names, namespace names,
|
||||||
|
label keys, or secret names out of the repository. Use the generic
|
||||||
|
placeholders already established in `SPEC.md` and
|
||||||
|
`config.example.yaml`.
|
||||||
|
- Pure/testable logic belongs in `internal/kctl` and `internal/config`;
|
||||||
|
anything that shells out to `kubectl`/`aws`/`tmux` belongs in
|
||||||
|
`internal/kubeexec` or directly in `cmd/kctl-tui`, and should stay thin
|
||||||
|
enough that it does not need its own test suite.
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
# kctl-tui
|
||||||
|
|
||||||
|
A small terminal entry point for everyday Kubernetes work: pick a context,
|
||||||
|
a team, and a namespace once, then drive status (via k9s), rollout
|
||||||
|
restarts, and an AWS Secrets Manager <-> Kubernetes Secret diff/force-sync
|
||||||
|
workflow from one place instead of retyping long `kubectl` commands.
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
Working with several clusters, many namespaces per team, and paired
|
||||||
|
environments (e.g. staging/production) quickly turns into a lot of repeated
|
||||||
|
typing with plain `kubectl`/`k9s`. kctl-tui adds:
|
||||||
|
|
||||||
|
- A guided **context -> team -> namespace** selection with sensible
|
||||||
|
defaults (the currently active context/namespace is pre-selected).
|
||||||
|
- Namespace grouping by an arbitrary, configurable **label** instead of
|
||||||
|
scrolling through every namespace in the cluster.
|
||||||
|
- A **3-pane view** (via `tmux`): one control pane for actions, two status
|
||||||
|
panes running `k9s` for the current namespace across two related
|
||||||
|
contexts.
|
||||||
|
- A guided **rollout restart** that lists deployments instead of requiring
|
||||||
|
you to know/type the exact deployment name.
|
||||||
|
- A guided **AWS Secrets Manager vs. Kubernetes Secret** comparison,
|
||||||
|
including an optional ExternalSecret force-sync annotation.
|
||||||
|
|
||||||
|
See [SPEC.md](SPEC.md) for the full requirements and design rationale, and
|
||||||
|
[PLAN.md](PLAN.md) for the implementation roadmap and current status.
|
||||||
|
|
||||||
|
## How it works
|
||||||
|
|
||||||
|
```
|
||||||
|
+--------------------------------------------------+
|
||||||
|
| Control pane: kctl-tui panel |
|
||||||
|
| -> Redeploy, Secrets diff/force-sync |
|
||||||
|
+--------------------------------------------------+
|
||||||
|
| k9s --context <context-a> -n <namespace> |
|
||||||
|
+--------------------------------------------------+
|
||||||
|
| k9s --context <context-b> -n <namespace> |
|
||||||
|
+--------------------------------------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Run `kctl-tui`. It walks you through context, team, and namespace
|
||||||
|
selection.
|
||||||
|
2. Once a namespace is confirmed, it opens a `tmux` session with the layout
|
||||||
|
above and attaches to it.
|
||||||
|
3. Inside the control pane you can trigger a rollout restart or compare/
|
||||||
|
force-sync a secret. The two status panes keep showing live pod state
|
||||||
|
via `k9s`, so there is no separate "status" menu entry.
|
||||||
|
4. Pressing `Esc` in the control pane closes the whole `tmux` session
|
||||||
|
(including both `k9s` panes) and returns you to the namespace
|
||||||
|
selection.
|
||||||
|
5. Pressing `Tab` in the control pane switches both status panes to the
|
||||||
|
paired context configured in `context_pairs` (see Configuration),
|
||||||
|
keeping the same namespace.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- `kubectl`, configured with access to your cluster(s).
|
||||||
|
- `k9s` (used for the two status panes).
|
||||||
|
- `tmux` (used for the 3-pane layout). On Windows, this means running
|
||||||
|
kctl-tui inside **WSL** — `tmux` has no native Windows port. Native
|
||||||
|
Windows Terminal has its own split-pane feature, but it cannot be
|
||||||
|
scripted from inside a pane the way `tmux` can, so the automated 3-pane
|
||||||
|
layout and the `Tab`/`Esc` session handling described above are only
|
||||||
|
fully supported under Linux/WSL. See SPEC.md section 3.6 for details.
|
||||||
|
- `aws` CLI, configured with credentials, only needed for the secrets
|
||||||
|
workflow.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Quick install (Linux/macOS/WSL)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://raw.githubusercontent.com/skoelle/kctl-tui/main/install.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
This downloads the latest release binary for your OS/architecture from
|
||||||
|
GitHub Releases and installs it to `/usr/local/bin/kctl-tui`.
|
||||||
|
|
||||||
|
### From source
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/skoelle/kctl-tui.git
|
||||||
|
cd kctl-tui
|
||||||
|
go build -o kctl-tui ./cmd/kctl-tui
|
||||||
|
sudo mv kctl-tui /usr/local/bin/
|
||||||
|
```
|
||||||
|
|
||||||
|
Requires Go 1.22+.
|
||||||
|
|
||||||
|
### Prebuilt binaries
|
||||||
|
|
||||||
|
Every tagged release (`vX.Y.Z`) is built for `linux`, `darwin`, and
|
||||||
|
`windows`, each for `amd64` and `arm64`, via the GitHub Actions workflow in
|
||||||
|
[.github/workflows/build.yml](.github/workflows/build.yml). Download the
|
||||||
|
matching asset from the [Releases page](https://github.com/skoelle/kctl-tui/releases).
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Copy [config.example.yaml](config.example.yaml) to `~/.kctl-tui/config.yaml`
|
||||||
|
and adjust it to your own cluster setup:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
context_pairs:
|
||||||
|
- name: "example-environment-pair"
|
||||||
|
contexts:
|
||||||
|
- "example-context-a"
|
||||||
|
- "example-context-b"
|
||||||
|
|
||||||
|
team_label_key: "example.org/team"
|
||||||
|
```
|
||||||
|
|
||||||
|
- `context_pairs`: groups of related `kubectl` contexts. `Tab` in the
|
||||||
|
control pane cycles through the contexts of whichever group the current
|
||||||
|
context belongs to.
|
||||||
|
- `team_label_key`: the Kubernetes namespace label used to group
|
||||||
|
namespaces by team/ownership in the team-selection screen. This is
|
||||||
|
entirely up to your organization's labeling convention; kctl-tui ships
|
||||||
|
with no default team label of its own.
|
||||||
|
|
||||||
|
`~/.kctl-tui/config.yaml` is not part of this repository and should stay
|
||||||
|
that way — it typically contains your organization's internal context and
|
||||||
|
label names.
|
||||||
|
|
||||||
|
## WSL setup notes
|
||||||
|
|
||||||
|
If `kubectx`/`kubens` or `kctl-tui` report a missing kubeconfig inside WSL,
|
||||||
|
your kubeconfig most likely only exists on the Windows side. Symlink it
|
||||||
|
into WSL:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mkdir -p ~/.kube
|
||||||
|
ln -s /mnt/c/Users/<your-windows-username>/.kube/config ~/.kube/config
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
go test ./...
|
||||||
|
go vet ./...
|
||||||
|
go build ./cmd/kctl-tui
|
||||||
|
```
|
||||||
|
|
||||||
|
Pure logic (context-pair matching, label filtering, config parsing) lives
|
||||||
|
in `internal/kctl` and `internal/config` and is covered by unit tests. Code
|
||||||
|
that shells out to `kubectl`/`aws`/`tmux` lives in `internal/kubeexec` and
|
||||||
|
in `cmd/kctl-tui` and is intentionally kept thin and untested, since it has
|
||||||
|
no meaningful behavior without a live cluster.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](LICENSE)
|
||||||
|
|||||||
@@ -0,0 +1,248 @@
|
|||||||
|
# SPEC: kctl-tui — Kubernetes Entry-Point TUI
|
||||||
|
|
||||||
|
## 1. Goal
|
||||||
|
|
||||||
|
A single terminal tool as the central entry point for everyday Kubernetes
|
||||||
|
work, bundling the most common workflows currently done via long
|
||||||
|
`kubectl`/`k9s`/`aws-cli` commands, operable through a text UI (arrow keys,
|
||||||
|
Esc, Tab) instead of long typed commands.
|
||||||
|
|
||||||
|
Target platform: **Linux / WSL** (primary usage scenario, since split
|
||||||
|
panes require a real terminal multiplexer). Native Windows (without WSL)
|
||||||
|
is possible but with reduced split-view functionality (see 3.6).
|
||||||
|
|
||||||
|
**Technology decision: Go + Bubble Tea** (see section 5).
|
||||||
|
|
||||||
|
## 2. Terminology
|
||||||
|
|
||||||
|
| Term | Meaning |
|
||||||
|
|---|---|
|
||||||
|
| Context | Kubernetes cluster connection (`kubectl config get-contexts`) |
|
||||||
|
| Namespace | Logical subdivision within a cluster/context |
|
||||||
|
| Deployment | Controls the pods of a service; its name does not have to match the namespace name |
|
||||||
|
| Pod | Running instance, automatically generated name, not needed manually for the restart workflow |
|
||||||
|
| Rollout Restart | Rolling restart of all pods of a deployment according to the RollingUpdate strategy — **not** a simultaneous hard-kill of all pods, except with 1 replica or the `Recreate` strategy |
|
||||||
|
| Control pane | The top tmux pane running the Go tool itself (menu for redeploy/secrets) |
|
||||||
|
| Status panes | The two lower tmux panes, each running a `k9s` instance |
|
||||||
|
| Team label | Any freely configurable namespace label used to group namespaces by team/ownership (key and values are project-specific, kept generic here) |
|
||||||
|
|
||||||
|
## 3. Functional Requirements
|
||||||
|
|
||||||
|
### 3.1 Start navigation (hierarchical, with defaults)
|
||||||
|
|
||||||
|
Order at program start (outside tmux, "full" mode):
|
||||||
|
|
||||||
|
1. **Context selection** — list of all available contexts, currently
|
||||||
|
active context pre-selected at the top as "(current)".
|
||||||
|
2. **Team selection** — list of all distinct values of a configurable
|
||||||
|
namespace label (key freely configurable, e.g.
|
||||||
|
`<organization>/<label-name>`), current team value pre-selected. A
|
||||||
|
"no filter" option is available.
|
||||||
|
3. **Namespace selection** — filtered by the chosen team label value,
|
||||||
|
active namespace pre-selected.
|
||||||
|
4. **Main view** — directly starts the tmux session with the three panes
|
||||||
|
(see 3.3).
|
||||||
|
|
||||||
|
Navigation:
|
||||||
|
|
||||||
|
- **Esc** in the control pane first ends the whole tmux session
|
||||||
|
(`tmux kill-session`, closing both k9s panes as well) and then moves the
|
||||||
|
Go tool's screen stack one level up: namespace selection -> team
|
||||||
|
selection -> context selection.
|
||||||
|
- **Tab** in the control pane switches the context pair according to the
|
||||||
|
context-pair pattern (see 3.6) for both status panes simultaneously; the
|
||||||
|
namespace stays the same.
|
||||||
|
|
||||||
|
### 3.2 Namespace grouping via labels
|
||||||
|
|
||||||
|
- Display all currently assigned labels per namespace:
|
||||||
|
`kubectl get ns --show-labels`.
|
||||||
|
- Query all distinct values of an arbitrary label key (including keys
|
||||||
|
with a dot/slash) via bracket notation in JSONPath. Example with a
|
||||||
|
generic placeholder key `<team-label-key>`:
|
||||||
|
```
|
||||||
|
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.labels["<team-label-key>"]}{"\n"}{end}' | sort -u
|
||||||
|
```
|
||||||
|
- The actual label key is project-specific and set via the configuration
|
||||||
|
file (see 3.6), not hardcoded.
|
||||||
|
- Namespace labeling is a prerequisite (one-time setup outside the tool).
|
||||||
|
|
||||||
|
### 3.3 Layout: 3-panel view (core design change vs. earlier drafts)
|
||||||
|
|
||||||
|
Once start navigation is complete, the tool opens a tmux session with
|
||||||
|
**three panes**, started with a single command:
|
||||||
|
|
||||||
|
```
|
||||||
|
+--------------------------------------------------+
|
||||||
|
| Pane 0 (top): Control pane |
|
||||||
|
| -> runs the kctl-tui binary in "panel" mode |
|
||||||
|
| -> menu: Redeploy, secrets diff |
|
||||||
|
+--------------------------------------------------+
|
||||||
|
| Pane 1 (middle): k9s --context <context-a> -n <ns>|
|
||||||
|
+--------------------------------------------------+
|
||||||
|
| Pane 2 (bottom): k9s --context <context-b> -n <ns>|
|
||||||
|
+--------------------------------------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
Important: a separate "status" menu item in the control pane is not
|
||||||
|
needed — status is continuously visible via the two k9s panes for as long
|
||||||
|
as the session runs. The control pane only contains the actions k9s does
|
||||||
|
not cover: **redeploy** and **secrets diff**.
|
||||||
|
|
||||||
|
Example startup command (generic placeholders):
|
||||||
|
|
||||||
|
```
|
||||||
|
tmux new-session -d -s kctl \
|
||||||
|
"kctl-tui panel --ctx=$CTX_A --ns=$NS --team=$TEAM" \; \
|
||||||
|
split-window -v "k9s --context $CTX_A -n $NS" \; \
|
||||||
|
split-window -v "k9s --context $CTX_B -n $NS" \; \
|
||||||
|
select-layout main-horizontal \; \
|
||||||
|
attach -t kctl
|
||||||
|
```
|
||||||
|
|
||||||
|
Switching between panes: `Ctrl-b` + arrow key, or `Ctrl-b` `o`.
|
||||||
|
|
||||||
|
### 3.4 Redeploy (rollout restart) — in the control pane
|
||||||
|
|
||||||
|
- List all deployments in the currently selected namespace for selection
|
||||||
|
(`kubectl -n <ns> get deploy`).
|
||||||
|
- Confirmation step before execution.
|
||||||
|
- Execute `kubectl -n <ns> rollout restart deploy/<name>` followed by
|
||||||
|
`kubectl -n <ns> rollout status deploy/<name>`.
|
||||||
|
- The result is immediately visible in the status panes below (pods get
|
||||||
|
recreated) — no separate status feedback channel needed in the tool
|
||||||
|
itself.
|
||||||
|
|
||||||
|
### 3.5 AWS Secrets Manager <-> Kubernetes Secret diff — in the control pane
|
||||||
|
|
||||||
|
1. Load the secret from AWS Secrets Manager:
|
||||||
|
`aws secretsmanager get-secret-value --secret-id <secret-id> --region <region> --query SecretString --output text`.
|
||||||
|
2. Show the contained keys for selection.
|
||||||
|
3. Load the matching Kubernetes secret field:
|
||||||
|
`kubectl -n <ns> get secret <secret-name> -o jsonpath='{.data.<field>}'`,
|
||||||
|
base64-decode it.
|
||||||
|
4. Compare the values (identical / different).
|
||||||
|
5. On mismatch, optionally request a force-sync:
|
||||||
|
`kubectl -n <ns> annotate externalsecret <name> force-sync=<unix-timestamp> --overwrite`.
|
||||||
|
|
||||||
|
All names (secret ID, secret name, field name, ExternalSecret name) are
|
||||||
|
asked for interactively at runtime, never hardcoded in the tool.
|
||||||
|
|
||||||
|
### 3.6 Context-pair pattern (configurable) — drives both status panes at once
|
||||||
|
|
||||||
|
Requirement: the Tab switch in the control pane must switch **both**
|
||||||
|
status panes below it, not just an internal state.
|
||||||
|
|
||||||
|
Configuration format (e.g. `~/.kctl-tui/config.yaml`), purely illustrative
|
||||||
|
with generic placeholders:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
context_pairs:
|
||||||
|
- name: "environment-pair-1"
|
||||||
|
contexts: ["<context-a1>", "<context-a2>"]
|
||||||
|
- name: "environment-pair-2"
|
||||||
|
contexts: ["<context-b1>", "<context-b2>"]
|
||||||
|
|
||||||
|
team_label_key: "<organization>/<label-name>"
|
||||||
|
```
|
||||||
|
|
||||||
|
Behavior on Tab in the control pane:
|
||||||
|
|
||||||
|
1. Determine the current context pair from the configuration.
|
||||||
|
2. Restart both k9s panes via
|
||||||
|
`tmux respawn-pane -k -t kctl:0.1 "k9s --context <newA> -n <ns>"` and
|
||||||
|
`... kctl:0.2 ...` (namespace stays the same).
|
||||||
|
3. If the current context is in no configured list: show a hint in the
|
||||||
|
control pane instead of an error.
|
||||||
|
4. No action outside this configuration — no error, only a hint.
|
||||||
|
|
||||||
|
**Platform limitation on Windows without WSL:** `respawn-pane`/
|
||||||
|
`kill-session` are tmux-specific. Windows Terminal (`wt.exe`) offers no
|
||||||
|
equivalent scripting to replace panes or end the session from inside a
|
||||||
|
pane. On plain Windows (without WSL), only a simplified flow is possible:
|
||||||
|
k9s panes are closed manually (`q`, then `Ctrl+Shift+W`); Tab switching and
|
||||||
|
automatic session termination are unavailable there. This limitation is
|
||||||
|
the main reason the primary target system is set to Linux/WSL.
|
||||||
|
|
||||||
|
## 4. Non-functional requirements
|
||||||
|
|
||||||
|
- **Primary platform Linux/WSL**, secondary native Windows with reduced
|
||||||
|
functionality.
|
||||||
|
- **Single-binary distribution** without external runtime dependency (Go
|
||||||
|
provides this natively).
|
||||||
|
- **External dependencies**: `kubectl` mandatory; `tmux`, `k9s`, `aws-cli`
|
||||||
|
depending on the action used.
|
||||||
|
- **Low startup time**, noticeably faster than the current `kubens`
|
||||||
|
experience.
|
||||||
|
- **No destructive actions without confirmation** (redeploy, force-sync).
|
||||||
|
- **No project- or company-specific names (contexts, namespaces, label
|
||||||
|
keys, secret names) in code or example files** — everything is sourced
|
||||||
|
via configuration or interactive input at runtime.
|
||||||
|
|
||||||
|
## 5. Technology decision: Go + Bubble Tea
|
||||||
|
|
||||||
|
Rationale:
|
||||||
|
|
||||||
|
- The Kubernetes tooling ecosystem (`kubectl`, `k9s`, `client-go`) is
|
||||||
|
itself written in Go — enabling direct API access instead of pure shell
|
||||||
|
calls in the future.
|
||||||
|
- Bubble Tea (Charm) is specifically built for hierarchical,
|
||||||
|
keyboard-driven TUIs with a screen stack, same look/feel as k9s.
|
||||||
|
- Static, small binary without runtime dependency; fast cross-compilation
|
||||||
|
(`GOOS=linux/windows`).
|
||||||
|
- Both Go and .NET are fundamentally cross-platform; since the real target
|
||||||
|
is Linux/WSL anyway (due to the split-view requirement), .NET's main
|
||||||
|
advantage (one runtime for both worlds in a single step) no longer
|
||||||
|
applies, so the choice is free to fall on the technically closest
|
||||||
|
ecosystem.
|
||||||
|
|
||||||
|
Rejected options (see discussion history):
|
||||||
|
|
||||||
|
- Python + Textual: good prototype, but requires an additional runtime, no
|
||||||
|
single binary without extra effort (PyInstaller).
|
||||||
|
- .NET + Terminal.Gui: technically equivalent, but larger binary, no
|
||||||
|
compelling advantage anymore with a Linux-only target.
|
||||||
|
- Rust + Ratatui: excellent TUI library, but a steeper learning curve
|
||||||
|
without a clear extra benefit over Go for this project.
|
||||||
|
|
||||||
|
## 6. Already solved by standard tooling (no custom build needed)
|
||||||
|
|
||||||
|
- Generic fuzzy selection of context/namespace: `kubectx` + `kubens` +
|
||||||
|
`fzf`.
|
||||||
|
- Ad-hoc actions directly from k9s with the current context/namespace/
|
||||||
|
resource name: k9s plugins (`~/.k9s/plugin.yml`).
|
||||||
|
- Split panes themselves: tmux (Linux/WSL) or native Windows Terminal
|
||||||
|
panes (`wt.exe split-pane`) — no custom multiplexer code needed, the
|
||||||
|
tool only orchestrates existing tools.
|
||||||
|
|
||||||
|
## 7. Environment prerequisites (WSL-specific, from troubleshooting)
|
||||||
|
|
||||||
|
- **kubectx/kubens incompletely installed:** Some Linux distro packages
|
||||||
|
for `kubectx` only ship the `kubectx` binary without `kubens`. Fix:
|
||||||
|
install via the distribution's package manager properly, or manually
|
||||||
|
symlink both scripts from the official project repository.
|
||||||
|
- **"kubeconfig file not found" in WSL:** The kubeconfig often only exists
|
||||||
|
in the Windows user profile; WSL has its own, separate home directory.
|
||||||
|
Fix via symlink:
|
||||||
|
```
|
||||||
|
mkdir -p ~/.kube
|
||||||
|
ln -s /mnt/c/Users/<windows-username>/.kube/config ~/.kube/config
|
||||||
|
```
|
||||||
|
or via the `KUBECONFIG` environment variable pointing to the same
|
||||||
|
Windows path.
|
||||||
|
- These fixes are a prerequisite before the tool can be meaningfully
|
||||||
|
tested, since it builds directly on `kubectl config`.
|
||||||
|
|
||||||
|
## 8. Open items / out of scope (v1)
|
||||||
|
|
||||||
|
- No automatic label setup for namespaces (migration is a separate,
|
||||||
|
one-time task).
|
||||||
|
- Split view v1 fixed at 2 status panes + 1 control pane (3 panes total).
|
||||||
|
- No RBAC/permission checks before executing sensitive actions — the tool
|
||||||
|
assumes existing kubectl permissions.
|
||||||
|
- Configuration file format (`config.yaml`) is a proposal, not finally
|
||||||
|
agreed; concrete label keys, context names, and namespace names are
|
||||||
|
project-specific and belong exclusively in the user's local, unversioned
|
||||||
|
configuration, not in this document or the source code.
|
||||||
|
- Native Windows (without WSL) remains a secondary platform with manual
|
||||||
|
pane handling instead of an automated tmux lifecycle.
|
||||||
Reference in New Issue
Block a user