diff --git a/src-tauri/src/commands/kube.rs b/src-tauri/src/commands/kube.rs index 918f042a..f783582d 100644 --- a/src-tauri/src/commands/kube.rs +++ b/src-tauri/src/commands/kube.rs @@ -270,7 +270,8 @@ pub async fn test_cluster_connection( let output = Command::new(kubectl_path) .arg("cluster-info") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -323,7 +324,8 @@ pub async fn discover_pods( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -458,8 +460,9 @@ pub async fn start_port_forward( // Spawn kubectl subprocess let child = Command::new(kubectl_path) .args(&args) + .arg("--context") + .arg(cluster.context.as_str()) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", &cluster.context) .spawn() .map_err(|e| format!("Failed to spawn kubectl: {e}"))?; @@ -768,7 +771,8 @@ pub async fn list_namespaces( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -854,7 +858,8 @@ pub async fn list_pods( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -976,7 +981,8 @@ pub async fn list_services( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -1133,7 +1139,8 @@ pub async fn list_deployments( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -1266,7 +1273,8 @@ pub async fn list_statefulsets( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -1383,7 +1391,8 @@ pub async fn list_daemonsets( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -1547,7 +1556,8 @@ pub async fn get_pod_logs( .arg("-c") .arg(container_name) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -1596,7 +1606,8 @@ pub async fn scale_deployment( .arg("-n") .arg(namespace) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -1641,7 +1652,8 @@ pub async fn restart_deployment( .arg("-n") .arg(namespace) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -1686,7 +1698,8 @@ pub async fn delete_resource( .arg("-n") .arg(namespace) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -1754,7 +1767,8 @@ pub async fn exec_pod( cmd.arg("--").arg(shell_cmd).arg("-c").arg(&command); cmd.env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context); + .arg("--context") + .arg(context.as_str()); let output = cmd .output() @@ -2014,7 +2028,8 @@ pub async fn list_replicasets( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -2131,7 +2146,8 @@ pub async fn list_jobs( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -2286,7 +2302,8 @@ pub async fn list_cronjobs( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -2412,7 +2429,8 @@ pub async fn list_configmaps( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -2509,7 +2527,8 @@ pub async fn list_secrets( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -2607,7 +2626,8 @@ pub async fn list_nodes( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -2799,7 +2819,8 @@ pub async fn list_events( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -2927,7 +2948,8 @@ pub async fn list_ingresses( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3052,7 +3074,8 @@ pub async fn list_persistentvolumeclaims( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3176,7 +3199,8 @@ pub async fn list_persistentvolumes( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3306,7 +3330,8 @@ pub async fn list_serviceaccounts( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3403,7 +3428,8 @@ pub async fn list_roles( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3487,7 +3513,8 @@ pub async fn list_clusterroles( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3566,7 +3593,8 @@ pub async fn list_rolebindings( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3661,7 +3689,8 @@ pub async fn list_clusterrolebindings( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3751,7 +3780,8 @@ pub async fn list_horizontalpodautoscalers( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3863,7 +3893,8 @@ pub async fn list_storageclasses( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -3972,7 +4003,8 @@ pub async fn list_networkpolicies( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -4082,7 +4114,8 @@ pub async fn list_resourcequotas( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -4202,7 +4235,8 @@ pub async fn list_limitranges( .arg("-o") .arg("json") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -4293,7 +4327,8 @@ pub async fn cordon_node( .arg("cordon") .arg(node_name) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -4333,7 +4368,8 @@ pub async fn uncordon_node( .arg("uncordon") .arg(node_name) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -4376,7 +4412,8 @@ pub async fn drain_node( .arg("--delete-emptydir-data") .arg("--force") .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -4421,7 +4458,8 @@ pub async fn rollback_deployment( .arg("-n") .arg(namespace) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .output() .await .map_err(|e| format!("Failed to execute kubectl: {e}"))?; @@ -4466,7 +4504,8 @@ pub async fn create_resource( .arg("-n") .arg(namespace) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()); @@ -4528,7 +4567,8 @@ pub async fn edit_resource( .arg("-n") .arg(namespace) .env("KUBECONFIG", temp_path.to_string_lossy().to_string()) - .env("KUBERNETES_CONTEXT", context) + .arg("--context") + .arg(context.as_str()) .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped()); diff --git a/src/components/Kubernetes/ClusterOverview.tsx b/src/components/Kubernetes/ClusterOverview.tsx index d9b2c87b..b5ae6517 100644 --- a/src/components/Kubernetes/ClusterOverview.tsx +++ b/src/components/Kubernetes/ClusterOverview.tsx @@ -117,9 +117,11 @@ export function ClusterOverview({ clusterId, clusterName }: ClusterOverviewProps

Cluster Overview

-

- {clusterName ?? clusterId} -

+ {clusterName && ( +

+ {clusterName} +

+ )}
-
@@ -33,33 +35,35 @@ export function Hotbar({ onRefresh, onAddResource, onSettings, onNotifications,
- {selectedCluster?.name || "No cluster selected"} + {clusterName ?? "No cluster selected"}
-
- - - -
+ + +
); diff --git a/src/components/ui/index.tsx b/src/components/ui/index.tsx index 519655a9..485c7900 100644 --- a/src/components/ui/index.tsx +++ b/src/components/ui/index.tsx @@ -605,13 +605,26 @@ export function DialogContent({ className, children }: { className?: string; chi if (!ctx.open) return null; return ( -
+
ctx.onOpenChange(false)} + >
e.stopPropagation()} > + {children}
diff --git a/src/pages/Kubernetes/KubernetesPage.tsx b/src/pages/Kubernetes/KubernetesPage.tsx index 95d5f74d..4009c822 100644 --- a/src/pages/Kubernetes/KubernetesPage.tsx +++ b/src/pages/Kubernetes/KubernetesPage.tsx @@ -594,11 +594,10 @@ export function KubernetesPage() { } if (activeSection === "overview") { - const overviewConfig = kubeconfigs.find((c) => c.id === selectedClusterId); return ( ); } @@ -706,6 +705,7 @@ export function KubernetesPage() { onAddResource={() => setIsCommandPaletteOpen(true)} onSettings={() => {}} onNotifications={() => setIsNotificationsOpen(true)} + clusterName={selectedConfig?.name} /> {/* Top bar: cluster selector + namespace selector */} diff --git a/tests/unit/ClusterOverview.test.tsx b/tests/unit/ClusterOverview.test.tsx index c603a9b8..2bc5bcb2 100644 --- a/tests/unit/ClusterOverview.test.tsx +++ b/tests/unit/ClusterOverview.test.tsx @@ -178,14 +178,20 @@ describe("ClusterOverview", () => { }); }); - it("falls back gracefully when clusterName prop is not provided", async () => { + it("hides the subtitle when clusterName prop is not provided (never shows UUID)", async () => { mockInvoke.mockImplementation(() => Promise.resolve([])); - render(); + render(); await waitFor(() => { - const header = screen.getByTestId("cluster-name-header"); - expect(header).toBeInTheDocument(); + // Heading still present + expect(screen.getByText("Cluster Overview")).toBeInTheDocument(); + // UUID must NOT be rendered anywhere + expect( + screen.queryByText("019e9ff0-b6a4-78e1-a566-7a0c05e32577") + ).not.toBeInTheDocument(); + // Subtitle element should not exist when no name is passed + expect(screen.queryByTestId("cluster-name-header")).not.toBeInTheDocument(); }); }); });