Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ca070e8
feat(k8s): add kubectl and kubeconfig override fields to models
metalgrid Jun 16, 2026
474598f
feat(k8s): plumb kubectl and kubeconfig overrides through tunnel and …
metalgrid Jun 16, 2026
0580d2f
feat(k8s): honor kubectl overrides in MCP connection expansion
metalgrid Jun 16, 2026
8a3f4c5
feat(k8s): pass kubectl overrides through frontend k8s utils
metalgrid Jun 16, 2026
955cb91
feat(k8s): add advanced kubectl settings to connection modals
metalgrid Jun 16, 2026
866d413
feat(k8s): translate advanced kubectl settings
metalgrid Jun 16, 2026
c289090
feat(k8s): add advanced path validation command
metalgrid Jun 23, 2026
4d89e35
feat(k8s): expose advanced path validation utility
metalgrid Jun 23, 2026
f48590c
feat(k8s): validate advanced paths in modals
metalgrid Jun 23, 2026
f6203af
docs(sponsors): add Vercel and Tolgee, update DevGlobe
debba Jun 23, 2026
19b5dc3
Add function to include headers in CSV output (#356)
Wilovy09 Jun 23, 2026
fac4c9e
Add IBM Informix plugin to registry
Jun 21, 2026
c52ca43
Bump Informix plugin to 0.1.1 (hidden console window)
Jun 22, 2026
927f6ee
Informix plugin 0.1.2: add linux-x64 asset
Jun 23, 2026
ddb27fe
feat(hooks): add useLatestAsync guard for cancellable async
metalgrid Jun 24, 2026
13b6039
fix(k8s): cancel stale async in K8s connections modal
metalgrid Jun 24, 2026
4331d0a
fix(k8s): cancel stale async and dedupe context fetch in new connecti…
metalgrid Jun 24, 2026
eafd430
Merge branch 'main' into enh/k8s-advanced-kubectl-settings
metalgrid Jun 24, 2026
da63880
Merge branch 'main' into enh/k8s-advanced-kubectl-settings
metalgrid Jun 24, 2026
20fcb55
Merge branch 'main' into enh/k8s-advanced-kubectl-settings
metalgrid Jun 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 64 additions & 8 deletions src-tauri/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,17 @@ fn resolve_k8s_params(params: &ConnectionParams) -> Result<ConnectionParams, Str
.ok_or("Missing K8s resource name")?;
let port = params.k8s_port.ok_or("Missing K8s port")?;

let options = crate::k8s_tunnel::K8sCommandOptions::new(
params.k8s_kubectl_path.clone(),
params.k8s_kubeconfig_path.clone(),
);
let map_key = crate::k8s_tunnel::build_tunnel_key(
context, namespace, resource_type, resource_name, port,
context,
namespace,
resource_type,
resource_name,
port,
&options,
);

// Check for existing tunnel
Expand All @@ -262,7 +271,12 @@ fn resolve_k8s_params(params: &ConnectionParams) -> Result<ConnectionParams, Str
);

let tunnel = crate::k8s_tunnel::K8sTunnel::new(
context, namespace, resource_type, resource_name, port,
context,
namespace,
resource_type,
resource_name,
port,
&options,
)
.map_err(|e| {
eprintln!("[Connection Error] K8s Tunnel setup failed: {}", e);
Expand Down Expand Up @@ -1453,6 +1467,8 @@ pub async fn save_k8s_connection<R: Runtime>(
resource_type: k8s.resource_type,
resource_name: k8s.resource_name,
port: k8s.port,
kubectl_path: k8s.kubectl_path,
kubeconfig_path: k8s.kubeconfig_path,
};

connections.push(connection.clone());
Expand Down Expand Up @@ -1490,6 +1506,8 @@ pub async fn update_k8s_connection<R: Runtime>(
resource_type: k8s.resource_type,
resource_name: k8s.resource_name,
port: k8s.port,
kubectl_path: k8s.kubectl_path,
kubeconfig_path: k8s.kubeconfig_path,
};

connections[idx] = connection.clone();
Expand Down Expand Up @@ -1526,23 +1544,32 @@ pub async fn test_k8s_connection_cmd<R: Runtime>(
_app: AppHandle<R>,
context: String,
namespace: String,
kubectl_path: Option<String>,
kubeconfig_path: Option<String>,
) -> Result<String, String> {
crate::k8s_tunnel::test_k8s_connection(&context, &namespace)
let options = crate::k8s_tunnel::K8sCommandOptions::new(kubectl_path, kubeconfig_path);
crate::k8s_tunnel::test_k8s_connection(&context, &namespace, &options)
}

#[tauri::command]
pub async fn get_k8s_contexts_cmd<R: Runtime>(
_app: AppHandle<R>,
kubectl_path: Option<String>,
kubeconfig_path: Option<String>,
) -> Result<Vec<String>, String> {
crate::k8s_tunnel::get_k8s_contexts()
let options = crate::k8s_tunnel::K8sCommandOptions::new(kubectl_path, kubeconfig_path);
crate::k8s_tunnel::get_k8s_contexts(&options)
}

#[tauri::command]
pub async fn get_k8s_namespaces_cmd<R: Runtime>(
_app: AppHandle<R>,
context: String,
kubectl_path: Option<String>,
kubeconfig_path: Option<String>,
) -> Result<Vec<String>, String> {
crate::k8s_tunnel::get_k8s_namespaces(&context)
let options = crate::k8s_tunnel::K8sCommandOptions::new(kubectl_path, kubeconfig_path);
crate::k8s_tunnel::get_k8s_namespaces(&context, &options)
}

#[tauri::command]
Expand All @@ -1551,8 +1578,11 @@ pub async fn get_k8s_resources_cmd<R: Runtime>(
context: String,
namespace: String,
resource_type: String,
kubectl_path: Option<String>,
kubeconfig_path: Option<String>,
) -> Result<Vec<String>, String> {
crate::k8s_tunnel::get_k8s_resources(&context, &namespace, &resource_type)
let options = crate::k8s_tunnel::K8sCommandOptions::new(kubectl_path, kubeconfig_path);
crate::k8s_tunnel::get_k8s_resources(&context, &namespace, &resource_type, &options)
}

#[tauri::command]
Expand All @@ -1562,15 +1592,28 @@ pub async fn get_k8s_resource_ports_cmd<R: Runtime>(
namespace: String,
resource_type: String,
resource_name: String,
kubectl_path: Option<String>,
kubeconfig_path: Option<String>,
) -> Result<Vec<u16>, String> {
let options = crate::k8s_tunnel::K8sCommandOptions::new(kubectl_path, kubeconfig_path);
crate::k8s_tunnel::get_k8s_resource_ports(
&context,
&namespace,
&resource_type,
&resource_name,
&options,
)
}

#[tauri::command]
pub async fn validate_k8s_path_cmd<R: Runtime>(
_app: AppHandle<R>,
path: String,
kind: String,
) -> Result<(), String> {
crate::k8s_tunnel::validate_k8s_path(&path, &kind)
}

/// Expand K8s connection params by loading saved config and creating/reusing a tunnel.
pub async fn expand_k8s_connection_params<R: Runtime>(
app: &AppHandle<R>,
Expand All @@ -1588,7 +1631,7 @@ pub async fn expand_k8s_connection_params<R: Runtime>(
}

// Resolve K8s params from saved connection if using connection_id
let (context, namespace, resource_type, resource_name, port) =
let (context, namespace, resource_type, resource_name, port, kubectl_path, kubeconfig_path) =
if let Some(k8s_id) = &params.k8s_connection_id {
let k8s_conn = get_k8s_connection_by_id(app, k8s_id).await?;
(
Expand All @@ -1597,6 +1640,8 @@ pub async fn expand_k8s_connection_params<R: Runtime>(
k8s_conn.resource_type,
k8s_conn.resource_name,
k8s_conn.port,
k8s_conn.kubectl_path,
k8s_conn.kubeconfig_path,
)
} else {
let ctx = params
Expand All @@ -1620,18 +1665,28 @@ pub async fn expand_k8s_connection_params<R: Runtime>(
.ok_or("Missing K8s resource name")?
.to_string();
let p = params.k8s_port.ok_or("Missing K8s port")?;
(ctx, ns, rt, rn, p)
(
ctx,
ns,
rt,
rn,
p,
params.k8s_kubectl_path.clone(),
params.k8s_kubeconfig_path.clone(),
)
};

let _remote_host = params.host.as_deref().unwrap_or("localhost");
let _remote_port = params.port.unwrap_or(DEFAULT_MYSQL_PORT);

let options = crate::k8s_tunnel::K8sCommandOptions::new(kubectl_path, kubeconfig_path);
let map_key = crate::k8s_tunnel::build_tunnel_key(
&context,
&namespace,
&resource_type,
&resource_name,
port,
&options,
);

// Check for existing tunnel
Expand Down Expand Up @@ -1666,6 +1721,7 @@ pub async fn expand_k8s_connection_params<R: Runtime>(
&resource_type,
&resource_name,
port,
&options,
)
.map_err(|e| {
eprintln!("[Connection Error] K8s Tunnel setup failed: {}", e);
Expand Down
Loading