Repository navigation
feat: add minimal API v2 controller runtime - #2442
Conversation
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
There was a problem hiding this comment.
Pull request overview
This PR introduces a minimal “API v2” controller runtime and aligns the Substrate integration with newer runtime defaults by switching ate-api authentication from bearer tokens/insecure TLS to projected PodCertificate-based mTLS, while also adding a generated typed clientset for Kagent v1alpha3 resources.
Changes:
- Add a standalone
controller-v2entrypoint and wire it to the v2 KRT runtime/collections using typed Kubernetes clients. - Switch Substrate ate-api connectivity to mTLS (ClusterTrustBundle + PodCertificate projections) and update Helm values/templates/tests accordingly.
- Introduce v1alpha3 typed clientset generation (
client-gen) and commit generated clientset code.
Reviewed changes
Copilot reviewed 25 out of 44 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| scripts/kind/kind-config.yaml | Enables Kind feature gates/runtime APIs needed for Substrate identity/trust-bundle projection. |
| Makefile | Updates controller image build to target the new controller-v2 entrypoint. |
| helm/kagent/values.yaml | Removes deprecated substrate ate-api token/insecure configuration values. |
| helm/kagent/tests/controller-deployment_test.yaml | Updates Helm unit tests to validate Substrate mTLS env/volume projections. |
| helm/kagent/templates/controller-deployment.yaml | Switches substrate volume/env wiring from projected SA tokens to ClusterTrustBundle + PodCertificate. |
| go/Makefile | Adds client-generate and includes it in generate. |
| go/core/v2/substrate/actor_template.go | Aligns generated ActorTemplate defaults with Substrate v0.0.11 (readyz timeout, snapshot resume). |
| go/core/v2/substrate/actor_template_test.go | Extends tests to assert new runtime contract defaults. |
| go/core/v2/controller/runtime.go | Uses the new v2 apiclient wrapper to create the KRT client. |
| go/core/v2/controller/reconciler.go | Switches status updates to use generated typed clientset UpdateStatus. |
| go/core/v2/controller/collections.go | Removes ad-hoc KRT type registration in favor of generated clients/registry wiring. |
| go/core/v2/controller/apiclient/types.go | Registers Kagent/Substrate types with KRT registry using generated clientsets. |
| go/core/v2/controller/apiclient/client.go | Introduces a composite client exposing both Istio kube client and generated clientsets. |
| go/core/pkg/sandboxbackend/substrate/config.go | Replaces token/insecure settings with CA + client cert file paths for mTLS. |
| go/core/pkg/sandboxbackend/substrate/client.go | Implements verified TLS + optional mTLS client cert loading for ate-api gRPC. |
| go/core/pkg/sandboxbackend/substrate/client_test.go | Updates tests for CA/client-cert based TLS config and verified dial path. |
| go/core/pkg/app/app.go | Updates Substrate config flags/env mapping to CA/client-cert files and wiring into substrate client. |
| go/core/pkg/app/app_test.go | Updates flag/env tests for the new Substrate mTLS flags/env vars. |
| go/core/cmd/controller-v2/main.go | Adds the standalone controller-v2 binary entrypoint and runtime wiring. |
| go/api/v1alpha3/remotemcpserver_types.go | Adds +genclient marker to enable typed client generation. |
| go/api/v1alpha3/modelconfig_types.go | Adds +genclient marker to enable typed client generation. |
| go/api/v1alpha3/harness_types.go | Adds +genclient marker to enable typed client generation. |
| go/api/v1alpha3/groupversion_info.go | Adds SchemeGroupVersion alias for generated client conventions. |
| go/api/v1alpha3/agenttemplate_types.go | Adds +genclient marker to enable typed client generation. |
| go/api/clientset/versioned/typed/api/v1alpha3/remotemcpserver.go | Generated typed client for RemoteMCPServer. |
| go/api/clientset/versioned/typed/api/v1alpha3/modelconfig.go | Generated typed client for ModelConfig. |
| go/api/clientset/versioned/typed/api/v1alpha3/harness.go | Generated typed client for Harness. |
| go/api/clientset/versioned/typed/api/v1alpha3/generated_expansion.go | Generated expansion interfaces for typed clients. |
| go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_remotemcpserver.go | Generated fake typed client for RemoteMCPServer. |
| go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_modelconfig.go | Generated fake typed client for ModelConfig. |
| go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_harness.go | Generated fake typed client for Harness. |
| go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_api_client.go | Generated fake API group client for v1alpha3. |
| go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_agenttemplate.go | Generated fake typed client for AgentTemplate. |
| go/api/clientset/versioned/typed/api/v1alpha3/fake/doc.go | Generated docs for fake typed clients. |
| go/api/clientset/versioned/typed/api/v1alpha3/doc.go | Generated docs for typed clients. |
| go/api/clientset/versioned/typed/api/v1alpha3/api_client.go | Generated API group client implementation for v1alpha3. |
| go/api/clientset/versioned/typed/api/v1alpha3/agenttemplate.go | Generated typed client for AgentTemplate. |
| go/api/clientset/versioned/scheme/register.go | Generated scheme registration for the clientset. |
| go/api/clientset/versioned/scheme/doc.go | Generated docs for clientset scheme package. |
| go/api/clientset/versioned/fake/register.go | Generated scheme registration for fake clientset. |
| go/api/clientset/versioned/fake/doc.go | Generated docs for fake clientset package. |
| go/api/clientset/versioned/fake/clientset_generated.go | Generated fake clientset implementation. |
| go/api/clientset/versioned/clientset.go | Generated real clientset implementation. |
| examples/substrate-openclaw/README.md | Updates Substrate version and removes insecure ate-api example configuration. |
Files not reviewed (19)
- go/api/clientset/versioned/clientset.go: Generated file
- go/api/clientset/versioned/fake/clientset_generated.go: Generated file
- go/api/clientset/versioned/fake/doc.go: Generated file
- go/api/clientset/versioned/fake/register.go: Generated file
- go/api/clientset/versioned/scheme/doc.go: Generated file
- go/api/clientset/versioned/scheme/register.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/agenttemplate.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/api_client.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/doc.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/fake/doc.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_agenttemplate.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_api_client.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_harness.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_modelconfig.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/fake/fake_remotemcpserver.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/generated_expansion.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/harness.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/modelconfig.go: Generated file
- go/api/clientset/versioned/typed/api/v1alpha3/remotemcpserver.go: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| func namespaces(value string) []string { | ||
| if value == "" { | ||
| return nil | ||
| } | ||
| return strings.Split(value, ",") | ||
| } |
There was a problem hiding this comment.
Fixed in cf0b325. WATCH_NAMESPACES entries are now trimmed and empty segments are dropped, with a focused parser test.
| kubeclient.Register( | ||
| kagentv1alpha3.GroupVersion.WithResource("agenttemplates"), | ||
| kagentv1alpha3.GroupVersion.WithKind("AgentTemplate"), | ||
| func(c kubeclient.ClientGetter, namespace string, options metav1.ListOptions) (runtime.Object, error) { | ||
| return c.(Client).Kagent().ApiV1alpha3().AgentTemplates(namespace).List(context.Background(), options) | ||
| }, |
There was a problem hiding this comment.
Leaving this as-is. These callbacks are registered specifically for this package’s composite Client, matching agentgateway’s KRT client pattern. The write callback cannot return an error, so a different ClientGetter here is a programmer wiring error rather than recoverable runtime input.
| func New(config *rest.Config) (Client, error) { | ||
| kubeClient, err := kube.NewClient(kube.NewClientConfigForRestConfig(config), cluster.ID("kagent")) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| kagent, err := kagentclient.NewForConfig(config) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| substrate, err := ateclient.NewForConfig(config) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
|
|
||
| RegisterTypes() | ||
| return &client{Client: kubeClient, kagent: kagent, substrate: substrate}, nil | ||
| } |
There was a problem hiding this comment.
Fixed in cf0b325. RegisterTypes is now guarded by sync.Once, and a concurrent registration test passes under the race detector.
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Summary
Verification
go test ./core/v2/... ./api/clientset/... ./core/cmd/controller-v2 ./core/pkg/app ./core/pkg/sandboxbackend/substratehelm unittest helm/kagent(268 tests)READY, Delete returnedDELETED, and subsequent Get returnednot_foundA2A behavior and gateway routing are intentionally deferred; this PR proves the imperative AgentInstance lifecycle.