Skip to content

Commit 3539edc

Browse files
authored
share the spoke informers (#88)
Signed-off-by: Wei Liu <[email protected]>
1 parent f9be1e1 commit 3539edc

File tree

3 files changed

+68
-57
lines changed

3 files changed

+68
-57
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ require (
2828
k8s.io/metrics v0.27.2
2929
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
3030
open-cluster-management.io/api v0.11.0
31-
open-cluster-management.io/ocm v0.0.0-20230606095507-6f21760b7e57
31+
open-cluster-management.io/ocm v0.0.0-20230613031015-b55881d6d261
3232
sigs.k8s.io/controller-runtime v0.15.0
3333
)
3434

@@ -157,7 +157,7 @@ require (
157157
go.uber.org/atomic v1.10.0 // indirect
158158
go.uber.org/multierr v1.8.0 // indirect
159159
go.uber.org/zap v1.24.0 // indirect
160-
golang.org/x/crypto v0.1.0 // indirect
160+
golang.org/x/crypto v0.3.0 // indirect
161161
golang.org/x/net v0.10.0 // indirect
162162
golang.org/x/sys v0.8.0 // indirect
163163
golang.org/x/time v0.3.0 // indirect

go.sum

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -739,8 +739,9 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
739739
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
740740
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
741741
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
742-
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
743742
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
743+
golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A=
744+
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
744745
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
745746
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
746747
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1260,8 +1261,8 @@ k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrC
12601261
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
12611262
open-cluster-management.io/api v0.11.0 h1:zBxa33Co3wseLBF4HEJobhl0P6ygj+Drhe7Wrfo0/h8=
12621263
open-cluster-management.io/api v0.11.0/go.mod h1:WgKUCJ7+Bf40DsOmH1Gdkpyj3joco+QLzrlM6Ak39zE=
1263-
open-cluster-management.io/ocm v0.0.0-20230606095507-6f21760b7e57 h1:QXk9xX9oNrYSfzABD5tVheY9X+n0htRdQGk7c3Nggt4=
1264-
open-cluster-management.io/ocm v0.0.0-20230606095507-6f21760b7e57/go.mod h1:d9nPyvcSqNsQTwaZqhmXDbQGNRawEy7uolHk2ZFshUI=
1264+
open-cluster-management.io/ocm v0.0.0-20230613031015-b55881d6d261 h1:IlSfvs+BCOmLRMBi8/mrKuDU6h70mP5LcreNhtf87jo=
1265+
open-cluster-management.io/ocm v0.0.0-20230613031015-b55881d6d261/go.mod h1:d9nPyvcSqNsQTwaZqhmXDbQGNRawEy7uolHk2ZFshUI=
12651266
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
12661267
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
12671268
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

pkg/agent/agent.go

Lines changed: 62 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1919
"k8s.io/apimachinery/pkg/util/wait"
2020
"k8s.io/client-go/dynamic"
21+
"k8s.io/client-go/informers"
2122
"k8s.io/client-go/kubernetes"
2223
"k8s.io/client-go/rest"
2324
"k8s.io/client-go/tools/clientcmd"
@@ -26,10 +27,11 @@ import (
2627
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
2728

2829
"github.com/openshift/library-go/pkg/assets"
29-
"github.com/openshift/library-go/pkg/controller/controllercmd"
3030
"github.com/openshift/library-go/pkg/operator/events"
3131
"github.com/openshift/library-go/pkg/operator/resource/resourceapply"
3232

33+
clusterv1client "open-cluster-management.io/api/client/cluster/clientset/versioned"
34+
clusterv1informers "open-cluster-management.io/api/client/cluster/informers/externalversions"
3335
workclientset "open-cluster-management.io/api/client/work/clientset/versioned"
3436
workinformers "open-cluster-management.io/api/client/work/informers/externalversions"
3537
ocmfeature "open-cluster-management.io/api/feature"
@@ -38,7 +40,7 @@ import (
3840
ocmfeatures "open-cluster-management.io/ocm/pkg/features"
3941
"open-cluster-management.io/ocm/pkg/registration/clientcert"
4042
"open-cluster-management.io/ocm/pkg/registration/spoke"
41-
"open-cluster-management.io/ocm/pkg/registration/spoke/managedcluster"
43+
"open-cluster-management.io/ocm/pkg/registration/spoke/registration"
4244
"open-cluster-management.io/ocm/pkg/work/helper"
4345
"open-cluster-management.io/ocm/pkg/work/spoke/auth"
4446
"open-cluster-management.io/ocm/pkg/work/spoke/controllers/appliedmanifestcontroller"
@@ -76,29 +78,27 @@ type AgentOptions struct {
7678
StatusSyncInterval time.Duration
7779
AppliedManifestWorkEvictionGracePeriod time.Duration
7880

79-
Burst int
80-
QPS float32
81-
8281
KubeConfig string
8382
WorkAgentID string
8483

84+
SpokeKubeInformerFactory informers.SharedInformerFactory
85+
SpokeClusterInformerFactory clusterv1informers.SharedInformerFactory
86+
8587
eventRecorder events.Recorder
8688
}
8789

8890
func NewAgentOptions() *AgentOptions {
8991
return &AgentOptions{
9092
RegistrationAgent: spoke.NewSpokeAgentOptions(),
9193
eventRecorder: util.NewLoggingRecorder("managed-cluster-agents"),
92-
Burst: 100,
93-
QPS: 50,
9494
StatusSyncInterval: 10 * time.Second,
9595
AppliedManifestWorkEvictionGracePeriod: 10 * time.Minute,
9696
}
9797
}
9898

9999
func (o *AgentOptions) AddFlags(fs *pflag.FlagSet) {
100100
features.DefaultAgentMutableFeatureGate.AddFlag(fs)
101-
fs.StringVar(&o.RegistrationAgent.ClusterName, "cluster-name", o.RegistrationAgent.ClusterName,
101+
fs.StringVar(&o.RegistrationAgent.AgentOptions.SpokeClusterName, "cluster-name", o.RegistrationAgent.AgentOptions.SpokeClusterName,
102102
"If non-empty, will use as cluster name instead of generated random name.")
103103
fs.StringVar(&o.RegistrationAgent.BootstrapKubeconfig, "bootstrap-kubeconfig", o.RegistrationAgent.BootstrapKubeconfig,
104104
"The path of the kubeconfig file for agent bootstrap.")
@@ -108,7 +108,7 @@ func (o *AgentOptions) AddFlags(fs *pflag.FlagSet) {
108108
"The mount path of hub-kubeconfig-secret in the container.")
109109
fs.StringVar(&o.KubeConfig, "kubeconfig", o.KubeConfig,
110110
"The path of the kubeconfig file for current cluster. If this is not set, will try to get the kubeconfig from cluster inside")
111-
fs.StringVar(&o.RegistrationAgent.SpokeKubeconfig, "spoke-kubeconfig", o.RegistrationAgent.SpokeKubeconfig,
111+
fs.StringVar(&o.RegistrationAgent.AgentOptions.SpokeKubeconfigFile, "spoke-kubeconfig", o.RegistrationAgent.AgentOptions.SpokeKubeconfigFile,
112112
"The path of the kubeconfig file for managed/spoke cluster. If this is not set, will use '--kubeconfig' to build client to connect to the managed cluster.")
113113
fs.StringVar(&o.WorkAgentID, "work-agent-id", o.WorkAgentID, "ID of the work agent to identify the work this agent should handle after restart/recovery.")
114114
fs.StringArrayVar(&o.RegistrationAgent.SpokeExternalServerURLs, "spoke-external-server-urls", o.RegistrationAgent.SpokeExternalServerURLs,
@@ -117,15 +117,17 @@ func (o *AgentOptions) AddFlags(fs *pflag.FlagSet) {
117117
"The period to check managed cluster kube-apiserver health")
118118
fs.IntVar(&o.RegistrationAgent.MaxCustomClusterClaims, "max-custom-cluster-claims", o.RegistrationAgent.MaxCustomClusterClaims,
119119
"The max number of custom cluster claims to expose.")
120-
fs.Float32Var(&o.QPS, "spoke-kube-api-qps", o.QPS, "QPS to use while talking with apiserver on spoke cluster.")
121-
fs.IntVar(&o.Burst, "spoke-kube-api-burst", o.Burst, "Burst to use while talking with apiserver on spoke cluster.")
120+
fs.Float32Var(&o.RegistrationAgent.AgentOptions.QPS, "spoke-kube-api-qps", o.RegistrationAgent.AgentOptions.QPS,
121+
"QPS to use while talking with apiserver on spoke cluster.")
122+
fs.IntVar(&o.RegistrationAgent.AgentOptions.Burst, "spoke-kube-api-burst", o.RegistrationAgent.AgentOptions.Burst,
123+
"Burst to use while talking with apiserver on spoke cluster.")
122124
fs.DurationVar(&o.StatusSyncInterval, "status-sync-interval", o.StatusSyncInterval, "Interval to sync resource status to hub.")
123125
fs.DurationVar(&o.AppliedManifestWorkEvictionGracePeriod, "appliedmanifestwork-eviction-grace-period", o.AppliedManifestWorkEvictionGracePeriod,
124126
"Grace period for appliedmanifestwork eviction")
125127
}
126128

127129
func (o *AgentOptions) WithClusterName(clusterName string) *AgentOptions {
128-
o.RegistrationAgent.ClusterName = clusterName
130+
o.RegistrationAgent.AgentOptions.SpokeClusterName = clusterName
129131
return o
130132
}
131133

@@ -135,7 +137,7 @@ func (o *AgentOptions) WithKubeconfig(kubeConfig string) *AgentOptions {
135137
}
136138

137139
func (o *AgentOptions) WithSpokeKubeconfig(spokeKubeConfig string) *AgentOptions {
138-
o.RegistrationAgent.SpokeKubeconfig = spokeKubeConfig
140+
o.RegistrationAgent.AgentOptions.SpokeKubeconfigFile = spokeKubeConfig
139141
return o
140142
}
141143

@@ -166,19 +168,21 @@ func (o *AgentOptions) RunAgent(ctx context.Context) error {
166168
}
167169
}
168170

169-
ctrlContext := &controllercmd.ControllerContext{
170-
KubeConfig: inClusterKubeConfig,
171-
EventRecorder: o.eventRecorder,
171+
// building kubeconfig for the spoke/managed cluster
172+
spokeKubeConfig, err := o.RegistrationAgent.AgentOptions.SpokeKubeConfig(inClusterKubeConfig)
173+
if err != nil {
174+
return err
172175
}
173176

174-
// building kubeconfig for the spoke/managed cluster
175-
spokeKubeConfig, err := o.spokeKubeConfig(ctrlContext)
177+
spokeKubeClient, err := kubernetes.NewForConfig(spokeKubeConfig)
176178
if err != nil {
177179
return err
178180
}
179181

180-
spokeKubeConfig.QPS = o.QPS
181-
spokeKubeConfig.Burst = o.Burst
182+
spokeClusterClient, err := clusterv1client.NewForConfig(spokeKubeConfig)
183+
if err != nil {
184+
return err
185+
}
182186

183187
apiExtensionsClient, err := apiextensionsclient.NewForConfig(spokeKubeConfig)
184188
if err != nil {
@@ -189,6 +193,9 @@ func (o *AgentOptions) RunAgent(ctx context.Context) error {
189193
return err
190194
}
191195

196+
o.SpokeKubeInformerFactory = informers.NewSharedInformerFactory(spokeKubeClient, 10*time.Minute)
197+
o.SpokeClusterInformerFactory = clusterv1informers.NewSharedInformerFactory(spokeClusterClient, 10*time.Minute)
198+
192199
klog.Infof("Starting registration agent")
193200
go func() {
194201
// set registration features
@@ -200,7 +207,15 @@ func (o *AgentOptions) RunAgent(ctx context.Context) error {
200207
klog.Fatalf("failed to set registration features, %v", err)
201208
}
202209

203-
if err := o.RegistrationAgent.RunSpokeAgent(ctx, ctrlContext); err != nil {
210+
if err := o.RegistrationAgent.RunSpokeAgentWithSpokeInformers(
211+
ctx,
212+
inClusterKubeConfig,
213+
spokeKubeConfig,
214+
spokeKubeClient,
215+
o.SpokeKubeInformerFactory,
216+
o.SpokeClusterInformerFactory,
217+
o.eventRecorder,
218+
); err != nil {
204219
klog.Fatalf("failed to run registration agent, %v", err)
205220
}
206221
}()
@@ -217,7 +232,13 @@ func (o *AgentOptions) RunAgent(ctx context.Context) error {
217232
}
218233

219234
klog.Infof("Starting work agent")
220-
if err := o.startWorkControllers(ctx, hubRestConfig, spokeKubeConfig, o.eventRecorder); err != nil {
235+
if err := o.startWorkControllers(
236+
ctx,
237+
hubRestConfig,
238+
spokeKubeConfig,
239+
o.RegistrationAgent.AgentOptions.SpokeClusterName,
240+
o.eventRecorder,
241+
); err != nil {
221242
klog.Fatalf("failed to run work agent, %v", err)
222243
}
223244

@@ -277,15 +298,16 @@ func (o *AgentOptions) WaitForValidHubKubeConfig(ctx context.Context, kubeconfig
277298
}
278299

279300
// check if the tls certificate is issued for the current cluster/agent
280-
clusterName, agentName, err := managedcluster.GetClusterAgentNamesFromCertificate(certData)
301+
clusterName, agentName, err := registration.GetClusterAgentNamesFromCertificate(certData)
281302
if err != nil {
282303
return false, nil
283304
}
284305

285-
if clusterName != o.RegistrationAgent.ClusterName || agentName != o.RegistrationAgent.AgentName {
306+
if clusterName != o.RegistrationAgent.AgentOptions.SpokeClusterName ||
307+
agentName != o.RegistrationAgent.AgentName {
286308
klog.V(4).Infof("Certificate in file %q is issued for agent %q instead of %q",
287309
certPath, fmt.Sprintf("%s:%s", clusterName, agentName),
288-
fmt.Sprintf("%s:%s", o.RegistrationAgent.ClusterName, o.RegistrationAgent.AgentName))
310+
fmt.Sprintf("%s:%s", o.RegistrationAgent.AgentOptions.SpokeClusterName, o.RegistrationAgent.AgentName))
289311
return false, nil
290312
}
291313

@@ -295,11 +317,11 @@ func (o *AgentOptions) WaitForValidHubKubeConfig(ctx context.Context, kubeconfig
295317
}
296318

297319
func (o *AgentOptions) startWorkControllers(ctx context.Context,
298-
hubRestConfig, spokeRestConfig *rest.Config, eventRecorder events.Recorder) error {
320+
hubRestConfig, spokeRestConfig *rest.Config, clusterName string, eventRecorder events.Recorder) error {
299321
hubhash := helper.HubHash(hubRestConfig.Host)
300322
agentID := o.WorkAgentID
301323
if len(agentID) == 0 {
302-
agentID = fmt.Sprintf("%s-%s", o.RegistrationAgent.ClusterName, hubhash)
324+
agentID = fmt.Sprintf("%s-%s", clusterName, hubhash)
303325
}
304326

305327
hubWorkClient, err := workclientset.NewForConfig(hubRestConfig)
@@ -338,14 +360,14 @@ func (o *AgentOptions) startWorkControllers(ctx context.Context,
338360

339361
// Only watch the cluster namespace on hub
340362
workInformerFactory := workinformers.NewSharedInformerFactoryWithOptions(
341-
hubWorkClient, 5*time.Minute, workinformers.WithNamespace(o.RegistrationAgent.ClusterName))
363+
hubWorkClient, 5*time.Minute, workinformers.WithNamespace(clusterName))
342364
spokeWorkInformerFactory := workinformers.NewSharedInformerFactory(spokeWorkClient, 5*time.Minute)
343365

344366
validator := auth.NewFactory(
345367
spokeRestConfig,
346368
spokeKubeClient,
347369
workInformerFactory.Work().V1().ManifestWorks(),
348-
o.RegistrationAgent.ClusterName,
370+
clusterName,
349371
eventRecorder,
350372
restMapper,
351373
).NewExecutorValidator(ctx, features.DefaultAgentMutableFeatureGate.Enabled(ocmfeature.ExecutorValidatingCaches))
@@ -355,9 +377,9 @@ func (o *AgentOptions) startWorkControllers(ctx context.Context,
355377
spokeDynamicClient,
356378
spokeKubeClient,
357379
spokeAPIExtensionClient,
358-
hubWorkClient.WorkV1().ManifestWorks(o.RegistrationAgent.ClusterName),
380+
hubWorkClient.WorkV1().ManifestWorks(clusterName),
359381
workInformerFactory.Work().V1().ManifestWorks(),
360-
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(o.RegistrationAgent.ClusterName),
382+
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(clusterName),
361383
spokeWorkClient.WorkV1().AppliedManifestWorks(),
362384
spokeWorkInformerFactory.Work().V1().AppliedManifestWorks(),
363385
hubhash,
@@ -368,9 +390,9 @@ func (o *AgentOptions) startWorkControllers(ctx context.Context,
368390

369391
addFinalizerController := finalizercontroller.NewAddFinalizerController(
370392
eventRecorder,
371-
hubWorkClient.WorkV1().ManifestWorks(o.RegistrationAgent.ClusterName),
393+
hubWorkClient.WorkV1().ManifestWorks(clusterName),
372394
workInformerFactory.Work().V1().ManifestWorks(),
373-
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(o.RegistrationAgent.ClusterName),
395+
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(clusterName),
374396
)
375397

376398
appliedManifestWorkFinalizeController := finalizercontroller.NewAppliedManifestWorkFinalizeController(
@@ -383,9 +405,9 @@ func (o *AgentOptions) startWorkControllers(ctx context.Context,
383405

384406
manifestWorkFinalizeController := finalizercontroller.NewManifestWorkFinalizeController(
385407
eventRecorder,
386-
hubWorkClient.WorkV1().ManifestWorks(o.RegistrationAgent.ClusterName),
408+
hubWorkClient.WorkV1().ManifestWorks(clusterName),
387409
workInformerFactory.Work().V1().ManifestWorks(),
388-
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(o.RegistrationAgent.ClusterName),
410+
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(clusterName),
389411
spokeWorkClient.WorkV1().AppliedManifestWorks(),
390412
spokeWorkInformerFactory.Work().V1().AppliedManifestWorks(),
391413
hubhash,
@@ -394,7 +416,7 @@ func (o *AgentOptions) startWorkControllers(ctx context.Context,
394416
unmanagedAppliedManifestWorkController := finalizercontroller.NewUnManagedAppliedWorkController(
395417
eventRecorder,
396418
workInformerFactory.Work().V1().ManifestWorks(),
397-
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(o.RegistrationAgent.ClusterName),
419+
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(clusterName),
398420
spokeWorkClient.WorkV1().AppliedManifestWorks(),
399421
spokeWorkInformerFactory.Work().V1().AppliedManifestWorks(),
400422
o.AppliedManifestWorkEvictionGracePeriod,
@@ -405,9 +427,9 @@ func (o *AgentOptions) startWorkControllers(ctx context.Context,
405427
appliedManifestWorkController := appliedmanifestcontroller.NewAppliedManifestWorkController(
406428
eventRecorder,
407429
spokeDynamicClient,
408-
hubWorkClient.WorkV1().ManifestWorks(o.RegistrationAgent.ClusterName),
430+
hubWorkClient.WorkV1().ManifestWorks(clusterName),
409431
workInformerFactory.Work().V1().ManifestWorks(),
410-
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(o.RegistrationAgent.ClusterName),
432+
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(clusterName),
411433
spokeWorkClient.WorkV1().AppliedManifestWorks(),
412434
spokeWorkInformerFactory.Work().V1().AppliedManifestWorks(),
413435
hubhash,
@@ -416,9 +438,9 @@ func (o *AgentOptions) startWorkControllers(ctx context.Context,
416438
availableStatusController := statuscontroller.NewAvailableStatusController(
417439
eventRecorder,
418440
spokeDynamicClient,
419-
hubWorkClient.WorkV1().ManifestWorks(o.RegistrationAgent.ClusterName),
441+
hubWorkClient.WorkV1().ManifestWorks(clusterName),
420442
workInformerFactory.Work().V1().ManifestWorks(),
421-
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(o.RegistrationAgent.ClusterName),
443+
workInformerFactory.Work().V1().ManifestWorks().Lister().ManifestWorks(clusterName),
422444
o.StatusSyncInterval,
423445
)
424446

@@ -435,15 +457,3 @@ func (o *AgentOptions) startWorkControllers(ctx context.Context,
435457

436458
return nil
437459
}
438-
439-
func (o *AgentOptions) spokeKubeConfig(controllerContext *controllercmd.ControllerContext) (*rest.Config, error) {
440-
if o.RegistrationAgent.SpokeKubeconfig == "" {
441-
return controllerContext.KubeConfig, nil
442-
}
443-
444-
spokeRestConfig, err := clientcmd.BuildConfigFromFlags("", o.RegistrationAgent.SpokeKubeconfig)
445-
if err != nil {
446-
return nil, fmt.Errorf("unable to load spoke kubeconfig from file %q: %v", o.RegistrationAgent.SpokeKubeconfig, err)
447-
}
448-
return spokeRestConfig, nil
449-
}

0 commit comments

Comments
 (0)