dsh-kube-lens: Add a default read-only Kubernetes cluster browser to DSH

Introduction

When troubleshooting clusters using the DSH Web GUI, the common practice is to keep the terminal open, run kubectl, and then paste the results back into the chat. Credentials in kubeconfig can be client certificates, bearer tokens, exec credential plugins (aws / gcloud / azure), or auth-provider fragments. Rewriting this logic on the plugin side is prone to errors, and managing multiple clusters requires repeatedly switching files and contexts.

The atticuswx/dsh-kube-lens plugin introduced below is designed for this purpose. It adds a Kubernetes icon to the plugin sidebar; the main area is a resource browser. The same set of operations is also exposed as Agent tools, eliminating the need to switch back and forth between the terminal and the web interface.

What is it

One-line positioning: A DSH plugin to access clusters via kubeconfig, wrapping kubectl into a panel and Agent tools, read-only by default.

  • Maintainer: atticuswx
  • License: MIT
  • Version: 0.3.0 (marked in code, version field in package.json, and supported v0.3.0 tag by dsh plugin add)
  • Category: admin-security direction, targeting cluster read operations and permission control
  • No extra dependencies: All cluster access goes through the host’s kubectl; the plugin itself does not rewrite credential logic

It is important to clarify one point first: it relies on the host having kubectl installed (Rancher Desktop usually has it at ~/.rd/bin/kubectl), and it requires a DSH that supports Web client bundles. There are no build steps in the package; client.js is loaded directly by the browser.

Installation and Enablement

Install from GitHub:

dsh plugin --profile web add github:atticuswx/dsh-kube-lens

After installation, refresh the page. A Kubernetes icon will appear in the sidebar. Clicking it opens the cluster browser. To lock the version, add a tag after the URL:

dsh plugin --profile web add github:atticuswx/dsh-kube-lens#v0.3.0

Local development (changes take effect immediately):

git clone https://github.com/atticuswx/dsh-kube-lens.git ~/dsh-plugins/dsh-kube-lens
dsh plugin --profile web add ~/dsh-plugins/dsh-kube-lens

Plugging it onto --profile web means this panel only appears in the Web GUI; Agent tools are available in the same host process.

What you get after installation

  • A Kubernetes icon appears in the sidebar; clicking it opens the cluster browser.
  • The Agent gains 6 read-only tools: kube_contexts, kube_get, kube_describe, kube_logs, kube_events, kube_diagnose.
  • Read-only by default. When write operations are disabled, the kube_write tool and the write button on the panel do not appear.

Configuration

Configuration is written in the config of cordis.patch.yml. The plugin needs to be reloaded after changes.

Key Default Description
kubeconfigPaths [] List of additional/specified kubeconfig files, read together according to kubectl’s merge rules. Empty means $KUBECONFIG, empty again means ~/.kube/config.
kubectlPath '' Fixed kubectl path. Empty means auto-detection: PATH, ~/.rd/bin, /usr/local/bin, /opt/homebrew/bin.
context '' Default context. Empty means using kubeconfig’s current-context.
namespace '' Default namespace. Empty means default.
allowWrites false Only appears when kube_write and the panel write button are enabled.
requestTimeoutMs 20000 Single kubectl timeout.

If you don’t want to touch the config file, the kubeconfig button in the top right of the panel can add/delete kubeconfigs at any time, taking effect immediately. Several pitfalls are detailed in the README: Each context only uses the file it belongs to; no cross-file name-based merging. This is because two kubeconfigs often name the cluster kubernetes; when kubectl merges, it only keeps the first, and the other context points to the wrong API server, resulting in Unauthorized. When the list is empty, it falls back to $KUBECONFIG, and then to ~/.kube/config. The save location is $DSH_HOME/kube-lens.json (default ~/.dsh/kube-lens.json). You can edit it manually. Custom display names are also stored here, recorded by kubeconfig file, so they won’t get misaligned when changing paths.

Browsing and Searching

The panel’s interaction follows common habits for cluster browsers. A few points worth noting:

  • The top displays the kubeconfig filename (e.g., prod-cluster), not that long string 123456789012345678-... context id; hover shows the full context, server, and file path.
  • A filter bar manages both namespace and search at the same time. The left side is the namespace trigger (‘All Namespaces’ or a specific namespace), the right side directly filters resource names; / focuses the input box, Esc clears or closes the menu.
  • ‘Show Only Exceptions’ filters by READY / STATUS columns: objects that are not ready (0/N) or in states like CrashLoopBackOff, ImagePullBackOff, Pending, Error, etc., used to locate problematic instances at first glance.
  • Count displays as Match Count / Total Count. Filtering is purely client-side and won’t repeatedly request the cluster due to input; re-requesting only happens when switching namespaces.

Keyboard-wise, clicking a column header cycles through Ascending → Descending → Cancel. CLUSTER-IP, PORT(S), CAPACITY are not sortable; ↑ / ↓ in the table move row focus, Home / End jump to first/last row, Enter or Space opens details; in the details page, Esc or the top-left back button returns to the list, focusing the row that entered the details.

Details Page: YAML and Logs

The details page has two tabs: YAML and Logs (new in 0.3.0).

The YAML tab editor is CodeMirror 6 (@codemirror/lang-yaml), bundled in the plugin’s viewer.js, no CDN, offline capable; only loaded on demand when first opened, falling back to a read-only <pre> view if loading fails. Supports syntax highlighting, line numbers, folding, bracket matching, undo/redo, auto-wrap, and ⌘F find. Also supports copy, download as <kind>-<name>.yaml, format (keep comments), and revert. YAML syntax is validated in real-time while editing; errors show wavy lines under them. A small yellow dot appears on the tab when there are unsaved changes.

‘Save to Cluster’ is only available when allowWrites: true. After clicking, a confirmation bar appears showing kubectl apply -f -, which is executed only after confirmation. Three scenarios are automatically read-only to avoid writing back sensitive or incomplete content to the cluster: Secrets, manifests truncated over 24k characters, and read failures.

The Logs tab uses SSE to continuously receive the output of kubectl logs -f --timestamps. It scrolls to the bottom by default; pausing and showing ‘Back to latest’ when scrolling up. The search box highlights all matches, Enter / Shift+Enter jumps to next/previous. Supports 200–2000 lines tail, copy all, and download raw logs with timestamps; multi-container Pods list container tabs; when restarting, an ‘Previous Run’ snapshot appears. Automatically reconnects after disconnection, filling gaps with --since-time using the last timestamp and deduplicating by timestamp, keeping only the most recent 5000 lines. Leaving the tab disconnects the kubectl subprocess, preventing background tailing.

Write Operations and Secret Protection

After allowWrites: true in config:

  • Every call to kube_write sends a one-time approval request to the user first, using the same channel as the bash tool approval; rejection, cancellation, or channel unavailability results in no execution.
  • Scrolling restarts, scale-ups/downs, and Pod deletion on the panel pop up a confirmation box first, then go to /kube-lens/api/write.
  • ‘Save to Cluster’ in the YAML details page shows a confirmation bar first, then goes to /kube-lens/api/apply; the server also checks allowWrites again, rejects Secrets, and rejects manifests with multiple top-level kinds`.

Secret handling is a separate layer: The content of Secrets is never returned. kube_get YAML and the panel YAML page only show type and key names for Secrets; the panel YAML page forces Secrets to be read-only, and the save interface also rejects them. Logs, events, and manifests are returned normally. For a plugin targeting an operations scenario, this strategy is more convenient than ‘read it out first and then see’—the risk of accidentally pasting a secret into the chat doesn’t exist from the start.

Agent Tools and kube_diagnose

All six tools are wrappers around the same set of kubectl calls. The design of kube_diagnose is worth mentioning separately: one call returns container status, restart count, last exit code and termination reason, scheduling failure events, Service endpoint coverage, previous run and current log tails, and gives conclusion-based findings.

The judgment rules are heuristic, and each conclusion is accompanied by evidence:

  • ImagePullBackOff / ErrImagePull -> image or registry credentials
  • CrashLoopBackOff -> restart count + last exit code
  • OOMKilled -> memory limit
  • CreateContainerConfigError -> referenced ConfigMap/Secret
  • Pending + FailedScheduling -> scheduler’s own words
  • Running but not Ready -> readiness probe
  • Service has no Endpoints -> distinguish between ‘wrong selector’ and ‘Pod not Ready’
  • Node Ready / MemoryPressure / DiskPressure / PIDPressure

For Agent workflows, this output format is easier to consume for the next action than directly throwing a kubectl describe.

Known Boundaries

  • Only implements deep diagnosis for Pod / Workloads / Service / Node; other resources fall back to kubectl describe.
  • Exec and port-forward are not implemented yet; YAML save goes via kubectl apply, only appears when allowWrites: true, and requires panel confirmation.
  • When a cluster is unreachable, the tool returns ‘Cluster Unreachable + Server Address + Next Steps’, not kubectl’s original stack trace.

Applicable Scenarios and Notes

Suitable for teams already using DSH Web GUI who want Agents to directly read cluster status for decision-making, especially with a small number of clusters and an existing kubectl environment. The diagnostic tools are targeted at Pod / Service / Node, while other resources are just describe forwards; don’t expect full audit capabilities.

Before installation, note two points as usual: The plugin runs with the permissions of the current dsh process, equivalent to the process being able to access all clusters in your configured kubeconfig. So review the source code (listed in the repo file list: index.js, kube.js, diagnose.js, cordis.patch.yml, etc.) and the MIT license before installing.

Also confirm that the host’s kubectl location is usable. Rancher Desktop users can explicitly configure kubectlPath if it’s not in PATH.

The project is still early; star count on the public repo is low. It is mainly maintained by the author personally, and issues tend to be reported in the repository Issues.

Conclusion

The value of dsh-kube-lens lies in combining ‘viewing clusters in the browser’ and ‘Agents reading clusters to diagnose’ into one place, and doing only one thing—using kubectl’s existing credential handling capabilities to make read-only browsing thorough, and narrowing write operations to explicit switches plus sequential approval.

Directory page: https://www.skillhub.cn/plugins/atticuswx/dsh-kube-lens
Source code: https://github.com/atticuswx/dsh-kube-lens

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye