@@ -20,6 +20,7 @@ import (
20
20
"context"
21
21
22
22
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
23
+ "k8s.io/apimachinery/pkg/labels"
23
24
"k8s.io/apimachinery/pkg/runtime"
24
25
"k8s.io/apimachinery/pkg/runtime/schema"
25
26
corev1 "k8s.io/client-go/listers/core/v1"
@@ -32,12 +33,14 @@ import (
32
33
"github.com/karmada-io/karmada/pkg/resourceinterpreter/customized/webhook/request"
33
34
"github.com/karmada-io/karmada/pkg/resourceinterpreter/default/native"
34
35
"github.com/karmada-io/karmada/pkg/resourceinterpreter/default/thirdparty"
36
+ "github.com/karmada-io/karmada/pkg/util"
35
37
"github.com/karmada-io/karmada/pkg/util/fedinformer/genericmanager"
38
+ "github.com/karmada-io/karmada/pkg/util/helper"
36
39
)
37
40
38
41
// ResourceInterpreter manages both default and customized webhooks to interpret custom resource structure.
39
42
type ResourceInterpreter interface {
40
- // Start starts running the component and will never stop running until the context is closed or an error occurs .
43
+ // Start initializes the resource interpreter and performs cache synchronization .
41
44
Start (ctx context.Context ) (err error )
42
45
43
46
// HookEnabled tells if any hook exist for specific resource type and operation.
@@ -85,13 +88,16 @@ type customResourceInterpreterImpl struct {
85
88
defaultInterpreter * native.DefaultInterpreter
86
89
}
87
90
88
- // Start starts running the component and will never stop running until the context is closed or an error occurs.
89
- func (i * customResourceInterpreterImpl ) Start (ctx context.Context ) (err error ) {
90
- klog .Infof ("Starting custom resource interpreter." )
91
+ // Start initializes all interpreters and load all ResourceInterpreterCustomization and
92
+ // ResourceInterpreterWebhookConfiguration configurations into the cache.
93
+ // It is recommended to be called before all controllers. After called, the resource interpreter
94
+ // will be ready to interpret custom resources.
95
+ func (i * customResourceInterpreterImpl ) Start (_ context.Context ) (err error ) {
96
+ klog .Infoln ("Starting resource interpreter." )
91
97
92
98
i .customizedInterpreter , err = webhook .NewCustomizedInterpreter (i .informer , i .serviceLister )
93
99
if err != nil {
94
- return
100
+ return err
95
101
}
96
102
i .configurableInterpreter = declarative .NewConfigurableInterpreter (i .informer )
97
103
@@ -100,8 +106,12 @@ func (i *customResourceInterpreterImpl) Start(ctx context.Context) (err error) {
100
106
101
107
i .informer .Start ()
102
108
i .informer .WaitForCacheSync ()
103
- <- ctx .Done ()
104
- klog .Infof ("Stopped as context canceled." )
109
+
110
+ if err = i .loadConfig (); err != nil {
111
+ return err
112
+ }
113
+
114
+ klog .Infoln ("Resource interpreter started." )
105
115
return nil
106
116
}
107
117
@@ -339,3 +349,46 @@ func (i *customResourceInterpreterImpl) InterpretHealth(object *unstructured.Uns
339
349
healthy , err = i .defaultInterpreter .InterpretHealth (object )
340
350
return
341
351
}
352
+
353
+ // loadConfig loads the full set of ResourceInterpreterCustomization and
354
+ // ResourceInterpreterWebhookConfiguration configurations into the cache. It avoids resource interpreter
355
+ // parsing errors when the resource interpreter starts and the cache is not synchronized.
356
+ func (i * customResourceInterpreterImpl ) loadConfig () error {
357
+ customizations , err := i .informer .Lister (util .ResourceInterpreterCustomizationsGVR ).List (labels .Everything ())
358
+ if err != nil {
359
+ klog .Errorf ("Failed to list resourceinterpretercustomizations: %v" , err )
360
+ return err
361
+ }
362
+ klog .V (5 ).Infof ("Found %d resourceinterpretercustomizations" , len (customizations ))
363
+
364
+ declareConfigs := make ([]* configv1alpha1.ResourceInterpreterCustomization , len (customizations ))
365
+ for index , c := range customizations {
366
+ config := & configv1alpha1.ResourceInterpreterCustomization {}
367
+ if err = helper .ConvertToTypedObject (c , config ); err != nil {
368
+ klog .Errorf ("Failed to convert resourceinterpretercustomization: %v" , err )
369
+ return err
370
+ }
371
+ declareConfigs [index ] = config
372
+ }
373
+ i .configurableInterpreter .LoadConfig (declareConfigs )
374
+
375
+ webhooks , err := i .informer .Lister (util .ResourceInterpreterWebhookConfigurationsGVR ).List (labels .Everything ())
376
+ if err != nil {
377
+ klog .Errorf ("Failed to list resourceinterpreterwebhookconfigurations: %v" , err )
378
+ return err
379
+ }
380
+ klog .V (5 ).Infof ("Found %d resourceinterpreterwebhookconfigurations" , len (webhooks ))
381
+
382
+ webhookConfigs := make ([]* configv1alpha1.ResourceInterpreterWebhookConfiguration , len (webhooks ))
383
+ for index , c := range webhooks {
384
+ config := & configv1alpha1.ResourceInterpreterWebhookConfiguration {}
385
+ if err = helper .ConvertToTypedObject (c , config ); err != nil {
386
+ klog .Errorf ("Failed to convert resourceinterpreterwebhookconfiguration: %v" , err )
387
+ return err
388
+ }
389
+ webhookConfigs [index ] = config
390
+ }
391
+ i .customizedInterpreter .LoadConfig (webhookConfigs )
392
+
393
+ return nil
394
+ }
0 commit comments