diff --git a/test/integration/controlplane/transformation/kms_transformation_test.go b/test/integration/controlplane/transformation/kms_transformation_test.go index 01858351ea3..3ecc322ab26 100644 --- a/test/integration/controlplane/transformation/kms_transformation_test.go +++ b/test/integration/controlplane/transformation/kms_transformation_test.go @@ -53,6 +53,8 @@ import ( mock "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing/v1beta1" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/dynamic" + clientfeatures "k8s.io/client-go/features" + clientfeaturestesting "k8s.io/client-go/features/testing" "k8s.io/client-go/rest" featuregatetesting "k8s.io/component-base/featuregate/testing" kmsapi "k8s.io/kms/apis/v1beta1" @@ -629,6 +631,9 @@ resources: // Need to enable this explicitly as the feature is deprecated featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.KMSv1, true) + // TODO: Remove this override when the codecs used for serving all built-in APIs are wired to the apiserver feature gate. + clientfeaturestesting.SetFeatureDuringTest(t, clientfeatures.ClientsPreferCBOR, false) + test, err := newTransformTest(t, encryptionConfig, false, "", nil) if err != nil { t.Fatalf("failed to start KUBE API Server with encryptionConfig") diff --git a/test/integration/etcd/etcd_storage_path_test.go b/test/integration/etcd/etcd_storage_path_test.go index 903f39f0ae6..5d13544dd1b 100644 --- a/test/integration/etcd/etcd_storage_path_test.go +++ b/test/integration/etcd/etcd_storage_path_test.go @@ -18,7 +18,6 @@ package etcd import ( "context" - "encoding/json" "fmt" "path/filepath" "reflect" @@ -33,10 +32,17 @@ import ( "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "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/apimachinery/pkg/runtime/serializer/recognizer" + utiljson "k8s.io/apimachinery/pkg/util/json" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/dynamic" + clientfeatures "k8s.io/client-go/features" + clientfeaturestesting "k8s.io/client-go/features/testing" featuregatetesting "k8s.io/component-base/featuregate/testing" ) @@ -77,6 +83,9 @@ func TestEtcdStoragePath(t *testing.T) { featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllAlpha", true) featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllBeta", true) + // TODO: Remove this override when the codecs used for serving all built-in APIs are wired to the apiserver feature gate. + clientfeaturestesting.SetFeatureDuringTest(t, clientfeatures.ClientsPreferCBOR, false) + apiServer := StartRealAPIServerOrDie(t) defer apiServer.Cleanup() defer dumpEtcdKVOnFailure(t, apiServer.KV) @@ -124,7 +133,8 @@ func TestEtcdStoragePath(t *testing.T) { err error ) if shouldCreate { - if input, err = jsonToMetaObject([]byte(testData.Stub)); err != nil || input.isEmpty() { + input = new(metaObject) + if err = utiljson.Unmarshal([]byte(testData.Stub), input); err != nil || input.isEmpty() { t.Fatalf("invalid test data for %s: %v", gvResource, err) } // unset type meta fields - we only set these in the CRD test data and it makes @@ -152,7 +162,20 @@ func TestEtcdStoragePath(t *testing.T) { } } - output, err := getFromEtcd(apiServer.KV, testData.ExpectedEtcdPath) + // Build a decoder that can decode JSON and CBOR from storage. + scheme := runtime.NewScheme() + if testData.ExpectedGVK != nil { + scheme.AddKnownTypeWithName(*testData.ExpectedGVK, &metaObject{}) + } else { + scheme.AddKnownTypeWithName(gvk, &metaObject{}) + + } + decoder := recognizer.NewDecoder( + cbor.NewSerializer(scheme, scheme), + json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, json.SerializerOptions{}), + ) + + output, err := getFromEtcd(decoder, apiServer.KV, testData.ExpectedEtcdPath) if err != nil { t.Fatalf("failed to get from etcd for %s: %#v", gvResource, err) } @@ -208,7 +231,7 @@ func TestEtcdStoragePath(t *testing.T) { ) } - actualGVK := output.getGVK() + actualGVK := output.GroupVersionKind() if actualGVK != expectedGVK { t.Errorf("GVK for %s does not match, expected %s got %s", kind, expectedGVK, actualGVK) } @@ -289,9 +312,7 @@ func getEtcdBucket(path string) string { // stable fields to compare as a sanity check type metaObject struct { - // all of type meta - Kind string `json:"kind,omitempty"` - APIVersion string `json:"apiVersion,omitempty"` + metav1.TypeMeta `json:",inline"` // parts of object meta Metadata struct { @@ -300,8 +321,10 @@ type metaObject struct { } `json:"metadata,omitempty"` } -func (obj *metaObject) getGVK() schema.GroupVersionKind { - return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind) +var _ runtime.Object = &metaObject{} + +func (*metaObject) DeepCopyObject() runtime.Object { + panic("unimplemented") } func (obj *metaObject) isEmpty() bool { @@ -315,14 +338,6 @@ type cleanupData struct { resource schema.GroupVersionResource } -func jsonToMetaObject(stub []byte) (*metaObject, error) { - obj := &metaObject{} - if err := json.Unmarshal(stub, obj); err != nil { - return nil, err - } - return obj, nil -} - func keyStringer(i interface{}) string { base := "\n\t" switch key := i.(type) { @@ -386,7 +401,7 @@ func (c *allClient) createPrerequisites(mapper meta.RESTMapper, ns string, prere return nil } -func getFromEtcd(keys clientv3.KV, path string) (*metaObject, error) { +func getFromEtcd(decoder runtime.Decoder, keys clientv3.KV, path string) (*metaObject, error) { response, err := keys.Get(context.Background(), path) if err != nil { return nil, err @@ -394,7 +409,11 @@ func getFromEtcd(keys clientv3.KV, path string) (*metaObject, error) { if response.More || response.Count != 1 || len(response.Kvs) != 1 { return nil, fmt.Errorf("Invalid etcd response (not found == %v): %#v", response.Count == 0, response) } - return jsonToMetaObject(response.Kvs[0].Value) + var obj metaObject + if err := runtime.DecodeInto(decoder, response.Kvs[0].Value, &obj); err != nil { + return nil, err + } + return &obj, nil } func diffMaps(a, b interface{}) ([]string, []string) {