Request for Enhancement: Feature Gate Support in controller-gen
Kubernetes core types support feature gates to control the exposure and behaviour of APIs under development. However, when working with CRDs through controller-gen, there is currently no built-in mechanism to conditionally generate CRD fields, RBAC, or webhook manifests based on feature gates. (https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/)
This makes it difficult to:
- Safely introduce new fields and behaviors in CRDs that are still experimental
- Prevent end users from using alpha-level features in production environments
- Run different controller configurations depending on enabled feature sets
Proposed Solution
Introduce a +kubebuilder:feature-gate=<gate-name> marker to allow Go struct fields, RBAC, and webhook configurations to be conditionally included or excluded in the generated output.
Additionally, support output segregation by gate level (e.g., alpha, beta, stable) so that manifests can be written into clearly separated folders or files for packaging and CI workflows.
Example: CRD Field Gating
// +kubebuilder:validation:MaxLength=63
// +kubebuilder:feature-gate=alpha
// +kubebuilder:validation:Required
Namespace string \`json:"namespace,omitempty"\`
Example: RBAC Marker Gating
// Always generated
// +kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch
// Only generated for the RBAC under the feature gate
// +kubebuilder:rbac:feature-gate=alpha;groups=apps,resources=deployments,verbs=get;list
Output Structure
To support separation of stable vs experimental manifests, controller-gen should allow gated manifests to be written to specific folders as follows:
```
config/crd/ ← default output for stable content
config/crd/alpha/ ← gated CRDs with alpha features enabled
config/rbac/ ← default RBAC rules
config/rbac/alpha/ ← additional RBAC for gated features
```
Makefile Integration
controller-gen should support new CLI flags that allow the user to pass feature gates and control the output directory per gate level.
Example Makefile usage:
.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." \
output:crd:artifacts:config=config/crd/bases
If not informed any path alpha(feature gate) will be output:crd:artifacts:config=config/crd/bases/
.PHONY: manifests
manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects.
$(CONTROLLER_GEN) rbac:roleName=manager-role crd webhook paths="./..." \
output:crd:artifacts:config=config/crd/bases
fetaure-gates:output:crd:artifacts:config=/to/path/<feature gate version>
I am as a dev I would like for example:
- Running `make manifests` for stable APIs
- Running `make manifests FEATURE_GATES=alpha` for alpha APIs=
- Running `make manifests` for both
- Having separate output trees per gate set for packaging and review
Thank you for your attention and time 🎉 Related to: https://github.com/kubernetes-sigs/kubebuilder/issues/849#issuecomment-3083772425
Introduce a +kubebuilder:feature-gate=
marker to allow Go struct fields, RBAC, and webhook configurations to be conditionally included or excluded in the generated output.
Does <gate-name> here refer to one of a specific set of choices, or, is it free-form text? Normally, feature gates are free form text, but you mention alpha, which I would refer to as a set of feature gates
Normally I would expect gates to move between sets (promote from alpha to beta) over time, I wouldn't expect to have to go change the feature code as part of this, but some atomic control would say this gate is now a different level or set
If these are freeform text, then we need to come up with a way to associate the gates to the levels/sets and then give that as input as an input to both the generators but also the controllers so that they are aligned.
Love it @camilamacedo86! I love it so much I requested it four years ago 😄
This RFE is basically a duplicate of #600 since it requests support for dropping both objects and fields if they are feature gated and that feature is not enabled.
The Kubernetes project currently lacks enough contributors to adequately respond to all issues.
This bot triages un-triaged issues according to the following rules:
- After 90d of inactivity,
lifecycle/staleis applied - After 30d of inactivity since
lifecycle/stalewas applied,lifecycle/rottenis applied - After 30d of inactivity since
lifecycle/rottenwas applied, the issue is closed
You can:
- Mark this issue as fresh with
/remove-lifecycle stale - Close this issue with
/close - Offer to help out with Issue Triage
Please send feedback to sig-contributor-experience at kubernetes/community.
/lifecycle stale
/remove-lifecycle stale /lifecycle frozen