kubekey
kubesphere/kubekey/AGENTS.md
This is the single entry point for any AI agent (or new contributor) working on the KubeKey v4 codebase. It covers what the project is, how the code actually flows, and the conventions you must follow when changing it. Read it top to bottom once; afterwards use §3 (Code Logic Map) and §8 (File-to-Concern Map) as lookup tables. Further reading: KubeKey v4 is a Go-based task execution framework modeled on Ansible. Its primary use case is installing and managing Kubernetes…
What's in it
- KubeKey Agent Guide
- 1. What is KubeKey?
- 2. Repository Layout
- 3. Code Logic Map
- 3.1 CLI Startup Flow
- 3.2 Manager Layer
- 3.3 Project Loading
- 3.4 Execution Engine
- 3.5 Variables
- 3.6 Connectors
- 3.7 Modules
- 3.8 Templates, when and Tags
- 3.9 Kubernetes Controllers
- 3.10 REST Proxy / Web
- 3.11 Built-in Kubernetes Install Flow
- 4. Universal Conventions
- 4.1 Logging
- 4.2 Errors
- 4.3 Naming
- 4.4 Architecture
- 4.5 Go Conventions
- 5. Build & Test
- 6. Debugging Tips
- 7. Git Commit & PR Conventions
- Commit Message Format
- Pull Request Description
- 8. Appendix: File-to-Concern Map
# KubeKey Agent Guide
This is the single entry point for any AI agent (or new contributor) working on the KubeKey v4 codebase. It covers **what the project is**, **how the code actually flows**, and **the conventions you must follow** when changing it.
Read it top to bottom once; afterwards use §3 (Code Logic Map) and §8 (File-to-Concern Map) as lookup tables.
Further reading:
- [README.md](README.md) – user-facing intro.
- [docs/en/framework/README.md](docs/en/framework/README.md) – writing custom playbooks.
## 1. What is KubeKey?
KubeKey v4 is a Go-based task execution framework modeled on Ansible. Its primary use case is installing and managing Kubernetes clusters, but the core engine is generic: it loads playbook projects (YAML), executes tasks across hosts via connectors (SSH/local/Kubernetes/Prometheus), and provides built-in modules (command, copy, template, image, etc.).
Two binaries are produced:
- `kk` – CLI tool that runs playbooks locally or inside a Kubernetes pod.
- `kk-controller-manager` – Kubernetes operator that watches `Playbook` CRs and spawns executor pods.
A third build target, `capkk`, provides the Cluster API infrastructure provider (built with the `clusterapi` tag).
## 2. Repository Layout
```text
kubekey/
├── cmd/kk # CLI binary entry
├── cmd/controller-manager # Operator binary entry
├── api/ # Separate Go module for CRD Go types
│ ├── core/v1 # Playbook / Inventory / Config CRDs
│ ├── core/v1alpha1 # Task CRD
│ └── project/v1 # Playbook YAML types (play/role/block/...)
├── pkg/ # Core packages
│ ├── executor/ # Playbook/role/block/task execution engine
│ ├── project/ # Project loading (builtin/local/git)
│ ├── modules/ # Built-in modules
│ ├── variable/ # Variable merging and lookup
│ ├── connector/ # SSH/local/k8s/prometheus connectors
│ ├── converter/ # Block↔Task conversion, template rendering
│ ├── manager/ # commandManager/controllerManager/webManager
│ ├── controllers/ # Kubernetes reconcilers and webhooks
│ ├── proxy/ # Hybrid REST API proxy
│ ├── web/ # HTTP services
│ ├── const/ # Constants, scheme, workdir helpers
│ └── utils/ # Small utilities
├── builtin/core/ # Embedded playbooks/roles (requires "builtin" tag)
├── plugins/ # Optional community playbooks/roles
├── config/ # Generated CRDs, Helm charts, Kustomize
├── docs/ # Documentation
│ └── en/framework/ # User-facing framework docs
├── Makefile # Build targets, generate, test, lint
├── go.mod # Main module
├── go.work # Workspace including ./api
└── version/ # Build-time version injection
```
## 3. Code Logic Map
Exact code paths for the most important flows, so you can jump straight to the right function when debugging or adding a feature.
### 3.1 CLI Startup Flow
`kk` binary entry:
```text
cmd/kk/kubekey.go:main()
└── app.NewRootCommand().Execute()
```
Root command construction:
```text
cmd/kk/app/root.go:NewRootCommand()
├── options.AddProfilingFlags() # pprof/gops
├── options.AddKlogFlags()
├── options.AddGOPSFlags()
├── newRunCommand()
├── newPlaybookCommand()
├── newVersionCommand()
├── newWebCommand()
└── internalCommand... # built-in commands registered by init()
```
Built-in commands registration (gated by `//go:build builtin`):
```text
cmd/kk/app/builtin.go:init()
└── imports cmd/kk/app/builtin/* packages
cmd/kk/app/builtin/create.go:init()
└── internalCommand = append(internalCommand, newCreateCommand())
cmd/kk/app/builtin/add.go:init()
cmd/kk/app/builtin/delete.go:init()
cmd/kk/app/builtin/init.go:init()
cmd/kk/app/builtin/precheck.go:init()
cmd/kk/app/builtin/artifact.go:init()
cmd/kk/app/builtin/certs.go:init()
```
Each built-in command constructs a `CommonOptions` and calls `CommonOptions.Run()`.
Built-in command flow (example: create cluster):
```text
cmd/kk/app/builtin/create.go:newCreateCommand()
└── cmd.RunE = func(...)
├── options.NewCommonOptions()
│ └── sets up Playbook/Inventory/Config references
├── options.Complete()
│ ├── resolve inventory/config files
│ ├── apply --set overrides
│ └── determine workdir
└── options.Run()
└── manager.NewCommandManager(playbook, inventory, config)
└── commandManager.Run()
└── executor.NewPlaybookExecutor(...).Exec(ctx)
```
Arbitrary playbook flow (`kk run`):
```text
cmd/kk/app/run.go:newRunCommand()
└── options.KubeKeyRunOptions.Complete()
├── project.New() for git/local project
└── build Playbook CR pointing at that project
└── options.Run() -> CommandManager -> PlaybookExecutor
```
In-cluster executor (`kk playbook`):
```text
cmd/kk/app/playbook.go:newPlaybookCommand()
└── PlaybookOptions.Complete()
├── read Playbook CR from API server
└── read Inventory/Config CRs
└── Run() -> CommandManager -> PlaybookExecutor
```
### 3.2 Manager Layer
All three binaries converge on the `Manager` interface in `pkg/manager/manager.go`.
Command manager:
```text
pkg/manager/command_manager.go:NewCommandManager()
└── Run(ctx)
├── create controller-runtime client for local file storage
├── if local run and not dry-run: create/update Playbook CR locally
└── PlaybookExecutor.Exec(ctx)
```
Controller manager:
```text
cmd/controller-manager/controller_manager.go:main()
└── app.NewControllerManagerCommand().Execute()
└── pkg/manager/controller_manager.go:NewControllerManager().Run(ctx)
├── create controller-runtime manager
├── register enabled controllers via options.Register()
└── mgr.Start(ctx)
```
Controllers register in `pkg/controllers/core/register.go:init()` and `pkg/controllers/infrastructure/register.go:init()`.
Web manager:
```text
pkg/manager/web_manager.go:NewWebManager().Run(ctx)
├── create local REST config via pkg/proxy
├── build go-restful container
├── pkg/web.NewCoreService()
├── pkg/web.NewSchemaService()
├── pkg/web.NewUIService()
└── http.ListenAndServe()
```
### 3.3 Project Loading
Project factory:
```text
pkg/project/project.go:New(ctx, playbook, update)
├── if playbook address looks like git: newGitProject()
│ └── go-git clone/pull into workdir
├── else if BuiltinsProjectAnnotation is set: builtinProjectFunc()
│ └── builtin/core.BuiltinPlaybook embed.FS
└── else: newLocalProject()
└── os.DirFS(path)
```
Playbook marshaling:
```text
pkg/project/project.go:MarshalPlaybook()
├── ReadFile(playbook.yaml)
├── yaml.Unmarshal -> kkprojectv1.Playbook
├── resolve import_playbook recursively
├── load vars_files
├── load roles:
│ ├── read defaults/main.yaml
│ ├── read meta/main.yaml dependencies
│ └── recursively marshal dependency roles
├── expand include_tasks
└── validate playbook/role/block
```
YAML project types live in `api/project/v1/`:
- `playbook.go:Playbook` – top-level list of Plays.
- `play.go:Play` – hosts, gather_facts, vars_files, roles, pre_tasks/tasks/post_tasks.
- `role.go:Role` / `RoleInfo` – dependencies, name, blocks.
- `block.go:Block` – nested block/rescue/always or leaf task.
- `base.go:Base` – name, connection, vars, environment, run_once, ignore_errors, become.
- `taggable.go:Taggable` – tags logic (always/never/all/tagged).
- `conditional.go:When` – conditional evaluation.
### 3.4 Execution Engine
Executor creation:
```text
pkg/executor/playbook_executor.go:NewPlaybookExecutor(client, playbook, variable, logOutput)
└── returns *playbookExecutor{ option{...}, project }
```
Playbook execution:
```text
pkg/executor/playbook_executor.go:Exec(ctx)
├── project.MarshalPlaybook() -> kkprojectv1.Playbook
├── set Playbook phase Running
├── for each Play:
│ ├── select hosts from inventory by pattern
│ ├── group hosts by serial batches
│ │ └── pkg/converter/converter.go:GroupHostBySerial()
│ ├── for each batch:
│ │ ├── gather_facts (if play.gather_facts != false)
│ │ │ └── setup module on each host
│ │ ├── run pre_tasks
│ │ ├── for each role:
│ │ │ └── roleExecutor.Exec(ctx)
│ │ ├── run tasks
│ │ └── run post_tasks
│ └── update Playbook status
├── set Playbook phase Succeeded/Failed
└── store final result
```
Role execution:
```text
pkg/executor/role_executor.go:Exec(ctx)
├── merge role defaults into variable system
├── recursively execute dependency roles
│ └── dependency role inherits parent role's when/tags/ignore_errors
└── for each block in role:
└── blockExecutor.Exec(ctx)
└── blocks inherit role's when conditions
```
`when` defined on a role is merged with parent conditions and passed down to all blocks and tasks within that role.
Block execution:
```text
pkg/executor/block_executor.go:Exec(ctx)
├── evaluate tags: skip block if tags don't match
├── merge block's when condition with parent when conditions
├── if block has nested block/rescue/always:
│ ├── run block tasks
│ ├── on failure: run rescue tasks
│ └── always: run always tasks
└── else (leaf task):
└── taskExecutor.Exec(ctx)
└── all inherited when conditions are evaluated per host
```
`when` conditions are cumulative: a block or task must satisfy its own `when` expressions **and** all inherited `when` expressions from parent blocks and roles.
Task execution:
```text
pkg/executor/task_executor.go:Exec(ctx)
├── if loop: expand loop items
├── create/update kkcorev1alpha1.Task CR
├── for each host in parallel (wait.Group):
│ ├── evaluate per-host when condition
│ ├── create progress bar
│ ├── FindModule(moduleName)
│ ├── moduleExecFunc(ctx, ExecOptions)
│ ├── evaluate failed_when
│ ├── handle ignore_errors
│ └── store register/result variables
└── update Task CR status
```
Module discovery:
```text
pkg/executor/block_executor.go:MarshalBlock()
├── iterate over UnknownField(s) in kkprojectv1.Block
└── first unknown key that matches a registered module -> ModuleName
```
### 3.5 Variables
Variable structure:
```text
pkg/variable/variable.go:value
├── Config kkcorev1.Config
├── Inventory kkcorev1.Inventory
├── Hosts map[string]host
│ ├── RemoteVars map[string]any # gather_facts
│ └── RuntimeVars map[string]any # set_fact, register
└── Result map[string]any
```
Lookup precedence:
```text
pkg/variable/variable_get.go:GetFunc
└── resolves in order:
1. Config vars
2. Host-specific inventory vars
3. Group vars (for groups containing host)
4. Inventory vars
5. Runtime vars
6. Remote vars
```
Merge paths:
```text
pkg/variable/variable_merge.go
├── MergeRemoteVariable() # gather_facts -> Hosts[host].RemoteVars
├── MergeRuntimeVariable() # set_fact/register -> Hosts[host].RuntimeVars
├── MergeHostsRuntimeVariable() # cross-host variable injection
└── MergeResultVariable() # task result -> Playbook.Status.Result
```
Persistence:
```text
pkg/variable/source/file_source.go
└── reads/writes per-host vars to
<workdir>/runtime/<namespace>/<playbook>/variable/<hostname>.yaml
```
### 3.6 Connectors
Factory:
```text
pkg/connector/connector.go:NewConnector(host, vars, logger)
├── connector.type == "local" -> localConnector
├── connector.type == "ssh" -> sshConnector
├── connector.type == "kubernetes" -> kubernetesConnector
├── connector.type == "prometheus" -> prometheusConnector
└── default:
├── localhost -> localConnector
└── otherwise -> sshConnector
```
SSH connector (`pkg/connector/ssh_connector.go`): `Init()` parses auth (password/key); `ExecuteCommand()` via `golang.org/x/crypto/ssh`; `PutFile()` / `FetchFile()` via sftp.
Local connector (`pkg/connector/local_connector.go`): `ExecuteCommand()` via `os/exec`; `PutFile()` / `FetchFile()` operate on the local filesystem.
Fact gathering (`pkg/connector/gather_facts.go`): local/ssh connectors implement `HostInfo()`, collecting OS, arch, hostname, IP, memory and CPU facts.
Modules must stay decoupled from the local OS: always go through the `Connector` interface, never hardcode Linux paths or bash-only syntax.
### 3.7 Modules
Registry:
```text
pkg/modules/internal/options.go
├── RegisterModule(fn, names...)
├── FindModule(name)
└── ModuleExecFunc signature
```
Module list (registered in `pkg/modules/module.go`):
| Module | Package | Key file |
|--------|---------|----------|
| add_hostvars | `pkg/modules/add_hostvars` | `add_hostvars.go` |
| assert | `pkg/modules/assert` | `assert.go` |
| command/shell | `pkg/modules/command` | `command.go` |
| copy | `pkg/modules/copy` | `copy.go` |
| debug | `pkg/modules/debug` | `debug.go` |
| fetch | `pkg/modules/fetch` | `fetch.go` |
| gen_cert | `pkg/modules/gen_cert` | `gen_cert.go` |
| http_get_file | `pkg/modules/http_get_file` | `http_get_file.go` |
| image | `pkg/modules/image` | `image.go`, `image_deprecated.go`, `repository.go` |
| include_vars | `pkg/modules/include_vars` | `include_vars.go` |
| prometheus | `pkg/modules/prometheus` | `prometheus.go` |
| result | `pkg/modules/result` | `result.go` |
| set_fact | `pkg/modules/set_fact` | `set_fact.go` |
| setup | `pkg/modules/setup` | `setup.go` |
| template | `pkg/modules/template` | `template.go` |
Representative implementations:
```text
pkg/modules/command/command.go:ModuleCommand(ctx, opts)
├── render args through template
├── build command string
├── opts.Connector.ExecuteCommand(cmd)
└── return stdout/stderr
pkg/modules/copy/copy.go:ModuleCopy(ctx, opts)
├── resolve src/content
├── optionally template content
├── opts.Connector.PutFile(data, dst, mode)
└── return result
pkg/modules/template/template.go:ModuleTemplate(ctx, opts)
├── read src template
├── render with variables
├── opts.Connector.PutFile(rendered, dst, mode)
└── return result
```
### 3.8 Templates, `when` and Tags
Rendering:
```text
pkg/converter/tmpl/template.go:ParseFunc()
├── if string contains "{{" and "}}":
│ └── text/template.Execute()
└── else return original string
```
Custom functions (`pkg/converter/tmpl/functions.go`), on top of Sprig:
```text
toYaml / fromYaml / toToml
ipInCIDR / ipFamily / isIP
pow / subtractList
fileExists / unquote / getStringSlice
toLowerByteUnit
mapToNamedStringArgs
```
**`when` conditions** (`api/project/v1/conditional.go`) are always wrapped as templates and rendered to a boolean-like result. They can be defined at **role**, **block** and **task** level:
- Role-level `when` is inherited by all blocks and tasks in that role.
- Block-level `when` is merged with parent block/role conditions and inherited by nested blocks and leaf tasks.
- Task-level `when` is evaluated per host right before module execution.
- All inherited conditions must evaluate to true for a task to run.
**Tags** (`api/project/v1/taggable.go`):
```text
Tags []string
AlwaysTag = "always"
NeverTag = "never"
AllTag = "all"
TaggedTag = "tagged"
IsEnabled(onlyTags, skipTags) bool
```
Tags are inherited the same way as `when`: role → block → nested block/task. Use `JoinTag()` to merge parent tags into child tags. Runtime filtering uses `playbook.Spec.Tags` (only run matching) and `playbook.Spec.SkipTags` (skip matching), typically set via CLI `--tags` and `--skip-tags`.
| Tag | Meaning |
|-----|---------|
| `always` | Always runs unless explicitly skipped by `always` in skipTags. |
| `never` | Never runs unless explicitly included. |
| `all` | Matches every block except those tagged `never`. |
| `tagged` | Matches any block that has at least one tag. |
Matching rules for `onlyTags`:
- A block with `always` runs.
- `all` or `tagged` runs everything except `never`.
- Otherwise the block runs if any of its tags intersect with `onlyTags`.
- Blocks without matching tags are skipped.
Matching rules for `skipTags`:
- `all` skips everything except blocks tagged `always` (unless `always` is also in skipTags).
- Any tag intersection with `skipTags` skips the block.
- `tagged` skips all tagged blocks.
Like `when`, declare tags at the highest applicable scope; do not repeat the same tag at every nested level (see §4.4).
### 3.9 Kubernetes Controllers
Playbook controller:
```text
pkg/controllers/core/playbook_controller.go:Reconcile()
├── fetch Playbook CR
├── if no executor Pod exists:
│ └── create Pod running "kk playbook --name <name> --namespace <ns>"
├── watch owned Pods
└── sync Playbook status from Pod phase/logs
```
CAPKK controllers live in `pkg/controllers/infrastructure/`: `inventory_controller.go`, `kkcluster_controller.go`, `kkmachine_controller.go`.
Registration:
```text
pkg/controllers/core/register.go:init()
├── options.Register(&PlaybookReconciler{})
└── options.Register(&PlaybookWebhook{})
pkg/controllers/infrastructure/register.go:init()
└── registers Inventory/KKCluster/KKMachine reconcilers
```
### 3.10 REST Proxy / Web
Hybrid REST config:
```text
pkg/proxy/transport.go:RestConfig()
├── if no k8s cluster: use file-based storage for Task/Inventory/Playbook
└── if cluster exists: forward non-local resources to API server,
keep Task local
```
This lets `kk` run without a Kubernetes cluster while still using controller-runtime clients.
Web services (`pkg/web/service.go`):
```text
NewCoreService() # /api/v1/playbooks, /inventories, /logs
NewSchemaService() # schema listing and config
NewUIService() # static SPA UI
NewSwaggerUIService() # swagger UI
NewAPIService() # OpenAPI JSON
```
### 3.11 Built-in Kubernetes Install Flow
High-level flow of `builtin/core/playbooks/create_cluster.yaml`:
```text
1. native/root role on all hosts
2. hook/pre_install.yaml
3. load defaults + precheck on all hosts
4. on localhost:
generate certs, download binaries/images
5. on etcd/k8s_cluster/image_registry/nfs:
run native role
6. on etcd hosts (when external):
etcd prepare/install
7. on image_registry hosts:
docker + registry
8. on localhost (when registry configured):
push images
9. on k8s_cluster hosts:
CRI install
kubernetes pre/init/join
certs renewal
custom labels/taints
10. on a random control plane host:
CNI + storage class
11. hook/post_install.yaml
```
Default variables are loaded from `builtin/core/defaults/` and merged before playbook execution.
## 4. Universal Conventions
Follow these conventions when producing or modifying code.
### 4.1 Logging
Choose the appropriate log level.
| Level | Usage |
|-------|-------|
| `klog.Info` | Main business events. |
| `klog.Warning` | Recoverable abnormal situations. |
| `klog.Error` | Errors requiring attention. |
| `klog.V(4)` | Framework execution flow. Examples: `project`, `proxy`, `variable`, `connector`, `web`, `manager`, `controllers`, `executor`. |
| `klog.V(5)` | Extension modules. Examples: `module`, `converter`. |
| `klog.V(6)` | Debug information. May include detailed intermediate values and execution flow. |
### 4.2 Errors
Wrap errors only where they originate.
- Lower layers should use `errors.Wrap` (or equivalent) to add context.
- Upper layers should return the error directly unless adding meaningful business context.
- Do not repeatedly wrap the same error.
KubeKey uses `github.com/cockroachdb/errors` with `errors.Wrapf` / `errors.Join`.
### 4.3 Naming
Keep names concise. Prefer meaningful short names. Avoid unnecessary abbreviations and verbose names.
Avoid:
```go
tmpData
managerObject
projectConfiguration
```
Prefer:
```go
cfg
proj
mgr
conn
```
### 4.4 Architecture
Prefer modifying existing code instead of introducing new abstractions.
- Do not introduce new structs or interfaces unless there is a clear benefit.
- Keep APIs stable.
- Minimize public surface.
- Favor composition over inheritance-like patterns.
- Do not repeat inherited conditions (e.g. `when`, `tags`) at every level; declare them at the highest applicable scope (see §3.8).
### 4.5 Go Conventions
- Package aliases: `kkcorev1`, `kkcorev1alpha1`, `kkprojectv1`.
- `pkg/const` is imported as `_const` to avoid keyword collision.
- Options structs have `Flags()` and `Complete()` methods.
- Modules return `(stdout, stderr, err)` triples.
- Controllers and built-in commands register via `init()` gated by build tags.
- Templates use Go `text/template` + Sprig + custom functions in `pkg/converter/tmpl/`.
## 5. Build & Test
Important Makefile targets:
| Target | Purpose |
|--------|---------|
| `make kk` | Build `kk` binary with `BUILDTAGS=builtin` |
| `make build-kk-dev` | Dev build with branch-based version |
| `make controller-manager` | Build operator image |
| `make generate` | Deepcopy, CRDs, RBAC, modules, goimports |
| `make generate-manifests-kubekey` | Generate CRDs to `config/kubekey/crds/` |
| `make verify` | Verify generated artifacts and modules are up to date |
| `make test` | Run unit/integration tests with envtest |
| `make lint` | Run golangci-lint |
Build tags:
- `builtin` – includes embedded playbooks/roles and built-in CLI commands.
- `clusterapi` – CAPKK controller-manager image build.
## 6. Debugging Tips
- **Find where a built-in command is defined:** search `cmd/kk/app/builtin/*.go` for the command name.
- **Find where a module is implemented:** search `pkg/modules/<name>/<name>.go` and confirm registration in `pkg/modules/module.go`.
- **Trace variable values:** start at `pkg/variable/variable_get.go` and add logging in `GetFunc`.
- **Trace task execution:** add logging in `pkg/executor/task_executor.go` before `FindModule`.
- **Test a module locally:** look at existing `*_test.go` files; many use the fake connector from `pkg/modules/internal/test.go`.
- **Regenerate CRDs:** `make generate-manifests-kubekey`.
- **Build with built-ins:** `make kk` (sets `BUILDTAGS=builtin`).
## 7. Git Commit & PR Conventions
### Commit Message Format
Follow [Conventional Commits](https://www.conventionalcommits.org/):
```text
<type>: <short description>
```
Common types:
- `feat:` – new feature
- `fix:` – bug fix
- `refactor:` – code refactoring
- `docs:` – documentation only
- `test:` – tests
- `chore:` – build, dependencies, tooling
Examples:
```text
feat: support multiple ssh private keys
fix: preserve proxy configuration during reconnect
```
### Pull Request Description
A PR description should include:
- **What** changed and **why**.
- **How** it was implemented (briefly).
- **Testing** performed.
- **Risks / breaking changes**.
## 8. Appendix: File-to-Concern Map
| Concern | File |
|---------|------|
| CLI root | `cmd/kk/app/root.go` |
| CLI options base | `cmd/kk/app/options/option.go` |
| Built-in commands | `cmd/kk/app/builtin/*.go` |
| Controller options | `cmd/controller-manager/app/options/controller_manager.go` |
| Playbook execution | `pkg/executor/playbook_executor.go` |
| Role execution | `pkg/executor/role_executor.go` |
| Block execution | `pkg/executor/block_executor.go` |
| Task execution | `pkg/executor/task_executor.go` |
| Project loading | `pkg/project/project.go` |
| Git project | `pkg/project/git.go` |
| Local project | `pkg/project/local.go` |
| Builtin project | `pkg/project/builtin.go` |
| Variable core | `pkg/variable/variable.go` |
| Variable get | `pkg/variable/variable_get.go` |
| Variable merge | `pkg/variable/variable_merge.go` |
| Variable source | `pkg/variable/source/file_source.go` |
| Connector factory | `pkg/connector/connector.go` |
| SSH connector | `pkg/connector/ssh_connector.go` |
| Local connector | `pkg/connector/local_connector.go` |
| Kubernetes connector | `pkg/connector/kubernetes_connector.go` |
| Prometheus connector | `pkg/connector/prometheus_connector.go` |
| Module registry | `pkg/modules/module.go` |
| Module internals | `pkg/modules/internal/options.go` |
| Template functions | `pkg/converter/tmpl/functions.go` |
| Template rendering | `pkg/converter/tmpl/template.go` |
| Block↔Task converter | `pkg/converter/converter.go` |
| Playbook CRD | `api/core/v1/playbook_types.go` |
| Inventory CRD | `api/core/v1/inventory_types.go` |
| Config CRD | `api/core/v1/config_types.go` |
| Task CRD | `api/core/v1alpha1/task_types.go` |
| Project YAML types | `api/project/v1/playbook.go`, `play.go`, `block.go`, `role.go`, `base.go`, `taggable.go`, `conditional.go` |
| Playbook controller | `pkg/controllers/core/playbook_controller.go` |
| Web services | `pkg/web/service.go` |
| REST proxy | `pkg/proxy/transport.go` |
| Constants/workdir | `pkg/const/common.go`, `pkg/const/workdir.go`, `pkg/const/scheme.go` |
More agent context in kubesphere/kubekey
One other file this repository gives its agents.
Skill
- kubekeyskills/kubekey/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
No reports yet. Be the first to say whether it worked.
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

