@@ -26,32 +26,38 @@ import (
2626 "sigs.k8s.io/controller-runtime/pkg/reconcile"
2727)
2828
29- type Provider interface {
30- operatorv1.GenericProvider
31- }
29+ // Provider is an GenericProvider.
30+ type Provider = operatorv1.GenericProvider
3231
32+ // ProviderList is a GenericProviderList satisfying ObjectList interface.
3333type ProviderList interface {
3434 client.ObjectList
3535 operatorv1.GenericProviderList
3636}
3737
38+ // Getter is a base interface for provider reconcilers.
3839type Getter interface {
3940 ClusterctlProviderType () clusterctlv1.ProviderType
4041 GenericProvider () Provider
4142 GetProviderList () ProviderList
4243}
4344
45+ // Connector is a base interface for building phase reconcile and accessing cluster via client.
4446type Connector interface {
4547 GetClient () client.Client
4648 GetConfig () * rest.Config
4749}
4850
51+ // GroupBuilder implementation allows to build a generic Group acting on specific provider type,
52+ // preserving the type info.
4953type GroupBuilder [P Provider ] interface {
5054 Connector
5155 Getter
5256 ClusterctlProvider (provider P ) * clusterctlv1.Provider
5357}
5458
59+ // Group is a generic interface with access to typed Provider object.
60+ // Each reconciler phase expected to work with a Provider Group.
5561type Group [P Provider ] interface {
5662 Connector
5763 Getter
@@ -62,6 +68,14 @@ type Group[P Provider] interface {
6268// NewGroup is a function that creates a new group.
6369type NewGroup [P Provider ] func (P , ProviderList , GroupBuilder [P ]) Group [P ]
6470
71+ // ProviderReconciler is a reconciler methods interface related to specified provider
72+ // The reconcile is split into 4 stages, each executed after another, and accepting any Provider object.
73+ // Each stage will return a list of phases for controller execution, typed for defined Provider:
74+ //
75+ // - PreflightChecks(ctx context.Context, provider P) []ReconcileFn[P, Group[P]]
76+ // - ReconcileNormal(ctx context.Context, provider P) []ReconcileFn[P, Group[P]]
77+ // - ReportStatus(ctx context.Context, provider P) []ReconcileFn[P, Group[P]]
78+ // - ReconcileDelete(ctx context.Context, provider P) []ReconcileFn[P, Group[P]].
6579type ProviderReconciler [P Provider ] interface {
6680 GroupBuilder [P ]
6781 Init ()
@@ -74,12 +88,27 @@ type ProviderReconciler[P Provider] interface {
7488// ReconcileFn is a function that represent a phase of the reconciliation.
7589type ReconcileFn [P Provider , G Group [P ]] func (context.Context , G ) (reconcile.Result , error )
7690
91+ // NewReconcileFnList created a list of reconcile phases, with a typed group working with a defined provider only
92+ // Example:
93+ //
94+ // generic.NewReconcileFnList(r.corePreflightChecks) // Will only compile when passed to core provider reconciler working on CoreProvider
95+ //
96+ // func (r *CoreProviderReconciler) corePreflightChecks(ctx context.Context, phase generic.Group[*operatorv1.CoreProvider]) (ctrl.Result, error) {
97+ // var p *operatorv1.CoreProvider
98+ // // getting actual core provider instead of interface for resource specific operations or validation
99+ // p = phase.GetProvider() // this works
100+ // }
77101func NewReconcileFnList [P Provider , G Group [P ]](phaseFunc ... ReconcileFn [P , G ]) []ReconcileFn [P , G ] {
78102 return phaseFunc
79103}
80104
105+ // ProviderReconcilers is a storage of registered provider reconcilers on controller startup.
106+ // It is used to access reconciler specific methods, allowing to map Clusterctl provider type
107+ // on an actual Provider object, which represents it.
81108var ProviderReconcilers = map [clusterctlv1.ProviderType ]Getter {}
82109
110+ // GetBuilder provides an initialized reconciler to fetch component in the domail of provider, like
111+ // provider list type, clusterctl provider, etc. without need to maintain an evergrowing switch statement.
83112func GetBuilder [P Provider ](_ P ) GroupBuilder [P ] {
84113 for _ , reconciler := range ProviderReconcilers {
85114 if r , ok := reconciler .(ProviderReconciler [P ]); ok {
0 commit comments