kubsome 1.0.0__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.
- kubsome-1.0.0/LICENSE +21 -0
- kubsome-1.0.0/MANIFEST.in +5 -0
- kubsome-1.0.0/PKG-INFO +186 -0
- kubsome-1.0.0/README.md +140 -0
- kubsome-1.0.0/api/__init__.py +0 -0
- kubsome-1.0.0/api/app.py +48 -0
- kubsome-1.0.0/api/routes/__init__.py +0 -0
- kubsome-1.0.0/api/routes/contexts.py +77 -0
- kubsome-1.0.0/api/routes/deployments.py +62 -0
- kubsome-1.0.0/api/routes/diagnostics.py +44 -0
- kubsome-1.0.0/api/routes/events.py +16 -0
- kubsome-1.0.0/api/routes/intelligence.py +63 -0
- kubsome-1.0.0/api/routes/logs.py +36 -0
- kubsome-1.0.0/api/routes/metrics.py +23 -0
- kubsome-1.0.0/api/routes/operations.py +279 -0
- kubsome-1.0.0/api/routes/overview.py +105 -0
- kubsome-1.0.0/api/routes/pods.py +16 -0
- kubsome-1.0.0/api/routes/terminal.py +182 -0
- kubsome-1.0.0/api/routes/ws.py +114 -0
- kubsome-1.0.0/api/serve.py +17 -0
- kubsome-1.0.0/config/__init__.py +0 -0
- kubsome-1.0.0/config/settings.py +3 -0
- kubsome-1.0.0/core/__init__.py +0 -0
- kubsome-1.0.0/core/ai/__init__.py +0 -0
- kubsome-1.0.0/core/ai/anomaly.py +227 -0
- kubsome-1.0.0/core/ai/correlation.py +124 -0
- kubsome-1.0.0/core/ai/engine.py +646 -0
- kubsome-1.0.0/core/ai/explain.py +180 -0
- kubsome-1.0.0/core/ai/generator.py +129 -0
- kubsome-1.0.0/core/ai/llm.py +102 -0
- kubsome-1.0.0/core/ai/nlp.py +120 -0
- kubsome-1.0.0/core/ai/playbooks.py +194 -0
- kubsome-1.0.0/core/ai/suggest.py +49 -0
- kubsome-1.0.0/core/analyzer.py +58 -0
- kubsome-1.0.0/core/audit.py +47 -0
- kubsome-1.0.0/core/banner.py +64 -0
- kubsome-1.0.0/core/bookmarks.py +59 -0
- kubsome-1.0.0/core/chaining.py +24 -0
- kubsome-1.0.0/core/collectors/__init__.py +0 -0
- kubsome-1.0.0/core/collectors/changes.py +217 -0
- kubsome-1.0.0/core/collectors/configs.py +81 -0
- kubsome-1.0.0/core/collectors/cost.py +318 -0
- kubsome-1.0.0/core/collectors/deployments.py +46 -0
- kubsome-1.0.0/core/collectors/diagnosis.py +27 -0
- kubsome-1.0.0/core/collectors/diff.py +178 -0
- kubsome-1.0.0/core/collectors/events.py +47 -0
- kubsome-1.0.0/core/collectors/image_pull.py +175 -0
- kubsome-1.0.0/core/collectors/inspect.py +173 -0
- kubsome-1.0.0/core/collectors/jobs.py +120 -0
- kubsome-1.0.0/core/collectors/labels.py +76 -0
- kubsome-1.0.0/core/collectors/logs.py +224 -0
- kubsome-1.0.0/core/collectors/metrics.py +119 -0
- kubsome-1.0.0/core/collectors/multicluster.py +97 -0
- kubsome-1.0.0/core/collectors/namespace.py +76 -0
- kubsome-1.0.0/core/collectors/network.py +145 -0
- kubsome-1.0.0/core/collectors/nodes.py +52 -0
- kubsome-1.0.0/core/collectors/pods.py +52 -0
- kubsome-1.0.0/core/collectors/rbac.py +94 -0
- kubsome-1.0.0/core/collectors/rollouts.py +133 -0
- kubsome-1.0.0/core/collectors/scaling.py +331 -0
- kubsome-1.0.0/core/collectors/search.py +66 -0
- kubsome-1.0.0/core/collectors/security.py +181 -0
- kubsome-1.0.0/core/collectors/services.py +293 -0
- kubsome-1.0.0/core/collectors/timeline.py +68 -0
- kubsome-1.0.0/core/collectors/trace.py +231 -0
- kubsome-1.0.0/core/commands.py +585 -0
- kubsome-1.0.0/core/completer.py +240 -0
- kubsome-1.0.0/core/config.py +98 -0
- kubsome-1.0.0/core/context.py +17 -0
- kubsome-1.0.0/core/context_formatter.py +38 -0
- kubsome-1.0.0/core/context_switcher.py +61 -0
- kubsome-1.0.0/core/diagnostics/__init__.py +0 -0
- kubsome-1.0.0/core/diagnostics/engine.py +260 -0
- kubsome-1.0.0/core/diagnostics/recommendations.py +38 -0
- kubsome-1.0.0/core/dispatcher.py +929 -0
- kubsome-1.0.0/core/executor.py +21 -0
- kubsome-1.0.0/core/export.py +150 -0
- kubsome-1.0.0/core/formatter.py +134 -0
- kubsome-1.0.0/core/health.py +75 -0
- kubsome-1.0.0/core/healthcheck.py +120 -0
- kubsome-1.0.0/core/history.py +12 -0
- kubsome-1.0.0/core/incident/__init__.py +0 -0
- kubsome-1.0.0/core/incident/manager.py +162 -0
- kubsome-1.0.0/core/insights.py +14 -0
- kubsome-1.0.0/core/k8s.py +67 -0
- kubsome-1.0.0/core/kubeconfig.py +79 -0
- kubsome-1.0.0/core/notify.py +60 -0
- kubsome-1.0.0/core/overview_formatter.py +162 -0
- kubsome-1.0.0/core/plugins.py +85 -0
- kubsome-1.0.0/core/pod_actions.py +135 -0
- kubsome-1.0.0/core/renderers/__init__.py +0 -0
- kubsome-1.0.0/core/renderers/ai_renderer.py +26 -0
- kubsome-1.0.0/core/renderers/anomaly_renderer.py +135 -0
- kubsome-1.0.0/core/renderers/changes_renderer.py +135 -0
- kubsome-1.0.0/core/renderers/compare_renderer.py +91 -0
- kubsome-1.0.0/core/renderers/cost_renderer.py +174 -0
- kubsome-1.0.0/core/renderers/diagnosis_renderer.py +110 -0
- kubsome-1.0.0/core/renderers/events_renderer.py +127 -0
- kubsome-1.0.0/core/renderers/help_renderer.py +165 -0
- kubsome-1.0.0/core/renderers/incident_renderer.py +92 -0
- kubsome-1.0.0/core/renderers/inspect_renderer.py +227 -0
- kubsome-1.0.0/core/renderers/logs_renderer.py +186 -0
- kubsome-1.0.0/core/renderers/metrics_renderer.py +136 -0
- kubsome-1.0.0/core/renderers/namespace_renderer.py +82 -0
- kubsome-1.0.0/core/renderers/ops_renderer.py +230 -0
- kubsome-1.0.0/core/renderers/rbac_renderer.py +135 -0
- kubsome-1.0.0/core/renderers/report_renderer.py +111 -0
- kubsome-1.0.0/core/renderers/rollout_renderer.py +123 -0
- kubsome-1.0.0/core/renderers/scaling_renderer.py +236 -0
- kubsome-1.0.0/core/renderers/search_renderer.py +59 -0
- kubsome-1.0.0/core/renderers/services_renderer.py +169 -0
- kubsome-1.0.0/core/renderers/trace_renderer.py +105 -0
- kubsome-1.0.0/core/renderers/workflow_renderer.py +68 -0
- kubsome-1.0.0/core/resolver.py +94 -0
- kubsome-1.0.0/core/safety.py +16 -0
- kubsome-1.0.0/core/selector.py +77 -0
- kubsome-1.0.0/core/spinner.py +17 -0
- kubsome-1.0.0/core/state.py +28 -0
- kubsome-1.0.0/core/theme.py +68 -0
- kubsome-1.0.0/core/watch_formatter.py +116 -0
- kubsome-1.0.0/core/workflows.py +112 -0
- kubsome-1.0.0/kubsome.egg-info/PKG-INFO +186 -0
- kubsome-1.0.0/kubsome.egg-info/SOURCES.txt +134 -0
- kubsome-1.0.0/kubsome.egg-info/dependency_links.txt +1 -0
- kubsome-1.0.0/kubsome.egg-info/entry_points.txt +2 -0
- kubsome-1.0.0/kubsome.egg-info/requires.txt +23 -0
- kubsome-1.0.0/kubsome.egg-info/top_level.txt +6 -0
- kubsome-1.0.0/main.py +296 -0
- kubsome-1.0.0/plugins/__init__.py +0 -0
- kubsome-1.0.0/plugins/example_health.py +27 -0
- kubsome-1.0.0/pyproject.toml +60 -0
- kubsome-1.0.0/requirements.txt +10 -0
- kubsome-1.0.0/setup.cfg +4 -0
- kubsome-1.0.0/tests/test_core.py +118 -0
- kubsome-1.0.0/tui/__init__.py +0 -0
- kubsome-1.0.0/tui/app.py +296 -0
kubsome-1.0.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Aloke Tewary
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
kubsome-1.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: kubsome
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: AI-native Kubernetes Operational Workspace
|
|
5
|
+
Author-email: Aloke Tewary <aloketewary@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/aloketewary/kubsome
|
|
8
|
+
Project-URL: Repository, https://github.com/aloketewary/kubsome
|
|
9
|
+
Project-URL: Issues, https://github.com/aloketewary/kubsome/issues
|
|
10
|
+
Keywords: kubernetes,k8s,cli,devops,operations,monitoring,diagnostics
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: System Administrators
|
|
15
|
+
Classifier: Topic :: System :: Systems Administration
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: rich>=13.0
|
|
27
|
+
Requires-Dist: prompt-toolkit>=3.0
|
|
28
|
+
Requires-Dist: questionary>=2.0
|
|
29
|
+
Requires-Dist: rapidfuzz>=3.0
|
|
30
|
+
Requires-Dist: humanize>=4.0
|
|
31
|
+
Requires-Dist: pyyaml>=6.0
|
|
32
|
+
Provides-Extra: tui
|
|
33
|
+
Requires-Dist: textual>=0.40; extra == "tui"
|
|
34
|
+
Provides-Extra: api
|
|
35
|
+
Requires-Dist: fastapi>=0.104.0; extra == "api"
|
|
36
|
+
Requires-Dist: uvicorn[standard]>=0.24.0; extra == "api"
|
|
37
|
+
Provides-Extra: all
|
|
38
|
+
Requires-Dist: textual>=0.40; extra == "all"
|
|
39
|
+
Requires-Dist: fastapi>=0.104.0; extra == "all"
|
|
40
|
+
Requires-Dist: uvicorn[standard]>=0.24.0; extra == "all"
|
|
41
|
+
Provides-Extra: dev
|
|
42
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
43
|
+
Requires-Dist: build; extra == "dev"
|
|
44
|
+
Requires-Dist: twine; extra == "dev"
|
|
45
|
+
Dynamic: license-file
|
|
46
|
+
|
|
47
|
+
# 🚀 Kubsome
|
|
48
|
+
|
|
49
|
+
**AI-native Kubernetes Operational Workspace**
|
|
50
|
+
|
|
51
|
+
Faster debugging. Safer operations. Less cognitive load.
|
|
52
|
+
|
|
53
|
+
## Install
|
|
54
|
+
|
|
55
|
+
### From PyPI (recommended)
|
|
56
|
+
```bash
|
|
57
|
+
pip install kubsome
|
|
58
|
+
kubsome init # Generate default config
|
|
59
|
+
kubsome # Start
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
With optional features:
|
|
63
|
+
```bash
|
|
64
|
+
pip install "kubsome[tui]" # + Full-screen TUI
|
|
65
|
+
pip install "kubsome[api]" # + REST API + Web UI
|
|
66
|
+
pip install "kubsome[all]" # Everything
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### From source
|
|
70
|
+
```bash
|
|
71
|
+
git clone https://github.com/aloketewary/kubsome.git && cd kubsome && ./install.sh
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Then:
|
|
75
|
+
```bash
|
|
76
|
+
source venv/bin/activate
|
|
77
|
+
kubsome
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Quick Start
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
kubsome # Interactive CLI
|
|
84
|
+
kubsome --exec "check" # Single command (CI/CD)
|
|
85
|
+
kubsome --exec "export json" # Generate report
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Commands (85+)
|
|
89
|
+
|
|
90
|
+
Type `help` inside Kubsome for the full list. Highlights:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Observe
|
|
94
|
+
overview # Cluster dashboard + anomaly alerts
|
|
95
|
+
pods # Pod list with health
|
|
96
|
+
pods watch # Live monitoring
|
|
97
|
+
top pods # CPU/memory usage
|
|
98
|
+
|
|
99
|
+
# Operate
|
|
100
|
+
logs payment # Fuzzy-match pod logs
|
|
101
|
+
logcat payment --follow # Combined logs from all replicas (logcat style)
|
|
102
|
+
rollout billing-api # Rollout status
|
|
103
|
+
restart gateway # Rolling restart
|
|
104
|
+
scale payment 5 # Scale replicas
|
|
105
|
+
|
|
106
|
+
# Diagnose
|
|
107
|
+
inspect customer # Deep pod inspection
|
|
108
|
+
diagnose payment # Root cause analysis + playbook
|
|
109
|
+
trace payment-api # Resource relationship map
|
|
110
|
+
netcheck auth # Network diagnostics
|
|
111
|
+
|
|
112
|
+
# AI (natural language)
|
|
113
|
+
why is payment-api failing # Root cause explanation
|
|
114
|
+
summarize cluster health # Health summary
|
|
115
|
+
which pods are unhealthy # Degraded pod list
|
|
116
|
+
any anomalies detected # Anomaly scan
|
|
117
|
+
what changed recently # Recent activity
|
|
118
|
+
|
|
119
|
+
# Security & Cost
|
|
120
|
+
security # Misconfiguration scan
|
|
121
|
+
optimize # Resource right-sizing
|
|
122
|
+
unused # Find orphaned resources
|
|
123
|
+
|
|
124
|
+
# Incident Mode
|
|
125
|
+
incident start API outage # Start tracking
|
|
126
|
+
note found OOM in payment # Add observation
|
|
127
|
+
incident stop # Close & export report
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Features
|
|
131
|
+
|
|
132
|
+
- **Fuzzy matching** — type partial names, Kubsome finds the resource
|
|
133
|
+
- **Smart suggestions** — typo correction ("Did you mean: pods")
|
|
134
|
+
- **Natural language** — "show me logs for payment" just works
|
|
135
|
+
- **Command chaining** — `pods && events && alerts`
|
|
136
|
+
- **Aliases** — `p`=pods, `o`=overview, `d`=diagnose, `l`=logs
|
|
137
|
+
- **Bookmarks** — save and recall frequent commands
|
|
138
|
+
- **Workflows** — chain commands into reusable sequences
|
|
139
|
+
- **Watch mode** — `watch <any-command>` for live refresh
|
|
140
|
+
- **Logcat** — combined logs from all pods of a deployment
|
|
141
|
+
- **Playbooks** — step-by-step remediation guides
|
|
142
|
+
- **Anomaly detection** — restart spikes, event storms, cascading failures
|
|
143
|
+
- **Multi-cluster compare** — drift detection between environments
|
|
144
|
+
- **Export** — Markdown/JSON reports for sharing
|
|
145
|
+
- **Audit log** — tracks all destructive operations
|
|
146
|
+
- **Desktop notifications** — alerts for critical issues
|
|
147
|
+
- **Plugin system** — extend with custom commands
|
|
148
|
+
- **Persistent history** — command recall across sessions
|
|
149
|
+
- **Production safety** — confirmation prompts for dangerous actions
|
|
150
|
+
|
|
151
|
+
## Requirements
|
|
152
|
+
|
|
153
|
+
- Python 3.9+
|
|
154
|
+
- kubectl configured with cluster access
|
|
155
|
+
- metrics-server (for `top` commands)
|
|
156
|
+
|
|
157
|
+
## Configuration
|
|
158
|
+
|
|
159
|
+
Settings in `~/.kubsome/config.yaml`:
|
|
160
|
+
```yaml
|
|
161
|
+
refresh_interval: 2
|
|
162
|
+
notifications: true
|
|
163
|
+
theme: dark # dark, light, minimal, hacker
|
|
164
|
+
aliases:
|
|
165
|
+
p: pods
|
|
166
|
+
o: overview
|
|
167
|
+
d: diagnose
|
|
168
|
+
llm:
|
|
169
|
+
provider: local # or: ollama (for AI-powered explain)
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## Architecture
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
main.py → 150 lines, clean entry point
|
|
176
|
+
core/dispatcher.py → Command handler registry
|
|
177
|
+
core/ai/ → 8 intelligence modules
|
|
178
|
+
core/collectors/ → 24 data collectors
|
|
179
|
+
core/renderers/ → 21 presentation renderers
|
|
180
|
+
core/diagnostics/ → Root cause engine
|
|
181
|
+
100 Python files → Complete operational platform
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## License
|
|
185
|
+
|
|
186
|
+
MIT
|
kubsome-1.0.0/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# 🚀 Kubsome
|
|
2
|
+
|
|
3
|
+
**AI-native Kubernetes Operational Workspace**
|
|
4
|
+
|
|
5
|
+
Faster debugging. Safer operations. Less cognitive load.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
### From PyPI (recommended)
|
|
10
|
+
```bash
|
|
11
|
+
pip install kubsome
|
|
12
|
+
kubsome init # Generate default config
|
|
13
|
+
kubsome # Start
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
With optional features:
|
|
17
|
+
```bash
|
|
18
|
+
pip install "kubsome[tui]" # + Full-screen TUI
|
|
19
|
+
pip install "kubsome[api]" # + REST API + Web UI
|
|
20
|
+
pip install "kubsome[all]" # Everything
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### From source
|
|
24
|
+
```bash
|
|
25
|
+
git clone https://github.com/aloketewary/kubsome.git && cd kubsome && ./install.sh
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Then:
|
|
29
|
+
```bash
|
|
30
|
+
source venv/bin/activate
|
|
31
|
+
kubsome
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Quick Start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
kubsome # Interactive CLI
|
|
38
|
+
kubsome --exec "check" # Single command (CI/CD)
|
|
39
|
+
kubsome --exec "export json" # Generate report
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Commands (85+)
|
|
43
|
+
|
|
44
|
+
Type `help` inside Kubsome for the full list. Highlights:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Observe
|
|
48
|
+
overview # Cluster dashboard + anomaly alerts
|
|
49
|
+
pods # Pod list with health
|
|
50
|
+
pods watch # Live monitoring
|
|
51
|
+
top pods # CPU/memory usage
|
|
52
|
+
|
|
53
|
+
# Operate
|
|
54
|
+
logs payment # Fuzzy-match pod logs
|
|
55
|
+
logcat payment --follow # Combined logs from all replicas (logcat style)
|
|
56
|
+
rollout billing-api # Rollout status
|
|
57
|
+
restart gateway # Rolling restart
|
|
58
|
+
scale payment 5 # Scale replicas
|
|
59
|
+
|
|
60
|
+
# Diagnose
|
|
61
|
+
inspect customer # Deep pod inspection
|
|
62
|
+
diagnose payment # Root cause analysis + playbook
|
|
63
|
+
trace payment-api # Resource relationship map
|
|
64
|
+
netcheck auth # Network diagnostics
|
|
65
|
+
|
|
66
|
+
# AI (natural language)
|
|
67
|
+
why is payment-api failing # Root cause explanation
|
|
68
|
+
summarize cluster health # Health summary
|
|
69
|
+
which pods are unhealthy # Degraded pod list
|
|
70
|
+
any anomalies detected # Anomaly scan
|
|
71
|
+
what changed recently # Recent activity
|
|
72
|
+
|
|
73
|
+
# Security & Cost
|
|
74
|
+
security # Misconfiguration scan
|
|
75
|
+
optimize # Resource right-sizing
|
|
76
|
+
unused # Find orphaned resources
|
|
77
|
+
|
|
78
|
+
# Incident Mode
|
|
79
|
+
incident start API outage # Start tracking
|
|
80
|
+
note found OOM in payment # Add observation
|
|
81
|
+
incident stop # Close & export report
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Features
|
|
85
|
+
|
|
86
|
+
- **Fuzzy matching** — type partial names, Kubsome finds the resource
|
|
87
|
+
- **Smart suggestions** — typo correction ("Did you mean: pods")
|
|
88
|
+
- **Natural language** — "show me logs for payment" just works
|
|
89
|
+
- **Command chaining** — `pods && events && alerts`
|
|
90
|
+
- **Aliases** — `p`=pods, `o`=overview, `d`=diagnose, `l`=logs
|
|
91
|
+
- **Bookmarks** — save and recall frequent commands
|
|
92
|
+
- **Workflows** — chain commands into reusable sequences
|
|
93
|
+
- **Watch mode** — `watch <any-command>` for live refresh
|
|
94
|
+
- **Logcat** — combined logs from all pods of a deployment
|
|
95
|
+
- **Playbooks** — step-by-step remediation guides
|
|
96
|
+
- **Anomaly detection** — restart spikes, event storms, cascading failures
|
|
97
|
+
- **Multi-cluster compare** — drift detection between environments
|
|
98
|
+
- **Export** — Markdown/JSON reports for sharing
|
|
99
|
+
- **Audit log** — tracks all destructive operations
|
|
100
|
+
- **Desktop notifications** — alerts for critical issues
|
|
101
|
+
- **Plugin system** — extend with custom commands
|
|
102
|
+
- **Persistent history** — command recall across sessions
|
|
103
|
+
- **Production safety** — confirmation prompts for dangerous actions
|
|
104
|
+
|
|
105
|
+
## Requirements
|
|
106
|
+
|
|
107
|
+
- Python 3.9+
|
|
108
|
+
- kubectl configured with cluster access
|
|
109
|
+
- metrics-server (for `top` commands)
|
|
110
|
+
|
|
111
|
+
## Configuration
|
|
112
|
+
|
|
113
|
+
Settings in `~/.kubsome/config.yaml`:
|
|
114
|
+
```yaml
|
|
115
|
+
refresh_interval: 2
|
|
116
|
+
notifications: true
|
|
117
|
+
theme: dark # dark, light, minimal, hacker
|
|
118
|
+
aliases:
|
|
119
|
+
p: pods
|
|
120
|
+
o: overview
|
|
121
|
+
d: diagnose
|
|
122
|
+
llm:
|
|
123
|
+
provider: local # or: ollama (for AI-powered explain)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Architecture
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
main.py → 150 lines, clean entry point
|
|
130
|
+
core/dispatcher.py → Command handler registry
|
|
131
|
+
core/ai/ → 8 intelligence modules
|
|
132
|
+
core/collectors/ → 24 data collectors
|
|
133
|
+
core/renderers/ → 21 presentation renderers
|
|
134
|
+
core/diagnostics/ → Root cause engine
|
|
135
|
+
100 Python files → Complete operational platform
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
MIT
|
|
File without changes
|
kubsome-1.0.0/api/app.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Kubsome API — FastAPI backend exposing the Kubernetes engine.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from fastapi import FastAPI
|
|
6
|
+
from fastapi.middleware.cors import CORSMiddleware
|
|
7
|
+
from fastapi.staticfiles import StaticFiles
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from api.routes import pods, overview, contexts, events, metrics, logs, deployments, diagnostics, intelligence, terminal, operations, ws
|
|
11
|
+
|
|
12
|
+
app = FastAPI(
|
|
13
|
+
title="Kubsome API",
|
|
14
|
+
version="1.0.0",
|
|
15
|
+
description="Kubernetes Operations Engine API",
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
app.add_middleware(
|
|
19
|
+
CORSMiddleware,
|
|
20
|
+
allow_origins=["http://localhost:3000", "http://localhost:3001"],
|
|
21
|
+
allow_credentials=True,
|
|
22
|
+
allow_methods=["*"],
|
|
23
|
+
allow_headers=["*"],
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
app.include_router(pods.router, prefix="/api")
|
|
27
|
+
app.include_router(overview.router, prefix="/api")
|
|
28
|
+
app.include_router(contexts.router, prefix="/api")
|
|
29
|
+
app.include_router(events.router, prefix="/api")
|
|
30
|
+
app.include_router(metrics.router, prefix="/api")
|
|
31
|
+
app.include_router(logs.router, prefix="/api")
|
|
32
|
+
app.include_router(deployments.router, prefix="/api")
|
|
33
|
+
app.include_router(diagnostics.router, prefix="/api")
|
|
34
|
+
app.include_router(intelligence.router, prefix="/api")
|
|
35
|
+
app.include_router(terminal.router, prefix="/api")
|
|
36
|
+
app.include_router(operations.router, prefix="/api")
|
|
37
|
+
app.include_router(ws.router)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@app.get("/health")
|
|
41
|
+
def health():
|
|
42
|
+
return {"status": "ok"}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# Serve Angular build in production
|
|
46
|
+
ui_dist = Path(__file__).parent.parent / "ui" / "dist" / "ui" / "browser"
|
|
47
|
+
if ui_dist.exists():
|
|
48
|
+
app.mount("/", StaticFiles(directory=str(ui_dist), html=True), name="ui")
|
|
File without changes
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from fastapi import APIRouter, HTTPException
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
|
|
4
|
+
from core.kubeconfig import enriched_contexts
|
|
5
|
+
from core.context_switcher import find_context, switch_context
|
|
6
|
+
from core.context import context
|
|
7
|
+
|
|
8
|
+
router = APIRouter(tags=["contexts"])
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SwitchRequest(BaseModel):
|
|
12
|
+
name: str
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@router.get("/contexts")
|
|
16
|
+
def get_contexts():
|
|
17
|
+
return {
|
|
18
|
+
"current": context.current_context,
|
|
19
|
+
"namespace": context.namespace,
|
|
20
|
+
"contexts": enriched_contexts(),
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@router.post("/switch-context")
|
|
25
|
+
def post_switch_context(req: SwitchRequest):
|
|
26
|
+
matches = find_context(req.name)
|
|
27
|
+
if not matches:
|
|
28
|
+
raise HTTPException(status_code=404, detail="No matching context")
|
|
29
|
+
|
|
30
|
+
target = matches[0]
|
|
31
|
+
switch_context(target)
|
|
32
|
+
return {
|
|
33
|
+
"switched_to": target["name"],
|
|
34
|
+
"namespace": target["namespace"],
|
|
35
|
+
"environment": target.get("environment"),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class NamespaceRequest(BaseModel):
|
|
40
|
+
namespace: str
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@router.get("/namespaces")
|
|
44
|
+
def get_namespaces():
|
|
45
|
+
import subprocess
|
|
46
|
+
result = subprocess.run(
|
|
47
|
+
f"kubectl --context {context.current_context} get namespaces -o jsonpath='{{.items[*].metadata.name}}'",
|
|
48
|
+
shell=True, capture_output=True, text=True,
|
|
49
|
+
)
|
|
50
|
+
if result.returncode != 0:
|
|
51
|
+
return {"namespaces": [], "current": context.namespace}
|
|
52
|
+
raw = result.stdout.strip().strip("'")
|
|
53
|
+
namespaces = sorted([ns for ns in raw.split() if ns])
|
|
54
|
+
return {"namespaces": namespaces, "current": context.namespace}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@router.post("/switch-namespace")
|
|
58
|
+
def post_switch_namespace(req: NamespaceRequest):
|
|
59
|
+
from core.state import save_state
|
|
60
|
+
context.namespace = req.namespace
|
|
61
|
+
save_state(context.current_context, context.namespace)
|
|
62
|
+
return {"namespace": context.namespace}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@router.get("/namespaces/{ctx}")
|
|
66
|
+
def get_namespaces_for(ctx: str):
|
|
67
|
+
"""Get namespaces for a specific context without switching global state."""
|
|
68
|
+
import subprocess
|
|
69
|
+
result = subprocess.run(
|
|
70
|
+
f"kubectl --context {ctx} get namespaces -o jsonpath='{{.items[*].metadata.name}}'",
|
|
71
|
+
shell=True, capture_output=True, text=True,
|
|
72
|
+
)
|
|
73
|
+
if result.returncode != 0:
|
|
74
|
+
return {"namespaces": []}
|
|
75
|
+
raw = result.stdout.strip().strip("'")
|
|
76
|
+
namespaces = sorted([ns for ns in raw.split() if ns])
|
|
77
|
+
return {"namespaces": namespaces}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from fastapi import APIRouter, HTTPException
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
|
|
4
|
+
from core.context import context
|
|
5
|
+
from core.collectors.deployments import collect_deployments
|
|
6
|
+
from core.collectors.rollouts import (
|
|
7
|
+
rollout_status, rollout_history,
|
|
8
|
+
rollout_rollback, rollout_restart,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
import subprocess
|
|
12
|
+
|
|
13
|
+
router = APIRouter(tags=["deployments"])
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ScaleRequest(BaseModel):
|
|
17
|
+
replicas: int
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@router.get("/deployments")
|
|
21
|
+
def get_deployments():
|
|
22
|
+
return {
|
|
23
|
+
"context": context.current_context,
|
|
24
|
+
"namespace": context.namespace,
|
|
25
|
+
"deployments": collect_deployments(),
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@router.get("/rollout/{name}")
|
|
30
|
+
def get_rollout(name: str):
|
|
31
|
+
status = rollout_status(name)
|
|
32
|
+
history = rollout_history(name)
|
|
33
|
+
return {"name": name, "status": status, "history": history}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@router.post("/restart/{name}")
|
|
37
|
+
def post_restart(name: str):
|
|
38
|
+
success, output = rollout_restart(name)
|
|
39
|
+
if not success:
|
|
40
|
+
raise HTTPException(status_code=500, detail="Restart failed")
|
|
41
|
+
return {"restarted": name}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@router.post("/rollback/{name}")
|
|
45
|
+
def post_rollback(name: str):
|
|
46
|
+
success, output = rollout_rollback(name)
|
|
47
|
+
if not success:
|
|
48
|
+
raise HTTPException(status_code=500, detail="Rollback failed")
|
|
49
|
+
return {"rolled_back": name}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@router.post("/scale/{name}")
|
|
53
|
+
def post_scale(name: str, req: ScaleRequest):
|
|
54
|
+
cmd = (
|
|
55
|
+
f"kubectl --context {context.current_context} "
|
|
56
|
+
f"scale deployment/{name} "
|
|
57
|
+
f"--replicas={req.replicas} -n {context.namespace}"
|
|
58
|
+
)
|
|
59
|
+
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
|
60
|
+
if result.returncode != 0:
|
|
61
|
+
raise HTTPException(status_code=500, detail=result.stderr.strip())
|
|
62
|
+
return {"scaled": name, "replicas": req.replicas}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from fastapi import APIRouter, HTTPException
|
|
2
|
+
|
|
3
|
+
from core.context import context
|
|
4
|
+
from core.collectors.inspect import inspect_pod, pod_events, extract_pod_details
|
|
5
|
+
from core.collectors.diagnosis import collect_diagnosis
|
|
6
|
+
from core.collectors.trace import trace_resource
|
|
7
|
+
from core.diagnostics.engine import diagnose
|
|
8
|
+
from core.diagnostics.recommendations import recommend
|
|
9
|
+
|
|
10
|
+
router = APIRouter(tags=["diagnostics"])
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@router.get("/inspect/{pod}")
|
|
14
|
+
def get_inspect(pod: str):
|
|
15
|
+
pod_data = inspect_pod(pod)
|
|
16
|
+
if not pod_data:
|
|
17
|
+
raise HTTPException(status_code=404, detail="Pod not found")
|
|
18
|
+
details = extract_pod_details(pod_data)
|
|
19
|
+
events = pod_events(pod)
|
|
20
|
+
recommendation = recommend(pod_data)
|
|
21
|
+
return {
|
|
22
|
+
"pod": pod,
|
|
23
|
+
"details": details,
|
|
24
|
+
"events": events,
|
|
25
|
+
"recommendation": recommendation,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@router.get("/diagnose/{pod}")
|
|
30
|
+
def get_diagnose(pod: str):
|
|
31
|
+
data = collect_diagnosis(pod)
|
|
32
|
+
if not data:
|
|
33
|
+
raise HTTPException(status_code=404, detail="Pod not found")
|
|
34
|
+
findings = diagnose(data)
|
|
35
|
+
return {
|
|
36
|
+
"pod": pod,
|
|
37
|
+
"findings": findings,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@router.get("/trace/{name}")
|
|
42
|
+
def get_trace(name: str):
|
|
43
|
+
data = trace_resource(name)
|
|
44
|
+
return {"name": name, "trace": data}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from fastapi import APIRouter
|
|
2
|
+
|
|
3
|
+
from core.collectors.events import collect_events
|
|
4
|
+
from core.context import context
|
|
5
|
+
|
|
6
|
+
router = APIRouter(tags=["events"])
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@router.get("/events")
|
|
10
|
+
def get_events(limit: int = 50):
|
|
11
|
+
events = collect_events(limit=limit)
|
|
12
|
+
return {
|
|
13
|
+
"context": context.current_context,
|
|
14
|
+
"namespace": context.namespace,
|
|
15
|
+
"events": events,
|
|
16
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
from fastapi import APIRouter, Query
|
|
2
|
+
from pydantic import BaseModel
|
|
3
|
+
|
|
4
|
+
from core.collectors.search import search_resources
|
|
5
|
+
from core.collectors.security import security_scan
|
|
6
|
+
from core.collectors.cost import resource_recommendations, find_unused_resources
|
|
7
|
+
from core.healthcheck import run_health_check
|
|
8
|
+
from core.ai.engine import handle_ai_query
|
|
9
|
+
from core.ai.anomaly import detect_anomalies
|
|
10
|
+
|
|
11
|
+
router = APIRouter(tags=["intelligence"])
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class AiRequest(BaseModel):
|
|
15
|
+
query: str
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@router.get("/search")
|
|
19
|
+
def get_search(q: str = Query(..., min_length=1)):
|
|
20
|
+
results = search_resources(q)
|
|
21
|
+
return {"query": q, "results": results}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@router.get("/security")
|
|
25
|
+
def get_security():
|
|
26
|
+
findings = security_scan()
|
|
27
|
+
return {"findings": findings}
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@router.get("/health-check")
|
|
31
|
+
def get_health_check():
|
|
32
|
+
return run_health_check()
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@router.get("/anomalies")
|
|
36
|
+
def get_anomalies():
|
|
37
|
+
alerts = detect_anomalies()
|
|
38
|
+
return {"alerts": alerts}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@router.get("/optimize")
|
|
42
|
+
def get_optimize():
|
|
43
|
+
recs = resource_recommendations()
|
|
44
|
+
return {"recommendations": recs}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@router.get("/unused")
|
|
48
|
+
def get_unused():
|
|
49
|
+
return {"resources": find_unused_resources()}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@router.post("/ai")
|
|
53
|
+
def post_ai(req: AiRequest):
|
|
54
|
+
import re
|
|
55
|
+
response = handle_ai_query(req.query)
|
|
56
|
+
# Strip Rich markup tags for API consumers
|
|
57
|
+
content = response.get("content", "")
|
|
58
|
+
content = re.sub(r'\[/?[^\]]+\]', '', content)
|
|
59
|
+
return {
|
|
60
|
+
"title": response.get("title", "").replace("🤖 ", ""),
|
|
61
|
+
"answer": content,
|
|
62
|
+
"severity": response.get("severity", "info"),
|
|
63
|
+
}
|