Skip to content

Commit 690e280

Browse files
committed
improve unstructured serialisation
Signed-off-by: Tim Ramlot <[email protected]>
1 parent 80c1894 commit 690e280

File tree

2 files changed

+9
-30
lines changed

2 files changed

+9
-30
lines changed

pkg/client/apiutil/apimachinery.go

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"k8s.io/apimachinery/pkg/runtime/schema"
3232
"k8s.io/apimachinery/pkg/runtime/serializer"
3333
"k8s.io/client-go/discovery"
34+
"k8s.io/client-go/dynamic"
3435
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
3536
"k8s.io/client-go/rest"
3637
"k8s.io/client-go/restmapper"
@@ -153,19 +154,6 @@ func RESTClientForGVK(gvk schema.GroupVersionKind, isUnstructured bool, baseConf
153154
return rest.RESTClientFor(createRestConfig(gvk, isUnstructured, baseConfig, codecs))
154155
}
155156

156-
// serializerWithDecodedGVK is a CodecFactory that overrides the DecoderToVersion of a WithoutConversionCodecFactory
157-
// in order to avoid clearing the GVK from the decoded object.
158-
//
159-
// See https://github.com/kubernetes/kubernetes/issues/80609.
160-
type serializerWithDecodedGVK struct {
161-
serializer.WithoutConversionCodecFactory
162-
}
163-
164-
// DecoderToVersion returns an decoder that does not do conversion.
165-
func (f serializerWithDecodedGVK) DecoderToVersion(serializer runtime.Decoder, _ runtime.GroupVersioner) runtime.Decoder {
166-
return serializer
167-
}
168-
169157
// createRestConfig copies the base config and updates needed fields for a new rest config.
170158
func createRestConfig(gvk schema.GroupVersionKind, isUnstructured bool, baseConfig *rest.Config, codecs serializer.CodecFactory) *rest.Config {
171159
gv := gvk.GroupVersion()
@@ -190,9 +178,8 @@ func createRestConfig(gvk schema.GroupVersionKind, isUnstructured bool, baseConf
190178
}
191179

192180
if isUnstructured {
193-
// If the object is unstructured, we need to preserve the GVK information.
194-
// Use our own custom serializer.
195-
cfg.NegotiatedSerializer = serializerWithDecodedGVK{serializer.WithoutConversionCodecFactory{CodecFactory: codecs}}
181+
// If the object is unstructured, we use the client-go dynamic serializer.
182+
cfg = dynamic.ConfigFor(cfg)
196183
} else {
197184
cfg.NegotiatedSerializer = serializerWithTargetZeroingDecode{NegotiatedSerializer: serializer.WithoutConversionCodecFactory{CodecFactory: codecs}}
198185
}

pkg/client/watch.go

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2424
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2525
"k8s.io/apimachinery/pkg/watch"
26-
"k8s.io/client-go/dynamic"
2726
"k8s.io/client-go/rest"
2827
)
2928

@@ -33,16 +32,11 @@ func NewWithWatch(config *rest.Config, options Options) (WithWatch, error) {
3332
if err != nil {
3433
return nil, err
3534
}
36-
dynamicClient, err := dynamic.NewForConfig(config)
37-
if err != nil {
38-
return nil, err
39-
}
40-
return &watchingClient{client: client, dynamic: dynamicClient}, nil
35+
return &watchingClient{client: client}, nil
4136
}
4237

4338
type watchingClient struct {
4439
*client
45-
dynamic dynamic.Interface
4640
}
4741

4842
func (w *watchingClient) Watch(ctx context.Context, list ObjectList, opts ...ListOption) (watch.Interface, error) {
@@ -82,20 +76,18 @@ func (w *watchingClient) metadataWatch(ctx context.Context, obj *metav1.PartialO
8276
}
8377

8478
func (w *watchingClient) unstructuredWatch(ctx context.Context, obj *unstructured.UnstructuredList, opts ...ListOption) (watch.Interface, error) {
85-
gvk := obj.GroupVersionKind()
86-
gvk.Kind = strings.TrimSuffix(gvk.Kind, "List")
87-
8879
r, err := w.client.unstructuredClient.resources.getResource(obj)
8980
if err != nil {
9081
return nil, err
9182
}
9283

9384
listOpts := w.listOpts(opts...)
9485

95-
if listOpts.Namespace != "" && r.isNamespaced() {
96-
return w.dynamic.Resource(r.mapping.Resource).Namespace(listOpts.Namespace).Watch(ctx, *listOpts.AsListOptions())
97-
}
98-
return w.dynamic.Resource(r.mapping.Resource).Watch(ctx, *listOpts.AsListOptions())
86+
return r.Get().
87+
NamespaceIfScoped(listOpts.Namespace, r.isNamespaced()).
88+
Resource(r.resource()).
89+
VersionedParams(listOpts.AsListOptions(), w.client.unstructuredClient.paramCodec).
90+
Watch(ctx)
9991
}
10092

10193
func (w *watchingClient) typedWatch(ctx context.Context, obj ObjectList, opts ...ListOption) (watch.Interface, error) {

0 commit comments

Comments
 (0)