mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
apiextensions-apiserver: Fix decoding of DeleteOptions.
This commit is contained in:
parent
6044bea32b
commit
0921c9a12a
@ -269,19 +269,8 @@ func (r *crdHandler) getServingInfoFor(crd *apiextensions.CustomResourceDefiniti
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
kind := schema.GroupVersionKind{Group: crd.Spec.Group, Version: crd.Spec.Version, Kind: crd.Spec.Names.Kind}
|
// In addition to Unstructured objects (Custom Resources), we also may sometimes need to
|
||||||
storage := customresource.NewREST(
|
// decode unversioned Options objects, so we delegate to parameterScheme for such types.
|
||||||
schema.GroupResource{Group: crd.Spec.Group, Resource: crd.Spec.Names.Plural},
|
|
||||||
schema.GroupVersionKind{Group: crd.Spec.Group, Version: crd.Spec.Version, Kind: crd.Spec.Names.ListKind},
|
|
||||||
UnstructuredCopier{},
|
|
||||||
customresource.NewStrategy(
|
|
||||||
discovery.NewUnstructuredObjectTyper(nil),
|
|
||||||
crd.Spec.Scope == apiextensions.NamespaceScoped,
|
|
||||||
kind,
|
|
||||||
),
|
|
||||||
r.restOptionsGetter,
|
|
||||||
)
|
|
||||||
|
|
||||||
parameterScheme := runtime.NewScheme()
|
parameterScheme := runtime.NewScheme()
|
||||||
parameterScheme.AddUnversionedTypes(schema.GroupVersion{Group: crd.Spec.Group, Version: crd.Spec.Version},
|
parameterScheme.AddUnversionedTypes(schema.GroupVersion{Group: crd.Spec.Group, Version: crd.Spec.Version},
|
||||||
&metav1.ListOptions{},
|
&metav1.ListOptions{},
|
||||||
@ -292,6 +281,24 @@ func (r *crdHandler) getServingInfoFor(crd *apiextensions.CustomResourceDefiniti
|
|||||||
parameterScheme.AddGeneratedDeepCopyFuncs(metav1.GetGeneratedDeepCopyFuncs()...)
|
parameterScheme.AddGeneratedDeepCopyFuncs(metav1.GetGeneratedDeepCopyFuncs()...)
|
||||||
parameterCodec := runtime.NewParameterCodec(parameterScheme)
|
parameterCodec := runtime.NewParameterCodec(parameterScheme)
|
||||||
|
|
||||||
|
kind := schema.GroupVersionKind{Group: crd.Spec.Group, Version: crd.Spec.Version, Kind: crd.Spec.Names.Kind}
|
||||||
|
typer := unstructuredObjectTyper{
|
||||||
|
delegate: parameterScheme,
|
||||||
|
unstructuredTyper: discovery.NewUnstructuredObjectTyper(nil),
|
||||||
|
}
|
||||||
|
creator := unstructuredCreator{}
|
||||||
|
storage := customresource.NewREST(
|
||||||
|
schema.GroupResource{Group: crd.Spec.Group, Resource: crd.Spec.Names.Plural},
|
||||||
|
schema.GroupVersionKind{Group: crd.Spec.Group, Version: crd.Spec.Version, Kind: crd.Spec.Names.ListKind},
|
||||||
|
UnstructuredCopier{},
|
||||||
|
customresource.NewStrategy(
|
||||||
|
typer,
|
||||||
|
crd.Spec.Scope == apiextensions.NamespaceScoped,
|
||||||
|
kind,
|
||||||
|
),
|
||||||
|
r.restOptionsGetter,
|
||||||
|
)
|
||||||
|
|
||||||
selfLinkPrefix := ""
|
selfLinkPrefix := ""
|
||||||
switch crd.Spec.Scope {
|
switch crd.Spec.Scope {
|
||||||
case apiextensions.ClusterScoped:
|
case apiextensions.ClusterScoped:
|
||||||
@ -315,14 +322,14 @@ func (r *crdHandler) getServingInfoFor(crd *apiextensions.CustomResourceDefiniti
|
|||||||
return ret
|
return ret
|
||||||
},
|
},
|
||||||
|
|
||||||
Serializer: UnstructuredNegotiatedSerializer{},
|
Serializer: unstructuredNegotiatedSerializer{typer: typer, creator: creator},
|
||||||
ParameterCodec: parameterCodec,
|
ParameterCodec: parameterCodec,
|
||||||
|
|
||||||
Creater: UnstructuredCreator{},
|
Creater: creator,
|
||||||
Convertor: unstructured.UnstructuredObjectConverter{},
|
Convertor: unstructured.UnstructuredObjectConverter{},
|
||||||
Defaulter: UnstructuredDefaulter{},
|
Defaulter: unstructuredDefaulter{parameterScheme},
|
||||||
Copier: UnstructuredCopier{},
|
Copier: UnstructuredCopier{},
|
||||||
Typer: discovery.NewUnstructuredObjectTyper(nil),
|
Typer: typer,
|
||||||
UnsafeConvertor: unstructured.UnstructuredObjectConverter{},
|
UnsafeConvertor: unstructured.UnstructuredObjectConverter{},
|
||||||
|
|
||||||
Resource: schema.GroupVersionResource{Group: crd.Spec.Group, Version: crd.Spec.Version, Resource: crd.Spec.Names.Plural},
|
Resource: schema.GroupVersionResource{Group: crd.Spec.Group, Version: crd.Spec.Version, Resource: crd.Spec.Names.Plural},
|
||||||
@ -341,30 +348,62 @@ func (r *crdHandler) getServingInfoFor(crd *apiextensions.CustomResourceDefiniti
|
|||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnstructuredNegotiatedSerializer struct{}
|
type unstructuredNegotiatedSerializer struct {
|
||||||
|
typer runtime.ObjectTyper
|
||||||
|
creator runtime.ObjectCreater
|
||||||
|
}
|
||||||
|
|
||||||
func (s UnstructuredNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInfo {
|
func (s unstructuredNegotiatedSerializer) SupportedMediaTypes() []runtime.SerializerInfo {
|
||||||
return []runtime.SerializerInfo{
|
return []runtime.SerializerInfo{
|
||||||
{
|
{
|
||||||
MediaType: "application/json",
|
MediaType: "application/json",
|
||||||
EncodesAsText: true,
|
EncodesAsText: true,
|
||||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, UnstructuredCreator{}, discovery.NewUnstructuredObjectTyper(nil), false),
|
Serializer: json.NewSerializer(json.DefaultMetaFactory, s.creator, s.typer, false),
|
||||||
PrettySerializer: json.NewSerializer(json.DefaultMetaFactory, UnstructuredCreator{}, discovery.NewUnstructuredObjectTyper(nil), true),
|
PrettySerializer: json.NewSerializer(json.DefaultMetaFactory, s.creator, s.typer, true),
|
||||||
StreamSerializer: &runtime.StreamSerializerInfo{
|
StreamSerializer: &runtime.StreamSerializerInfo{
|
||||||
EncodesAsText: true,
|
EncodesAsText: true,
|
||||||
Serializer: json.NewSerializer(json.DefaultMetaFactory, UnstructuredCreator{}, discovery.NewUnstructuredObjectTyper(nil), false),
|
Serializer: json.NewSerializer(json.DefaultMetaFactory, s.creator, s.typer, false),
|
||||||
Framer: json.Framer,
|
Framer: json.Framer,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s UnstructuredNegotiatedSerializer) EncoderForVersion(serializer runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
|
func (s unstructuredNegotiatedSerializer) EncoderForVersion(serializer runtime.Encoder, gv runtime.GroupVersioner) runtime.Encoder {
|
||||||
return versioning.NewDefaultingCodecForScheme(Scheme, crEncoderInstance, nil, gv, nil)
|
return versioning.NewDefaultingCodecForScheme(Scheme, crEncoderInstance, nil, gv, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s UnstructuredNegotiatedSerializer) DecoderToVersion(serializer runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder {
|
func (s unstructuredNegotiatedSerializer) DecoderToVersion(serializer runtime.Decoder, gv runtime.GroupVersioner) runtime.Decoder {
|
||||||
return unstructured.UnstructuredJSONScheme
|
return unstructuredDecoder{delegate: Codecs.DecoderToVersion(serializer, gv)}
|
||||||
|
}
|
||||||
|
|
||||||
|
type unstructuredDecoder struct {
|
||||||
|
delegate runtime.Decoder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d unstructuredDecoder) Decode(data []byte, defaults *schema.GroupVersionKind, into runtime.Object) (runtime.Object, *schema.GroupVersionKind, error) {
|
||||||
|
// Delegate for things other than Unstructured.
|
||||||
|
if _, ok := into.(runtime.Unstructured); !ok && into != nil {
|
||||||
|
return d.delegate.Decode(data, defaults, into)
|
||||||
|
}
|
||||||
|
return unstructured.UnstructuredJSONScheme.Decode(data, defaults, into)
|
||||||
|
}
|
||||||
|
|
||||||
|
type unstructuredObjectTyper struct {
|
||||||
|
delegate runtime.ObjectTyper
|
||||||
|
unstructuredTyper runtime.ObjectTyper
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t unstructuredObjectTyper) ObjectKinds(obj runtime.Object) ([]schema.GroupVersionKind, bool, error) {
|
||||||
|
// Delegate for things other than Unstructured.
|
||||||
|
if _, ok := obj.(runtime.Unstructured); !ok {
|
||||||
|
return t.delegate.ObjectKinds(obj)
|
||||||
|
}
|
||||||
|
return t.unstructuredTyper.ObjectKinds(obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t unstructuredObjectTyper) Recognizes(gvk schema.GroupVersionKind) bool {
|
||||||
|
return t.delegate.Recognizes(gvk) || t.unstructuredTyper.Recognizes(gvk)
|
||||||
}
|
}
|
||||||
|
|
||||||
var crEncoderInstance = crEncoder{}
|
var crEncoderInstance = crEncoder{}
|
||||||
@ -390,9 +429,9 @@ func (crEncoder) Encode(obj runtime.Object, w io.Writer) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnstructuredCreator struct{}
|
type unstructuredCreator struct{}
|
||||||
|
|
||||||
func (UnstructuredCreator) New(kind schema.GroupVersionKind) (runtime.Object, error) {
|
func (c unstructuredCreator) New(kind schema.GroupVersionKind) (runtime.Object, error) {
|
||||||
ret := &unstructured.Unstructured{}
|
ret := &unstructured.Unstructured{}
|
||||||
ret.SetGroupVersionKind(kind)
|
ret.SetGroupVersionKind(kind)
|
||||||
return ret, nil
|
return ret, nil
|
||||||
@ -401,6 +440,14 @@ func (UnstructuredCreator) New(kind schema.GroupVersionKind) (runtime.Object, er
|
|||||||
type UnstructuredCopier struct{}
|
type UnstructuredCopier struct{}
|
||||||
|
|
||||||
func (UnstructuredCopier) Copy(obj runtime.Object) (runtime.Object, error) {
|
func (UnstructuredCopier) Copy(obj runtime.Object) (runtime.Object, error) {
|
||||||
|
if _, ok := obj.(runtime.Unstructured); !ok {
|
||||||
|
// Callers should not use this UnstructuredCopier for things other than Unstructured.
|
||||||
|
// If they do, the copy they get back will become Unstructured, which can lead to
|
||||||
|
// difficult-to-debug errors downstream. To make such errors more obvious,
|
||||||
|
// we explicitly reject anything that isn't Unstructured.
|
||||||
|
return nil, fmt.Errorf("UnstructuredCopier can't copy type %T", obj)
|
||||||
|
}
|
||||||
|
|
||||||
// serialize and deserialize to ensure a clean copy
|
// serialize and deserialize to ensure a clean copy
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
err := unstructured.UnstructuredJSONScheme.Encode(obj, buf)
|
err := unstructured.UnstructuredJSONScheme.Encode(obj, buf)
|
||||||
@ -412,9 +459,16 @@ func (UnstructuredCopier) Copy(obj runtime.Object) (runtime.Object, error) {
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
type UnstructuredDefaulter struct{}
|
type unstructuredDefaulter struct {
|
||||||
|
delegate runtime.ObjectDefaulter
|
||||||
|
}
|
||||||
|
|
||||||
func (UnstructuredDefaulter) Default(in runtime.Object) {}
|
func (d unstructuredDefaulter) Default(in runtime.Object) {
|
||||||
|
// Delegate for things other than Unstructured.
|
||||||
|
if _, ok := in.(runtime.Unstructured); !ok {
|
||||||
|
d.delegate.Default(in)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type CRDRESTOptionsGetter struct {
|
type CRDRESTOptionsGetter struct {
|
||||||
StorageConfig storagebackend.Config
|
StorageConfig storagebackend.Config
|
||||||
|
Loading…
Reference in New Issue
Block a user