Skip to content

feat: Kubernetes port-forward tunnel support#246

Merged
debba merged 18 commits into
TabularisDB:mainfrom
metalgrid:feat/kubernetes-tunnel
May 29, 2026
Merged

feat: Kubernetes port-forward tunnel support#246
debba merged 18 commits into
TabularisDB:mainfrom
metalgrid:feat/kubernetes-tunnel

Conversation

@metalgrid
Copy link
Copy Markdown
Contributor

@metalgrid metalgrid commented May 23, 2026

Summary

Adds built-in Kubernetes port-forward support as a first-class transport option (alongside SSH tunnels). Users can
connect to any database running inside a Kubernetes cluster by configuring a kubectl context, namespace, resource
(service/pod), and container port.

How it works

  • Runs kubectl port-forward as a managed child process, binding a local port that the database driver connects to
    transparently
  • Tunnels are reused across connections to the same resource (keyed by context/namespace/resource/port)
  • Auto-discovers kubectl contexts, namespaces, and resources from ~/.kube/config
  • Saved K8s connections persist in k8s_connections.json (same pattern as SSH)
  • Mutually exclusive with SSH — enabling K8s disables SSH and vice versa

New files

File Purpose
src-tauri/src/k8s_tunnel.rs Tunnel lifecycle, discovery functions, 12 unit tests
src/utils/k8s.ts Frontend CRUD, discovery, validation
src/components/modals/K8sConnectionsModal.tsx Manage saved K8s connections
tests/utils/k8s.test.ts 24 frontend unit tests

Modified files

  • src-tauri/src/models.rs — K8s fields on ConnectionParams, new structs
  • src-tauri/src/commands.rs — K8s commands, tunnel expansion, export/import, 6 tests
  • src-tauri/src/lib.rs — Module + command registration
  • src/components/modals/NewConnectionModal.tsx — Kubernetes tab with cascading dropdowns
  • src/components/connections/ + sidebar/ — Blue K8s badge on connections
  • src/utils/connectionManager.ts / connections.ts — K8s fields in types
  • Existing test files updated to use ..Default::default() spread

Test coverage

  • 594 Rust tests pass (18 new K8s-specific)
  • 24 new TypeScript tests
  • Manually smoke-tested with a real K8s cluster

Requirements

  • kubectl installed and in $PATH
  • A valid kubeconfig (~/.kube/config or $KUBECONFIG)
image image

metalgrid added 8 commits May 23, 2026 09:46
Add K8s fields to ConnectionParams (k8s_enabled, k8s_connection_id,
k8s_context, k8s_namespace, k8s_resource_type, k8s_resource_name,
k8s_port) and create K8sConnection, K8sConnectionInput, K8sTestParams
structs. Update ExportPayload with k8s_connections. Simplify existing
test ConnectionParams literals with ..Default::default() spread.
New k8s_tunnel.rs with K8sTunnel struct, global tunnel map for reuse,
lifecycle management (spawn, health-check, stop), discovery functions
(get_k8s_contexts, get_k8s_namespaces, get_k8s_resources), test helper,
and 12 unit tests covering tunnel key generation and output parsing.
Add K8s CRUD commands (get/save/update/delete_k8s_connection), discovery
commands (get_k8s_contexts/namespaces/resources_cmd), test command, and
expand_k8s_connection_params. Wire K8s into resolve_connection_params
and test_connection with SSH mutual exclusion. Include K8s connections
in export/import. Add 6 unit tests for K8s param validation.
New k8s.ts with K8sConnection interface, CRUD functions (load/save/
update/delete), discovery wrappers (contexts/namespaces/resources),
testK8sConnection, formatK8sConnectionString, and validateK8sConnection.
Add K8s fields to ConnectionParams type in connections.ts.
Add Kubernetes tab to NewConnectionModal with enable toggle, mode
selector (saved/inline), cascading dropdowns for context→namespace→
resource type→resource name populated via kubectl discovery, container
port input, and SSH/K8s mutual exclusion. Add K8sConnectionsModal for
managing saved K8s connections with add/edit/delete/test.
Display blue K8s shield badge on ConnectionCard, ConnectionListItem,
and OpenConnectionItem when k8s_enabled is true. Add k8sEnabled field
to ConnectionStatus in connectionManager.
Add 24 tests covering validateK8sConnection (required fields, resource
type, port), formatK8sConnectionString, testK8sConnection, discovery
functions (contexts, namespaces, resources), and CRUD operations.
Update connectionManager test to include k8sEnabled field.
Comment thread src-tauri/src/commands.rs
}

/// Resolve K8s tunnel params synchronously (no saved-connection lookup; uses inline fields only).
fn resolve_k8s_params(params: &ConnectionParams) -> Result<ConnectionParams, String> {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRITICAL: resolve_k8s_params only reads inline K8s fields and ignores k8s_connection_id

Since expand_k8s_connection_params (which resolves saved connection IDs) is only called in test_connection, all other database commands will fail with "Missing K8s context" when a saved K8s connection is used. Either resolve_k8s_params must also look up saved connections, or all database commands need to call expand_k8s_connection_params before resolve_connection_params_with_id, just like they already do for SSH.

Comment thread src-tauri/src/commands.rs
);

let mut expanded_params = expand_ssh_connection_params(&app, &request.params).await?;
expanded_params = expand_k8s_connection_params(&app, &expanded_params).await?;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CRITICAL: expand_k8s_connection_params is only called in test_connection

Every other database command (get_schemas, get_tables, list_databases, query, etc.) already calls expand_ssh_connection_params but does NOT call expand_k8s_connection_params. This means connections using a saved K8s connection ID will work during the connection test but fail for all actual database operations.

@kilo-code-bot
Copy link
Copy Markdown

kilo-code-bot Bot commented May 23, 2026

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 1
WARNING 0
SUGGESTION 0
Issue Details (click to expand)

CRITICAL

File Line Issue
src-tauri/src/commands.rs 223 resolve_k8s_params only reads inline K8s fields and ignores k8s_connection_id

RESOLVED

File Line Issue
src-tauri/src/commands.rs 1618 expand_k8s_connection_params is now called in all database commands in commands.rs
src-tauri/src/clipboard_import.rs 79 Now calls expand_k8s_connection_params
src-tauri/src/dump_commands.rs 65 Now calls expand_k8s_connection_params
src-tauri/src/dump_commands.rs 438 Now calls expand_k8s_connection_params
src-tauri/src/export.rs 78 Now calls expand_k8s_connection_params
src-tauri/src/health_check.rs 144 Now calls expand_k8s_connection_params
src-tauri/src/health_check.rs 172 Now calls expand_k8s_connection_params
src-tauri/src/mcp/mod.rs 202 MCP mode now calls expand_k8s_params_for_mcp
src-tauri/src/mcp/mod.rs 429 MCP mode now expands K8s params before resolve_connection_params
Files Reviewed (8 files)
  • src-tauri/src/commands.rs — 0 new issues, 1 carried forward
  • src-tauri/src/clipboard_import.rs — 0 new issues, 1 resolved
  • src-tauri/src/dump_commands.rs — 0 new issues, 2 resolved
  • src-tauri/src/export.rs — 0 new issues, 1 resolved
  • src-tauri/src/health_check.rs — 0 new issues, 2 resolved
  • src-tauri/src/mcp/mod.rs — 0 new issues, 2 resolved
  • src/components/modals/K8sConnectionsModal.tsx — 0 new issues
  • src/components/modals/NewConnectionModal.tsx — 0 new issues

Fix these issues in Kilo Cloud


Reviewed by kimi-k2.6-20260420 · 1,203,671 tokens

metalgrid added 7 commits May 23, 2026 10:30
Add expand_k8s_connection_params call alongside every
expand_ssh_connection_params call site (~34 locations). Without this,
saved K8s connections (using k8s_connection_id) would fail with
"Missing K8s context" for all operations except test_connection.

Mirrors the existing SSH pattern exactly: async expand resolves saved
connection ID into inline fields, then sync resolve creates the tunnel.
When editing a connection with inline K8s fields, the mode defaulted to
"existing" because setK8sMode was never called — mirroring the existing
setSshMode logic on the same path.
Add useEffect hooks that watch k8s_context, k8s_namespace, and
k8s_resource_type to trigger cascading loads of namespaces and
resources. Previously these only loaded inside onChange handlers,
so editing a saved inline K8s connection showed empty dropdowns
until the user manually re-selected the context.

Remove the inline load calls from onChange handlers since the
useEffects are now the single source of truth for cascading loads.
@debba
Copy link
Copy Markdown
Collaborator

debba commented May 25, 2026

Hi @metalgrid
Thanks for this PR, it has beenrequested a lot in the past.
We'll review ASAP.

@NewtTheWolf
Copy link
Copy Markdown
Contributor

@debba i will review

@NewtTheWolf
Copy link
Copy Markdown
Contributor

but will review it tomorrow! (CET)

@NewtTheWolf
Copy link
Copy Markdown
Contributor

@metalgrid awesome contribution!
Try to fix the Conflicts

@debba or @metalgrid could u polish the ui a bit? so it is alligned to the rest of the connection modal?

@debba debba self-assigned this May 29, 2026
debba added 2 commits May 29, 2026 06:17
Replace hardcoded strings with i18n keys across locales
Resolve conflicts in NewConnectionModal (combine k8s and appearance tabs)
and mcp/mod.rs (drop duplicate schema resolution now handled by
resolve_db_params, which already expands SSH and K8s params).
@debba
Copy link
Copy Markdown
Collaborator

debba commented May 29, 2026

Hey @metalgrid, thanks for this work. I pushed a few things on top of your branch:

  • Reworked the selects in the connection modals (SSH/K8s and the New Connection dialog) to use our shared Select component, so they match the rest of the UI instead of the native browser dropdowns.
  • Added the missing translations for the Kubernetes parts across all 8 languages. The K8s connections modal and the K8s tab in the New Connection dialog were English-only/hardcoded before.
  • Merged latest main and resolved the conflicts: combined your k8s tab with the new appearance tab, and dropped a leftover duplicate schema lookup in mcp/mod.rs since resolve_db_params already expands the SSH and K8s params.

Everything builds locally (tsc + cargo check) and the branch is clean against main now. If you're happy with these changes I'll go ahead and merge.

@metalgrid
Copy link
Copy Markdown
Contributor Author

@debba , you beat me to it! :) Looks good to me, so if everyone is happy, feel free to merge this.

@debba
Copy link
Copy Markdown
Collaborator

debba commented May 29, 2026

@metalgrid That's great, thanks for this feature, feel free to open new PRs .
You can also reach us on our Discord server if you want .

@debba debba closed this May 29, 2026
@debba debba reopened this May 29, 2026
@debba debba merged commit 66a0aec into TabularisDB:main May 29, 2026
1 check passed
debba added a commit that referenced this pull request May 29, 2026
The K8s tunnel feature (#246) added k8s_* fields to ConnectionParams in
connections.ts but not to the inline params type on the SavedConnection
interface, breaking tsc -b where conn.params.k8s_enabled is accessed in
ConnectionCard, ConnectionListItem and connectionManager.
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.

3 participants