in pkg/controller/integrationkit/integrationkit_controller.go [72:172]
func add(_ context.Context, mgr manager.Manager, r reconcile.Reconciler) error {
c, err := controller.New("integrationkit-controller", mgr, controller.Options{Reconciler: r})
if err != nil {
return err
}
// Watch for changes to primary resource IntegrationKit
err = c.Watch(
source.Kind(
mgr.GetCache(),
&v1.IntegrationKit{},
&handler.TypedEnqueueRequestForObject[*v1.IntegrationKit]{},
platform.FilteringFuncs[*v1.IntegrationKit]{
UpdateFunc: func(e event.TypedUpdateEvent[*v1.IntegrationKit]) bool {
// Ignore updates to the integration kit status in which case metadata.Generation
// does not change, or except when the integration kit phase changes as it's used
// to transition from one phase to another
return e.ObjectOld.Generation != e.ObjectNew.Generation ||
e.ObjectOld.Status.Phase != e.ObjectNew.Status.Phase
},
DeleteFunc: func(e event.TypedDeleteEvent[*v1.IntegrationKit]) bool {
// Evaluates to false if the object has been confirmed deleted
return !e.DeleteStateUnknown
},
},
),
)
if err != nil {
return err
}
// Watch for changes to secondary resource Builds and requeue the owner IntegrationKit
err = c.Watch(
source.Kind(mgr.GetCache(),
&v1.Build{},
handler.TypedEnqueueRequestForOwner[*v1.Build](
mgr.GetScheme(),
mgr.GetRESTMapper(),
&v1.IntegrationKit{},
handler.OnlyControllerOwner(),
),
platform.FilteringFuncs[*v1.Build]{
UpdateFunc: func(e event.TypedUpdateEvent[*v1.Build]) bool {
// Ignore updates to the build CR except when the build phase changes
// as it's used to transition the integration kit from one phase
// to another during the image build
return e.ObjectOld.Status.Phase != e.ObjectNew.Status.Phase
},
},
),
)
if err != nil {
return err
}
// Watch for IntegrationPlatform phase transitioning to ready and enqueue
// requests for any integration kits that are in phase waiting for platform
err = c.Watch(
source.Kind(
mgr.GetCache(),
&v1.IntegrationPlatform{},
handler.TypedEnqueueRequestsFromMapFunc(func(ctx context.Context, itp *v1.IntegrationPlatform) []reconcile.Request {
var requests []reconcile.Request
if itp.Status.Phase == v1.IntegrationPlatformPhaseReady {
list := &v1.IntegrationKitList{}
if err := mgr.GetClient().List(ctx, list, ctrl.InNamespace(itp.Namespace)); err != nil {
log.Error(err, "Failed to list integration kits")
return requests
}
for _, kit := range list.Items {
if v, ok := kit.Annotations[v1.PlatformSelectorAnnotation]; ok && v != itp.Name {
log.Infof("Integration kit %s is waiting for selected integration platform '%s' - skip it now", kit.Name, v)
continue
}
if v, ok := kit.Annotations[v1.OperatorIDAnnotation]; ok && v != itp.Name {
// kit waiting for another platform to become ready - skip here
log.Debugf("Integration kit %s is waiting for another integration platform '%s' - skip it now", kit.Name, v)
continue
}
if kit.Status.Phase == v1.IntegrationKitPhaseWaitingForPlatform {
log.Infof("Platform %s ready, wake-up integration kit: %s", itp.Name, kit.Name)
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Namespace: kit.Namespace,
Name: kit.Name,
},
})
}
}
}
return requests
}),
),
)
if err != nil {
return err
}
return nil
}