@@ -26,32 +26,38 @@ import (
26
26
"sigs.k8s.io/controller-runtime/pkg/reconcile"
27
27
)
28
28
29
- type Provider interface {
30
- operatorv1.GenericProvider
31
- }
29
+ // Provider is an GenericProvider.
30
+ type Provider = operatorv1.GenericProvider
32
31
32
+ // ProviderList is a GenericProviderList satisfying ObjectList interface.
33
33
type ProviderList interface {
34
34
client.ObjectList
35
35
operatorv1.GenericProviderList
36
36
}
37
37
38
+ // Getter is a base interface for provider reconcilers.
38
39
type Getter interface {
39
40
ClusterctlProviderType () clusterctlv1.ProviderType
40
41
GenericProvider () Provider
41
42
GetProviderList () ProviderList
42
43
}
43
44
45
+ // Connector is a base interface for building phase reconcile and accessing cluster via client.
44
46
type Connector interface {
45
47
GetClient () client.Client
46
48
GetConfig () * rest.Config
47
49
}
48
50
51
+ // GroupBuilder implementation allows to build a generic Group acting on specific provider type,
52
+ // preserving the type info.
49
53
type GroupBuilder [P Provider ] interface {
50
54
Connector
51
55
Getter
52
56
ClusterctlProvider (provider P ) * clusterctlv1.Provider
53
57
}
54
58
59
+ // Group is a generic interface with access to typed Provider object.
60
+ // Each reconciler phase expected to work with a Provider Group.
55
61
type Group [P Provider ] interface {
56
62
Connector
57
63
Getter
@@ -62,6 +68,14 @@ type Group[P Provider] interface {
62
68
// NewGroup is a function that creates a new group.
63
69
type NewGroup [P Provider ] func (P , ProviderList , GroupBuilder [P ]) Group [P ]
64
70
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]].
65
79
type ProviderReconciler [P Provider ] interface {
66
80
GroupBuilder [P ]
67
81
Init ()
@@ -74,12 +88,27 @@ type ProviderReconciler[P Provider] interface {
74
88
// ReconcileFn is a function that represent a phase of the reconciliation.
75
89
type ReconcileFn [P Provider , G Group [P ]] func (context.Context , G ) (reconcile.Result , error )
76
90
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
+ // }
77
101
func NewReconcileFnList [P Provider , G Group [P ]](phaseFunc ... ReconcileFn [P , G ]) []ReconcileFn [P , G ] {
78
102
return phaseFunc
79
103
}
80
104
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.
81
108
var ProviderReconcilers = map [clusterctlv1.ProviderType ]Getter {}
82
109
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.
83
112
func GetBuilder [P Provider ](_ P ) GroupBuilder [P ] {
84
113
for _ , reconciler := range ProviderReconcilers {
85
114
if r , ok := reconciler .(ProviderReconciler [P ]); ok {
0 commit comments