devantler-tech / devantler-tech/ksail
Evaluate Kubebuilder PROJECT support for controller scaffolding
- Dominant language
- Go
- Stars
- 165
- Forks
- 12
- Avg merge
- 5h 51m
- Merged PRs (30d)
- 347
Description
> 🤖 Generated by the Agentic Engineer
## Summary
Timebox a go/no-go decision on adopting a root `PROJECT` file and the Kubebuilder CLI as KSail's maintained scaffolding contract for future Kubernetes APIs, controllers, and webhooks. A metadata-only `PROJECT` file is explicitly not a successful outcome.
## Evidence
At live `main` commit [`db472e9a`](https://github.com/devantler-tech/ksail/tree/db472e9a411017f239850f4438f598250aba0fd9):
- KSail has a real controller-runtime operator, but no root `PROJECT` file or Kubebuilder `config/` tree.
- The shared CLI/CRD model lives in [`pkg/apis/cluster/v1alpha1`](https://github.com/devantler-tech/ksail/tree/db472e9a411017f239850f4438f598250aba0fd9/pkg/apis/cluster/v1alpha1), the reconciler in [`internal/controller`](https://github.com/devantler-tech/ksail/tree/db472e9a411017f239850f4438f598250aba0fd9/internal/controller), manager wiring in [`pkg/operator`](https://github.com/devantler-tech/ksail/tree/db472e9a411017f239850f4438f598250aba0fd9/pkg/operator), and deployment in [`charts/ksail-operator`](https://github.com/devantler-tech/ksail/tree/db472e9a411017f239850f4438f598250aba0fd9/charts/ksail-operator).
- KSail already uses Kubebuilder API/RBAC markers and pinned `controller-gen` invocations to generate DeepCopy code and the Helm-shipped CRD through `make generate`.
- The repository has no `+kubebuilder:scaffold:*` insertion markers, Kubebuilder CLI workflow, or envtest harness. Those are the integration points used by `kubebuilder create api` rather than information supplied by `PROJECT` alone.
Kubebuilder documents `PROJECT` as versioned CLI/plugin input metadata used to make scaffolding decisions. Its default `go/v4` layout composes Go scaffolding with Kustomize output under `config/` and relies on scaffold markers in expected files. KSail's current package, manager, and Helm layout therefore needs executable compatibility proof before claiming that contract.
## Audience and problem
Contributors and agents adding another KSail operator API, controller, or webhook currently have no reproducible repository-level scaffold that wires the API, scheme, manager, generated artifacts, tests, and deployment surfaces together. Repeating that wiring manually risks drift, but adding a hand-authored `PROJECT` file without a working CLI path would be worse: it would advertise compatibility that future scaffolds cannot use safely.
## Hypothesis and success signal
**Hypothesis:** if a pinned Kubebuilder version can scaffold a disposable second API/controller into KSail's approved architecture without moving its public API package or replacing the Helm delivery path, a maintained `PROJECT` contract will reduce setup drift for future operator growth.
**Success signal:** from a clean, exact KSail revision, a documented Kubebuilder command creates and registers a disposable probe API/controller; the resulting diff touches only approved surfaces; regeneration and repository validation pass; and the same command is protected by a small CI contract. The result must be reproducible by a future contributor without hand-editing generated files.
## Guardrails
- Preserve `github.com/devantler-tech/ksail/v7/pkg/apis/cluster/v1alpha1` as the public Go API and the shared CLI/CRD model.
- Preserve Helm as the operator deployment and CRD delivery surface unless a separate evidence-backed roadmap decision changes it.
- Never hand-edit generated CRDs, DeepCopy code, schemas, or generated documentation.
- Do not commit a `PROJECT` file merely to satisfy tool detection; the pinned CLI must consume it successfully.
- Keep implementation outside this Spike. Its output is a recorded decision and separately tracked delivery work.
## Investigation
1. Select and record a Kubebuilder CLI version compatible with KSail's current Kubernetes and controller-runtime dependencies.
2. From a disposable clean worktree, test the narrowest suitable official plugin/layout and scaffold one probe API/controller.
3. Capture the exact command, generated diff, manager/scheme registration behavior, CRD/RBAC output path, and any incompatibilities with KSail's package and Helm layout.
4. Compare the result with two alternatives: retain the current `controller-gen` workflow plus a small KSail-owned scaffold, or perform a broader Kubebuilder layout migration as separate roadmap work.
5. Remove the disposable probe and record the go/no-go decision on this issue.
## Acceptance criteria
- [ ] Record the exact baseline commit, Kubebuilder version, plugin/layout, and dependency-compatibility rationale.
- [ ] Demonstrate an end-to-end disposable API/controller scaffold, or reproduce precisely why the CLI cannot support KSail's architecture.
- [ ] Verify API placement, scheme registration, controller registration, CRD generation, RBAC treatment, Helm integration, and test placement rather than checking only that files were emitted.
- [ ] Run `make generate`, `go build -o /tmp/ksail-maint .`, `go test ./...`, and `golangci-lint run --timeout 5m` against the evaluated result, recording any failure as evidence rather than weakening a gate.
- [ ] Record a decision comment containing evidence, options considered, the chosen path, and why it meets the guardrails.
- [ ] File and link the delivery issue(s) implied by the chosen path as real sub-issues before closing this Spike.
## Decision rules
Choose `PROJECT` only when the pinned Kubebuilder CLI can consume it end to end, future scaffolds land in approved paths, and CI can detect contract drift. Choose a KSail-owned scaffold instead if standard plugins require a broad layout migration or a custom plugin whose maintenance cost exceeds the expected controller growth. A broader migration must be justified and tracked independently; it is not an implicit outcome of this Spike.
## Alternatives considered
- Keep the current markers plus `controller-gen` workflow and document manual wiring.
- Add a small KSail-owned generator or template that matches the existing package and Helm architecture.
- Migrate the operator to a conventional Kubebuilder layout in separate, incremental delivery issues.
## Rough size
**S — one focused investigation.** Any implementation is separate delivery work.
## References
- [Kubebuilder project configuration](https://master.book.kubebuilder.io/reference/project-config.html)
- [Kubebuilder go/v4 plugin](https://book.kubebuilder.io/plugins/available/go-v4-plugin.html)
- [Kubebuilder scaffold markers](https://book.kubebuilder.io/reference/markers/scaffold.html)
- [Kubebuilder Kustomize v2 plugin](https://book.kubebuilder.io/plugins/available/kustomize-v2.html)
Contributor guide
Research direction
Start with pkg/apis/cluster/v1alpha1, internal/controller, pkg/operator, and charts/ksail-operator, then inspect the existing make generate workflow and Kubebuilder project configuration. In a disposable clean worktree, run the pinned CLI against a probe API/controller and then run make generate, go build -o /tmp/ksail-maint ., go test ./..., and golangci-lint run --timeout 5m. Done means recording compatibility evidence, the generated diff, a go/no-go decision, and linked delivery issues.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, helm, kubernetes
- Domain
- build-system, devops, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100