controller-tools icon indicating copy to clipboard operation
controller-tools copied to clipboard

Request for Enhancement: Feature Gate Support in controller-gen

Open camilamacedo86 opened this issue 5 months ago • 4 comments

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/ Otherwise, we could either:

.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

camilamacedo86 avatar Jul 17 '25 13:07 camilamacedo86

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.

JoelSpeed avatar Jul 17 '25 15:07 JoelSpeed

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.

akutz avatar Aug 13 '25 13:08 akutz

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/stale is applied
  • After 30d of inactivity since lifecycle/stale was applied, lifecycle/rotten is applied
  • After 30d of inactivity since lifecycle/rotten was 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

k8s-triage-robot avatar Nov 11 '25 14:11 k8s-triage-robot

/remove-lifecycle stale /lifecycle frozen

sbueringer avatar Nov 11 '25 16:11 sbueringer