https://github.com/jingle2008/toolkit
Toolkit — Cross-platform CLI for cloud & infrastructure automation, written in Go. Fast filtering, templating, Kubernetes helpers, Terraform tooling, rich TUI, and more — one binary for everyday DevOps tasks.
https://github.com/jingle2008/toolkit
automation cli command-line devops go kubernetes terraform toolkit tui
Last synced: 24 days ago
JSON representation
Toolkit — Cross-platform CLI for cloud & infrastructure automation, written in Go. Fast filtering, templating, Kubernetes helpers, Terraform tooling, rich TUI, and more — one binary for everyday DevOps tasks.
- Host: GitHub
- URL: https://github.com/jingle2008/toolkit
- Owner: jingle2008
- License: mit
- Created: 2025-05-31T14:23:51.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2026-05-25T06:08:02.000Z (26 days ago)
- Last Synced: 2026-05-25T06:40:14.420Z (26 days ago)
- Topics: automation, cli, command-line, devops, go, kubernetes, terraform, toolkit, tui
- Language: Go
- Homepage:
- Size: 1.36 MB
- Stars: 2
- Watchers: 0
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# Toolkit
[](https://github.com/jingle2008/toolkit/actions/workflows/ci.yml)
[](https://goreportcard.com/report/github.com/jingle2008/toolkit)
[](https://pkg.go.dev/github.com/jingle2008/toolkit)
[](https://codecov.io/gh/jingle2008/toolkit)
Toolkit is a collection of reusable Go components exposed through a modular CLI and optional TUI (built with [Bubble Tea](https://github.com/charmbracelet/bubbletea)).
It targets day-to-day DevOps & development automation: querying Kubernetes, parsing Terraform plans, mass-editing config files, and inspecting large data tables directly in your terminal.
- [User Manual](docs/USER_MANUAL.md)
- [Kubernetes Client Fakes & Testing Patterns](docs/guide/k8s-fake-patterns.md)
---
## Feature Highlights
| Area | Packages | Notes |
| -------------- | ------------------------------- | ----- |
| **CLI core** | `internal/cli` | Cobra-based, flags auto-generated |
| **Interactive TUI** | `internal/ui/tui` | Sort/search/filter large tabular datasets |
| **Infrastructure loaders** | `internal/infra/k8s`, `internal/infra/terraform` | Uniform abstraction for K8s & TF |
| **Config loading & validation** | `internal/config`, `internal/configloader` | JSON / YAML with defaulting & schema checks |
| **Collections helpers** | `internal/collections` | Generic filter/sort with predicates |
| **Encoding helpers** | `internal/encoding/jsonutil` | Fast JSON pointer traversal |
| **Error & logging** | `pkg/infra/logging` | Typed errors via std errors; zap logger |
## Architecture at a glance
```mermaid
flowchart LR
subgraph CFG ["Config sources"]
flags["CLI flags
TOOLKIT_* env"]
file["~/.config/toolkit/config.yaml"]
end
flags --> viper((viper
merge))
file --> viper
viper --> Cfg["config.Config"]
subgraph SRC ["Data sources"]
tf["Terraform repo
(repo-path)"]
k8s["Kubernetes API
(kubeconfig)"]
oci["OCI APIs
(env-realm)"]
end
Cfg --> Loader
tf --> Loader
k8s --> Loader
oci --> Loader
Loader["internal/infra/loader
(composite)"]
Loader --> TUI["TUI
toolkit"]
Loader --> Get["Headless
toolkit get / config / doctor"]
Loader --> MCP["MCP server
toolkit mcp"]
Loader --> Mut["Mutations
cordon · drain · reboot
scale · delete · terminate"]
```
The loader composite is the single funnel every entry point goes through, so the four surfaces (TUI, headless `get`, MCP, mutations) all see identical data and the same partial-load semantics.
---
## Install
```bash
# Latest release
go install github.com/jingle2008/toolkit/cmd/toolkit@latest
# From source
git clone https://github.com/jingle2008/toolkit.git
cd toolkit && make
```
```zsh
# From Homebrew (macOS/Linux)
brew install jingle2008/tap/toolkit
```
> **Already on the old `jingle2008/homebrew-toolkit` tap?** It's archived as of v0.3.x and won't receive new releases. Migrate with (order matters — `brew untap` refuses while the formula is still installed):
> ```zsh
> brew uninstall toolkit
> brew untap jingle2008/toolkit # canonical short name; the homebrew- prefix is implied
> brew install jingle2008/tap/toolkit
> ```
---
## Getting Started
After installation, try these quick commands:
```sh
toolkit init
# Scaffold an example config file at ~/.config/toolkit/config.yaml
toolkit config --validate
# Sanity-check the effective config; exits non-zero on failure
toolkit completion bash # or zsh/fish
# Output shell completion script for your shell
toolkit version --check-updates
# Print your installed version and check for updates
```
---
## Usage
```bash
toolkit --help # all global flags
```
### Global Flags
| Flag | Default | Description |
| ---- | ------- | ----------- |
| `--config` | `~/.config/toolkit/config.yaml` | Path to config file (YAML or JSON) |
| `--repo-path` | | Path to the repository |
| `--env-type` | | Environment type (e.g. dev, prod) |
| `--env-region` | | Environment region |
| `--env-realm` | | Environment realm |
| `--category, -c` | | Category to display |
| `--filter, -f` | | Initial filter for current category |
| `--metadata-file` | `~/.config/toolkit/metadata.yaml` | Optional additional metadata file |
| `--kubeconfig` | `~/.kube/config` | Path to kubeconfig file |
| `--log-file` | `toolkit.log` | Path to log file |
| `--debug` | `false` | Enable debug logging |
| `--log-format` | `console` | Log format: `console`, `json`, or `slog` |
| `--log-level` | | Minimum log level: `debug`, `info`, `warn`, `error` (empty uses `--debug` flag) |
| `--mutation-env-override-allowed` | `false` | Allow MCP mutation tools to override the startup env per call (off by default for safety) |
*(See `internal/cli/flags.go` for the authoritative list.)*
### Headless `get` (for scripts and LLM integration)
`toolkit get ` is the non-TUI equivalent of selecting a category in the interactive UI. It uses the same loaders and emits machine-friendly output for piping into `jq`, posting to LLM tools, feeding spreadsheets, or driving shell pipelines.
Supported formats (`-o`): `table` (default), `json`, `jsonl`, `yaml`, `csv`, `tsv`.
```bash
# JSON array (default pretty-printed)
toolkit get tenant -o json
# Line-delimited JSON (great for streaming / `xargs`)
toolkit get gpunode -f us-ashburn-1 -o jsonl
# Plain table (default)
toolkit get dac
# YAML
toolkit get basemodel -f cohere -o yaml
# CSV for spreadsheets (proper quoting via encoding/csv)
toolkit get tenant -o csv > tenants.csv
# TSV for `cut` / `awk` pipelines
toolkit get gpupool -o tsv | cut -f1,3
# Suppress headers (table/csv/tsv)
toolkit get tenant --no-headers
```
Category aliases match the TUI (`t`, `bm`, `gn`, `dac`, …). Run `toolkit get alias` for the full list, or enable shell completion (`toolkit completion zsh`) for tab-completion. Logs are written to `--log-file` (default `toolkit.log`) so stdout stays clean for parsing.
For `gpunode`, `dac`, `modelartifact`, and the tenancy-override categories, the structured outputs (`json`, `jsonl`, `yaml`) are a flat array of objects with the originating group key injected as `pool`, `tenant`, or `model` — easier for `jq` and LLM consumers than the previous map-shaped output.
### Inspect effective config (`toolkit config`)
`toolkit config` prints the merged view every other subcommand sees — defaults + `TOOLKIT_*` env + config file + flags — so you can see what's actually in effect without opening the YAML by hand:
```bash
toolkit config # YAML (default)
toolkit config -o json # JSON for `jq`
toolkit config --pretty=false # compact JSON
toolkit config --validate # run config.Validate(); exit non-zero on failure
```
`--validate` mode emits a structured `{valid, config_file, error?}` payload and exits non-zero on failure — suitable for `if ! toolkit config --validate; then abort; fi` precondition checks in CI/scripts.
### Cluster mutations
Maintenance operations the TUI exposes via keyboard shortcuts are also available as scriptable subcommands. All mutations support `--dry-run` (preview the action) and `--yes` / `-y` (skip the interactive prompt). Each call writes a JSON line to the audit log.
| Command | Effect |
| ------- | ------ |
| `toolkit cordon ` / `toolkit uncordon ` | Toggle scheduling on a Kubernetes node |
| `toolkit drain ` | Evict pods and cordon |
| `toolkit reboot ` | Reboot the underlying instance |
| `toolkit scale gpu-pool ` | Sync OCI instance-pool size to the Terraform-declared `pool.Size` (no `--size` flag — Terraform is the source of truth). The `gpupool` alias is accepted for back-compat. |
| `toolkit delete dac ` | Delete a dedicated AI cluster (destructive — requires `--yes`) |
| `toolkit terminate ` | Terminate the underlying OCI instance (destructive — requires `--yes`) |
Example:
```bash
toolkit drain node-42 --dry-run # preview
toolkit drain node-42 -y # run without prompt
```
See [docs/recipes.md](docs/recipes.md) for end-to-end flows (MCP setup, maintenance windows, audit exports, Slack digests).
### MCP server (`toolkit mcp`)
For agent integration via the [Model Context Protocol](https://modelcontextprotocol.io), `toolkit mcp` boots a stdio MCP server that exposes the same loader surface as `get` — but as typed tools an AI agent can call directly, no shell-out needed.
Configure once in your MCP client. Claude Desktop / Claude Code use JSON:
```jsonc
{
"mcpServers": {
"toolkit": {
"command": "toolkit",
"args": ["mcp"]
}
}
}
```
Codex CLI (`~/.codex/config.toml`) uses TOML:
```toml
[mcp_servers.toolkit]
command = "toolkit"
args = ["mcp"]
```
See [docs/recipes.md](docs/recipes.md) for the per-client file paths and first prompts to try.
**Read tools** — return a `{ "items": [...], "count": N, "warnings": [...] }` envelope:
| Tool | Description |
| ---- | ----------- |
| `list_tenants` | Tenants in the configured realm |
| `list_base_models` | Base models from the cluster |
| `list_gpu_pools` | GPU pools (partial-load warnings surfaced) |
| `list_gpu_nodes` | GPU nodes (flat, with `pool` field) |
| `list_dacs` | Dedicated AI clusters (flat, with `tenant` field) |
| `list_environments` | All known toolkit environments |
| `list_service_tenancies` | Service tenancies from the repo |
| `list_model_artifacts` | Model artifacts (flat, with `model` field) |
| `list_definitions` | `kind`: `limit` / `console_property` / `property` |
| `list_tenancy_overrides` | Same `kind` enum, tenancy-scoped |
| `list_regional_overrides` | Same `kind` enum, region-scoped |
| `list_aliases` | Discovery — every category alias |
Every read tool takes an optional `filter` (fuzzy substring) and optional `env_type` / `env_region` / `env_realm` to override the startup env per-call, so a single running server can answer questions across multiple environments.
**Mutation tools** — gated on `confirm: true`. The same safety model as the CLI: failures surface via `notifications/message`, every call writes to the audit log:
| Tool | Effect |
| ---- | ------ |
| `cordon_node` / `uncordon_node` | Toggle Kubernetes node scheduling |
| `drain_node` | Evict pods and cordon |
| `reboot_node` | Reboot the underlying instance |
| `scale_gpu_pool` | Resize an OCI GPU instance pool |
| `delete_dac` | Delete a dedicated AI cluster |
| `terminate_node` | Terminate the underlying OCI instance |
By default, mutation tools ignore any per-call `env_type` / `env_region` / `env_realm` (MCP tool input fields — these stay snake_case as the JSON-schema field names) and only act in the startup env — the operator's credentials decide the maximum blast radius, not the agent. Pass `--mutation-env-override-allowed` at server start to opt in to per-call env routing.
---
## Project Layout
```
.
├── cmd/
│ └── toolkit/ # main()
├── internal/
│ ├── cli/ # cobra root & sub-commands
│ ├── ui/tui/ # Bubble Tea models & views
│ ├── infra/
│ │ ├── k8s/ # K8s data sources
│ │ └── terraform/ # Terraform provider
│ ├── config/ # typed config structs
│ ├── configloader/ # env + file loader
│ ├── collections/ # generic filter/sort
│ └── encoding/jsonutil/ # JSON helpers
├── pkg/
│ ├── infra/logging/ # zap-based logging
│ └── models/ # domain models and types
└── test/
└── integration/
```
---
### Build
```sh
make
```
or
```sh
go build -o bin/toolkit ./cmd/toolkit
```
### Run
```sh
./bin/toolkit --help
```
or, if built with Go:
```sh
go run ./cmd/toolkit --help
```
## Testing
Run all tests with:
```sh
go test ./...
```
#### Running tests
- Unit tests (default):
```sh
make test
```
- Integration tests (with build tag):
```sh
make test-int
```
- Coverage reports:
```sh
make cover # unit test coverage
make cover-int # integration test coverage
```
#### Continuous Integration
- **Unit tests** run on all pushes and pull requests.
- **Integration tests** run on pushes to `main` and nightly (see `.github/workflows/ci.yml`).
- **CI target**: Run `make ci` to execute both lint and test in one step (recommended for local and CI use).
## Developer Workflow
- One-time setup: `make setup` (installs golangci-lint, gofumpt, goimports)
- Optional: enable git hooks with pre-commit: `pre-commit install`
- Run `make ci` before pushing to ensure code passes lint and tests.
- Use `make lint` to check for style and static analysis issues.
- Use `make test` for a full race-enabled test run.
- Use `make fmt` and `make tidy` to auto-format and tidy dependencies.
## Architecture Overview
Toolkit follows a modular, testable architecture:
- **Loaders**: `internal/infra/loader` provides concrete and interface-based loaders for datasets (K8s, Terraform, OCI), enabling dependency injection and testability.
- **TUI Model**: `internal/ui/tui` contains Bubble Tea models, views, and update loop; composed via functional options.
- **Domain types**: `pkg/models` defines strongly-typed domain models used across loaders and UI.
- **Category enum**: `internal/domain/category.go` provides strongly-typed categories and parsing.
- **Logging**: `pkg/infra/logging` wraps zap for structured logs with configurable format and file path.
## Logging
Toolkit uses [zap](https://github.com/uber-go/zap) for structured, machine-readable logging. By default logs are written to `toolkit.log` (configurable via `--log-file`) and support `--log-format` of `console`, `json`, or `slog`. The minimum log level can be set via `--log-level` (`debug`, `info`, `warn`, `error`).
## Contributing
Contributions are welcome! Please open issues or submit pull requests for new features, bug fixes, or improvements.
---
## License
This project is licensed under the MIT License.