mirror of
https://github.com/kubernetes/client-go.git
synced 2025-07-21 02:20:34 +00:00
Merge pull request #128243 from benluddy/cbor-dynamic-integration
KEP-4222: Add CBOR variant of admission webhook integration test. Kubernetes-commit: 5147eebf224ae41892b736179ca91c47fd794565
This commit is contained in:
commit
3dc7fd5f4c
@ -21,7 +21,9 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime/serializer/cbor"
|
||||||
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
"k8s.io/apimachinery/pkg/runtime/serializer/json"
|
||||||
|
"k8s.io/client-go/features"
|
||||||
)
|
)
|
||||||
|
|
||||||
var basicScheme = runtime.NewScheme()
|
var basicScheme = runtime.NewScheme()
|
||||||
@ -35,11 +37,8 @@ func init() {
|
|||||||
metav1.AddToGroupVersion(parameterScheme, versionV1)
|
metav1.AddToGroupVersion(parameterScheme, versionV1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// basicNegotiatedSerializer is used to handle discovery and error handling serialization
|
func newBasicNegotiatedSerializer() basicNegotiatedSerializer {
|
||||||
type basicNegotiatedSerializer struct{}
|
supportedMediaTypes := []runtime.SerializerInfo{
|
||||||
|
|
||||||
func (s basicNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInfo {
|
|
||||||
return []runtime.SerializerInfo{
|
|
||||||
{
|
{
|
||||||
MediaType: "application/json",
|
MediaType: "application/json",
|
||||||
MediaTypeType: "application",
|
MediaTypeType: "application",
|
||||||
@ -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 {
|
func (s basicNegotiatedSerializer) EncoderForVersion(encoder runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
|
||||||
|
@ -29,6 +29,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
|
"k8s.io/client-go/features"
|
||||||
"k8s.io/client-go/rest"
|
"k8s.io/client-go/rest"
|
||||||
"k8s.io/client-go/util/consistencydetector"
|
"k8s.io/client-go/util/consistencydetector"
|
||||||
"k8s.io/client-go/util/watchlist"
|
"k8s.io/client-go/util/watchlist"
|
||||||
@ -45,9 +46,17 @@ var _ Interface = &DynamicClient{}
|
|||||||
// appropriate dynamic client defaults set.
|
// appropriate dynamic client defaults set.
|
||||||
func ConfigFor(inConfig *rest.Config) *rest.Config {
|
func ConfigFor(inConfig *rest.Config) *rest.Config {
|
||||||
config := rest.CopyConfig(inConfig)
|
config := rest.CopyConfig(inConfig)
|
||||||
config.AcceptContentTypes = "application/json"
|
|
||||||
config.ContentType = "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 == "" {
|
if config.UserAgent == "" {
|
||||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,11 @@ package features
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
"sync/atomic"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE: types Feature, FeatureSpec, prerelease (and its values)
|
// NOTE: types Feature, FeatureSpec, prerelease (and its values)
|
||||||
@ -141,3 +143,43 @@ var (
|
|||||||
// should use AddFeaturesToExistingFeatureGates followed by ReplaceFeatureGates.
|
// should use AddFeaturesToExistingFeatureGates followed by ReplaceFeatureGates.
|
||||||
featureGates = &atomic.Value{}
|
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
|
||||||
|
}
|
||||||
|
@ -41,6 +41,27 @@ const (
|
|||||||
// owner: @nilekhc
|
// owner: @nilekhc
|
||||||
// alpha: v1.30
|
// alpha: v1.30
|
||||||
InformerResourceVersion Feature = "InformerResourceVersion"
|
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.
|
// defaultKubernetesFeatureGates consists of all known Kubernetes-specific feature keys.
|
||||||
|
2
go.mod
2
go.mod
@ -27,7 +27,7 @@ require (
|
|||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.34.2
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.12.0
|
gopkg.in/evanphx/json-patch.v4 v4.12.0
|
||||||
k8s.io/api v0.0.0-20241024015157-dac1d89c7f69
|
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/klog/v2 v2.130.1
|
||||||
k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2
|
k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2
|
||||||
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8
|
||||||
|
4
go.sum
4
go.sum
@ -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=
|
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 h1:vzBFFi/vVmi3J3HyNc02Bijse3LusTUDzvNXYpBdqHM=
|
||||||
k8s.io/api v0.0.0-20241024015157-dac1d89c7f69/go.mod h1:OIAurRK8KzzpBNXtbVYeGeeoww3j5JLZFLfrV8ZAy0Y=
|
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-20241025000453-124c262107b0 h1:6dJVqURMs0HNPdaaIJ0UqpwB39zuTdaMxYMTNKXiAis=
|
||||||
k8s.io/apimachinery v0.0.0-20241018042225-cfee47580787/go.mod h1:y/FzDt/GaPgPceo5rJcCtD4qW5l8SwtbzESSMGEY6P8=
|
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 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||||
k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI=
|
k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI=
|
||||||
|
Loading…
Reference in New Issue
Block a user