Skip to content

feat: add troubleshoot tab#505

Closed
sed-i wants to merge 1 commit intokdash-rs:mainfrom
sed-i:feature/troubleshooting
Closed

feat: add troubleshoot tab#505
sed-i wants to merge 1 commit intokdash-rs:mainfrom
sed-i:feature/troubleshooting

Conversation

@sed-i
Copy link
Copy Markdown
Contributor

@sed-i sed-i commented Mar 1, 2026

Hey @deepu105,
A potential new concept for your consideration!
I couldn't find a k8s diagnosis helper I liked, and kdash being read-only seemed like a suitable place to implement such a feature.


This PR adds a new, rules-based "Troubleshoot" tab.

  • Add new app/troubleshoot module, with per-resource rules.
  • Check signatures look like this: fn check_pod_phase(pod: &KubePod) -> Option<Finding<PodFinding>>, and they are all collected and rendered in the troubleshoot tab, sorted by prescribed priority.

AI usage:

  • Claude Opus 4.6 and GPT 5.2 Codex for iterating on the feature.
  • GitHub Copilot for code review.
image

refactor: drop dsl, use generics and closures

take reason, message from pod condition

add yaml view

drop issue count from troubleshooting tab label

troubleshoot pvcs

troubleshoot rs

add utests

Only compute troubleshoot findings when Troubleshoot tab is active

Co-authored-by: sed-i <82407168+sed-i@users.noreply.github.com>

troubleshoot module
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new rules-based Troubleshoot tab to the TUI, generating prioritized “findings” across multiple Kubernetes resource types and rendering them in a dedicated view (with describe/YAML subviews).

Changes:

  • Introduces app/troubleshoot module with Pod/PVC/ReplicaSet checks and a unified DisplayFinding row model.
  • Wires a new RouteId::Troubleshoot / ActiveBlock::Troubleshoot through UI rendering, keybindings, handlers, and network polling (IoEvent::GetTroubleshootFindings).
  • Adds strum for display/ordering derives and applies a few small formatting cleanups.

Reviewed changes

Copilot reviewed 11 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/ui/mod.rs Adds Troubleshoot route rendering and header hints.
src/network/mod.rs Adds GetTroubleshootFindings event and dispatch to TroubleshootResource.
src/handlers/mod.rs Adds routing + describe/YAML actions for Troubleshoot findings and scroll handling.
src/app/troubleshoot/mod.rs Implements findings model, evaluation, rendering, and network fetch for Troubleshoot tab.
src/app/troubleshoot/pod.rs Adds initial Pod rules (phase + condition-derived reason/message) with tests.
src/app/troubleshoot/pvc.rs Adds initial PVC rules (non-Bound phase) with tests.
src/app/troubleshoot/rs.rs Adds initial ReplicaSet rule (status replica-count mismatch) with tests.
src/app/mod.rs Registers new module, route/block, data table, tab entry, and polling dispatch.
src/app/key_binding.rs Adds jump_to_troubleshoot binding and minor help-row refactor.
src/app/ingress.rs Minor formatting-only adjustment in format_backend.
rustfmt.toml Formatting-only tweak.
Cargo.toml / Cargo.lock Adds strum dependency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +700 to +714
let yaml = match finding.resource_kind {
ResourceKind::Pod => app
.data
.pods
.items
.iter()
.find(|p| {
p.name == finding.describe_name
&& finding
.describe_namespace
.as_deref()
.is_none_or(|ns| p.namespace == ns)
})
.map(|p| p.resource_to_yaml())
.unwrap_or_default(),
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

resource_yaml for Troubleshoot findings looks up the underlying object in app.data.pods / pvcs / replica_sets, but the Troubleshoot tab’s network fetch only populates troubleshoot_findings (and the app does not poll pods/pvcs/replicasets while on the Troubleshoot route). This can lead to empty YAML output for findings (especially for PVC/ReplicaSet) unless the user previously visited those resource tabs. Consider populating the relevant app.data.* caches when building findings, or storing the source k8s object / YAML directly on the finding so YAML view is always available.

Copilot uses AI. Check for mistakes.

let findings = evaluate_findings(&pods, &pvcs, &replica_sets);

let mut app = network.app.lock().await;
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

TroubleshootResource::get_resource fetches pods/PVCs/ReplicaSets, but only writes the derived troubleshoot_findings back into app.data. Since the YAML action in the Troubleshoot route currently relies on app.data.pods / pvcs / replica_sets, the fetched objects are effectively discarded and YAML may be unavailable/empty. Consider also updating the corresponding app.data.*.set_items(...) here (or changing findings to carry the object/YAML needed for the YAML view).

Suggested change
let mut app = network.app.lock().await;
let mut app = network.app.lock().await;
app.data.pods.set_items(pods);
app.data.pvcs.set_items(pvcs);
app.data.replica_sets.set_items(replica_sets);

Copilot uses AI. Check for mistakes.
self.dispatch(IoEvent::GetMetrics).await;
}
RouteId::Troubleshoot => {
self.dispatch(IoEvent::GetTroubleshootFindings).await;
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

On the Troubleshoot route the app dispatches GetTroubleshootFindings on every poll interval regardless of the active block. When the user is in Describe/Yaml subviews this will still trigger periodic list calls and set is_loading, even though the table isn’t visible. Consider gating this dispatch to ActiveBlock::Troubleshoot (similar to how the Home route avoids polling while in Describe/Yaml) to reduce unnecessary API traffic and UI loading state churn.

Suggested change
self.dispatch(IoEvent::GetTroubleshootFindings).await;
if self.get_current_route().active_block == ActiveBlock::Troubleshoot {
self.dispatch(IoEvent::GetTroubleshootFindings).await;
}

Copilot uses AI. Check for mistakes.
@deepu105
Copy link
Copy Markdown
Contributor

deepu105 commented Apr 3, 2026

Thanks @sed-i , thats a great feature, i'll check and merge asap

@deepu105
Copy link
Copy Markdown
Contributor

deepu105 commented Apr 3, 2026

Manually merged 4091201. Thank you @sed-i 🙏

@deepu105 deepu105 closed this Apr 3, 2026
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