Skip to content

Commit 072dfcb

Browse files
committed
Add CBOR feature gates.
For alpha, there is one apiserver feature gate and two client-go feature gates controlling CBOR. They were initially wired to separate test-only feature gate instances in order to prevent them from being configurable at runtime via command-line flags or environment variables (for client-go feature gates outside of Kubernetes components). All of the integration tests required by the KEP as alpha criteria have been implemented. This adds the feature gates to the usual feature gate instances and removes the temporary code to support separate test-only feature gate instances.
1 parent 175a5b9 commit 072dfcb

File tree

29 files changed

+105
-167
lines changed

29 files changed

+105
-167
lines changed

pkg/features/client_adapter.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,10 @@ func (a *clientAdapter) Add(in map[clientfeatures.Feature]clientfeatures.Feature
6767
}
6868
return a.mfg.Add(out)
6969
}
70+
71+
// Set implements the unexported interface that client-go feature gate testing expects for
72+
// ek8s.io/client-go/features/testing.SetFeatureDuringTest. This is necessary for integration tests
73+
// to set test overrides for client-go feature gates.
74+
func (a *clientAdapter) Set(name clientfeatures.Feature, enabled bool) error {
75+
return a.mfg.SetFromMap(map[string]bool{string(name): enabled})
76+
}

pkg/features/versioned_kube_features.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
245245
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
246246
},
247247

248+
genericfeatures.CBORServingAndStorage: {
249+
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
250+
},
251+
248252
genericfeatures.ConcurrentWatchObjectDecode: {
249253
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta},
250254
},

staging/src/k8s.io/apiextensions-apiserver/pkg/apiserver/customresource_handler.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ func (r *crdHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
327327
string(types.MergePatchType),
328328
string(types.ApplyYAMLPatchType),
329329
}
330-
if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
330+
if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
331331
supportedTypes = append(supportedTypes, string(types.ApplyCBORPatchType))
332332
}
333333

@@ -913,7 +913,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
913913
},
914914
}
915915

916-
if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
916+
if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
917917
negotiatedSerializer.supportedMediaTypes = append(negotiatedSerializer.supportedMediaTypes, newCBORSerializerInfo(creator, typer))
918918
}
919919

@@ -981,7 +981,7 @@ func (r *crdHandler) getOrCreateServingInfoFor(uid types.UID, name string) (*crd
981981
scaleConverter := scale.NewScaleConverter()
982982
scaleScope.Subresource = "scale"
983983
var opts []serializer.CodecFactoryOptionsMutator
984-
if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
984+
if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
985985
opts = append(opts, serializer.WithSerializer(newCBORSerializerInfo))
986986
}
987987
scaleScope.Serializer = serializer.NewCodecFactory(scaleConverter.Scheme(), opts...)

staging/src/k8s.io/apiextensions-apiserver/pkg/cmd/server/options/options.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ func NewCRDRESTOptionsGetter(etcdOptions genericoptions.EtcdOptions, resourceTra
139139
ucbor := cbor.NewSerializer(unstructuredscheme.NewUnstructuredCreator(), unstructuredscheme.NewUnstructuredObjectTyper())
140140

141141
encoder := unstructured.UnstructuredJSONScheme
142-
if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
142+
if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
143143
encoder = ucbor
144144
}
145145

staging/src/k8s.io/apiextensions-apiserver/test/integration/cbor_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func TestCBORStorageEnablement(t *testing.T) {
6969

7070
func() {
7171
t.Log("starting server with feature gate disabled")
72-
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.TestOnlyFeatureGate, features.TestOnlyCBORServingAndStorage, false)
72+
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CBORServingAndStorage, false)
7373
tearDown, apiExtensionsClientset, dynamicClient, etcdClient, _, err := fixtures.StartDefaultServerWithClientsAndEtcd(t, "--etcd-prefix", etcdPrefix)
7474
if err != nil {
7575
t.Fatal(err)
@@ -109,7 +109,7 @@ func TestCBORStorageEnablement(t *testing.T) {
109109

110110
func() {
111111
t.Log("starting server with feature gate enabled")
112-
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.TestOnlyFeatureGate, features.TestOnlyCBORServingAndStorage, true)
112+
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CBORServingAndStorage, true)
113113
tearDown, _, dynamicClient, etcdClient, _, err := fixtures.StartDefaultServerWithClientsAndEtcd(t, "--etcd-prefix", etcdPrefix)
114114
if err != nil {
115115
t.Fatal(err)
@@ -159,7 +159,7 @@ func TestCBORStorageEnablement(t *testing.T) {
159159

160160
func() {
161161
t.Log("starting server with feature gate disabled")
162-
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.TestOnlyFeatureGate, features.TestOnlyCBORServingAndStorage, false)
162+
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CBORServingAndStorage, false)
163163
tearDown, _, dynamicClient, _, _, err := fixtures.StartDefaultServerWithClientsAndEtcd(t, "--etcd-prefix", etcdPrefix)
164164
if err != nil {
165165
t.Fatal(err)
@@ -185,7 +185,7 @@ func TestCBORServingEnablement(t *testing.T) {
185185
{name: "disabled", enabled: false},
186186
} {
187187
t.Run(tc.name, func(t *testing.T) {
188-
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.TestOnlyFeatureGate, features.TestOnlyCBORServingAndStorage, tc.enabled)
188+
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CBORServingAndStorage, tc.enabled)
189189

190190
tearDown, config, _, err := fixtures.StartDefaultServer(t)
191191
if err != nil {

staging/src/k8s.io/apiserver/pkg/endpoints/handlers/patch.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func PatchResource(r rest.Patcher, scope *RequestScope, admit admission.Interfac
138138
case types.ApplyYAMLPatchType:
139139
baseContentType = runtime.ContentTypeYAML
140140
case types.ApplyCBORPatchType:
141-
if !utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
141+
if !utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
142142
// This request should have already been rejected by the
143143
// Content-Type allowlist check. Return 500 because assumptions are
144144
// already broken and the feature is not GA.
@@ -673,7 +673,7 @@ func (p *patcher) patchResource(ctx context.Context, scope *RequestScope) (runti
673673
p.mechanism = newApplyPatcher(p, scope.FieldManager, yaml.Unmarshal, yaml.UnmarshalStrict)
674674
p.forceAllowCreate = true
675675
case types.ApplyCBORPatchType:
676-
if !utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
676+
if !utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
677677
utilruntime.HandleErrorWithContext(context.TODO(), nil, "CBOR apply requests should be rejected before reaching this point unless the feature gate is enabled.")
678678
return nil, false, fmt.Errorf("%v: unimplemented patch type", p.patchType)
679679
}

staging/src/k8s.io/apiserver/pkg/endpoints/handlers/responsewriters/writers.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ func WriteObjectNegotiated(s runtime.NegotiatedSerializer, restrictions negotiat
286286
audit.LogResponseObject(req.Context(), object, gv, s)
287287

288288
var encoder runtime.Encoder
289-
if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
289+
if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
290290
encoder = s.EncoderForVersion(runtime.UseNondeterministicEncoding(serializer.Serializer), gv)
291291
} else {
292292
encoder = s.EncoderForVersion(serializer.Serializer, gv)

staging/src/k8s.io/apiserver/pkg/endpoints/handlers/watch.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func serveWatchHandler(watcher watch.Interface, scope *RequestScope, mediaTypeOp
7777
}
7878
framer := serializer.StreamSerializer.Framer
7979
var encoder runtime.Encoder
80-
if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
80+
if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
8181
encoder = scope.Serializer.EncoderForVersion(runtime.UseNondeterministicEncoding(serializer.StreamSerializer.Serializer), scope.Kind.GroupVersion())
8282
} else {
8383
encoder = scope.Serializer.EncoderForVersion(serializer.StreamSerializer.Serializer, scope.Kind.GroupVersion())
@@ -102,13 +102,13 @@ func serveWatchHandler(watcher watch.Interface, scope *RequestScope, mediaTypeOp
102102
if !ok {
103103
return nil, fmt.Errorf("no encoder for %q exists in the requested target %#v", serializer.MediaType, contentSerializer)
104104
}
105-
if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
105+
if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
106106
negotiatedEncoder = contentSerializer.EncoderForVersion(runtime.UseNondeterministicEncoding(info.Serializer), contentKind.GroupVersion())
107107
} else {
108108
negotiatedEncoder = contentSerializer.EncoderForVersion(info.Serializer, contentKind.GroupVersion())
109109
}
110110
} else {
111-
if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
111+
if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
112112
negotiatedEncoder = scope.Serializer.EncoderForVersion(runtime.UseNondeterministicEncoding(serializer.Serializer), contentKind.GroupVersion())
113113
} else {
114114
negotiatedEncoder = scope.Serializer.EncoderForVersion(serializer.Serializer, contentKind.GroupVersion())

staging/src/k8s.io/apiserver/pkg/endpoints/installer.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -895,7 +895,7 @@ func (a *APIInstaller) registerResourceHandlers(path string, storage rest.Storag
895895
string(types.StrategicMergePatchType),
896896
string(types.ApplyYAMLPatchType),
897897
}
898-
if utilfeature.TestOnlyFeatureGate.Enabled(features.TestOnlyCBORServingAndStorage) {
898+
if utilfeature.DefaultFeatureGate.Enabled(features.CBORServingAndStorage) {
899899
supportedTypes = append(supportedTypes, string(types.ApplyCBORPatchType))
900900
}
901901
handler := metrics.InstrumentRouteFunc(action.Verb, group, version, resource, subresource, requestScope, metrics.APIServerComponent, deprecated, removedRelease, restfulPatchResource(patcher, reqScope, admit, supportedTypes))

staging/src/k8s.io/apiserver/pkg/features/kube_features.go

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,7 @@ const (
9292
//
9393
// Enables CBOR as a supported encoding for requests and responses, and as the
9494
// preferred storage encoding for custom resources.
95-
//
96-
// This feature is currently PRE-ALPHA and MUST NOT be enabled outside of integration tests.
97-
TestOnlyCBORServingAndStorage featuregate.Feature = "TestOnlyCBORServingAndStorage"
95+
CBORServingAndStorage featuregate.Feature = "CBORServingAndStorage"
9896

9997
// owner: @serathius
10098
//
@@ -245,7 +243,6 @@ const (
245243
func init() {
246244
runtime.Must(utilfeature.DefaultMutableFeatureGate.Add(defaultKubernetesFeatureGates))
247245
runtime.Must(utilfeature.DefaultMutableFeatureGate.AddVersioned(defaultVersionedKubernetesFeatureGates))
248-
runtime.Must(utilfeature.TestOnlyMutableFeatureGate.AddVersioned(testOnlyVersionedKubernetesFeatureGates))
249246
}
250247

251248
// defaultVersionedKubernetesFeatureGates consists of all known Kubernetes-specific feature keys with VersionedSpecs.
@@ -306,6 +303,10 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
306303
{Version: version.MustParse("1.32"), Default: true, PreRelease: featuregate.Beta},
307304
},
308305

306+
CBORServingAndStorage: {
307+
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
308+
},
309+
309310
ConcurrentWatchObjectDecode: {
310311
{Version: version.MustParse("1.31"), Default: false, PreRelease: featuregate.Beta},
311312
},
@@ -417,12 +418,3 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
417418
// defaultKubernetesFeatureGates consists of legacy unversioned Kubernetes-specific feature keys.
418419
// Please do not add to this struct and use defaultVersionedKubernetesFeatureGates instead.
419420
var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{}
420-
421-
// testOnlyVersionedKubernetesFeatureGates consists of features that require programmatic enablement
422-
// for integration testing, but have not yet graduated to alpha in a release and must not be enabled
423-
// by a runtime option.
424-
var testOnlyVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate.VersionedSpecs{
425-
TestOnlyCBORServingAndStorage: {
426-
{Version: version.MustParse("1.32"), Default: false, PreRelease: featuregate.Alpha},
427-
},
428-
}

0 commit comments

Comments
 (0)