@@ -23,6 +23,7 @@ import (
23
23
"github.com/go-logr/logr"
24
24
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25
25
"k8s.io/apimachinery/pkg/runtime/schema"
26
+ "k8s.io/client-go/discovery"
26
27
27
28
"sigs.k8s.io/controller-runtime/pkg/client"
28
29
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
@@ -72,6 +73,7 @@ type ForInput struct {
72
73
predicates []predicate.Predicate
73
74
objectProjection objectProjection
74
75
err error
76
+ conditional bool
75
77
}
76
78
77
79
// For defines the type of Object being *reconciled*, and configures the ControllerManagedBy to respond to create / delete /
@@ -97,6 +99,7 @@ type OwnsInput struct {
97
99
object client.Object
98
100
predicates []predicate.Predicate
99
101
objectProjection objectProjection
102
+ conditional bool
100
103
}
101
104
102
105
// Owns defines types of Objects being *generated* by the ControllerManagedBy, and configures the ControllerManagedBy to respond to
@@ -118,6 +121,7 @@ type WatchesInput struct {
118
121
eventhandler handler.EventHandler
119
122
predicates []predicate.Predicate
120
123
objectProjection objectProjection
124
+ conditional bool
121
125
}
122
126
123
127
// Watches exposes the lower-level ControllerManagedBy Watches functions through the builder. Consider using
@@ -216,13 +220,52 @@ func (blder *Builder) project(obj client.Object, proj objectProjection) (client.
216
220
}
217
221
}
218
222
223
+ func (blder * Builder ) generateConditionalSource (typeForSrc client.Object ) (source.Source , error ) {
224
+ gvk , err := getGvk (blder .forInput .object , blder .mgr .GetScheme ())
225
+ if err != nil {
226
+ return nil , err
227
+ }
228
+ fmt .Printf ("gvk = %+v\n " , gvk )
229
+ dc , err := discovery .NewDiscoveryClientForConfig (blder .mgr .GetConfig ())
230
+ if err != nil {
231
+ return nil , err
232
+ }
233
+ existsInDiscovery := func () bool {
234
+ resources , err := dc .ServerResourcesForGroupVersion (gvk .GroupVersion ().String ())
235
+ if err != nil {
236
+ fmt .Printf ("NOT in discovery gvk = %+v\n " , gvk )
237
+ return false
238
+ }
239
+ for _ , res := range resources .APIResources {
240
+ if res .Kind == gvk .Kind {
241
+ fmt .Printf ("YES in discovery gvk = %+v\n " , gvk )
242
+ return true
243
+ }
244
+ }
245
+ fmt .Printf ("NOT in discovery kind = %+v\n " , gvk )
246
+ return false
247
+ }
248
+ return & source.ConditionalKind {Kind : source.Kind {Type : typeForSrc }, DiscoveryCheck : existsInDiscovery }, nil
249
+
250
+ }
251
+
219
252
func (blder * Builder ) doWatch () error {
220
253
// Reconcile type
221
254
typeForSrc , err := blder .project (blder .forInput .object , blder .forInput .objectProjection )
222
255
if err != nil {
223
256
return err
224
257
}
225
- src := & source.Kind {Type : typeForSrc }
258
+
259
+ var src source.Source
260
+ if blder .forInput .conditional {
261
+ var err error
262
+ src , err = blder .generateConditionalSource (typeForSrc )
263
+ if err != nil {
264
+ return err
265
+ }
266
+ } else {
267
+ src = & source.Kind {Type : typeForSrc }
268
+ }
226
269
hdler := & handler.EnqueueRequestForObject {}
227
270
allPredicates := append (blder .globalPredicates , blder .forInput .predicates ... )
228
271
if err := blder .ctrl .Watch (src , hdler , allPredicates ... ); err != nil {
@@ -235,7 +278,17 @@ func (blder *Builder) doWatch() error {
235
278
if err != nil {
236
279
return err
237
280
}
238
- src := & source.Kind {Type : typeForSrc }
281
+
282
+ var src source.Source
283
+ if own .conditional {
284
+ var err error
285
+ src , err = blder .generateConditionalSource (typeForSrc )
286
+ if err != nil {
287
+ return err
288
+ }
289
+ } else {
290
+ src = & source.Kind {Type : typeForSrc }
291
+ }
239
292
hdler := & handler.EnqueueRequestForOwner {
240
293
OwnerType : blder .forInput .object ,
241
294
IsController : true ,
0 commit comments