Skip to content

Commit 82d4212

Browse files
committed
Support metadata-only client operations
This adds support for a metadata-only client. It only implements the operations supported by metadata (delete, deleteallof, patch, get, list, status.patch). The higher-level client will now delegate to this for when a PartialObjectMetadata object is passed in.
1 parent d598b2d commit 82d4212

File tree

3 files changed

+981
-313
lines changed

3 files changed

+981
-313
lines changed

pkg/client/client.go

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@ import (
2121
"fmt"
2222

2323
"k8s.io/apimachinery/pkg/api/meta"
24+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2425
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2526
"k8s.io/apimachinery/pkg/runtime"
2627
"k8s.io/apimachinery/pkg/runtime/schema"
2728
"k8s.io/apimachinery/pkg/runtime/serializer"
2829
"k8s.io/client-go/kubernetes/scheme"
30+
"k8s.io/client-go/metadata"
2931
"k8s.io/client-go/rest"
32+
3033
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
3134
)
3235

@@ -76,6 +79,11 @@ func New(config *rest.Config, options Options) (Client, error) {
7679
resourceByType: make(map[schema.GroupVersionKind]*resourceMeta),
7780
}
7881

82+
rawMetaClient, err := metadata.NewForConfig(config)
83+
if err != nil {
84+
return nil, fmt.Errorf("unable to construct metadata-only client for use as part of client: %w", err)
85+
}
86+
7987
c := &client{
8088
typedClient: typedClient{
8189
cache: clientcache,
@@ -85,6 +93,10 @@ func New(config *rest.Config, options Options) (Client, error) {
8593
cache: clientcache,
8694
paramCodec: noConversionParamCodec{},
8795
},
96+
metadataClient: metadataClient{
97+
client: rawMetaClient,
98+
restMapper: options.Mapper,
99+
},
88100
scheme: options.Scheme,
89101
mapper: options.Mapper,
90102
}
@@ -99,6 +111,7 @@ var _ Client = &client{}
99111
type client struct {
100112
typedClient typedClient
101113
unstructuredClient unstructuredClient
114+
metadataClient metadataClient
102115
scheme *runtime.Scheme
103116
mapper meta.RESTMapper
104117
}
@@ -125,67 +138,88 @@ func (c *client) RESTMapper() meta.RESTMapper {
125138

126139
// Create implements client.Client
127140
func (c *client) Create(ctx context.Context, obj runtime.Object, opts ...CreateOption) error {
128-
_, ok := obj.(*unstructured.Unstructured)
129-
if ok {
141+
switch obj.(type) {
142+
case *unstructured.Unstructured:
130143
return c.unstructuredClient.Create(ctx, obj, opts...)
144+
case *metav1.PartialObjectMetadata:
145+
return fmt.Errorf("cannot create using only metadata")
146+
default:
147+
return c.typedClient.Create(ctx, obj, opts...)
131148
}
132-
return c.typedClient.Create(ctx, obj, opts...)
133149
}
134150

135151
// Update implements client.Client
136152
func (c *client) Update(ctx context.Context, obj runtime.Object, opts ...UpdateOption) error {
137153
defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
138-
_, ok := obj.(*unstructured.Unstructured)
139-
if ok {
154+
switch obj.(type) {
155+
case *unstructured.Unstructured:
140156
return c.unstructuredClient.Update(ctx, obj, opts...)
157+
case *metav1.PartialObjectMetadata:
158+
return fmt.Errorf("cannot update using only metadata -- did you mean to patch?")
159+
default:
160+
return c.typedClient.Update(ctx, obj, opts...)
141161
}
142-
return c.typedClient.Update(ctx, obj, opts...)
143162
}
144163

145164
// Delete implements client.Client
146165
func (c *client) Delete(ctx context.Context, obj runtime.Object, opts ...DeleteOption) error {
147-
_, ok := obj.(*unstructured.Unstructured)
148-
if ok {
166+
switch obj.(type) {
167+
case *unstructured.Unstructured:
149168
return c.unstructuredClient.Delete(ctx, obj, opts...)
169+
case *metav1.PartialObjectMetadata:
170+
return c.metadataClient.Delete(ctx, obj, opts...)
171+
default:
172+
return c.typedClient.Delete(ctx, obj, opts...)
150173
}
151-
return c.typedClient.Delete(ctx, obj, opts...)
152174
}
153175

154176
// DeleteAllOf implements client.Client
155177
func (c *client) DeleteAllOf(ctx context.Context, obj runtime.Object, opts ...DeleteAllOfOption) error {
156-
_, ok := obj.(*unstructured.Unstructured)
157-
if ok {
178+
switch obj.(type) {
179+
case *unstructured.Unstructured:
158180
return c.unstructuredClient.DeleteAllOf(ctx, obj, opts...)
181+
case *metav1.PartialObjectMetadata:
182+
return c.metadataClient.DeleteAllOf(ctx, obj, opts...)
183+
default:
184+
return c.typedClient.DeleteAllOf(ctx, obj, opts...)
159185
}
160-
return c.typedClient.DeleteAllOf(ctx, obj, opts...)
161186
}
162187

163188
// Patch implements client.Client
164189
func (c *client) Patch(ctx context.Context, obj runtime.Object, patch Patch, opts ...PatchOption) error {
165190
defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
166-
_, ok := obj.(*unstructured.Unstructured)
167-
if ok {
191+
switch obj.(type) {
192+
case *unstructured.Unstructured:
168193
return c.unstructuredClient.Patch(ctx, obj, patch, opts...)
194+
case *metav1.PartialObjectMetadata:
195+
return c.metadataClient.Patch(ctx, obj, patch, opts...)
196+
default:
197+
return c.typedClient.Patch(ctx, obj, patch, opts...)
169198
}
170-
return c.typedClient.Patch(ctx, obj, patch, opts...)
171199
}
172200

173201
// Get implements client.Client
174202
func (c *client) Get(ctx context.Context, key ObjectKey, obj runtime.Object) error {
175-
_, ok := obj.(*unstructured.Unstructured)
176-
if ok {
203+
switch obj.(type) {
204+
case *unstructured.Unstructured:
177205
return c.unstructuredClient.Get(ctx, key, obj)
206+
case *metav1.PartialObjectMetadata:
207+
return c.metadataClient.Get(ctx, key, obj)
208+
default:
209+
return c.typedClient.Get(ctx, key, obj)
178210
}
179-
return c.typedClient.Get(ctx, key, obj)
180211
}
181212

182213
// List implements client.Client
183214
func (c *client) List(ctx context.Context, obj runtime.Object, opts ...ListOption) error {
184-
_, ok := obj.(*unstructured.UnstructuredList)
185-
if ok {
215+
switch obj.(type) {
216+
case *unstructured.Unstructured:
186217
return c.unstructuredClient.List(ctx, obj, opts...)
218+
case *metav1.PartialObjectMetadata:
219+
return c.metadataClient.List(ctx, obj, opts...)
220+
default:
221+
return c.typedClient.List(ctx, obj, opts...)
187222
}
188-
return c.typedClient.List(ctx, obj, opts...)
189223
}
190224

191225
// Status implements client.StatusClient
@@ -204,19 +238,25 @@ var _ StatusWriter = &statusWriter{}
204238
// Update implements client.StatusWriter
205239
func (sw *statusWriter) Update(ctx context.Context, obj runtime.Object, opts ...UpdateOption) error {
206240
defer sw.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
207-
_, ok := obj.(*unstructured.Unstructured)
208-
if ok {
241+
switch obj.(type) {
242+
case *unstructured.Unstructured:
209243
return sw.client.unstructuredClient.UpdateStatus(ctx, obj, opts...)
244+
case *metav1.PartialObjectMetadata:
245+
return fmt.Errorf("cannot update status using only metadata -- did you mean to patch?")
246+
default:
247+
return sw.client.typedClient.UpdateStatus(ctx, obj, opts...)
210248
}
211-
return sw.client.typedClient.UpdateStatus(ctx, obj, opts...)
212249
}
213250

214251
// Patch implements client.Client
215252
func (sw *statusWriter) Patch(ctx context.Context, obj runtime.Object, patch Patch, opts ...PatchOption) error {
216253
defer sw.client.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
217-
_, ok := obj.(*unstructured.Unstructured)
218-
if ok {
254+
switch obj.(type) {
255+
case *unstructured.Unstructured:
219256
return sw.client.unstructuredClient.PatchStatus(ctx, obj, patch, opts...)
257+
case *metav1.PartialObjectMetadata:
258+
return sw.client.metadataClient.PatchStatus(ctx, obj, patch, opts...)
259+
default:
260+
return sw.client.typedClient.PatchStatus(ctx, obj, patch, opts...)
220261
}
221-
return sw.client.typedClient.PatchStatus(ctx, obj, patch, opts...)
222262
}

0 commit comments

Comments
 (0)