logs: add alpha+beta feature gates

It is useful to have the ability to control whether alpha or beta features are
enabled. We can group features under LoggingAlphaOptions and LoggingBetaOptions
because the configuration is designed so that each feature individually must be
enabled via its own option.

Currently, the JSON format itself is beta (graduated in 1.23) but additional
options for it were only added in 1.23 and thus are still alpha:

  $ go run ./staging/src/k8s.io/component-base/logs/example/cmd/logger.go --logging-format=json --log-json-split-stream --log-json-info-buffer-size 1M --feature-gates LoggingBetaOptions=false
  [format: Forbidden: Log format json is BETA and disabled, see LoggingBetaOptions feature, options.json.splitStream: Forbidden: Feature LoggingAlphaOptions is disabled, options.json.infoBufferSize: Forbidden: Feature LoggingAlphaOptions is disabled]

  $ go run ./staging/src/k8s.io/component-base/logs/example/cmd/logger.go --logging-format=json --log-json-split-stream --log-json-info-buffer-size 1M
  [options.json.splitStream: Forbidden: Feature LoggingAlphaOptions is disabled, options.json.infoBufferSize: Forbidden: Feature LoggingAlphaOptions is disabled]

This is the same approach that was taken for CPUManagerPolicyAlphaOptions and
CPUManagerPolicyBetaOptions.

In order to test this without modifying the global feature gate in a test file,
ValidateKubeletConfiguration must take a feature gate as argument.
This commit is contained in:
Patrick Ohly
2022-01-18 16:50:55 +01:00
parent 1aceac797d
commit ea3f25f49b
14 changed files with 268 additions and 44 deletions

View File

@@ -24,7 +24,7 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
utilvalidation "k8s.io/apimachinery/pkg/util/validation"
"k8s.io/apimachinery/pkg/util/validation/field"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/component-base/featuregate"
"k8s.io/component-base/metrics"
"k8s.io/kubernetes/pkg/features"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
@@ -38,12 +38,12 @@ var (
)
// ValidateKubeletConfiguration validates `kc` and returns an error if it is invalid
func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration) error {
func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration, featureGate featuregate.FeatureGate) error {
allErrors := []error{}
// Make a local copy of the global feature gates and combine it with the gates set by this configuration.
// Make a local copy of the feature gates and combine it with the gates set by this configuration.
// This allows us to validate the config against the set of gates it will actually run against.
localFeatureGate := utilfeature.DefaultFeatureGate.DeepCopy()
localFeatureGate := featureGate.DeepCopy()
if err := localFeatureGate.SetFromMap(kc.FeatureGates); err != nil {
return err
}

View File

@@ -23,6 +23,7 @@ import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilfeature "k8s.io/apiserver/pkg/util/feature"
logsapi "k8s.io/component-base/logs/api/v1"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
"k8s.io/kubernetes/pkg/kubelet/apis/config/validation"
@@ -75,6 +76,9 @@ var (
)
func TestValidateKubeletConfiguration(t *testing.T) {
featureGate := utilfeature.DefaultFeatureGate.DeepCopy()
logsapi.AddFeatureGates(featureGate)
cases := []struct {
name string
configure func(config *kubeletconfig.KubeletConfiguration) *kubeletconfig.KubeletConfiguration
@@ -497,7 +501,7 @@ func TestValidateKubeletConfiguration(t *testing.T) {
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
errs := validation.ValidateKubeletConfiguration(tc.configure(successConfig.DeepCopy()))
errs := validation.ValidateKubeletConfiguration(tc.configure(successConfig.DeepCopy()), featureGate)
if len(tc.errMsg) == 0 {
if errs != nil {