-
Notifications
You must be signed in to change notification settings - Fork 591
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature gates #1970
feature gates #1970
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Feature Gates | ||
|
||
Upstream [Kubernetes][k8s] includes [Feature Gates][gates] to enable or disable features with flags and track the maturity of a feature using [Feature Stages][stages]. Here in the Kubernetes Ingress Controller (KIC) we use the same definitions of `Feature Gates` and `Feature Stages` from upstream Kubernetes, but with our own list of features. | ||
|
||
Using `Feature Gates` enables contributors to add and manage new (and potentially) experimental functionality to the KIC in a controlled manner: the features will be "hidden" until generally available (GA) and the progress and maturity of features on their path to GA will be documented. Feature gates also create a clear path for deprecating features. | ||
|
||
See below for current features and their statuses, and follow the links to the relevant feature documentation. | ||
|
||
[k8s]:https://kubernetes.io | ||
[gates]:https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/ | ||
[stages]:https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/#feature-stages | ||
|
||
## Feature gates | ||
|
||
Below you will find the overviews of features at various maturity levels: | ||
|
||
- [Feature gates for graduated or deprecated features](/#feature-gates-for-graduated-or-deprecated-features) | ||
- [Feature gates for Alpha or Beta features](/#feature-gates-for-alpha-or-beta-features) | ||
|
||
Please read the [Important Notes](/#important-notes) section before using any `Alpha` or `Beta` features. | ||
|
||
### Important notes | ||
|
||
- Most features will be planned and detailed using [Kubernetes Enhancement Proposals (KEP)][k8s-kep]: If you're interested in the development side of features familiarize yourself with our [KEPs][kic-keps] | ||
- The `Since` and `Until` rows in below tables refer to [KIC Releases][releases] | ||
- For `GA` features the documentation exists in the main [Kong Documentation][kong-docs], see the [API reference][api-ref] and [Guides][kic-guides] | ||
|
||
An additional **warning** for end-users who are reading this documentation and trying to enable `Alpha` or `Beta` features: it is **very important** to understand that features that are currently in an `Alpha` or `Beta` state may **become `Deprecated` at any time** and **may be removed as part of the next consecutive minor release**. This is especially true for `Alpha` maturity features. In other words, **until a feature becomes GA there are no guarantees that it's going to continue being available**. To avoid disruption to your services engage with the community and read the [CHANGELOG](/CHANGELOG.md) carefully to track progress. Alternatively **do not use features until they have reached a GA status**. | ||
|
||
[k8s-keps]:https:/kubernetes/enhancements | ||
[kic-keps]:https:/Kong/kubernetes-ingress-controller/tree/main/keps | ||
[releases]:https:/Kong/kubernetes-ingress-controller/releases | ||
[kong-docs]:https:/Kong/docs.konghq.com | ||
[api-ref]:https://docs.konghq.com/kubernetes-ingress-controller/latest/references/custom-resources/ | ||
[kic-guides]:https://docs.konghq.com/kubernetes-ingress-controller/latest/guides/overview/ | ||
|
||
### Feature gates for graduated or deprecated features | ||
|
||
{{< table caption="Feature Gates for Graduated or Deprecated Features" >}} | ||
|
||
| Feature | Default | Stage | Since | Until | | ||
|----------------------------|---------|------------|-------|-------| | ||
|
||
{{< /table >}} | ||
|
||
Features that reach GA and over time become stable will be removed from this table, they can be found in the main [KIC CRD Documentation][specs] and [Guides][guides]. | ||
|
||
[specs]:https://docs.konghq.com/kubernetes-ingress-controller/latest/references/custom-resources/ | ||
[guides]:https://docs.konghq.com/kubernetes-ingress-controller/latest/guides/overview/ | ||
|
||
### Feature gates for Alpha or Beta features | ||
|
||
{{< table caption="Feature gates for features in Alpha or Beta states" >}} | ||
|
||
| Feature | Default | Stage | Since | Until | | ||
|----------------------------|---------|-------|-------|-------| | ||
| [Knative](#Knative) | `true` | Alpha | 0.8.0 | TBD | | ||
| [GatewayAPI](#Gateway-API) | `false` | Alpha | TBD | TBD | | ||
|
||
{{< /table > }} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,7 +59,7 @@ func (c *ControllerDef) MaybeSetupWithManager(mgr ctrl.Manager) error { | |
// Controller Manager - Controller Setup Functions | ||
// ----------------------------------------------------------------------------- | ||
|
||
func setupControllers(mgr manager.Manager, proxy proxy.Proxy, c *Config) ([]ControllerDef, error) { | ||
func setupControllers(mgr manager.Manager, proxy proxy.Proxy, c *Config, featureGates map[string]bool) ([]ControllerDef, error) { | ||
// Choose the best API version of Ingress to inform which ingress controller to enable. | ||
var ingressPicker ingressControllerStrategy | ||
if err := ingressPicker.Initialize(c, mgr.GetClient()); err != nil { | ||
|
@@ -196,8 +196,14 @@ func setupControllers(mgr manager.Manager, proxy proxy.Proxy, c *Config) ([]Cont | |
IngressClassName: c.IngressClassName, | ||
}, | ||
}, | ||
// --------------------------------------------------------------------------- | ||
// Other Controllers | ||
// --------------------------------------------------------------------------- | ||
{ | ||
Enabled: c.KnativeIngressEnabled, | ||
// knative is a special case because it existed before we added feature gates functionality | ||
// for this controller (only) the existing --enable-controller-knativeingress flag overrides | ||
// any feature gate configuration. See FEATURE_GATES.md for more information. | ||
Enabled: featureGates["Knative"] || c.KnativeIngressEnabled, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that feature gate names deserve a dedicated enum type, and they definitely deserve |
||
AutoHandler: crdExistsChecker{GVR: schema.GroupVersionResource{ | ||
Group: knativev1alpha1.SchemeGroupVersion.Group, | ||
Version: knativev1alpha1.SchemeGroupVersion.Version, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package manager | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/go-logr/logr" | ||
) | ||
|
||
// featureGatesDocsURL provides a link to the documentation for feature gates in the KIC repository | ||
const featureGatesDocsURL = "https:/Kong/kubernetes-ingress-controller/blob/main/FEATURE_GATES.md" | ||
|
||
// setupFeatureGates converts feature gates to controller enablement | ||
func setupFeatureGates(setupLog logr.Logger, c *Config) (map[string]bool, error) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function could have a simpler and cohesive mental model: take two |
||
// generate a map of feature gates by string names to their controller enablement | ||
ctrlMap := getFeatureGatesDefaults() | ||
|
||
// override the default settings | ||
for feature, enabled := range c.FeatureGates { | ||
setupLog.Info("found configuration option for gated feature", "feature", feature, "enabled", enabled) | ||
_, ok := ctrlMap[feature] | ||
if !ok { | ||
return ctrlMap, fmt.Errorf("%s is not a valid feature, please see the documentation: %s", feature, featureGatesDocsURL) | ||
} | ||
ctrlMap[feature] = enabled | ||
} | ||
|
||
return ctrlMap, nil | ||
} | ||
|
||
// getFeatureGatesDefaults initializes a feature gate map given the currently | ||
// supported feature gates options and derives defaults for them based on | ||
// manager configuration options if present. | ||
// | ||
// NOTE: if you're adding a new feature gate, it needs to be added here. | ||
func getFeatureGatesDefaults() map[string]bool { | ||
return map[string]bool{ | ||
"Knative": false, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package manager | ||
|
||
import ( | ||
"bytes" | ||
"testing" | ||
|
||
"github.com/bombsimon/logrusr" | ||
"github.com/sirupsen/logrus" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestFeatureGates(t *testing.T) { | ||
t.Log("setting up configurations and logging for feature gates testing") | ||
out := new(bytes.Buffer) | ||
baseLogger := logrus.New() | ||
baseLogger.SetOutput(out) | ||
baseLogger.SetLevel(logrus.DebugLevel) | ||
setupLog := logrusr.NewLogger(baseLogger) | ||
config := new(Config) | ||
|
||
t.Log("verifying feature gates setup defaults when no feature gates are configured") | ||
fgs, err := setupFeatureGates(setupLog, config) | ||
assert.NoError(t, err) | ||
assert.Len(t, fgs, len(getFeatureGatesDefaults())) | ||
|
||
t.Log("verifying feature gates setup results when valid feature gates options are present") | ||
config.FeatureGates = map[string]bool{"Knative": true} | ||
fgs, err = setupFeatureGates(setupLog, config) | ||
assert.NoError(t, err) | ||
assert.True(t, fgs["Knative"]) | ||
|
||
t.Log("configuring several invalid feature gates options") | ||
config.FeatureGates = map[string]bool{"Batman": true} | ||
|
||
t.Log("verifying feature gates setup results when invalid feature gates options are present") | ||
_, err = setupFeatureGates(setupLog, config) | ||
assert.Error(t, err) | ||
assert.Contains(t, err.Error(), "Batman is not a valid feature") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
YAGNI - suggestion: delete