diff --git a/pkg/genericapiserver/endpoints/apiserver_test.go b/pkg/genericapiserver/endpoints/apiserver_test.go index bab943fd9a9..b0869dda9d6 100644 --- a/pkg/genericapiserver/endpoints/apiserver_test.go +++ b/pkg/genericapiserver/endpoints/apiserver_test.go @@ -1994,7 +1994,7 @@ func TestDeleteWithOptionsQuery(t *testing.T) { t.Fatalf("unexpected error: %v", err) } if res.StatusCode != http.StatusOK { - t.Errorf("unexpected response: %s %#v", request.URL, res) + t.Fatalf("unexpected response: %s %#v", request.URL, res) s, err := ioutil.ReadAll(res.Body) if err != nil { t.Fatalf("unexpected error: %v", err) @@ -2002,7 +2002,7 @@ func TestDeleteWithOptionsQuery(t *testing.T) { t.Logf(string(s)) } if simpleStorage.deleted != ID { - t.Errorf("Unexpected delete: %s, expected %s", simpleStorage.deleted, ID) + t.Fatalf("Unexpected delete: %s, expected %s", simpleStorage.deleted, ID) } simpleStorage.deleteOptions.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{}) if !api.Semantic.DeepEqual(simpleStorage.deleteOptions, item) { diff --git a/pkg/genericapiserver/endpoints/handlers/rest.go b/pkg/genericapiserver/endpoints/handlers/rest.go index 80819364799..1dd89983266 100644 --- a/pkg/genericapiserver/endpoints/handlers/rest.go +++ b/pkg/genericapiserver/endpoints/handlers/rest.go @@ -140,7 +140,7 @@ func GetResource(r rest.Getter, e rest.Exporter, scope RequestScope) restful.Rou options := metav1.GetOptions{} if values := req.Request.URL.Query(); len(values) > 0 { exports := metav1.ExportOptions{} - if err := scope.ParameterCodec.DecodeParameters(values, schema.GroupVersion{Version: "v1"}, &exports); err != nil { + if err := metainternalversion.ParameterCodec.DecodeParameters(values, scope.MetaGroupVersion, &exports); err != nil { return nil, err } if exports.Export { @@ -149,7 +149,7 @@ func GetResource(r rest.Getter, e rest.Exporter, scope RequestScope) restful.Rou } return e.Export(ctx, name, exports) } - if err := scope.ParameterCodec.DecodeParameters(values, schema.GroupVersion{Version: "v1"}, &options); err != nil { + if err := metainternalversion.ParameterCodec.DecodeParameters(values, scope.MetaGroupVersion, &options); err != nil { return nil, err } } @@ -818,13 +818,15 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco return } if len(body) > 0 { - s, err := negotiation.NegotiateInputSerializer(req.Request, scope.Serializer) + s, err := negotiation.NegotiateInputSerializer(req.Request, metainternalversion.Codecs) if err != nil { scope.err(err, res.ResponseWriter, req.Request) return } - defaultGVK := scope.Kind.GroupVersion().WithKind("DeleteOptions") - obj, _, err := scope.Serializer.DecoderToVersion(s.Serializer, defaultGVK.GroupVersion()).Decode(body, &defaultGVK, options) + // For backwards compatibility, we need to allow existing clients to submit per group DeleteOptions + // It is also allowed to pass a body with meta.k8s.io/v1.DeleteOptions + defaultGVK := scope.MetaGroupVersion.WithKind("DeleteOptions") + obj, _, err := metainternalversion.Codecs.DecoderToVersion(s.Serializer, defaultGVK.GroupVersion()).Decode(body, &defaultGVK, options) if err != nil { scope.err(err, res.ResponseWriter, req.Request) return @@ -835,7 +837,7 @@ func DeleteResource(r rest.GracefulDeleter, allowsOptions bool, scope RequestSco } } else { if values := req.Request.URL.Query(); len(values) > 0 { - if err := scope.ParameterCodec.DecodeParameters(values, scope.Kind.GroupVersion(), options); err != nil { + if err := metainternalversion.ParameterCodec.DecodeParameters(values, scope.MetaGroupVersion, options); err != nil { scope.err(err, res.ResponseWriter, req.Request) return } diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/register.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/register.go index 4a76c03e07e..6aeae230b73 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/register.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/register.go @@ -29,8 +29,8 @@ const GroupName = "meta.k8s.io" // Scheme is the registry for any type that adheres to the meta API spec. var scheme = runtime.NewScheme() -// Codecs provides access to encoding and decoding for the scheme -var codecs = serializer.NewCodecFactory(scheme) +// Codecs provides access to encoding and decoding for the scheme. +var Codecs = serializer.NewCodecFactory(scheme) // SchemeGroupVersion is group version used to register these objects var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} @@ -61,9 +61,16 @@ func addToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion) Convert_internalversion_ListOptions_To_v1_ListOptions, Convert_v1_ListOptions_To_internalversion_ListOptions, ) + // ListOptions is the only options struct which needs conversion (it exposes labels and fields + // as selectors for convenience). The other types have only a single representation today. scheme.AddKnownTypes(SchemeGroupVersion, &ListOptions{}, + &metav1.GetOptions{}, + &metav1.ExportOptions{}, + &metav1.DeleteOptions{}, ) + // Allow delete options to be decoded across all version in this scheme (we may want to be more clever than this) + scheme.AddUnversionedTypes(SchemeGroupVersion, &metav1.DeleteOptions{}) metav1.AddToGroupVersion(scheme, metav1.SchemeGroupVersion) return nil } diff --git a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/register.go b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/register.go index 735f5e6cad8..3b8580340b2 100644 --- a/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/register.go +++ b/staging/src/k8s.io/apimachinery/pkg/apis/meta/v1/register.go @@ -42,6 +42,7 @@ func AddToGroupVersion(scheme *runtime.Scheme, groupVersion schema.GroupVersion) schema.GroupVersion{Group: groupVersion.Group, Version: runtime.APIVersionInternal}.WithKind(WatchEventKind), &InternalEvent{}, ) + // Supports legacy code paths, most callers should use metav1.ParameterCodec for now scheme.AddKnownTypes(groupVersion, &ListOptions{}, &ExportOptions{}, @@ -65,5 +66,8 @@ var ParameterCodec = runtime.NewParameterCodec(scheme) func init() { scheme.AddUnversionedTypes(SchemeGroupVersion, &ListOptions{}, + &ExportOptions{}, + &GetOptions{}, + &DeleteOptions{}, ) }