Technical Briefing – lfk (Lightning Fast Kubernetes navigator)


The Problem

Navigating and managing Kubernetes clusters from a terminal is traditionally fragmented: separate kubectl commands, clunky YAML editors, and manual log/exec workflows. LFK solves this by providing a single, keyboard‑driven Miller‑columns UI that clusters resources by owner, offers instant actions (logs, exec, scale, delete, etc.), and keeps the whole session in one view.

What This Does

LFK is a Go‑based TUI that wraps a three‑column Miller layout (internal/app/tabs.go) with an owner‑based hierarchy (Clusters → Resource Types → Resources → Owned Resources → Containers). Core data flow originates from main in cmd/themegen/main.go:22, which calls run → parseThemeFile → parseConfigLine to load user configuration from ~/.kube/config and KUBECONFIG env‑var (see internal/app/options.go). The runtime model is built by NewModel (internal/app/app.go:917), which loads pinned CRD groups, kubeconfig contexts, and initialises the baseModel that drives all subsequent UI updates.

Key navigation and action flows travel through a handful of hub functions identified in the internal call graph:

FunctionCallers (approx.)Typical downstream effect
baseModelCov189Coverage‑aware model state; ripples through every update
baseFinalModel189Final model construction after all loads
executeAction174Dispatches logs, exec, scale, delete, etc.
setCursor147Cursor movement & wrap‑around logic
keyMsg127Key‑binding handling and status messaging

(Full graph: 6 000 resolved call edges; see the “INTERNAL CALL GRAPH” block.)

Updates are driven by message types defined in internal/app/messages.go (resourceTypesMsg, ownedLoadedMsg, etc.) and processed by update.go (Update, updateResourceMsg, updateResultMsg), which reads/writes the filesystem via os.Open/os.ReadFile when loading themes or pinned state.

How It Is Wired

Execution starts at cmd/themegen/main.go (main → run). From there the call graph fans out:

  1. run parses the theme YAML and config, then invokes Init (internal/app/app.go:1129).
  2. Init creates the initial NewModel, which spawns goroutines for background tasks (bgtasks) and registers key‑binding handlers.
  3. User keystrokes flow through keyMsg → executeAction → concrete actions such as setStatusMessage, scheduleStatusClear, or trackBgTask.
  4. UI redraws are triggered by update.go → tabs.go layout functions (pushLeft, popLeft, clearRight).

Paths that leave the process:

  • main → run → parseThemeFile – opens theme files on disk (os.Open).
  • NewModel → loadPinnedState – reads the pinned CRD groups file (os.ReadFile).

No external database or network calls are made beyond the initial kubeconfig load; all further interaction happens via kubectl‑compatible API calls embedded in the action handlers.

File‑by‑file responsibility (ranked by routing volume):

  • internal/app/update_msg_test.go – 247 functions, defines update‑message tests.
  • internal/app/update_actions_test.go – 239 functions, defines delete‑action tests.
  • internal/app/update_keys_test.go – 145 functions, key‑handling logic.
  • internal/app/tabs.go – 46 functions, layout & tab management.
  • internal/app/cursor.go – 26 functions, cursor/clamp logic.
  • internal/app/messages.go – 67 type definitions, message payloads.

How To Use It

Setup

# Clone the repository (verbatim URL)
git clone https://github.com/moses-y/lfk

# Build with the included Makefile (or use go directly)
make build          # produces the lfk binary
# Or via Docker (Dockerfile present)
docker build -t lfk .

Configuration

  • Place a kubeconfig file at ~/.kube/config (or set KUBECONFIG).
  • Customise pinned CRD groups via pinned_groups in config-example.yaml (see docs/config-example.yaml) or interactively with the p key (stored per‑context).

Running it

./lfk          # from the repo root after `make build`
# or
docker run --rm -it -v $HOME/.kube:/root/.kube lfk

The binary entry point is the compiled lfk executable; the source entry point is cmd/themegen/main.go.

Real‑World Use

A site‑reliability engineer needs to investigate a failing pod across three clusters. With LFK open, they press Shift+F to expand the middle column, type :pods to filter, then Enter on the pod. Pressing l streams logs, e opens an editor, and d deletes the resource—all without leaving the terminal. The “API Explorer” (I key) reveals the pod’s container spec, and the “Monitoring” dashboard (@ key) shows associated Prometheus alerts.

Code Health & Issues

  • Pin third‑party GitHub Actions – .github/workflows uses @v6, @v9, @v4 tags for codecov, golangci‑lint, docker/setup‑qemu/buildx. Replace each with the 40‑character commit SHA (Dependabot can keep them current).
  • Pin container base image by digest – Dockerfile references golang:1.26.2-alpine and alpine:3.23 without digests; pinning eliminates drift in libc and CVEs.
  • Large binaries outside repo – docs/imgs/themes.gif (5.5 MB) and other assets over 5 MB should be tracked with Git LFS or fetched in a CI setup step to keep clones lightweight.
  • Set timeout‑minutes on workflow jobs – four CI jobs have no timeout-minutes; add realistic bounds (e.g., 60 min) to avoid six‑hour platform defaults overlapping on a two‑hourly schedule.

All findings above stem from the static‑analysis run (132 measured issues, 21 high, 111 medium). No structural red flags beyond those listed were detected.

The Bottom Line

LFK delivers a fast, keyboard‑centric navigation layer for multi‑cluster Kubernetes management, with a clean Miller‑columns layout and rich action menus. The codebase is well‑structured in Go, has solid test coverage, and ships with Docker and GitHub‑Actions CI. However, action‑graph hubs (e.g., baseModelCov, executeAction) are called from hundreds of places, making large‑scale refactors risky, and several hygiene items (action‑image pins, image digests, LFS for media, CI timeouts) need attention before a production rollout. Teams that value terminal‑first Kubernetes workflows and are comfortable with a moderately large Go codebase will find LFK a valuable addition; others may prefer lighter-weight tools until the hygiene items are resolved.