Gate the remaining Enterprise-only code behind the variant extensions - #5170
Gate the remaining Enterprise-only code behind the variant extensions#5170caseydavenport wants to merge 14 commits into
Conversation
The certificate signing controller, the API server controller and the cluster connection controller take the variant's certificates from pkg/extensions.
The shared controller utils no longer reach into the Elasticsearch renderers.
The exception list names the three files that still do.
There was a problem hiding this comment.
Pull request overview
This PR continues the variant-extension refactor to keep core operator code variant-blind, moving remaining Enterprise-only behaviors (watches, startup checks, and Elasticsearch helpers) behind pkg/extensions to prepare for the OSS/Enterprise repo split.
Changes:
- Add new variant hooks for CSR and startup configuration validation, and route CSR controller behavior/watches through the extension interface.
- Move Elasticsearch helpers from shared controller utils into
pkg/controller/logstorage/esutilsand update callers accordingly. - Add an Enterprise boundary test to prevent core packages from importing Enterprise-only renderers (with a shrinking exception list), and update clusterconnection/apiserver secret watches to be variant-owned.
Reviewed changes
Copilot reviewed 37 out of 42 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| pkg/extensions/startup.go | New startup extension interface + noop implementation. |
| pkg/extensions/extensions.go | Wire CSR() and Startup() accessors into the extension registry. |
| pkg/extensions/csr.go | New CSR extension interface + noop implementation. |
| pkg/extensions/clusterconnection.go | Add TrustedBundleSecrets() to clusterconnection extension contract. |
| pkg/enterprise/startup/extension.go | Enterprise startup hook to validate internal/external ES cert mode. |
| pkg/enterprise/register.go | Register Enterprise implementations for CSR + startup extensions. |
| pkg/enterprise/options/options.go | Extend Enterprise options with ES mode fields needed by startup hook. |
| pkg/enterprise/enterprise_suite_test.go | New Enterprise package ginkgo suite entrypoint. |
| pkg/enterprise/csr/suite_test.go | New ginkgo suite for Enterprise CSR extension tests. |
| pkg/enterprise/csr/extension.go | Enterprise CSR behavior (signable assets, needs-role decision, watches). |
| pkg/enterprise/csr/extension_test.go | Unit tests for Enterprise CSR extension behavior change. |
| pkg/enterprise/clusterconnection/extension.go | Enterprise Guardian trusted-bundle secret list exposed via extension. |
| pkg/enterprise/boundary_test.go | New test enforcing no core imports of Enterprise-only render packages. |
| pkg/enterprise/apiserver/extension.go | Move Dex + Prometheus client cert watches into Enterprise apiserver hook. |
| pkg/controller/utils/utils.go | Remove ES-specific helpers from shared controller utils. |
| pkg/controller/utils/utils_test.go | Remove tests for ES helpers that moved out of shared utils. |
| pkg/controller/manager/manager_controller.go | Switch ES license lookup to logstorage/esutils. |
| pkg/controller/logstorage/users/users_controller.go | Switch ES helpers/types to logstorage/esutils. |
| pkg/controller/logstorage/users/users_controller_test.go | Update tests to use logstorage/esutils helpers/types. |
| pkg/controller/logstorage/linseed/linseed_controller.go | Switch ES readiness lookup to logstorage/esutils. |
| pkg/controller/logstorage/kubecontrollers/es_kube_controllers.go | Switch ES readiness lookup to logstorage/esutils. |
| pkg/controller/logstorage/esutils/test_files/01_put_policy.json | Test fixture for ES ILM policy PUT (case 01). |
| pkg/controller/logstorage/esutils/test_files/01_get_policy.json | Test fixture for ES ILM policy GET (case 01). |
| pkg/controller/logstorage/esutils/test_files/02_put_policy.json | Test fixture for ES ILM policy PUT (case 02). |
| pkg/controller/logstorage/esutils/test_files/02_put_policy_readonly.json | Test fixture for ES ILM policy PUT readonly (case 02). |
| pkg/controller/logstorage/esutils/test_files/02_get_policy.json | Test fixture for ES ILM policy GET (case 02). |
| pkg/controller/logstorage/esutils/esutils_suite_test.go | New ginkgo suite entrypoint for esutils. |
| pkg/controller/logstorage/esutils/elasticsearch.go | Move/rename ES helper package to esutils and add license + ES getters. |
| pkg/controller/logstorage/esutils/elasticsearch_test.go | Update package name + add moved tests for ES users + licensing helpers. |
| pkg/controller/logstorage/esutils/elasticsearch_cloud.go | Update package name to esutils. |
| pkg/controller/logstorage/elastic/mock.go | Update mock interfaces/types to esutils. |
| pkg/controller/logstorage/elastic/elastic_controller.go | Switch ES helpers to esutils. |
| pkg/controller/logstorage/elastic/elastic_controller_test.go | Update test helper signature to esutils creator type. |
| pkg/controller/logstorage/dashboards/dashboards_controller.go | Switch ES readiness lookup to esutils. |
| pkg/controller/intrusiondetection/intrusiondetection_controller.go | Switch ES readiness lookup to esutils. |
| pkg/controller/inputs.go | Add new CSR input name constant. |
| pkg/controller/csr/csr_controller.go | Route watches/assets/role-decision via CSR extension instead of Enterprise hard-codes. |
| pkg/controller/csr/csr_controller_test.go | Update CSR controller tests to use a stub CSR extension. |
| pkg/controller/clusterconnection/clusterconnection_controller.go | Build Guardian trusted bundle from core + extension-provided secret list. |
| pkg/controller/apiserver/apiserver_controller.go | Remove Enterprise-only secret watches from core apiserver controller. |
| docs/principles.md | Document product-variant principles and the Enterprise render boundary rule. |
| cmd/main.go | Move startup config validation behind the new startup extension hook. |
Suppressed comments (2)
pkg/controller/logstorage/esutils/elasticsearch.go:713
- logr.Logger.Info does not do printf-style formatting. Using a "%s" format string here will produce a misleading log entry (and can drop the value as an unmatched key). Use structured key/value logging instead.
pkg/controller/csr/csr_controller.go:110 - This error message references "monitor-controller", but this is the CSR controller watching the Installation resource. The mismatched controller name makes startup failures harder to diagnose.
if err = opts.Extensions.CSR().Watches(c); err != nil {
return fmt.Errorf("csr-controller failed to set up extension watches: %w", err)
}
if err = c.WatchObject(&operatorv1.Installation{}, &handler.EnqueueRequestForObject{}); err != nil {
return fmt.Errorf("monitor-controller failed to watch primary resource: %w", err)
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| // Watches registers the Monitor CR, which decides whether the CSR role is needed. | ||
| func (e *Extension) Watches(c ctrlruntime.Controller) error { | ||
| if err := c.WatchObject(&operatorv1.Monitor{}, &handler.EnqueueRequestForObject{}); err != nil { | ||
| return fmt.Errorf("csr-controller failed to watch Monitor: %w", err) | ||
| } | ||
| return nil | ||
| } |
The OSS operator will not ship the Enterprise CRDs, so core controllers and render packages must stop referring to their Go types. Seventeen files still do and are on an exception list.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 37 out of 42 changed files in this pull request and generated no new comments.
Suppressed comments (3)
pkg/controller/csr/csr_controller.go:110
- The Installation watch error message references "monitor-controller", which is misleading in CSR controller setup and makes troubleshooting harder.
if err = c.WatchObject(&operatorv1.Installation{}, &handler.EnqueueRequestForObject{}); err != nil {
return fmt.Errorf("monitor-controller failed to watch primary resource: %w", err)
}
pkg/controller/logstorage/esutils/elasticsearch.go:713
- logr's Info() is not printf-style; passing a format string with a single arg results in an odd key/value pair and a malformed log entry. Use structured logging (or fmt.Sprintf) instead.
pkg/enterprise/csr/extension.go:80 - NeedsCSRRole() checks for a NonClusterHost, but Watches() only watches the Monitor CR. If a NonClusterHost is created/removed after startup, the CSR controller may not reconcile to create/delete the CSR ClusterRole before the first CSR is submitted (which can block CSR creation). Add a watch for NonClusterHost to keep the signing-role decision reactive.
Typha, the istio policy-sync prefix, and the webhooks management-cluster config now take plain values instead of reading Enterprise CRs in core.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 55 out of 60 changed files in this pull request and generated no new comments.
Suppressed comments (2)
pkg/controller/logstorage/esutils/elasticsearch.go:712
- logr.Logger.Info does not support printf-style formatting. This call will log the literal "%s" rather than the license value, which makes troubleshooting harder.
pkg/enterprise/csr/extension.go:80 - NeedsCSRRole() depends on the NonClusterHost CR, but the extension only watches Monitor. Creating/deleting a NonClusterHost will not trigger reconciliation, so the CSR ClusterRole may not be created/removed until some unrelated event occurs.
The certificate manager only needed to know whether the cluster is multi-tenant, and the two tenant-scoped render helpers moved to their own Enterprise-only file.
The shared controller utils package no longer reads Enterprise-only CRs, and core code importing anything under pkg/enterprise is now a boundary violation too.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 85 out of 93 changed files in this pull request and generated no new comments.
Suppressed comments (2)
pkg/controller/logstorage/esutils/elasticsearch.go:713
logr.Logger'sInfodoes not support printf-style formatting; passing a single extra argument also results in an odd key/value list. Log the license as a structured field instead.
pkg/enterprise/utils/utils.go:58- Typo in the comment: “AplicationLayer” should be “ApplicationLayer”.
The es-kube-controllers assembler now wraps the generic config with the Authentication and ManagementCluster it reads. The Tenant field was dead - its only caller always passed nil.
The cloudconfig package no longer builds an Enterprise CR.
The tiers controller no longer branches on the variant to decide which namespaces need DNS access, nor watches Tenant itself.
It only runs in multi-tenant mode, so it is deleted wholesale on the OSS side. No core file names an Enterprise-only kind now.
Creating a NonClusterHost now triggers a reconcile, so the signing role appears without waiting for an unrelated event. Also fixes a printf-style log call and two misleading strings.
Description
Prep for splitting the operator across the OSS and Enterprise monorepos. Core code should never name an Enterprise-only resource, and a handful of places still did.
One behavior change worth flagging: with no monitoring resource present, the signing-role decision now falls through to the non-cluster host check instead of returning early. The non-cluster host check was being skipped in that case.