Skip to content

feat: web terminal + Headlamp-style K8s browser#1

Open
fropa wants to merge 1 commit into
mainfrom
feat/web-terminal-k8s-browser
Open

feat: web terminal + Headlamp-style K8s browser#1
fropa wants to merge 1 commit into
mainfrom
feat/web-terminal-k8s-browser

Conversation

@fropa

@fropa fropa commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

Self-hosted browser terminal (PTY to nodes and pods) plus a Headlamp-style read-only K8s resource browser. Fully self-hosted — no third-party SaaS. Also folds in correctness/cost fixes from the earlier review pass.

Web terminal

  • Backend: byte relay over Redis pub/sub (worker-safe), client + agent WS endpoints, TerminalSession audit row, first-message API-key auth (key kept off the URL).
  • Agent: hand-rolled stdlib RFC6455 WS client (keeps agent zero-dep) + pty.fork, driven off the existing exec poll.
  • Frontend: xterm.js TerminalPanel, Terminal tab on nodes.
  • Security (design borrowed from DirectGate, adapted to a trusted self-hosted relay): tenant/node scoped, concurrency cap, idle + max-duration timeouts, fully audited. Shell runs as the agent's restricted user.

K8s browser (read-only)

  • Agent ships extended resource kinds (services, configmaps, statefulsets, daemonsets, jobs, ingresses, endpoints, networkpolicies, pvcs, pvs, events, …). Secret values stripped on the host.
  • Frontend Resources tab + YAML drawer (js-yaml); pod rows get Shell + YAML actions.
  • Shell into pods via kubectl exec, reusing the terminal infra. K8s names regex-validated against argv injection.

Review fixes

  • Traces background task now opens its own DB session (was reusing the closed request session).
  • datetime.utcnow()datetime.now(timezone.utc) across routes.
  • Claude model tiering: RCA → Opus, chat/topology → Haiku, balanced default.
  • Added missing vite-env.d.ts; fixed a pre-existing Dashboard type error → tsc clean.

Status / caveats

  • Backend py_compile, agent py_compile, and frontend tsc --noEmit all pass.
  • Not yet run live — verify on a real host/cluster: kubectl-exec PTY, systemd hardening vs pty.fork, and large-cluster Redis payload size.
  • Deferred (north-star): cross-environment session/network flow (on-prem ↔ pod).

🤖 Generated with Claude Code

Web terminal (browser PTY, self-hosted, no third party):
- backend relay over Redis pub/sub (worker-safe), 2 WS endpoints,
  TerminalSession audit row, first-message API-key auth (key off URL)
- agent: stdlib RFC6455 WS client + pty.fork, hooked into exec poll
- frontend: xterm.js TerminalPanel, Terminal tab on nodes
- security borrowed from DirectGate: tenant/node scoped, concurrency cap,
  idle + max-duration timeouts, audited; shell runs as restricted agent user

K8s resource browser (Headlamp-style, read-only):
- agent collects extended kinds (services/configmaps/statefulsets/ingresses/
  pvcs/events/...), secret values stripped on host; tags push with agent_node
- frontend Resources tab + YAML drawer (js-yaml), pod Shell + YAML actions
- shell into pods via kubectl exec, reusing terminal infra (argv generalized,
  k8s names regex-validated against injection)

Review fixes from earlier pass:
- traces background task uses its own DB session (was reusing closed request session)
- datetime.utcnow() -> datetime.now(timezone.utc) across routes
- Claude model tiering: RCA->opus, chat/topology->haiku, balanced default

Chore: add missing vite-env.d.ts, fix Dashboard generic-index type; tsc clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant