diff --git a/go.mod b/go.mod index 72cde1066..1c77caa4e 100644 --- a/go.mod +++ b/go.mod @@ -52,7 +52,7 @@ require ( gopkg.in/square/go-jose.v2 v2.6.0 k8s.io/api v0.0.0-20241105230147-1ddf895d7e74 k8s.io/apimachinery v0.0.0-20241105225905-b5e810677b4f - k8s.io/client-go v0.0.0-20241105230542-c1010ffd7de3 + k8s.io/client-go v0.0.0-20241106030549-9d76eb1606c5 k8s.io/component-base v0.0.0-20241105231555-33a822ed3833 k8s.io/klog/v2 v2.130.1 k8s.io/kms v0.0.0-20241101191923-aa635f2d841b diff --git a/go.sum b/go.sum index 72912414d..6935b1cbb 100644 --- a/go.sum +++ b/go.sum @@ -367,8 +367,8 @@ k8s.io/api v0.0.0-20241105230147-1ddf895d7e74 h1:omoqr99s5DbyApsEajh0iIyKzGL/5vk k8s.io/api v0.0.0-20241105230147-1ddf895d7e74/go.mod h1:QMjNGKwUJOiB0TWCMJWLvhiVAvOrl9I+MTeV0dr56NE= k8s.io/apimachinery v0.0.0-20241105225905-b5e810677b4f h1:MTmedS366tu07Nh6HBoXS90/6DA5gP62gMyYTF+lT+Q= k8s.io/apimachinery v0.0.0-20241105225905-b5e810677b4f/go.mod h1:HqhdaJUgQqky29T1V0o2yFkt/pZqLFIDyn9Zi/8rxoY= -k8s.io/client-go v0.0.0-20241105230542-c1010ffd7de3 h1:ZgoctdRlDLgbqPdEdcgyoyBbVGgNmfcokEkFYjpHZ68= -k8s.io/client-go v0.0.0-20241105230542-c1010ffd7de3/go.mod h1:p8opQH8f5aM1YzHrN0yWNcD4qqfAJIaR0+kVTU/TIBw= +k8s.io/client-go v0.0.0-20241106030549-9d76eb1606c5 h1:TKKepvH+s8JURpM+nwV6fwfJu8LEL1aJxYiCssL9Wac= +k8s.io/client-go v0.0.0-20241106030549-9d76eb1606c5/go.mod h1:p8opQH8f5aM1YzHrN0yWNcD4qqfAJIaR0+kVTU/TIBw= k8s.io/component-base v0.0.0-20241105231555-33a822ed3833 h1:85DceDhD40wu9EBtSDCkSHnYB1Lx0hVgu4pj/ZQLioU= k8s.io/component-base v0.0.0-20241105231555-33a822ed3833/go.mod h1:LiXjb6P40r1C7CAwQfD9HDBX7LzkVHFgYJOzj1oaFO4= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= diff --git a/pkg/endpoints/handlers/patch.go b/pkg/endpoints/handlers/patch.go index 097107842..acfff1961 100644 --- a/pkg/endpoints/handlers/patch.go +++ b/pkg/endpoints/handlers/patch.go @@ -138,7 +138,7 @@ func PatchResource(r rest.Patcher, scope *RequestScope, admit admission.Interfac case types.ApplyYAMLPatchType: baseContentType = runtime.ContentTypeYAML case types.ApplyCBORPatchType: - if !utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + if !utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) { // This request should have already been rejected by the // Content-Type allowlist check. Return 500 because assumptions are // already broken and the feature is not GA. @@ -673,7 +673,7 @@ func (p *patcher) patchResource(ctx context.Context, scope *RequestScope) (runti p.mechanism = newApplyPatcher(p, scope.FieldManager, yaml.Unmarshal, yaml.UnmarshalStrict) p.forceAllowCreate = true case types.ApplyCBORPatchType: - if !utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + if !utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) { utilruntime.HandleErrorWithContext(context.TODO(), nil, "CBOR apply requests should be rejected before reaching this point unless the feature gate is enabled.") return nil, false, fmt.Errorf("%v: unimplemented patch type", p.patchType) } diff --git a/pkg/endpoints/handlers/responsewriters/writers.go b/pkg/endpoints/handlers/responsewriters/writers.go index 9b9e10ad1..3ca5cba8c 100644 --- a/pkg/endpoints/handlers/responsewriters/writers.go +++ b/pkg/endpoints/handlers/responsewriters/writers.go @@ -286,7 +286,7 @@ func WriteObjectNegotiated(s runtime.NegotiatedSerializer, restrictions negotiat audit.LogResponseObject(req.Context(), object, gv, s) var encoder runtime.Encoder - if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) { encoder = s.EncoderForVersion(runtime.UseNondeterministicEncoding(serializer.Serializer), gv) } else { encoder = s.EncoderForVersion(serializer.Serializer, gv) diff --git a/pkg/endpoints/handlers/watch.go b/pkg/endpoints/handlers/watch.go index 938e8ef5b..8876a19cd 100644 --- a/pkg/endpoints/handlers/watch.go +++ b/pkg/endpoints/handlers/watch.go @@ -77,7 +77,7 @@ func serveWatchHandler(watcher watch.Interface, scope *RequestScope, mediaTypeOp } framer := serializer.StreamSerializer.Framer var encoder runtime.Encoder - if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) { encoder = scope.Serializer.EncoderForVersion(runtime.UseNondeterministicEncoding(serializer.StreamSerializer.Serializer), scope.Kind.GroupVersion()) } else { encoder = scope.Serializer.EncoderForVersion(serializer.StreamSerializer.Serializer, scope.Kind.GroupVersion()) @@ -102,13 +102,13 @@ func serveWatchHandler(watcher watch.Interface, scope *RequestScope, mediaTypeOp if !ok { return nil, fmt.Errorf("no encoder for %q exists in the requested target %#v", serializer.MediaType, contentSerializer) } - if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) { negotiatedEncoder = contentSerializer.EncoderForVersion(runtime.UseNondeterministicEncoding(info.Serializer), contentKind.GroupVersion()) } else { negotiatedEncoder = contentSerializer.EncoderForVersion(info.Serializer, contentKind.GroupVersion()) } } else { - if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) { negotiatedEncoder = scope.Serializer.EncoderForVersion(runtime.UseNondeterministicEncoding(serializer.Serializer), contentKind.GroupVersion()) } else { negotiatedEncoder = scope.Serializer.EncoderForVersion(serializer.Serializer, contentKind.GroupVersion()) diff --git a/pkg/endpoints/installer.go b/pkg/endpoints/installer.go index 6a1826b4e..78e67109f 100644 --- a/pkg/endpoints/installer.go +++ b/pkg/endpoints/installer.go @@ -895,7 +895,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag string(types.StrategicMergePatchType), string(types.ApplyYAMLPatchType), } - if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) { + if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) { supportedTypes = append(supportedTypes, string(types.ApplyCBORPatchType)) } handler := metrics.InstrumentRouteFunc(action.Verb, group, version, resource, subresource, requestScope, metrics.APIServerComponent, deprecated, removedRelease, restfulPatchResource(patcher, reqScope, admit, supportedTypes)) diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 336e29d99..02debfb76 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -92,9 +92,7 @@ const ( // // Enables CBOR as a supported encoding for requests and responses, and as the // preferred storage encoding for custom resources. - // - // This feature is currently PRE-ALPHA and MUST NOT be enabled outside of integration tests. - TestOnlyCBORServingAndStorage featuregate.Feature = "TestOnlyCBORServingAndStorage" + CBORServingAndStorage featuregate.Feature = "CBORServingAndStorage" // owner: @serathius // @@ -245,7 +243,6 @@ const ( func init() { runtime.Must(utilfeature.DefaultMutableFeatureGate.Add(defaultKubernetesFeatureGates)) runtime.Must(utilfeature.DefaultMutableFeatureGate.AddVersioned(defaultVersionedKubernetesFeatureGates)) - runtime.Must(utilfeature.TestOnlyMutableFeatureGate.AddVersioned(testOnlyVersionedKubernetesFeatureGates)) } // defaultVersionedKubernetesFeatureGates consists of all known Kubernetes-specific feature keys with VersionedSpecs. @@ -306,6 +303,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate {Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta}, }, + CBORServingAndStorage: { + {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, + }, + ConcurrentWatchObjectDecode: { {Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta}, }, @@ -417,12 +418,3 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate // defaultKubernetesFeatureGates consists of legacy unversioned Kubernetes-specific feature keys. // Please do not add to this struct and use defaultVersionedKubernetesFeatureGates instead. var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{} - -// testOnlyVersionedKubernetesFeatureGates consists of features that require programmatic enablement -// for integration testing, but have not yet graduated to alpha in a release and must not be enabled -// by a runtime option. -var testOnlyVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate.VersionedSpecs{ - TestOnlyCBORServingAndStorage: { - {Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha}, - }, -} diff --git a/pkg/server/config.go b/pkg/server/config.go index fe9dca9dc..b37728556 100644 --- a/pkg/server/config.go +++ b/pkg/server/config.go @@ -756,7 +756,7 @@ func (c completedConfig) New(name string, delegationTarget DelegationTarget) (*G return nil, fmt.Errorf("Genericapiserver.New() called with config.Serializer == nil") } allowedMediaTypes := defaultAllowedMediaTypes - if utilfeature.TestOnlyFeatureGate.Enabled(genericfeatures.TestOnlyCBORServingAndStorage) { + if utilfeature.DefaultFeatureGate.Enabled(genericfeatures.CBORServingAndStorage) { allowedMediaTypes = append(allowedMediaTypes, runtime.ContentTypeCBOR) } for _, info := range c.Serializer.SupportedMediaTypes() { diff --git a/pkg/server/config_test.go b/pkg/server/config_test.go index f6447eef7..1f30143a9 100644 --- a/pkg/server/config_test.go +++ b/pkg/server/config_test.go @@ -424,7 +424,7 @@ func TestNewErrorForbiddenSerializer(t *testing.T) { } func TestNewFeatureGatedSerializer(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.TestOnlyFeatureGate, features.TestOnlyCBORServingAndStorage, true) + featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CBORServingAndStorage, true) config := NewConfig(serializer.NewCodecFactory(scheme, serializer.WithSerializer(func(creater runtime.ObjectCreater, typer runtime.ObjectTyper) runtime.SerializerInfo { return runtime.SerializerInfo{ diff --git a/pkg/util/feature/feature_gate.go b/pkg/util/feature/feature_gate.go index 7c061042a..00a9e099b 100644 --- a/pkg/util/feature/feature_gate.go +++ b/pkg/util/feature/feature_gate.go @@ -31,15 +31,3 @@ var ( // Top-level commands/options setup that needs to modify this feature gate should use DefaultMutableFeatureGate. DefaultFeatureGate featuregate.FeatureGate = DefaultMutableFeatureGate ) - -var ( - // TestOnlyMutableFeatureGate is a mutable version of TestOnlyFeatureGate. Only top-level - // commands/options setup and the k8s.io/component-base/featuregate/testing package should - // make use of this. - TestOnlyMutableFeatureGate featuregate.MutableVersionedFeatureGate = featuregate.NewFeatureGate() - - // TestOnlyFeatureGate is a shared global FeatureGate for features that have not yet - // graduated to alpha and require programmatic feature enablement for pre-alpha integration - // testing without exposing the feature as a runtime option. - TestOnlyFeatureGate featuregate.FeatureGate = TestOnlyMutableFeatureGate -)