Skip to content

Commit

Permalink
Merge pull request #128243 from benluddy/cbor-dynamic-integration
Browse files Browse the repository at this point in the history
KEP-4222: Add CBOR variant of admission webhook integration test.

Kubernetes-commit: 5147eebf224ae41892b736179ca91c47fd794565
  • Loading branch information
k8s-publishing-bot committed Oct 25, 2024
2 parents abe0e99 + 1cca19d commit 3dc7fd5
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 11 deletions.
30 changes: 25 additions & 5 deletions dynamic/scheme.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/cbor"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/client-go/features"
)

var basicScheme = runtime.NewScheme()
Expand All @@ -35,11 +37,8 @@ func init() {
metav1.AddToGroupVersion(parameterScheme, versionV1)
}

// basicNegotiatedSerializer is used to handle discovery and error handling serialization
type basicNegotiatedSerializer struct{}

func (s basicNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInfo {
return []runtime.SerializerInfo{
func newBasicNegotiatedSerializer() basicNegotiatedSerializer {
supportedMediaTypes := []runtime.SerializerInfo{
{
MediaType: "application/json",
MediaTypeType: "application",
Expand All @@ -54,6 +53,27 @@ func (s basicNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInf
},
},
}
if features.TestOnlyFeatureGates.Enabled(features.TestOnlyClientAllowsCBOR) {
supportedMediaTypes = append(supportedMediaTypes, runtime.SerializerInfo{
MediaType: "application/cbor",
MediaTypeType: "application",
MediaTypeSubType: "cbor",
Serializer: cbor.NewSerializer(unstructuredCreater{basicScheme}, unstructuredTyper{basicScheme}),
StreamSerializer: &runtime.StreamSerializerInfo{
Serializer: cbor.NewSerializer(basicScheme, basicScheme, cbor.Transcode(false)),
Framer: cbor.NewFramer(),
},
})
}
return basicNegotiatedSerializer{supportedMediaTypes: supportedMediaTypes}
}

type basicNegotiatedSerializer struct {
supportedMediaTypes []runtime.SerializerInfo
}

func (s basicNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInfo {
return s.supportedMediaTypes
}

func (s basicNegotiatedSerializer) EncoderForVersion(encoder runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
Expand Down
13 changes: 11 additions & 2 deletions dynamic/simple.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/features"
"k8s.io/client-go/rest"
"k8s.io/client-go/util/consistencydetector"
"k8s.io/client-go/util/watchlist"
Expand All @@ -45,9 +46,17 @@ var _ Interface = &DynamicClient{}
// appropriate dynamic client defaults set.
func ConfigFor(inConfig *rest.Config) *rest.Config {
config := rest.CopyConfig(inConfig)
config.AcceptContentTypes = "application/json"

config.ContentType = "application/json"
config.NegotiatedSerializer = basicNegotiatedSerializer{} // this gets used for discovery and error handling types
config.AcceptContentTypes = "application/json"
if features.TestOnlyFeatureGates.Enabled(features.TestOnlyClientAllowsCBOR) {
config.AcceptContentTypes = "application/json;q=0.9,application/cbor;q=1"
if features.TestOnlyFeatureGates.Enabled(features.TestOnlyClientPrefersCBOR) {
config.ContentType = "application/cbor"
}
}

config.NegotiatedSerializer = newBasicNegotiatedSerializer()
if config.UserAgent == "" {
config.UserAgent = rest.DefaultKubernetesUserAgent()
}
Expand Down
44 changes: 43 additions & 1 deletion features/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ package features

import (
"errors"
"fmt"
"sync"
"sync/atomic"

utilruntime "k8s.io/apimachinery/pkg/util/runtime"
"sync/atomic"
)

// NOTE: types Feature, FeatureSpec, prerelease (and its values)
Expand Down Expand Up @@ -141,3 +143,43 @@ var (
// should use AddFeaturesToExistingFeatureGates followed by ReplaceFeatureGates.
featureGates = &atomic.Value{}
)

// TestOnlyFeatureGates is a distinct registry of pre-alpha client features that must not be
// included in runtime wiring to command-line flags or environment variables. It exists as a risk
// mitigation to allow only programmatic enablement of CBOR serialization for integration testing
// purposes.
//
// TODO: Once all required integration test coverage is complete, this will be deleted and the
// test-only feature gates will be replaced by normal feature gates.
var TestOnlyFeatureGates = &testOnlyFeatureGates{
features: map[Feature]bool{
TestOnlyClientAllowsCBOR: false,
TestOnlyClientPrefersCBOR: false,
},
}

type testOnlyFeatureGates struct {
lock sync.RWMutex
features map[Feature]bool
}

func (t *testOnlyFeatureGates) Enabled(feature Feature) bool {
t.lock.RLock()
defer t.lock.RUnlock()

enabled, ok := t.features[feature]
if !ok {
panic(fmt.Sprintf("test-only feature %q not recognized", feature))
}
return enabled
}

func (t *testOnlyFeatureGates) Set(feature Feature, enabled bool) error {
t.lock.Lock()
defer t.lock.Unlock()
if _, ok := t.features[feature]; !ok {
return fmt.Errorf("test-only feature %q not recognized", feature)
}
t.features[feature] = enabled
return nil
}
21 changes: 21 additions & 0 deletions features/known_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,27 @@ const (
// owner: @nilekhc
// alpha: v1.30
InformerResourceVersion Feature = "InformerResourceVersion"

// owner: @benluddy
// kep: https://kep.k8s.io/4222
//
// If disabled, clients configured to accept "application/cbor" will instead accept
// "application/json" with the same relative preference, and clients configured to write
// "application/cbor" or "application/apply-patch+cbor" will instead write
// "application/json" or "application/apply-patch+yaml", respectively.
//
// This feature is currently PRE-ALPHA and MUST NOT be enabled outside of integration tests.
TestOnlyClientAllowsCBOR Feature = "TestOnlyClientAllowsCBOR"

// owner: @benluddy
// kep: https://kep.k8s.io/4222
//
// If enabled AND TestOnlyClientAllowsCBOR is also enabled, the default request content type
// (if not explicitly configured) and the dynamic client's request content type both become
// "application/cbor".
//
// This feature is currently PRE-ALPHA and MUST NOT be enabled outside of integration tests.
TestOnlyClientPrefersCBOR Feature = "TestOnlyClientPrefersCBOR"
)

// defaultKubernetesFeatureGates consists of all known Kubernetes-specific feature keys.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ require (
google.golang.org/protobuf v1.34.2
gopkg.in/evanphx/json-patch.v4 v4.12.0
k8s.io/api v0.0.0-20241024015157-dac1d89c7f69
k8s.io/apimachinery v0.0.0-20241018042225-cfee47580787
k8s.io/apimachinery v0.0.0-20241025000453-124c262107b0
k8s.io/klog/v2 v2.130.1
k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.0.0-20241024015157-dac1d89c7f69 h1:vzBFFi/vVmi3J3HyNc02Bijse3LusTUDzvNXYpBdqHM=
k8s.io/api v0.0.0-20241024015157-dac1d89c7f69/go.mod h1:OIAurRK8KzzpBNXtbVYeGeeoww3j5JLZFLfrV8ZAy0Y=
k8s.io/apimachinery v0.0.0-20241018042225-cfee47580787 h1:cxDsuM/daoEa1+BWlatVGAHIkKOHpZ+2BCdP25Qmw+E=
k8s.io/apimachinery v0.0.0-20241018042225-cfee47580787/go.mod h1:y/FzDt/GaPgPceo5rJcCtD4qW5l8SwtbzESSMGEY6P8=
k8s.io/apimachinery v0.0.0-20241025000453-124c262107b0 h1:6dJVqURMs0HNPdaaIJ0UqpwB39zuTdaMxYMTNKXiAis=
k8s.io/apimachinery v0.0.0-20241025000453-124c262107b0/go.mod h1:y/FzDt/GaPgPceo5rJcCtD4qW5l8SwtbzESSMGEY6P8=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI=
Expand Down

0 comments on commit 3dc7fd5

Please sign in to comment.