kx-cli 0.0.8__tar.gz → 0.0.10__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kx_cli-0.0.8/src/kx_cli.egg-info → kx_cli-0.0.10}/PKG-INFO +51 -65
- {kx_cli-0.0.8 → kx_cli-0.0.10}/README.md +50 -64
- {kx_cli-0.0.8 → kx_cli-0.0.10}/pyproject.toml +1 -1
- kx_cli-0.0.10/src/kx/commands/_metadata.py +16 -0
- kx_cli-0.0.10/src/kx/commands/annotations.py +12 -0
- kx_cli-0.0.10/src/kx/commands/context.py +13 -0
- kx_cli-0.0.10/src/kx/commands/contexts.py +28 -0
- kx_cli-0.0.10/src/kx/commands/diagnostic.py +396 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/events.py +16 -9
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/labels.py +2 -6
- kx_cli-0.0.10/src/kx/commands/metadata_write.py +54 -0
- kx_cli-0.0.10/src/kx/commands/scan.py +122 -0
- kx_cli-0.0.10/src/kx/commands/top.py +131 -0
- kx_cli-0.0.10/src/kx/commands/yaml.py +43 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/config.py +7 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/console.py +202 -57
- kx_cli-0.0.10/src/kx/diagnostics.py +738 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/events.py +16 -1
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/graph.py +36 -4
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/index.py +20 -0
- kx_cli-0.0.10/src/kx/kubectl.py +64 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/main.py +244 -19
- kx_cli-0.0.10/src/kx/scanner.py +99 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/state.py +30 -7
- {kx_cli-0.0.8 → kx_cli-0.0.10/src/kx_cli.egg-info}/PKG-INFO +51 -65
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx_cli.egg-info/SOURCES.txt +20 -0
- kx_cli-0.0.10/tests/test_annotations.py +54 -0
- kx_cli-0.0.10/tests/test_cli_context.py +54 -0
- kx_cli-0.0.10/tests/test_cli_label_annotate.py +57 -0
- kx_cli-0.0.10/tests/test_cli_top.py +81 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_config.py +34 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_console.py +283 -15
- kx_cli-0.0.10/tests/test_context.py +49 -0
- kx_cli-0.0.10/tests/test_contexts.py +58 -0
- kx_cli-0.0.10/tests/test_diagnostic.py +838 -0
- kx_cli-0.0.10/tests/test_diagnostics.py +1165 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_events.py +37 -11
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_index.py +44 -0
- kx_cli-0.0.10/tests/test_kubectl.py +87 -0
- kx_cli-0.0.10/tests/test_metadata_helper.py +56 -0
- kx_cli-0.0.10/tests/test_metadata_write.py +112 -0
- kx_cli-0.0.10/tests/test_scan.py +358 -0
- kx_cli-0.0.10/tests/test_scanner.py +114 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_state.py +59 -0
- kx_cli-0.0.10/tests/test_top.py +234 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_yaml.py +22 -0
- kx_cli-0.0.8/src/kx/commands/diagnostic.py +0 -195
- kx_cli-0.0.8/src/kx/commands/yaml.py +0 -32
- kx_cli-0.0.8/src/kx/diagnostics.py +0 -363
- kx_cli-0.0.8/src/kx/kubectl.py +0 -39
- kx_cli-0.0.8/tests/test_diagnostic.py +0 -241
- kx_cli-0.0.8/tests/test_diagnostics.py +0 -415
- {kx_cli-0.0.8 → kx_cli-0.0.10}/LICENSE +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/setup.cfg +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/__init__.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/__init__.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/back.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/delete.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/describe.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/drop.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/edit.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/exec.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/forward.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/get.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/logs.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/namespace.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/port_forward.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/rollout.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/scale.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/state.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/theme.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/commands/tree.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/errors.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/k8s.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/kinds.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/refresh.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/themes.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx/types.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx_cli.egg-info/dependency_links.txt +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx_cli.egg-info/entry_points.txt +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx_cli.egg-info/requires.txt +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/src/kx_cli.egg-info/top_level.txt +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_back.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_cli_get.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_cli_help.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_cli_kind_alias.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_delete.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_describe.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_drop.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_edit.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_error_handling.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_exec.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_forward.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_get.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_graph.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_kinds.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_labels.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_logs.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_namespace.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_port_forward.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_refresh.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_rollout.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_scale.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_theme.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_themes.py +0 -0
- {kx_cli-0.0.8 → kx_cli-0.0.10}/tests/test_tree.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kx-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.10
|
|
4
4
|
Summary: kubectl wrapper with index-based resource selection
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.11
|
|
@@ -70,7 +70,7 @@ With pip:
|
|
|
70
70
|
pip install kx-cli
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
As a kubectl plugin via [krew](https://krew.sigs.k8s.io/), where kx is published as `idx` (no Python required
|
|
73
|
+
As a kubectl plugin via [krew](https://krew.sigs.k8s.io/), where kx is published as `idx` (no Python required):
|
|
74
74
|
|
|
75
75
|
```bash
|
|
76
76
|
kubectl krew install idx
|
|
@@ -88,26 +88,9 @@ pipx run --spec kx-cli kx get pods
|
|
|
88
88
|
|
|
89
89
|
## Usage
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
`kx get <resource>` fetches resources and assigns each row an index; every other command takes those indexes. Extra flags pass through to kubectl (`-n <namespace>`, selectors, ...), and `--match`/`-m` filters rows by name substring. All-namespace listings (`-A`) are display-only — names aren't unique across namespaces.
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
kx get <resource> [--match|-m <substring>] [kubectl flags...]
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Fetches resources and assigns index numbers. Any extra flags (e.g. `-n <namespace>`, `-A`) are passed through to kubectl. Use `--match`/`-m` to filter results by name (substring, case-insensitive). All-namespace listings (`-A`) are display-only — rows aren't indexed, since names aren't unique across namespaces; scope to a namespace to select.
|
|
98
|
-
|
|
99
|
-
Known kinds can drop the `get`: `kx pods`, `kx deploy -n kube-system`, `kx svc --match api`. This covers the built-in kinds and their kubectl shorthands (`po`, `deploy`, `svc`, `sts`, ...); existing commands take precedence, so `kx ns 3` still switches namespaces (bare `kx ns` lists them). CRDs and other resource types still use `kx get <resource>`. An integer after a kind is an index into the current state: `kx po 3` (or `kx get po 3`) relists just that pod, erroring if index 3 isn't a pod. Multiple indexes work too: `kx po 1 3`.
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
$ kx get pods
|
|
103
|
-
Pods · default · 3 items
|
|
104
|
-
X NAME READY STATUS RESTARTS AGE
|
|
105
|
-
1 api-7d9f4b8c6-xkp2q 1/1 Running 0 2d
|
|
106
|
-
2 worker-6c8b5f7d9-mnt4r 1/1 Running 3 5h
|
|
107
|
-
3 postgres-0 1/1 Running 0 12d
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
All subsequent commands reference resources by their `X` index from the last `kx get`.
|
|
93
|
+
Known kinds can drop the `get`: `kx pods`, `kx deploy -n kube-system`, `kx svc --match api` — kubectl shorthands (`po`, `deploy`, `svc`, `sts`, ...) included. An integer after a kind relists just that index: `kx po 3`. CRDs and other resource types still use `kx get <resource>`.
|
|
111
94
|
|
|
112
95
|
Global flags: `--no-color` disables styled output, `-v`/`--version` prints the installed version, and `--help` on any command shows usage, examples, and aliases.
|
|
113
96
|
|
|
@@ -117,10 +100,15 @@ Global flags: `--no-color` disables styled output, `-v`/`--version` prints the i
|
|
|
117
100
|
| Command | Description |
|
|
118
101
|
|---|---|
|
|
119
102
|
| `kx get <resource> [--match/-m str] [kubectl flags...]` | List resources and assign index numbers for use with other commands; shorthand: kx <kind> (e.g. kx pods, kx po 3). |
|
|
103
|
+
| `kx top [--match/-m str] [--no-limits] [kubectl flags...]` | List CPU/memory usage for pods in the current namespace and assign index numbers, like kx get; shows usage as a percent of each pod's resource limits unless --no-limits. |
|
|
120
104
|
| `kx describe <indexes>... [kubectl flags...]` | Show full kubectl describe output for one or more indexed resources. |
|
|
121
105
|
| `kx events <indexes>...` | Show Kubernetes events for one or more indexed resources. |
|
|
122
106
|
| `kx logs <index> [kubectl flags...]` | Stream logs for an indexed resource; aggregates across pods for Deployments, StatefulSets, DaemonSets, and Services. |
|
|
107
|
+
| `kx scan [<index>] [--engine str] [--full] [kubectl flags...]` | Scan the unique container images of an indexed workload for vulnerabilities, or the whole namespace when no index is given; prints a severity summary table by default, or the raw scanner output with --full. |
|
|
123
108
|
| `kx labels <indexes>... [--selector/-s]` | Show labels for one or more indexed resources; --selector formats output as a label selector. |
|
|
109
|
+
| `kx annotations <indexes>...` | Show annotations for one or more indexed resources. |
|
|
110
|
+
| `kx label <index> [<pairs>...] [--remove str] [--overwrite]` | Set or remove labels on an indexed resource. |
|
|
111
|
+
| `kx annotate <index> [<pairs>...] [--remove str] [--overwrite]` | Set or remove annotations on an indexed resource. |
|
|
124
112
|
| `kx yaml <indexes>... [--show str]` | Print the raw YAML manifest for one or more indexed resources; --show filters to specific top-level fields. |
|
|
125
113
|
| `kx delete <indexes>... [--yes/-y]` | Delete one or more indexed resources (prompts for confirmation unless --yes). |
|
|
126
114
|
| `kx edit <index> [kubectl flags...]` | Open an indexed resource in your editor via kubectl edit. |
|
|
@@ -129,8 +117,9 @@ Global flags: `--no-color` disables styled output, `-v`/`--version` prints the i
|
|
|
129
117
|
| `kx rollout <action> <index>` | Run a rollout action (status, restart, pause, resume, history, undo) on a Deployment, StatefulSet, or DaemonSet. |
|
|
130
118
|
| `kx scale <index> <replicas>` | Scale an indexed Deployment, StatefulSet, or ReplicaSet to a given replica count. |
|
|
131
119
|
| `kx port-forward <index> <port> [kubectl flags...]` | Forward a local port to an indexed resource (Pod, Deployment, ReplicaSet, StatefulSet, DaemonSet, Service). |
|
|
132
|
-
| `kx diagnostic <index
|
|
120
|
+
| `kx diagnostic [<index>]` | Diagnose an indexed Deployment, StatefulSet, DaemonSet, Job, CronJob, Service, PersistentVolumeClaim, or Pod, or triage the whole namespace when no index is given; alias: kx diag. |
|
|
133
121
|
| `kx namespace [<index>]` | List namespaces, or switch to an indexed one; alias: kx ns. |
|
|
122
|
+
| `kx context [<index>]` | List kubeconfig contexts, or switch to an indexed one; alias: kx contexts. |
|
|
134
123
|
| `kx theme [<name>]` | List available color themes or persist a choice by name or index. |
|
|
135
124
|
| `kx state [<position>] [--all/-a]` | Show current state, jump to a history position, or list all entries with --all. |
|
|
136
125
|
| `kx drop <position>` | Remove a history entry by position (shown in kx state --all). |
|
|
@@ -138,48 +127,41 @@ Global flags: `--no-color` disables styled output, `-v`/`--version` prints the i
|
|
|
138
127
|
| `kx forward` | Navigate to the next kx get result. |
|
|
139
128
|
<!-- commands-table-end -->
|
|
140
129
|
|
|
141
|
-
###
|
|
130
|
+
### Triage a namespace
|
|
142
131
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
kx
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
kx events 2
|
|
150
|
-
|
|
151
|
-
# drill into a pod
|
|
152
|
-
kx get pods
|
|
153
|
-
kx logs 1
|
|
154
|
-
kx exec 1 # opens bash/sh
|
|
155
|
-
kx exec 1 -- env # run a specific command
|
|
156
|
-
|
|
157
|
-
# forward local port 8080 to port 80 on a service
|
|
158
|
-
kx get services
|
|
159
|
-
kx port-forward 2 8080:80
|
|
160
|
-
|
|
161
|
-
# navigate history after multiple gets
|
|
162
|
-
kx get pods
|
|
163
|
-
kx get deployments
|
|
164
|
-
kx logs 1 # logs from pod index 1
|
|
165
|
-
kx state --all # review full history
|
|
166
|
-
|
|
167
|
-
# clean up
|
|
168
|
-
kx delete 3
|
|
169
|
-
```
|
|
132
|
+
Bare `kx diag` sweeps the current namespace — Deployments, StatefulSets,
|
|
133
|
+
DaemonSets, Jobs, CronJobs, Services, and PersistentVolumeClaims, plus pods
|
|
134
|
+
nothing owns — and prints a ranked table of what's unhealthy. Findings also
|
|
135
|
+
draw on live resource usage (`kx top`): a pod running hot against its memory
|
|
136
|
+
limit is flagged as an OOMKill risk before it dies. The rows are indexed, so
|
|
137
|
+
`kx diag 1` or `kx logs 2` drill straight in.
|
|
170
138
|
|
|
171
|
-
|
|
139
|
+
<div align="center">
|
|
140
|
+
<img src="https://raw.githubusercontent.com/jzills/kx/main/demo/diag.gif" alt="kx diag demo" width="800"/>
|
|
141
|
+
</div>
|
|
172
142
|
|
|
173
|
-
`kx
|
|
143
|
+
`kx diag <index>` diagnoses a single resource: a verdict banner, a `SUMMARY`
|
|
144
|
+
of findings (CrashLoopBackOff, image pull failures, OOMKills, unschedulable
|
|
145
|
+
pods, stalled rollouts, missing Service endpoints, Pending PVCs, failed
|
|
146
|
+
CronJob runs, usage near limits), a per-pod status table, recent log tails
|
|
147
|
+
from broken containers, and warning events — one screen instead of four
|
|
148
|
+
kubectl commands.
|
|
174
149
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
150
|
+
### Scan images for vulnerabilities
|
|
151
|
+
|
|
152
|
+
`kx scan <index>` scans the unique container images of an indexed workload
|
|
153
|
+
(init containers and CronJob job templates included); bare `kx scan` sweeps
|
|
154
|
+
every workload in the namespace. Results come back as a severity summary,
|
|
155
|
+
or the full per-image CVE report with `--full`. Requires
|
|
156
|
+
[Docker Scout](https://docs.docker.com/scout/).
|
|
157
|
+
|
|
158
|
+
<div align="center">
|
|
159
|
+
<img src="https://raw.githubusercontent.com/jzills/kx/main/demo/scan.gif" alt="kx scan demo" width="800"/>
|
|
160
|
+
</div>
|
|
161
|
+
|
|
162
|
+
## State
|
|
181
163
|
|
|
182
|
-
|
|
164
|
+
`kx` maintains a history of up to 10 `kx get` results in `~/.kx/state.json`. A cursor tracks your current position; index-based commands always resolve against the entry at the cursor. `kx state --all` lists the history, `kx state <position>` jumps to an entry, `kx back`/`kx forward` step through it, and `kx drop <position>` removes one.
|
|
183
165
|
|
|
184
166
|
## Configuration
|
|
185
167
|
|
|
@@ -194,13 +176,13 @@ Use `kx state <position>` to jump directly to any history entry, and `kx drop <p
|
|
|
194
176
|
|
|
195
177
|
Styled output is emitted only when stdout is a terminal — piped or redirected output is plain text, so `kx get pods | grep worker` stays clean. The [`NO_COLOR`](https://no-color.org/) convention is honored as well.
|
|
196
178
|
|
|
197
|
-
|
|
179
|
+
## Themes
|
|
198
180
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
kx
|
|
203
|
-
|
|
181
|
+
`kx theme` lists the available themes with a preview of each; `kx theme <name|index>` persists a choice to `~/.kx/config.toml`.
|
|
182
|
+
|
|
183
|
+
<div align="center">
|
|
184
|
+
<img src="https://raw.githubusercontent.com/jzills/kx/main/demo/theme.gif" alt="kx theme demo" width="800"/>
|
|
185
|
+
</div>
|
|
204
186
|
|
|
205
187
|
Prefab themes: `github-dark` (default), `dracula`, `nord`, `gruvbox`, `solarized-dark`, `catppuccin-mocha`, `tokyo-night`, `rose-pine`, `mono`, `light` (for light terminal backgrounds), and `plain` (no styling at all).
|
|
206
188
|
|
|
@@ -217,3 +199,7 @@ Run the CLI directly:
|
|
|
217
199
|
```bash
|
|
218
200
|
python -m kx.main --help
|
|
219
201
|
```
|
|
202
|
+
|
|
203
|
+
The demo GIFs are rendered from [VHS](https://github.com/charmbracelet/vhs)
|
|
204
|
+
tapes — see [`demo/README.md`](demo/README.md) for seeding the demo namespace
|
|
205
|
+
and re-recording.
|
|
@@ -47,7 +47,7 @@ With pip:
|
|
|
47
47
|
pip install kx-cli
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
As a kubectl plugin via [krew](https://krew.sigs.k8s.io/), where kx is published as `idx` (no Python required
|
|
50
|
+
As a kubectl plugin via [krew](https://krew.sigs.k8s.io/), where kx is published as `idx` (no Python required):
|
|
51
51
|
|
|
52
52
|
```bash
|
|
53
53
|
kubectl krew install idx
|
|
@@ -65,26 +65,9 @@ pipx run --spec kx-cli kx get pods
|
|
|
65
65
|
|
|
66
66
|
## Usage
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
`kx get <resource>` fetches resources and assigns each row an index; every other command takes those indexes. Extra flags pass through to kubectl (`-n <namespace>`, selectors, ...), and `--match`/`-m` filters rows by name substring. All-namespace listings (`-A`) are display-only — names aren't unique across namespaces.
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
kx get <resource> [--match|-m <substring>] [kubectl flags...]
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Fetches resources and assigns index numbers. Any extra flags (e.g. `-n <namespace>`, `-A`) are passed through to kubectl. Use `--match`/`-m` to filter results by name (substring, case-insensitive). All-namespace listings (`-A`) are display-only — rows aren't indexed, since names aren't unique across namespaces; scope to a namespace to select.
|
|
75
|
-
|
|
76
|
-
Known kinds can drop the `get`: `kx pods`, `kx deploy -n kube-system`, `kx svc --match api`. This covers the built-in kinds and their kubectl shorthands (`po`, `deploy`, `svc`, `sts`, ...); existing commands take precedence, so `kx ns 3` still switches namespaces (bare `kx ns` lists them). CRDs and other resource types still use `kx get <resource>`. An integer after a kind is an index into the current state: `kx po 3` (or `kx get po 3`) relists just that pod, erroring if index 3 isn't a pod. Multiple indexes work too: `kx po 1 3`.
|
|
77
|
-
|
|
78
|
-
```
|
|
79
|
-
$ kx get pods
|
|
80
|
-
Pods · default · 3 items
|
|
81
|
-
X NAME READY STATUS RESTARTS AGE
|
|
82
|
-
1 api-7d9f4b8c6-xkp2q 1/1 Running 0 2d
|
|
83
|
-
2 worker-6c8b5f7d9-mnt4r 1/1 Running 3 5h
|
|
84
|
-
3 postgres-0 1/1 Running 0 12d
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
All subsequent commands reference resources by their `X` index from the last `kx get`.
|
|
70
|
+
Known kinds can drop the `get`: `kx pods`, `kx deploy -n kube-system`, `kx svc --match api` — kubectl shorthands (`po`, `deploy`, `svc`, `sts`, ...) included. An integer after a kind relists just that index: `kx po 3`. CRDs and other resource types still use `kx get <resource>`.
|
|
88
71
|
|
|
89
72
|
Global flags: `--no-color` disables styled output, `-v`/`--version` prints the installed version, and `--help` on any command shows usage, examples, and aliases.
|
|
90
73
|
|
|
@@ -94,10 +77,15 @@ Global flags: `--no-color` disables styled output, `-v`/`--version` prints the i
|
|
|
94
77
|
| Command | Description |
|
|
95
78
|
|---|---|
|
|
96
79
|
| `kx get <resource> [--match/-m str] [kubectl flags...]` | List resources and assign index numbers for use with other commands; shorthand: kx <kind> (e.g. kx pods, kx po 3). |
|
|
80
|
+
| `kx top [--match/-m str] [--no-limits] [kubectl flags...]` | List CPU/memory usage for pods in the current namespace and assign index numbers, like kx get; shows usage as a percent of each pod's resource limits unless --no-limits. |
|
|
97
81
|
| `kx describe <indexes>... [kubectl flags...]` | Show full kubectl describe output for one or more indexed resources. |
|
|
98
82
|
| `kx events <indexes>...` | Show Kubernetes events for one or more indexed resources. |
|
|
99
83
|
| `kx logs <index> [kubectl flags...]` | Stream logs for an indexed resource; aggregates across pods for Deployments, StatefulSets, DaemonSets, and Services. |
|
|
84
|
+
| `kx scan [<index>] [--engine str] [--full] [kubectl flags...]` | Scan the unique container images of an indexed workload for vulnerabilities, or the whole namespace when no index is given; prints a severity summary table by default, or the raw scanner output with --full. |
|
|
100
85
|
| `kx labels <indexes>... [--selector/-s]` | Show labels for one or more indexed resources; --selector formats output as a label selector. |
|
|
86
|
+
| `kx annotations <indexes>...` | Show annotations for one or more indexed resources. |
|
|
87
|
+
| `kx label <index> [<pairs>...] [--remove str] [--overwrite]` | Set or remove labels on an indexed resource. |
|
|
88
|
+
| `kx annotate <index> [<pairs>...] [--remove str] [--overwrite]` | Set or remove annotations on an indexed resource. |
|
|
101
89
|
| `kx yaml <indexes>... [--show str]` | Print the raw YAML manifest for one or more indexed resources; --show filters to specific top-level fields. |
|
|
102
90
|
| `kx delete <indexes>... [--yes/-y]` | Delete one or more indexed resources (prompts for confirmation unless --yes). |
|
|
103
91
|
| `kx edit <index> [kubectl flags...]` | Open an indexed resource in your editor via kubectl edit. |
|
|
@@ -106,8 +94,9 @@ Global flags: `--no-color` disables styled output, `-v`/`--version` prints the i
|
|
|
106
94
|
| `kx rollout <action> <index>` | Run a rollout action (status, restart, pause, resume, history, undo) on a Deployment, StatefulSet, or DaemonSet. |
|
|
107
95
|
| `kx scale <index> <replicas>` | Scale an indexed Deployment, StatefulSet, or ReplicaSet to a given replica count. |
|
|
108
96
|
| `kx port-forward <index> <port> [kubectl flags...]` | Forward a local port to an indexed resource (Pod, Deployment, ReplicaSet, StatefulSet, DaemonSet, Service). |
|
|
109
|
-
| `kx diagnostic <index
|
|
97
|
+
| `kx diagnostic [<index>]` | Diagnose an indexed Deployment, StatefulSet, DaemonSet, Job, CronJob, Service, PersistentVolumeClaim, or Pod, or triage the whole namespace when no index is given; alias: kx diag. |
|
|
110
98
|
| `kx namespace [<index>]` | List namespaces, or switch to an indexed one; alias: kx ns. |
|
|
99
|
+
| `kx context [<index>]` | List kubeconfig contexts, or switch to an indexed one; alias: kx contexts. |
|
|
111
100
|
| `kx theme [<name>]` | List available color themes or persist a choice by name or index. |
|
|
112
101
|
| `kx state [<position>] [--all/-a]` | Show current state, jump to a history position, or list all entries with --all. |
|
|
113
102
|
| `kx drop <position>` | Remove a history entry by position (shown in kx state --all). |
|
|
@@ -115,48 +104,41 @@ Global flags: `--no-color` disables styled output, `-v`/`--version` prints the i
|
|
|
115
104
|
| `kx forward` | Navigate to the next kx get result. |
|
|
116
105
|
<!-- commands-table-end -->
|
|
117
106
|
|
|
118
|
-
###
|
|
107
|
+
### Triage a namespace
|
|
119
108
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
kx
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
kx events 2
|
|
127
|
-
|
|
128
|
-
# drill into a pod
|
|
129
|
-
kx get pods
|
|
130
|
-
kx logs 1
|
|
131
|
-
kx exec 1 # opens bash/sh
|
|
132
|
-
kx exec 1 -- env # run a specific command
|
|
133
|
-
|
|
134
|
-
# forward local port 8080 to port 80 on a service
|
|
135
|
-
kx get services
|
|
136
|
-
kx port-forward 2 8080:80
|
|
137
|
-
|
|
138
|
-
# navigate history after multiple gets
|
|
139
|
-
kx get pods
|
|
140
|
-
kx get deployments
|
|
141
|
-
kx logs 1 # logs from pod index 1
|
|
142
|
-
kx state --all # review full history
|
|
143
|
-
|
|
144
|
-
# clean up
|
|
145
|
-
kx delete 3
|
|
146
|
-
```
|
|
109
|
+
Bare `kx diag` sweeps the current namespace — Deployments, StatefulSets,
|
|
110
|
+
DaemonSets, Jobs, CronJobs, Services, and PersistentVolumeClaims, plus pods
|
|
111
|
+
nothing owns — and prints a ranked table of what's unhealthy. Findings also
|
|
112
|
+
draw on live resource usage (`kx top`): a pod running hot against its memory
|
|
113
|
+
limit is flagged as an OOMKill risk before it dies. The rows are indexed, so
|
|
114
|
+
`kx diag 1` or `kx logs 2` drill straight in.
|
|
147
115
|
|
|
148
|
-
|
|
116
|
+
<div align="center">
|
|
117
|
+
<img src="https://raw.githubusercontent.com/jzills/kx/main/demo/diag.gif" alt="kx diag demo" width="800"/>
|
|
118
|
+
</div>
|
|
149
119
|
|
|
150
|
-
`kx
|
|
120
|
+
`kx diag <index>` diagnoses a single resource: a verdict banner, a `SUMMARY`
|
|
121
|
+
of findings (CrashLoopBackOff, image pull failures, OOMKills, unschedulable
|
|
122
|
+
pods, stalled rollouts, missing Service endpoints, Pending PVCs, failed
|
|
123
|
+
CronJob runs, usage near limits), a per-pod status table, recent log tails
|
|
124
|
+
from broken containers, and warning events — one screen instead of four
|
|
125
|
+
kubectl commands.
|
|
151
126
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
127
|
+
### Scan images for vulnerabilities
|
|
128
|
+
|
|
129
|
+
`kx scan <index>` scans the unique container images of an indexed workload
|
|
130
|
+
(init containers and CronJob job templates included); bare `kx scan` sweeps
|
|
131
|
+
every workload in the namespace. Results come back as a severity summary,
|
|
132
|
+
or the full per-image CVE report with `--full`. Requires
|
|
133
|
+
[Docker Scout](https://docs.docker.com/scout/).
|
|
134
|
+
|
|
135
|
+
<div align="center">
|
|
136
|
+
<img src="https://raw.githubusercontent.com/jzills/kx/main/demo/scan.gif" alt="kx scan demo" width="800"/>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
## State
|
|
158
140
|
|
|
159
|
-
|
|
141
|
+
`kx` maintains a history of up to 10 `kx get` results in `~/.kx/state.json`. A cursor tracks your current position; index-based commands always resolve against the entry at the cursor. `kx state --all` lists the history, `kx state <position>` jumps to an entry, `kx back`/`kx forward` step through it, and `kx drop <position>` removes one.
|
|
160
142
|
|
|
161
143
|
## Configuration
|
|
162
144
|
|
|
@@ -171,13 +153,13 @@ Use `kx state <position>` to jump directly to any history entry, and `kx drop <p
|
|
|
171
153
|
|
|
172
154
|
Styled output is emitted only when stdout is a terminal — piped or redirected output is plain text, so `kx get pods | grep worker` stays clean. The [`NO_COLOR`](https://no-color.org/) convention is honored as well.
|
|
173
155
|
|
|
174
|
-
|
|
156
|
+
## Themes
|
|
175
157
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
kx
|
|
180
|
-
|
|
158
|
+
`kx theme` lists the available themes with a preview of each; `kx theme <name|index>` persists a choice to `~/.kx/config.toml`.
|
|
159
|
+
|
|
160
|
+
<div align="center">
|
|
161
|
+
<img src="https://raw.githubusercontent.com/jzills/kx/main/demo/theme.gif" alt="kx theme demo" width="800"/>
|
|
162
|
+
</div>
|
|
181
163
|
|
|
182
164
|
Prefab themes: `github-dark` (default), `dracula`, `nord`, `gruvbox`, `solarized-dark`, `catppuccin-mocha`, `tokyo-night`, `rose-pine`, `mono`, `light` (for light terminal backgrounds), and `plain` (no styling at all).
|
|
183
165
|
|
|
@@ -194,3 +176,7 @@ Run the CLI directly:
|
|
|
194
176
|
```bash
|
|
195
177
|
python -m kx.main --help
|
|
196
178
|
```
|
|
179
|
+
|
|
180
|
+
The demo GIFs are rendered from [VHS](https://github.com/charmbracelet/vhs)
|
|
181
|
+
tapes — see [`demo/README.md`](demo/README.md) for seeding the demo namespace
|
|
182
|
+
and re-recording.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import json
|
|
2
|
+
|
|
3
|
+
from kx.kubectl import KubectlServiceProtocol
|
|
4
|
+
from kx.state import StateServiceProtocol
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def fetch_metadata_field(
|
|
8
|
+
kubectl: KubectlServiceProtocol,
|
|
9
|
+
state: StateServiceProtocol,
|
|
10
|
+
index: int,
|
|
11
|
+
field: str,
|
|
12
|
+
) -> dict[str, str]:
|
|
13
|
+
name, namespace, kind = state.fields(index)
|
|
14
|
+
raw = kubectl.run(["get", kind, name, "-n", namespace, "-o", "json"])
|
|
15
|
+
obj = json.loads(raw)
|
|
16
|
+
return obj.get("metadata", {}).get(field) or {}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from kx.commands._metadata import fetch_metadata_field
|
|
2
|
+
from kx.kubectl import KubectlServiceProtocol
|
|
3
|
+
from kx.state import StateServiceProtocol
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AnnotationsCommand:
|
|
7
|
+
def __init__(self, state: StateServiceProtocol, kubectl: KubectlServiceProtocol):
|
|
8
|
+
self.state = state
|
|
9
|
+
self.kubectl = kubectl
|
|
10
|
+
|
|
11
|
+
def execute(self, index: int) -> dict[str, str]:
|
|
12
|
+
return fetch_metadata_field(self.kubectl, self.state, index, "annotations")
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from kx.kubectl import KubectlServiceProtocol
|
|
2
|
+
from kx.state import StateServiceProtocol
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ContextCommand:
|
|
6
|
+
def __init__(self, state: StateServiceProtocol, kubectl: KubectlServiceProtocol):
|
|
7
|
+
self.state = state
|
|
8
|
+
self.kubectl = kubectl
|
|
9
|
+
|
|
10
|
+
def execute(self, index: int) -> str:
|
|
11
|
+
name, _, _ = self.state.fields(index)
|
|
12
|
+
self.kubectl.run(["config", "use-context", name])
|
|
13
|
+
return name
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
from kx.index import IndexServiceProtocol
|
|
2
|
+
from kx.kubectl import KubectlServiceProtocol
|
|
3
|
+
from kx.state import State, StateServiceProtocol
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ContextsCommand:
|
|
7
|
+
def __init__(
|
|
8
|
+
self,
|
|
9
|
+
kubectl: KubectlServiceProtocol,
|
|
10
|
+
state: StateServiceProtocol,
|
|
11
|
+
index: IndexServiceProtocol,
|
|
12
|
+
):
|
|
13
|
+
self.kubectl = kubectl
|
|
14
|
+
self.state = state
|
|
15
|
+
self.index = index
|
|
16
|
+
|
|
17
|
+
def execute(self) -> str:
|
|
18
|
+
output = self.kubectl.run(["config", "get-contexts"])
|
|
19
|
+
indexed_output, names = self.index.add(output)
|
|
20
|
+
if names:
|
|
21
|
+
current = self.kubectl.current_context()
|
|
22
|
+
self.state.save(
|
|
23
|
+
State(
|
|
24
|
+
resources={name: "Context" for name in names},
|
|
25
|
+
namespace=current,
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
return indexed_output
|