Skip to content

Commit 6533c61

Browse files
committed
Add GetOptions as optional argument of client.Reader and all its implementation
Signed-off-by: FillZpp <[email protected]>
1 parent 196828e commit 6533c61

17 files changed

+105
-23
lines changed

pkg/cache/informer_cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ type informerCache struct {
5151
}
5252

5353
// Get implements Reader.
54-
func (ip *informerCache) Get(ctx context.Context, key client.ObjectKey, out client.Object) error {
54+
func (ip *informerCache) Get(ctx context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error {
5555
gvk, err := apiutil.GVKForObject(out, ip.Scheme)
5656
if err != nil {
5757
return err

pkg/cache/informertest/fake_cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func (c *FakeInformers) IndexField(ctx context.Context, obj client.Object, field
131131
}
132132

133133
// Get implements Cache.
134-
func (c *FakeInformers) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
134+
func (c *FakeInformers) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
135135
return nil
136136
}
137137

pkg/cache/internal/cache_reader.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ type CacheReader struct {
5454
}
5555

5656
// Get checks the indexer for the object and writes a copy of it if found.
57-
func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object) error {
57+
func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Object, opts ...client.GetOption) error {
5858
if c.scopeName == apimeta.RESTScopeNameRoot {
5959
key.Namespace = ""
6060
}

pkg/cache/multi_namespace_cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func (c *multiNamespaceCache) IndexField(ctx context.Context, obj client.Object,
200200
return nil
201201
}
202202

203-
func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
203+
func (c *multiNamespaceCache) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
204204
isNamespaced, err := objectutil.IsAPINamespaced(obj, c.Scheme, c.RESTMapper)
205205
if err != nil {
206206
return err

pkg/client/client.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -241,16 +241,16 @@ func (c *client) Patch(ctx context.Context, obj Object, patch Patch, opts ...Pat
241241
}
242242

243243
// Get implements client.Client.
244-
func (c *client) Get(ctx context.Context, key ObjectKey, obj Object) error {
244+
func (c *client) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
245245
switch obj.(type) {
246246
case *unstructured.Unstructured:
247-
return c.unstructuredClient.Get(ctx, key, obj)
247+
return c.unstructuredClient.Get(ctx, key, obj, opts...)
248248
case *metav1.PartialObjectMetadata:
249249
// Metadata only object should always preserve the GVK coming in from the caller.
250250
defer c.resetGroupVersionKind(obj, obj.GetObjectKind().GroupVersionKind())
251-
return c.metadataClient.Get(ctx, key, obj)
251+
return c.metadataClient.Get(ctx, key, obj, opts...)
252252
default:
253-
return c.typedClient.Get(ctx, key, obj)
253+
return c.typedClient.Get(ctx, key, obj, opts...)
254254
}
255255
}
256256

pkg/client/client_test.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2913,6 +2913,24 @@ var _ = Describe("Client", func() {
29132913
})
29142914
})
29152915

2916+
Describe("GetOptions", func() {
2917+
It("should be convertable to metav1.GetOptions", func() {
2918+
o := (&client.GetOptions{}).ApplyOptions([]client.GetOption{
2919+
&client.GetOptions{Raw: &metav1.GetOptions{ResourceVersion: "RV0"}},
2920+
})
2921+
mo := o.AsGetOptions()
2922+
Expect(mo).NotTo(BeNil())
2923+
Expect(mo.ResourceVersion).To(Equal("RV0"))
2924+
})
2925+
2926+
It("should produce empty metav1.GetOptions if nil", func() {
2927+
var o *client.GetOptions
2928+
Expect(o.AsGetOptions()).To(Equal(&metav1.GetOptions{}))
2929+
o = &client.GetOptions{}
2930+
Expect(o.AsGetOptions()).To(Equal(&metav1.GetOptions{}))
2931+
})
2932+
})
2933+
29162934
Describe("ListOptions", func() {
29172935
It("should be convertable to metav1.ListOptions", func() {
29182936
lo := (&client.ListOptions{}).ApplyOptions([]client.ListOption{
@@ -3389,7 +3407,7 @@ type fakeReader struct {
33893407
Called int
33903408
}
33913409

3392-
func (f *fakeReader) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
3410+
func (f *fakeReader) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
33933411
f.Called++
33943412
return nil
33953413
}

pkg/client/dryrun.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ func (c *dryRunClient) Patch(ctx context.Context, obj Object, patch Patch, opts
7272
}
7373

7474
// Get implements client.Client.
75-
func (c *dryRunClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
76-
return c.client.Get(ctx, key, obj)
75+
func (c *dryRunClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
76+
return c.client.Get(ctx, key, obj, opts...)
7777
}
7878

7979
// List implements client.Client.

pkg/client/fake/client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ func (t versionedTracker) Update(gvr schema.GroupVersionResource, obj runtime.Ob
329329
return t.ObjectTracker.Update(gvr, obj, ns)
330330
}
331331

332-
func (c *fakeClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
332+
func (c *fakeClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
333333
gvr, err := getGVRFromObject(obj, c.scheme)
334334
if err != nil {
335335
return err

pkg/client/interfaces.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ type Reader interface {
5050
// Get retrieves an obj for the given object key from the Kubernetes Cluster.
5151
// obj must be a struct pointer so that obj can be updated with the response
5252
// returned by the Server.
53-
Get(ctx context.Context, key ObjectKey, obj Object) error
53+
Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error
5454

5555
// List retrieves list of objects for a given namespace and list options. On a
5656
// successful call, Items field in the list will be populated with the

pkg/client/metadata_client.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,20 +116,23 @@ func (mc *metadataClient) Patch(ctx context.Context, obj Object, patch Patch, op
116116
}
117117

118118
// Get implements client.Client.
119-
func (mc *metadataClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
119+
func (mc *metadataClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
120120
metadata, ok := obj.(*metav1.PartialObjectMetadata)
121121
if !ok {
122122
return fmt.Errorf("metadata client did not understand object: %T", obj)
123123
}
124124

125125
gvk := metadata.GroupVersionKind()
126126

127+
getOpts := GetOptions{}
128+
getOpts.ApplyOptions(opts)
129+
127130
resInt, err := mc.getResourceInterface(gvk, key.Namespace)
128131
if err != nil {
129132
return err
130133
}
131134

132-
res, err := resInt.Get(ctx, key.Name, metav1.GetOptions{})
135+
res, err := resInt.Get(ctx, key.Name, *getOpts.AsGetOptions())
133136
if err != nil {
134137
return err
135138
}

pkg/client/namespaced_client.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ func (n *namespacedClient) Patch(ctx context.Context, obj Object, patch Patch, o
138138
}
139139

140140
// Get implements client.Client.
141-
func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
141+
func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
142142
isNamespaceScoped, err := objectutil.IsAPINamespaced(obj, n.Scheme(), n.RESTMapper())
143143
if err != nil {
144144
return fmt.Errorf("error finding the scope of the object: %w", err)
@@ -149,7 +149,7 @@ func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object) e
149149
}
150150
key.Namespace = n.namespace
151151
}
152-
return n.client.Get(ctx, key, obj)
152+
return n.client.Get(ctx, key, obj, opts...)
153153
}
154154

155155
// List implements client.Client.

pkg/client/options.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ type DeleteOption interface {
3737
ApplyToDelete(*DeleteOptions)
3838
}
3939

40+
// GetOption is some configuration that modifies options for a get request.
41+
type GetOption interface {
42+
// ApplyToGet applies this configuration to the given get options.
43+
ApplyToGet(*GetOptions)
44+
}
45+
4046
// ListOption is some configuration that modifies options for a list request.
4147
type ListOption interface {
4248
// ApplyToList applies this configuration to the given list options.
@@ -311,6 +317,45 @@ func (p PropagationPolicy) ApplyToDeleteAllOf(opts *DeleteAllOfOptions) {
311317

312318
// }}}
313319

320+
// {{{ Get Options
321+
322+
// GetOptions contains options for get operation.
323+
// Now it only has a Raw field, with support for specific resourceVersion.
324+
type GetOptions struct {
325+
// Raw represents raw GetOptions, as passed to the API server. Note
326+
// that these may not be respected by all implementations of interface.
327+
Raw *metav1.GetOptions
328+
}
329+
330+
var _ GetOption = &GetOptions{}
331+
332+
// ApplyToGet implements GetOption for GetOptions.
333+
func (o *GetOptions) ApplyToGet(lo *GetOptions) {
334+
if o.Raw != nil {
335+
lo.Raw = o.Raw
336+
}
337+
}
338+
339+
// AsGetOptions returns these options as a flattened metav1.GetOptions.
340+
// This may mutate the Raw field.
341+
func (o *GetOptions) AsGetOptions() *metav1.GetOptions {
342+
if o == nil || o.Raw == nil {
343+
return &metav1.GetOptions{}
344+
}
345+
return o.Raw
346+
}
347+
348+
// ApplyOptions applies the given get options on these options,
349+
// and then returns itself (for convenient chaining).
350+
func (o *GetOptions) ApplyOptions(opts []GetOption) *GetOptions {
351+
for _, opt := range opts {
352+
opt.ApplyToGet(o)
353+
}
354+
return o
355+
}
356+
357+
// }}}
358+
314359
// {{{ List Options
315360

316361
// ListOptions contains options for limiting or filtering results.

pkg/client/options_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,15 @@ var _ = Describe("ListOptions", func() {
7474
})
7575
})
7676

77+
var _ = Describe("GetOptions", func() {
78+
It("Should set Raw", func() {
79+
o := &client.GetOptions{Raw: &metav1.GetOptions{ResourceVersion: "RV0"}}
80+
newGetOpts := &client.GetOptions{}
81+
o.ApplyToGet(newGetOpts)
82+
Expect(newGetOpts).To(Equal(o))
83+
})
84+
})
85+
7786
var _ = Describe("CreateOptions", func() {
7887
It("Should set DryRun", func() {
7988
o := &client.CreateOptions{DryRun: []string{"Hello", "Theodore"}}

pkg/client/split.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,13 +121,13 @@ func (d *delegatingReader) shouldBypassCache(obj runtime.Object) (bool, error) {
121121
}
122122

123123
// Get retrieves an obj for a given object key from the Kubernetes Cluster.
124-
func (d *delegatingReader) Get(ctx context.Context, key ObjectKey, obj Object) error {
124+
func (d *delegatingReader) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
125125
if isUncached, err := d.shouldBypassCache(obj); err != nil {
126126
return err
127127
} else if isUncached {
128-
return d.ClientReader.Get(ctx, key, obj)
128+
return d.ClientReader.Get(ctx, key, obj, opts...)
129129
}
130-
return d.CacheReader.Get(ctx, key, obj)
130+
return d.CacheReader.Get(ctx, key, obj, opts...)
131131
}
132132

133133
// List retrieves list of objects for a given namespace and list options.

pkg/client/typed_client.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,17 @@ func (c *typedClient) Patch(ctx context.Context, obj Object, patch Patch, opts .
132132
}
133133

134134
// Get implements client.Client.
135-
func (c *typedClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
135+
func (c *typedClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
136136
r, err := c.cache.getResource(obj)
137137
if err != nil {
138138
return err
139139
}
140+
getOpts := GetOptions{}
141+
getOpts.ApplyOptions(opts)
140142
return r.Get().
141143
NamespaceIfScoped(key.Namespace, r.isNamespaced()).
142144
Resource(r.resource()).
145+
VersionedParams(getOpts.AsGetOptions(), c.paramCodec).
143146
Name(key.Name).Do(ctx).Into(obj)
144147
}
145148

pkg/client/unstructured_client.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,17 @@ func (uc *unstructuredClient) Patch(ctx context.Context, obj Object, patch Patch
165165
}
166166

167167
// Get implements client.Client.
168-
func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object) error {
168+
func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object, opts ...GetOption) error {
169169
u, ok := obj.(*unstructured.Unstructured)
170170
if !ok {
171171
return fmt.Errorf("unstructured client did not understand object: %T", obj)
172172
}
173173

174174
gvk := u.GroupVersionKind()
175175

176+
getOpts := GetOptions{}
177+
getOpts.ApplyOptions(opts)
178+
176179
r, err := uc.cache.getResource(obj)
177180
if err != nil {
178181
return err
@@ -181,6 +184,7 @@ func (uc *unstructuredClient) Get(ctx context.Context, key ObjectKey, obj Object
181184
result := r.Get().
182185
NamespaceIfScoped(key.Namespace, r.isNamespaced()).
183186
Resource(r.resource()).
187+
VersionedParams(getOpts.AsGetOptions(), uc.paramCodec).
184188
Name(key.Name).
185189
Do(ctx).
186190
Into(obj)

pkg/controller/controllerutil/controllerutil_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,6 @@ type errorReader struct {
832832
client.Client
833833
}
834834

835-
func (e errorReader) Get(ctx context.Context, key client.ObjectKey, into client.Object) error {
835+
func (e errorReader) Get(ctx context.Context, key client.ObjectKey, into client.Object, opts ...client.GetOption) error {
836836
return fmt.Errorf("unexpected error")
837837
}

0 commit comments

Comments
 (0)