You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CSPL-4630: add feature gate infrastructure using k8s FeatureGate pattern
Introduce a feature gate registry backed by k8s.io/component-base/featuregate
so new capabilities can be gated behind --feature-gates=<Gate>=true|false with
Alpha/Beta/GA lifecycle. Migrate the validation webhook toggle from the
ENABLE_VALIDATION_WEBHOOK env var to a ValidationWebhook feature gate with
backwards-compatible env var support.
- Add pkg/config/featuregates.go registry with SetupFeatureGates and
IsFeatureGateEnabled helpers, plus unit tests
- Wire feature gate flags into cmd/main.go and log effective gate states
at startup
- Use os.LookupEnv for ENABLE_VALIDATION_WEBHOOK so the deprecation
warning fires whenever the env var is set, not just when it equals "true"
- Update kustomization files with SPLUNK_GENERAL_TERMS value
- Add docs/FeatureGates.md with usage and instructions for adding new gates
- Update docs/ValidationWebhook.md with CLI-over-env-var precedence note
// Parse optional timeout configurations from environment
294
+
if_, ok:=os.LookupEnv("ENABLE_VALIDATION_WEBHOOK"); ok {
295
+
setupLog.Info("DEPRECATED: ENABLE_VALIDATION_WEBHOOK env var is deprecated and will be removed in a future release; use --feature-gates=ValidationWebhook=true instead")
The Splunk Operator uses the Kubernetes [FeatureGate](https://pkg.go.dev/k8s.io/component-base/featuregate) pattern to control rollout of new functionality. Feature gates allow new code to be merged to the main branch without activating in production, giving teams a safe, per-environment opt-in mechanism.
4
+
5
+
## Usage
6
+
7
+
Enable or disable feature gates at operator startup:
Check the gate wherever the feature-specific logic runs:
49
+
50
+
```go
51
+
if config.DefaultMutableFeatureGate.Enabled(config.MyNewFeature) {
52
+
// feature-specific logic
53
+
}
54
+
```
55
+
56
+
This can guard anything — a reconciler code path, a helper function, a webhook handler, an HTTP endpoint, etc.
57
+
58
+
### Example: Gating a New Controller (CRD)
59
+
60
+
When the feature gate introduces an entirely new CRD and controller, there are additional steps beyond the basic gate check. All three steps below are **mandatory** for any new CRD behind a feature gate.
61
+
62
+
#### a. Gate controller registration in `cmd/main.go`
63
+
64
+
Wrap the `SetupWithManager` call so the controller only starts when the gate is on:
65
+
66
+
```go
67
+
if config.DefaultMutableFeatureGate.Enabled(config.MyNewFeature) {
68
+
if err = (&controller.MyNewReconciler{
69
+
Client: mgr.GetClient(),
70
+
Scheme: mgr.GetScheme(),
71
+
}).SetupWithManager(mgr); err != nil {
72
+
setupLog.Error(err, "unable to create controller", "controller", "MyNew")
73
+
os.Exit(1)
74
+
}
75
+
}
76
+
```
77
+
78
+
#### b. Add a validating webhook for the gated CRD group
79
+
80
+
A validating webhook **must** reject CR creation when the gate is off. Without this, users can create resources that no controller will reconcile, leading to silent failures:
if !config.DefaultMutableFeatureGate.Enabled(config.MyNewFeature) {
85
+
returnnil, fmt.Errorf(
86
+
"the MyNewFeature feature is not enabled; "+
87
+
"set --feature-gates=MyNewFeature=true to activate")
88
+
}
89
+
returnnil, nil
90
+
}
91
+
```
92
+
93
+
#### c. Label the CRD manifests
94
+
95
+
Every gated CRD **must** carry maturity annotations and labels in `config/crd/bases/`. These signal to operators and tooling which gate controls the CRD and its current stability level:
96
+
97
+
```yaml
98
+
metadata:
99
+
annotations:
100
+
splunk.com/feature-gate: MyNewFeature
101
+
splunk.com/feature-stage: Alpha
102
+
labels:
103
+
splunk.com/feature-stage: alpha
104
+
```
105
+
106
+
## Promoting a Gate
107
+
108
+
- **Alpha → Beta**: Change `Default: false` to `Default: true` in `featuregates.go`; update the CRD label to `beta`
109
+
- **Beta → GA**: Set `LockToDefault: true` in the `FeatureSpec`; update the CRD label to `ga`
110
+
- **GA → Removed**: Delete the constant and `FeatureSpec` entry; remove the `if` guard in `cmd/main.go`; remove the CRD annotations/labels and the validating webhook
0 commit comments