Skip to content

Commit 7cef34f

Browse files
committed
Add feature gate discovery tests and improve parser
1 parent 5d99803 commit 7cef34f

File tree

7 files changed

+494
-193
lines changed

7 files changed

+494
-193
lines changed

FEATURE_GATES.md

Lines changed: 0 additions & 191 deletions
This file was deleted.

docs/book/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
- [Object/DeepCopy](./reference/markers/object.md)
9696
- [RBAC](./reference/markers/rbac.md)
9797
- [Scaffold](./reference/markers/scaffold.md)
98+
- [Feature Gates](./reference/markers/feature-gates.md)
9899

99100
- [controller-gen CLI](./reference/controller-gen.md)
100101
- [completion](./reference/completion.md)

docs/book/src/reference/markers.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ controller-gen:
3838

3939
- `make manifests` generates Kubernetes object YAML, like
4040
[CustomResourceDefinitions](./markers/crd.md),
41-
[WebhookConfigurations](./markers/webhook.md), and [RBAC
42-
roles](./markers/rbac.md).
41+
[WebhookConfigurations](./markers/webhook.md), [RBAC
42+
roles](./markers/rbac.md), and [Feature Gates](./markers/feature-gates.md).
4343

4444
- `make generate` generates code, like [runtime.Object/DeepCopy
4545
implementations](./markers/object.md).
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Feature Gates
2+
3+
Feature gates allow you to enable or disable experimental features in your Kubebuilder controllers. This is similar to how Kubernetes core uses feature gates to manage experimental functionality.
4+
5+
## Overview
6+
7+
Feature gates provide a mechanism to:
8+
- Control the availability of experimental features
9+
- Enable gradual rollout of new functionality
10+
- Maintain backward compatibility during API evolution
11+
12+
## Usage
13+
14+
### Marking Fields with Feature Gates
15+
16+
Use the `+feature-gate` marker to mark experimental fields in your API types:
17+
18+
```go
19+
type MyResourceSpec struct {
20+
// Standard field
21+
Name string `json:"name"`
22+
23+
// Experimental field that requires the "experimental-bar" feature gate
24+
// +feature-gate experimental-bar
25+
Bar *string `json:"bar,omitempty"`
26+
}
27+
```
28+
29+
### Running with Feature Gates
30+
31+
Enable feature gates when running your controller:
32+
33+
```bash
34+
# Enable a single feature gate
35+
./manager --feature-gates=experimental-bar
36+
37+
# Enable multiple feature gates
38+
./manager --feature-gates=experimental-bar,advanced-features
39+
40+
# Mixed enabled/disabled states
41+
./manager --feature-gates=experimental-bar=true,advanced-features=false
42+
```
43+
44+
### Feature Gate Formats
45+
46+
The `--feature-gates` flag accepts:
47+
- `feature1` - Enables feature1 (defaults to true)
48+
- `feature1=true` - Explicitly enables feature1
49+
- `feature1=false` - Explicitly disables feature1
50+
- `feature1,feature2` - Enables both features
51+
- `feature1=true,feature2=false` - Mixed states
52+
53+
## Best Practices
54+
55+
### Naming Conventions
56+
57+
Use descriptive, lowercase names with hyphens:
58+
-`experimental-bar`
59+
-`advanced-features`
60+
-`ExperimentalBar`
61+
-`advanced_features`
62+
63+
### Documentation
64+
65+
Always document feature-gated fields:
66+
67+
```go
68+
// Bar is an experimental field that requires the "experimental-bar" feature gate
69+
// +feature-gate experimental-bar
70+
// +optional
71+
Bar *string `json:"bar,omitempty"`
72+
```
73+
74+
### Gradual Rollout Strategy
75+
76+
1. **Alpha**: Feature behind feature gate
77+
2. **Beta**: Feature enabled by default, gate for opt-out
78+
3. **Stable**: Remove feature gate, feature always available
79+
80+
## Future Integration
81+
82+
When [controller-tools supports feature gates](https://github.com/kubernetes-sigs/controller-tools/issues/1238), you'll be able to use:
83+
84+
```go
85+
// +kubebuilder:feature-gate=experimental-bar
86+
// +optional
87+
Bar *string `json:"bar,omitempty"`
88+
```
89+
90+
This will automatically exclude the field from CRD schemas when the feature gate is disabled.
91+
92+
## Examples
93+
94+
### Basic Example
95+
96+
```go
97+
type CronJobSpec struct {
98+
// Standard fields
99+
Schedule string `json:"schedule"`
100+
101+
// Experimental timezone support
102+
// +feature-gate timezone-support
103+
Timezone *string `json:"timezone,omitempty"`
104+
}
105+
```
106+
107+
### Controller Logic
108+
109+
```go
110+
func (r *CronJobReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
111+
// Check if timezone feature is enabled
112+
if featureGates.IsEnabled("timezone-support") {
113+
// Use timezone-aware scheduling
114+
return r.reconcileWithTimezone(ctx, req)
115+
}
116+
117+
// Fall back to standard scheduling
118+
return r.reconcileStandard(ctx, req)
119+
}
120+
```
121+
122+
## Troubleshooting
123+
124+
### Common Issues
125+
126+
1. **Feature gate not discovered**: Ensure the `+feature-gate` marker is on the line before the field
127+
2. **Invalid feature gate name**: Use lowercase with hyphens only
128+
3. **Validation errors**: Check that all specified gates are available
129+
130+
### Debugging
131+
132+
Enable debug logging to see feature gate discovery:
133+
134+
```bash
135+
./manager --feature-gates=experimental-bar --zap-log-level=debug
136+
```

0 commit comments

Comments
 (0)