Skip to content

Commit 4b60fd6

Browse files
Merge pull request #21 from ncdc/kcp/rebase-1.24
Rebase: kcp-0.7+ / kube 1.24
2 parents 02fb225 + 989a925 commit 4b60fd6

File tree

14 files changed

+277
-68
lines changed

14 files changed

+277
-68
lines changed

go.mod

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ require (
77
github.com/fsnotify/fsnotify v1.5.1
88
github.com/go-logr/logr v1.2.0
99
github.com/go-logr/zapr v1.2.0
10+
github.com/kcp-dev/apimachinery v0.0.0-20220803185518-868856d14e8a
11+
github.com/kcp-dev/logicalcluster/v2 v2.0.0-alpha.1
1012
github.com/onsi/ginkgo v1.16.5
1113
github.com/onsi/gomega v1.18.1
1214
github.com/prometheus/client_golang v1.12.1
@@ -16,10 +18,10 @@ require (
1618
golang.org/x/sys v0.0.0-20220209214540-3681064d5158
1719
golang.org/x/time v0.0.0-20220210224613-90d013bbcef8
1820
gomodules.xyz/jsonpatch/v2 v2.2.0
19-
k8s.io/api v0.24.2
21+
k8s.io/api v0.24.3
2022
k8s.io/apiextensions-apiserver v0.24.2
21-
k8s.io/apimachinery v0.24.2
22-
k8s.io/client-go v0.24.2
23+
k8s.io/apimachinery v0.24.3
24+
k8s.io/client-go v0.24.3
2325
k8s.io/component-base v0.24.2
2426
k8s.io/klog/v2 v2.60.1
2527
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9

go.sum

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,10 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X
300300
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
301301
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
302302
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
303+
github.com/kcp-dev/apimachinery v0.0.0-20220803185518-868856d14e8a h1:lJyVMNywLln1x5A3WVELeDpftc5FktP3asI1Prx0lOU=
304+
github.com/kcp-dev/apimachinery v0.0.0-20220803185518-868856d14e8a/go.mod h1:qnvUHkdxOrNzX17yX+z8r81CZEBuFdveNzWqFlwZ55w=
305+
github.com/kcp-dev/logicalcluster/v2 v2.0.0-alpha.1 h1:6EMfOioekQNrpcHEK7k2ANBWogFMlf+3xTB3CC4k+2s=
306+
github.com/kcp-dev/logicalcluster/v2 v2.0.0-alpha.1/go.mod h1:lfWJL764jKFJxZWOGuFuT3PCCLPo6lV5Cl8P7u9T05g=
303307
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
304308
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
305309
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -447,8 +451,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
447451
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
448452
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
449453
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
450-
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
451454
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
455+
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
456+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
452457
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
453458
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
454459
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -931,15 +936,18 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
931936
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
932937
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
933938
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
934-
k8s.io/api v0.24.2 h1:g518dPU/L7VRLxWfcadQn2OnsiGWVOadTLpdnqgY2OI=
935939
k8s.io/api v0.24.2/go.mod h1:AHqbSkTm6YrQ0ObxjO3Pmp/ubFF/KuM7jU+3khoBsOg=
940+
k8s.io/api v0.24.3 h1:tt55QEmKd6L2k5DP6G/ZzdMQKvG5ro4H4teClqm0sTY=
941+
k8s.io/api v0.24.3/go.mod h1:elGR/XSZrS7z7cSZPzVWaycpJuGIw57j9b95/1PdJNI=
936942
k8s.io/apiextensions-apiserver v0.24.2 h1:/4NEQHKlEz1MlaK/wHT5KMKC9UKYz6NZz6JE6ov4G6k=
937943
k8s.io/apiextensions-apiserver v0.24.2/go.mod h1:e5t2GMFVngUEHUd0wuCJzw8YDwZoqZfJiGOW6mm2hLQ=
938-
k8s.io/apimachinery v0.24.2 h1:5QlH9SL2C8KMcrNJPor+LbXVTaZRReml7svPEh4OKDM=
939944
k8s.io/apimachinery v0.24.2/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
945+
k8s.io/apimachinery v0.24.3 h1:hrFiNSA2cBZqllakVYyH/VyEh4B581bQRmqATJSeQTg=
946+
k8s.io/apimachinery v0.24.3/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
940947
k8s.io/apiserver v0.24.2/go.mod h1:pSuKzr3zV+L+MWqsEo0kHHYwCo77AT5qXbFXP2jbvFI=
941-
k8s.io/client-go v0.24.2 h1:CoXFSf8if+bLEbinDqN9ePIDGzcLtqhfd6jpfnwGOFA=
942948
k8s.io/client-go v0.24.2/go.mod h1:zg4Xaoo+umDsfCWr4fCnmLEtQXyCNXCvJuSsglNcV30=
949+
k8s.io/client-go v0.24.3 h1:Nl1840+6p4JqkFWEW2LnMKU667BUxw03REfLAVhuKQY=
950+
k8s.io/client-go v0.24.3/go.mod h1:AAovolf5Z9bY1wIg2FZ8LPQlEdKHjLI7ZD4rw920BJw=
943951
k8s.io/code-generator v0.24.2/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w=
944952
k8s.io/component-base v0.24.2 h1:kwpQdoSfbcH+8MPN4tALtajLDfSfYxBDYlXobNWI6OU=
945953
k8s.io/component-base v0.24.2/go.mod h1:ucHwW76dajvQ9B7+zecZAP3BVqvrHoOxm8olHEg0nmM=

pkg/cache/cache.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,14 @@ type Options struct {
108108
// So that all informers will not send list requests simultaneously.
109109
Resync *time.Duration
110110

111+
// NewInformerFunc is a function that is used to create SharedIndexInformers.
112+
// Defaults to cache.NewSharedIndexInformer from client-go
113+
NewInformerFunc client.NewInformerFunc
114+
115+
// Indexers is the indexers that the informers will be configured to use.
116+
// Will always have the standard NamespaceIndex.
117+
Indexers toolscache.Indexers
118+
111119
// Namespace restricts the cache's ListWatch to the desired namespace
112120
// Default watches all namespaces
113121
Namespace string
@@ -163,7 +171,7 @@ func New(config *rest.Config, opts Options) (Cache, error) {
163171
return nil, err
164172
}
165173

166-
im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace, selectorsByGVK, disableDeepCopyByGVK, transformByGVK)
174+
im := internal.NewInformersMap(config, opts.Scheme, opts.Mapper, *opts.Resync, opts.Namespace, selectorsByGVK, disableDeepCopyByGVK, transformByGVK, opts.NewInformerFunc, opts.Indexers)
167175
return &informerCache{InformersMap: im}, nil
168176
}
169177

@@ -216,6 +224,10 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
216224
if opts.Resync == nil {
217225
opts.Resync = &defaultResyncTime
218226
}
227+
228+
if opts.NewInformerFunc == nil {
229+
opts.NewInformerFunc = toolscache.NewSharedIndexInformer
230+
}
219231
return opts, nil
220232
}
221233

pkg/cache/internal/cache_reader.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ import (
2121
"fmt"
2222
"reflect"
2323

24+
kcpcache "github.com/kcp-dev/apimachinery/pkg/cache"
25+
"github.com/kcp-dev/logicalcluster/v2"
26+
2427
apierrors "k8s.io/apimachinery/pkg/api/errors"
2528
apimeta "k8s.io/apimachinery/pkg/api/meta"
2629
"k8s.io/apimachinery/pkg/fields"
@@ -54,11 +57,11 @@ type CacheReader struct {
5457
}
5558

5659
// 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 {
60+
func (c *CacheReader) Get(ctx context.Context, key client.ObjectKey, out client.Object) error {
5861
if c.scopeName == apimeta.RESTScopeNameRoot {
5962
key.Namespace = ""
6063
}
61-
storeKey := objectKeyToStoreKey(key)
64+
storeKey := objectKeyToStoreKey(ctx, key)
6265

6366
// Lookup the object from the indexer cache
6467
obj, exists, err := c.indexer.GetByKey(storeKey)
@@ -105,13 +108,15 @@ func (c *CacheReader) Get(_ context.Context, key client.ObjectKey, out client.Ob
105108
}
106109

107110
// List lists items out of the indexer and writes them to out.
108-
func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...client.ListOption) error {
111+
func (c *CacheReader) List(ctx context.Context, out client.ObjectList, opts ...client.ListOption) error {
109112
var objs []interface{}
110113
var err error
111114

112115
listOpts := client.ListOptions{}
113116
listOpts.ApplyOptions(opts)
114117

118+
clusterName, _ := logicalcluster.ClusterFromContext(ctx)
119+
115120
switch {
116121
case listOpts.FieldSelector != nil:
117122
// TODO(directxman12): support more complicated field selectors by
@@ -125,9 +130,17 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
125130
// namespace.
126131
objs, err = c.indexer.ByIndex(FieldIndexName(field), KeyToNamespacedKey(listOpts.Namespace, val))
127132
case listOpts.Namespace != "":
128-
objs, err = c.indexer.ByIndex(cache.NamespaceIndex, listOpts.Namespace)
133+
if clusterName.Empty() {
134+
objs, err = c.indexer.ByIndex(cache.NamespaceIndex, listOpts.Namespace)
135+
} else {
136+
objs, err = c.indexer.ByIndex(kcpcache.ClusterAndNamespaceIndexName, kcpcache.ToClusterAwareKey(clusterName.String(), listOpts.Namespace, ""))
137+
}
129138
default:
130-
objs = c.indexer.List()
139+
if clusterName.Empty() {
140+
objs = c.indexer.List()
141+
} else {
142+
objs, err = c.indexer.ByIndex(kcpcache.ClusterIndexName, kcpcache.ToClusterAwareKey(clusterName.String(), "", ""))
143+
}
131144
}
132145
if err != nil {
133146
return err
@@ -179,7 +192,12 @@ func (c *CacheReader) List(_ context.Context, out client.ObjectList, opts ...cli
179192
// It's akin to MetaNamespaceKeyFunc. It's separate from
180193
// String to allow keeping the key format easily in sync with
181194
// MetaNamespaceKeyFunc.
182-
func objectKeyToStoreKey(k client.ObjectKey) string {
195+
func objectKeyToStoreKey(ctx context.Context, k client.ObjectKey) string {
196+
cluster, ok := logicalcluster.ClusterFromContext(ctx)
197+
if ok {
198+
return kcpcache.ToClusterAwareKey(cluster.String(), k.Namespace, k.Name)
199+
}
200+
183201
if k.Namespace == "" {
184202
return k.Name
185203
}

pkg/cache/internal/deleg_map.go

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import (
2727
"k8s.io/apimachinery/pkg/runtime/schema"
2828
"k8s.io/client-go/rest"
2929
"k8s.io/client-go/tools/cache"
30+
31+
"sigs.k8s.io/controller-runtime/pkg/client"
3032
)
3133

3234
// InformersMap create and caches Informers for (runtime.Object, schema.GroupVersionKind) pairs.
@@ -53,11 +55,13 @@ func NewInformersMap(config *rest.Config,
5355
selectors SelectorsByGVK,
5456
disableDeepCopy DisableDeepCopyByGVK,
5557
transformers TransformFuncByObject,
58+
newInformerFunc client.NewInformerFunc,
59+
indexers cache.Indexers,
5660
) *InformersMap {
5761
return &InformersMap{
58-
structured: newStructuredInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers),
59-
unstructured: newUnstructuredInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers),
60-
metadata: newMetadataInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers),
62+
structured: newStructuredInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, newInformerFunc, indexers),
63+
unstructured: newUnstructuredInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, newInformerFunc, indexers),
64+
metadata: newMetadataInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, newInformerFunc, indexers),
6165

6266
Scheme: scheme,
6367
}
@@ -109,18 +113,18 @@ func (m *InformersMap) Get(ctx context.Context, gvk schema.GroupVersionKind, obj
109113

110114
// newStructuredInformersMap creates a new InformersMap for structured objects.
111115
func newStructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration,
112-
namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK, transformers TransformFuncByObject) *specificInformersMap {
113-
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, createStructuredListWatch)
116+
namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK, transformers TransformFuncByObject, newInformerFunc client.NewInformerFunc, indexers cache.Indexers) *specificInformersMap {
117+
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, createStructuredListWatch, newInformerFunc, indexers)
114118
}
115119

116120
// newUnstructuredInformersMap creates a new InformersMap for unstructured objects.
117121
func newUnstructuredInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration,
118-
namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK, transformers TransformFuncByObject) *specificInformersMap {
119-
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, createUnstructuredListWatch)
122+
namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK, transformers TransformFuncByObject, newInformerFunc client.NewInformerFunc, indexers cache.Indexers) *specificInformersMap {
123+
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, createUnstructuredListWatch, newInformerFunc, indexers)
120124
}
121125

122126
// newMetadataInformersMap creates a new InformersMap for metadata-only objects.
123127
func newMetadataInformersMap(config *rest.Config, scheme *runtime.Scheme, mapper meta.RESTMapper, resync time.Duration,
124-
namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK, transformers TransformFuncByObject) *specificInformersMap {
125-
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, createMetadataListWatch)
128+
namespace string, selectors SelectorsByGVK, disableDeepCopy DisableDeepCopyByGVK, transformers TransformFuncByObject, newInformerFunc client.NewInformerFunc, indexers cache.Indexers) *specificInformersMap {
129+
return newSpecificInformersMap(config, scheme, mapper, resync, namespace, selectors, disableDeepCopy, transformers, createMetadataListWatch, newInformerFunc, indexers)
126130
}

pkg/cache/internal/informers_map.go

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"k8s.io/client-go/rest"
3636
"k8s.io/client-go/tools/cache"
3737

38+
"sigs.k8s.io/controller-runtime/pkg/client"
3839
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
3940
)
4041

@@ -56,21 +57,25 @@ func newSpecificInformersMap(config *rest.Config,
5657
disableDeepCopy DisableDeepCopyByGVK,
5758
transformers TransformFuncByObject,
5859
createListWatcher createListWatcherFunc,
60+
newInformerFunc client.NewInformerFunc,
61+
indexers cache.Indexers,
5962
) *specificInformersMap {
6063
ip := &specificInformersMap{
61-
config: config,
62-
Scheme: scheme,
63-
mapper: mapper,
64-
informersByGVK: make(map[schema.GroupVersionKind]*MapEntry),
65-
codecs: serializer.NewCodecFactory(scheme),
66-
paramCodec: runtime.NewParameterCodec(scheme),
67-
resync: resync,
68-
startWait: make(chan struct{}),
69-
createListWatcher: createListWatcher,
70-
namespace: namespace,
71-
selectors: selectors.forGVK,
72-
disableDeepCopy: disableDeepCopy,
73-
transformers: transformers,
64+
config: config,
65+
Scheme: scheme,
66+
mapper: mapper,
67+
informersByGVK: make(map[schema.GroupVersionKind]*MapEntry),
68+
codecs: serializer.NewCodecFactory(scheme),
69+
paramCodec: runtime.NewParameterCodec(scheme),
70+
resync: resync,
71+
startWait: make(chan struct{}),
72+
createListWatcher: createListWatcher,
73+
namespace: namespace,
74+
selectors: selectors.forGVK,
75+
disableDeepCopy: disableDeepCopy,
76+
transformers: transformers,
77+
newInformerFunc: newInformerFunc,
78+
additionalIndexers: indexers,
7479
}
7580
return ip
7681
}
@@ -141,6 +146,12 @@ type specificInformersMap struct {
141146

142147
// transform funcs are applied to objects before they are committed to the cache
143148
transformers TransformFuncByObject
149+
150+
// additionalIndexers is the indexers that the informers will be configured to use.
151+
// Will not allow overwriting the standard NamespaceIndex.
152+
additionalIndexers cache.Indexers
153+
154+
newInformerFunc client.NewInformerFunc
144155
}
145156

146157
// Start calls Run on each of the informers and sets started to true. Blocks on the context.
@@ -230,9 +241,13 @@ func (ip *specificInformersMap) addInformerToMap(gvk schema.GroupVersionKind, ob
230241
if err != nil {
231242
return nil, false, err
232243
}
233-
ni := cache.NewSharedIndexInformer(lw, obj, resyncPeriod(ip.resync)(), cache.Indexers{
234-
cache.NamespaceIndex: cache.MetaNamespaceIndexFunc,
235-
})
244+
indexers := cache.Indexers{}
245+
for indexName, indexer := range ip.additionalIndexers {
246+
indexers[indexName] = indexer
247+
}
248+
indexers[cache.NamespaceIndex] = cache.MetaNamespaceIndexFunc
249+
250+
ni := ip.newInformerFunc(lw, obj, resyncPeriod(ip.resync)(), indexers)
236251

237252
// Check to see if there is a transformer for this gvk
238253
if err := ni.SetTransform(ip.transformers.Get(gvk)); err != nil {

pkg/client/apiutil/apimachinery.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ package apiutil
2121

2222
import (
2323
"fmt"
24+
"net/http"
2425
"reflect"
2526
"sync"
2627

@@ -122,6 +123,13 @@ func RESTClientForGVK(gvk schema.GroupVersionKind, isUnstructured bool, baseConf
122123
return rest.RESTClientFor(createRestConfig(gvk, isUnstructured, baseConfig, codecs))
123124
}
124125

126+
// RESTClientForGVKAndClient constructs a new rest.Interface capable of accessing the resource associated
127+
// wwith the give GroupVersionKind. The REST client will be configured to use provided http.Client, and the
128+
// negotiated serializer from baseConfig, if set.
129+
func RESTClientForGVKAndClient(gvk schema.GroupVersionKind, client *http.Client, isUnstructured bool, baseConfig *rest.Config, codecs serializer.CodecFactory) (rest.Interface, error) {
130+
return rest.RESTClientForConfigAndClient(createRestConfig(gvk, isUnstructured, baseConfig, codecs), client)
131+
}
132+
125133
// serializerWithDecodedGVK is a CodecFactory that overrides the DecoderToVersion of a WithoutConversionCodecFactory
126134
// in order to avoid clearing the GVK from the decoded object.
127135
//

pkg/client/client.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package client
1919
import (
2020
"context"
2121
"fmt"
22+
"net/http"
2223
"strings"
2324

2425
"k8s.io/apimachinery/pkg/api/meta"
@@ -57,6 +58,9 @@ type Options struct {
5758
// Mapper, if provided, will be used to map GroupVersionKinds to Resources
5859
Mapper meta.RESTMapper
5960

61+
// HTTPClient, if provided, will be used by all constructed clients to talk to the apiserver
62+
HTTPClient *http.Client
63+
6064
// Opts is used to configure the warning handler responsible for
6165
// surfacing and handling warnings messages sent by the API server.
6266
Opts WarningHandlerOptions
@@ -81,6 +85,14 @@ func newClient(config *rest.Config, options Options) (*client, error) {
8185
return nil, fmt.Errorf("must provide non-nil rest.Config to client.New")
8286
}
8387

88+
if options.HTTPClient == nil {
89+
httpClient, err := rest.HTTPClientFor(config)
90+
if err != nil {
91+
return nil, fmt.Errorf("error creating HTTPClient from config: %w", err)
92+
}
93+
options.HTTPClient = httpClient
94+
}
95+
8496
if !options.Opts.SuppressWarnings {
8597
// surface warnings
8698
logger := log.Log.WithName("KubeAPIWarningLogger")
@@ -113,16 +125,17 @@ func newClient(config *rest.Config, options Options) (*client, error) {
113125
}
114126

115127
clientcache := &clientCache{
116-
config: config,
117-
scheme: options.Scheme,
118-
mapper: options.Mapper,
119-
codecs: serializer.NewCodecFactory(options.Scheme),
128+
config: config,
129+
httpClient: options.HTTPClient,
130+
scheme: options.Scheme,
131+
mapper: options.Mapper,
132+
codecs: serializer.NewCodecFactory(options.Scheme),
120133

121134
structuredResourceByType: make(map[schema.GroupVersionKind]*resourceMeta),
122135
unstructuredResourceByType: make(map[schema.GroupVersionKind]*resourceMeta),
123136
}
124137

125-
rawMetaClient, err := metadata.NewForConfig(config)
138+
rawMetaClient, err := metadata.NewForConfigAndClient(config, options.HTTPClient)
126139
if err != nil {
127140
return nil, fmt.Errorf("unable to construct metadata-only client for use as part of client: %w", err)
128141
}

0 commit comments

Comments
 (0)