feat: implement full Lens-like Kubernetes UI with resource discovery and management #75
No reviewers
Labels
No Label
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: sarman/tftsr-devops_investigation#75
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "feature/kubernetes-management"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Automated PR Review (qwen3-coder-next via liteLLM):\n\nSummary
This PR introduces comprehensive Kubernetes resource discovery and management capabilities via a Lens-like UI, including new Tauri commands for listing and managing Kubernetes resources (namespaces, pods, deployments, services, statefulsets, daemonsets) and frontend components to render them. A critical bug is present in Rust JSON parsing where YAML parsing is incorrectly used for JSON output, leading to runtime panics or incorrect data interpretation. Additionally, the frontend
PodList.tsxcomponent incorrectly assumes only one container exists per pod, limiting functionality.Findings
[BLOCKER] src-tauri/src/commands/kube.rs:731 - Rust function
parse_pods_jsonusesserde_yaml::from_strto parse JSON output fromkubectl, causing runtime parse failures when actualkubectlreturns JSON.Evidence:
let value: Value = serde_yaml::from_str(json_str)inparse_pods_jsonat line 731 and similarly inparse_namespaces_json,parse_services_json,parse_deployments_json,parse_statefulsets_json,parse_daemonsets_json.Fix: Replace
serde_yaml::from_strwithserde_json::from_strin all these parsing functions.[BLOCKER] src-tauri/src/commands/kube.rs:739 - Same issue in
parse_namespaces_json,parse_services_json, etc., whereserde_yaml::from_stris used on kubectl's JSON output.Evidence: Line 615 (
parse_namespaces_json), line 674 (parse_services_json), line 825 (parse_deployments_json), line 938 (parse_statefulsets_json), line 1051 (parse_daemonsets_json) all useserde_yaml::from_str(json_str).Fix: Replace
serde_yaml::from_strwithserde_json::from_strin all listed functions.[WARNING] src/components/Kubernetes/PodList.tsx:117 -
containersarray only includes pod name, ignoring actual container names frompod.containers, causing log fetch UI to show only pod name, not real containers.Evidence:
const containers = selectedPod ? [selectedPod.name] : [];at line 117.Fix: Retrieve actual container names from
selectedPod.containersif thePodInfostruct is extended to includecontainers: string[].[WARNING] src-tauri/src/commands/kube.rs:1177 -
exec_podcommand hardcodes shell asshwith-cand does not handleshavailability (e.g., containers usingashorbusybox). Should allow configurable shell or fallback.Evidence:
.arg("sh").arg("-c").arg(command)at line 1177.Fix: Add optional shell command parameter with default fallback (e.g.,
sh -corash -c) and validate command safety.[WARNING] src/components/Kubernetes/PodList.tsx:140 - Dialog height
max-h-[80vh]may cause overflow or clipping on small screens without proper scroll handling.Evidence:
<DialogContent className="max-w-4xl max-h-[80vh] flex flex-col">.Fix: Ensure inner layout handles scroll when content exceeds viewport, especially given dynamic tab switching.
[WARNING] src/components/Kubernetes/ResourceBrowser.tsx:57 - Loading "All Namespaces" with
namespace=""may fail because backend validates non-empty namespace orkubectl get pods -n ""is invalid; should default to"default"or skip fetching if"all".Evidence:
selectedNamespace === "all" ? listPodsCmd(clusterId, "") : listPodsCmd(clusterId, selectedNamespace).Fix: Replace
""with"default"or avoid calling list commands when"all"; handle per-namespace fetching separately.[WARNING] src/components/Kubernetes/PodList.tsx:118 - Log fetcher uses
selectedPod.nameas a container name (line 118 in originalcontainersarray usespod.name) but does not validate container existence; may cause UI confusion.Evidence: Line 117-120 sets
containers = [selectedPod.name], but actual container names are missing fromPodInfo.[SUGGESTION] src-tauri/src/commands/kube.rs:1411 -
parse_creation_timestamplogic duplicates logic previously used indiscover_podsand removed; ensure consistent age formatting across all resources.Evidence:
parse_creation_timestampimplementation (lines 1411+) usessigned_duration_since, while previous (removed) implementation usednum_seconds,num_hours,num_days. Ensure alignment.[SUGGESTION] src/components/Kubernetes/PodList.tsx:83 - Error handling does not expose underlying kubectl error details in UI, only generic
err.message; consider showing stderr from kubectl inLogResponseif available.Evidence:
setError(err instanceof Error ? err.message : "Failed to fetch logs");at line 83.[SUGGESTION] src/components/Kubernetes/ResourceBrowser.tsx:122 -
getNamespaceOptions()builds options on every render; consider memoizing to avoid unnecessary recomputation.Evidence:
const getNamespaceOptions = () => { ... };at line 122, called inside render.Verdict: REQUEST CHANGES
Blockers in JSON parsing must be fixed immediately. Additional high-priority items (container name handling, shell handling) must be addressed before production use.
Automated PR Review (qwen3-coder-next via liteLLM):\n\nSummary
This PR implements a comprehensive Kubernetes UI with resource discovery and management, fixing several critical issues identified in the PR review, especially regarding JSON parsing (changing from
serde_yamltoserde_json) and correct argument ordering in kubectl exec calls. The changes are well-documented inTICKET-kube-pr-review-fixes.mdand include comprehensive unit testing and type safety updates across frontend and backend.Findings
[BLOCKER]
src-tauri/src/commands/kube.rs:603-exec_podcommand incorrectly places container-cflag after--, causing it to be passed to the shell inside the pod instead of kubectl.Evidence:
cmd.arg("--").arg(shell_cmd).arg("-c").arg(&command);Fix: Move container argument before
--:[BLOCKER] Multiple
parse_*_jsonfunctions (parse_pods_json,parse_namespaces_json,parse_services_json, etc.) incorrectly useserde_yaml::Valueto parse kubectl JSON output, causing silent mis-parsing or runtime errors.Evidence:
fn parse_pods_json(json_str: &str) -> Result<Vec<PodInfo>, String> {let value: Value = serde_json::from_str(json_str)→ butValueimported asserde_yaml::Valueat top of fileFix: Use
serde_json::Valuefor all JSON-parsing functions (already implemented in diff), and keepserde_yaml::Valueonly for kubeconfig YAML parsing.[WARNING]
src-tauri/src/commands/kube.rs:436-453—exec_podallows shells not in allowlist, e.g.,zsh, becauseALLOWED_SHELLSis declared aftershellparameter usage. Though actually in the diff,ALLOWED_SHELLSis defined before usage (at line 545), so this is fixed — but the original code may have been vulnerable.Evidence:
No change needed — fix already in place.
[WARNING]
src-tauri/src/commands/kube.rs:182-185— kubeconfig parsing functions useserde_yaml::Value, butuse serde_json::Value;is at the top — soValueisserde_jsonand will fail to parse YAML.Evidence:
use serde_yaml::Value;→use serde_json::Value;→ final import isserde_json::Value.Yet
extract_contextandextract_server_urluse:let value: Value = serde_yaml::from_str(content)?;This is now incompatible because
Valueisserde_json::Value.Fix: Explicitly qualify YAML parsing with
serde_yaml::Value(already done in diff —let value: serde_yaml::Value = serde_yaml::from_str(...)).[WARNING]
src/components/Kubernetes/PodList.tsx:120— before fix, container selector defaulted toselectedPod.name. After fix, usesselectedPod?.containers ?? [], which is correct. No code change needed, but confirming fix is applied.Evidence:
const containers = selectedPod?.containers ?? [];— correct.[WARNING]
src/components/Kubernetes/ResourceBrowser.tsx:115— namespace filter uses empty string for "All Namespaces", whichkubectl -n ""rejects.Evidence:
✅ Fix applied — empty string now correctly routes to
--all-namespaces.Verdict: APPROVE WITH COMMENTS
Rationale: All BLOCKER issues identified in the ticket are fixed, including JSON/YAML parser mismatch and kubectl exec argument ordering. Remaining WARNING items are minor edge cases that are either already fixed in the diff or handled by existing validation/logic. The PR includes a clear ticket doc and robust tests.
Automated PR Review (qwen3-coder-next via liteLLM):\n\nSummary
This PR implements a full Lens-like Kubernetes UI with resource discovery and management, resolving all blockers identified in the automated PR review, particularly switching YAML parsers to JSON for kubectl JSON output. No security bugs, logic errors, or data loss risks were found in the changed files.
Findings
use serde_yaml::Value;is replaced withuse serde_json::Value;for kubectl JSON output parsing, butextract_contextandextract_server_urlremain correctly typed asserde_yaml::Value. The import change is correct; no action needed.list_namespaces,list_pods,list_services,list_deployments,list_statefulsets,list_daemonsetshandle empty namespace with--all-namespaces, butexec_poduses namespace directly without this handling. However,exec_podexpects a specific namespace and doesn't support--all-namespaces, so this is intentional and acceptable.const containers = selectedPod?.containers ?? [];followed by<option value="">Select container...</option>. Fix: pre-select first container whenselectedPodis set andcontainers.length > 0.Verdict: APPROVE WITH COMMENTS
Automated PR Review (qwen3-coder-next via liteLLM):\n\nSummary
The PR implements a full Kubernetes UI with resource discovery and management. All identified issues in the ticket have been resolved: JSON parsing now correctly uses
serde_json,PodInfocarries container names,exec_podhas corrected argument order and shell validation, and empty namespace routing now uses--all-namespaces. No further blocking or high-severity issues were found in the code.Findings
[SUGGESTION] src-tauri/src/commands/kube.rs:275 -
PodInfo.containersinitialized withVec::new()in default case instead ofVec::with_capacity(0)for clarityEvidence:
let containers = item .get("spec") .and_then(|s| s.get("containers")) .and_then(|c| c.as_array()) .map(|spec_containers| { ... }) .unwrap_or_default();Fix: Use
.unwrap_or_default()is acceptable; if optimization needed,.unwrap_or(Vec::with_capacity(0))is equivalent in behavior for emptyVec.[SUGGESTION] src/components/Kubernetes/ResourceBrowser.tsx:59 -
loadDatadependency array includesselectedNamespace, butuseMemomemoization ofnamespaceOptionsshould be safe and efficient for typical cluster sizesEvidence:
const loadData = useCallback(async () => { ... }, [clusterId, selectedNamespace]);followed byconst namespaceOptions = useMemo(() => { ... }, [namespaces]);Fix: No change required; this is a minor readability note.
[SUGGESTION] src/components/Kubernetes/PodList.tsx:56 - Empty container selector dropdown shows "Select container..." instead of "No containers available" when pod has zero containers
Evidence:
option value="">Select container...</option>is static,containers.map(...)only renders ifcontainers.length > 0Fix: Consider dynamic text like
{containers.length === 0 ? "No containers available" : "Select container..."}.Verdict: APPROVE WITH COMMENTS