refactor: webhook migration runtime swap - #2024
Conversation
Title(Describe updated until commit f3580d7)refactor: migrate webhook infrastructure from Knative to controller-runtime Description
Changes walkthrough 📝
|
PR Reviewer Guide 🔍(Review updated until commit f3580d7)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to f3580d7
Previous suggestionsSuggestions up to commit ca82959
|
Add the Knative-compatible surface that the validation files depend on so PR B can swap their import path without rewriting them: - Also(other): nil-safe accumulation of sibling errors via an internal slice so chained .Also calls do not lose entries. - ViaField(prefix...): nil-safe path prepending across the receiver and any accumulated children. ViaIndex(i) wraps it for [i] segments. - ErrGeneric(msg, paths...): generic constructor with optional paths. - Details string field, rendered on a new line after the message+path. - Error() rewritten to flatten and stably-sort accumulated entries into a single newline-separated message. - WithBaseline / GetBaseline for create-vs-update detection in Validate(ctx), keyed off an unexported context-key type. Existing exports (ErrInvalidValue, ErrMissingField, ConditionType, ConditionReady) are unchanged. Behavior is covered by a new unit test file that exercises nil-safety, accumulation, path prepending under ViaField+ViaIndex, baseline round-trip, and Details rendering.
…n files
Mechanical import-path swap from knative.dev/pkg/apis to the KAITO local
shim (github.com/kaito-project/kaito/pkg/apis) across all Validate(...)
methods on Workspace, InferenceSet, RAGEngine, and tuning/inference
ConfigMap helpers, plus the GetOutputDirFromTrainingArgs helper in
pkg/workspace/tuning.
To match Knative's signatures so this swap stays mechanical, the shim
gains:
- variadic Also(others ...*FieldError) so existing chained calls keep
compiling unchanged.
- variadic ErrInvalidValue(value, field, details ...string) so call
sites passing extra context (e.g. inferenceset_validation.go) continue
to work.
- WithinUpdate / WithinCreate aliases mirroring the Knative spelling
used in api/v1beta1/workspace_validation_test.go.
go test ./pkg/apis/... ./api/... passes. The knative-typed webhook
bootstraps in pkg/{workspace,ragengine}/webhooks still fail to compile
against the new shim-typed Validate; rewriting them onto controller-
runtime is the next checkpoint.
…Validator
Replace the Knative validation.NewAdmissionController + GenericCRD
registration in pkg/{workspace,ragengine}/webhooks with controller-runtime
admission.CustomValidator handlers.
The validator types are intentionally thin bridges: each ValidateCreate /
ValidateUpdate narrows the runtime.Object to the concrete KAITO type and
delegates to the existing Validate(ctx) (*apis.FieldError) method. The
update path stamps apis.WithinUpdate on the context first so Validate's
apis.GetBaseline branch fires (matching Knative's create-vs-update semantics).
ValidateDelete is a no-op, mirroring the prior Knative configuration which
only registered Create + Update via SupportedVerbs.
SetupWebhooksWithManager is the new entrypoint each cmd/main.go will call
to register handlers against mgr.GetWebhookServer(). cert-controller wiring
(reserving certs, gating startup on rotator readiness) is the next checkpoint.
webhooks_test.go is replaced: the old tests asserted on Knative-only
exports (NewControllerWebhooks, WorkspaceResources, InferenceSetResources)
that no longer exist. The new tests cover the bridge: type-mismatch returns
an error instead of panicking, ValidateDelete is a no-op, and ValidateUpdate
seeds apis.GetBaseline with the old object.
Replace the legacy knative.dev/pkg sharedmain.MainWithConfig webhook bootstrap in both cmd/workspace/main.go and cmd/ragengine/main.go with controller-runtime's webhook server backed by open-policy-agent cert-controller for TLS rotation. In each binary: - Add an `if enableWebhook` block that constructs a rotator.CertRotator pointed at the existing webhook Secret (workspace-webhook-cert / ragengine-webhook-cert) and ValidatingWebhookConfiguration (validation.workspace.kaito.sh / validation.ragengine.kaito.sh). - Configure mgr.GetWebhookServer().(*webhook.DefaultServer).Options with the same CertDir cert-controller writes to, plus the port from the WEBHOOK_PORT env var. - Spawn a goroutine that waits on rotator.IsReady before calling the package-local webhooks.SetupWebhooksWithManager so the server never serves a request without valid TLS material. - Use the existing withShutdownSignal context for mgr.Start instead of ctrl.SetupSignalHandler, so cancellation flows through both halves. Also fold in two trivial gofmt-only fixups left over from the earlier import-swap commit so the tree is gofmt-clean.
go mod tidy after the cmd/{workspace,ragengine} swap removes
knative.dev/pkg and a long tail of its transitive deps
(opencensus, zapdriver, grpc-gateway, etc.) and pulls in the
cert-controller transitive set (notably go.uber.org/atomic).
Pinned to cert-controller v0.15.0 to avoid the v0.16+ bump of
sigs.k8s.io/controller-runtime to v0.23.x, which would force a
larger upgrade outside the scope of this PR.
The `_ = time.Second` lines in cmd/workspace/main.go and cmd/ragengine/main.go were scaffolding I left in while iterating on the cert-controller swap, to keep the `time` import valid between edits. The new bootstrap doesn't sleep anywhere (the old knative path slept 2s after starting the webhook goroutine), so both the placeholder and the import can go.
assert.Error / assert.NoError continue past a failure, which makes later assertions panic on the nil err / nil return value rather than report the actual problem. Switch the four error-path assertions in the kaitoValidator bridge tests to require.* so the failing test stops at the line that actually broke. Untouched: assert.Nil / assert.Same calls that legitimately tolerate later assertions running.
…ject) The mechanical knative.dev/pkg/apis -> github.com/kaito-project/kaito/pkg/apis swap in d5ffab3 dropped the new import next to the unrelated k8s.io / sigs.k8s.io block, which trips gci. Re-run gci with the project's configured ordering (standard, prefix(github.com/kaito-project), default) across every file the swap touched so the kaito import lives in the kaito group with a blank line separating it from the third-party block.
Reason for Change:
Wire up the new webhook controller runtime for #1981
Requirements
Issue Fixed:
Notes for Reviewers: