@@ -25,6 +25,7 @@ import (
2525 "maps"
2626 "os"
2727 "strconv"
28+ "time"
2829
2930 corev1 "k8s.io/api/core/v1"
3031 kerrors "k8s.io/apimachinery/pkg/util/errors"
@@ -47,13 +48,17 @@ import (
4748
4849 turtlesv1 "github.com/rancher/turtles/api/v1alpha1"
4950 "github.com/rancher/turtles/internal/controllers/clusterctl"
51+ "github.com/rancher/turtles/internal/sync"
5052)
5153
5254const (
5355 configSecretNameField = "spec.configSecret.name" //nolint:gosec
5456 configSecretNamespaceField = "spec.configSecret.namespace" //nolint:gosec
5557 providerTypeField = "spec.type" //nolint:gosec
5658 providerNameField = "spec.name" //nolint:gosec
59+
60+ azureProvider = "azure"
61+ gcpProvider = "gcp"
5762)
5863
5964// OperatorReconciler is a mapping wrapper for CAPIProvider -> operator provider resources.
@@ -76,6 +81,16 @@ func (r *OperatorReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Mana
7681 return err
7782 }
7883
84+ if err := (& controller.GenericProviderHealthCheckReconciler {
85+ Client : mgr .GetClient (),
86+ Provider : & turtlesv1.CAPIProvider {},
87+ }).SetupWithManager (mgr , options ); err != nil {
88+ log := log .FromContext (ctx )
89+ log .Error (err , "unable to create controller" , "controller" , "GenericProviderHealthCheck" )
90+
91+ return err
92+ }
93+
7994 return nil
8095}
8196
@@ -87,7 +102,7 @@ type ClientWrapper struct {
87102// Patch shadows the upstream patch method, ignoring CAPIProvider spec patch.
88103func (c * ClientWrapper ) Patch (ctx context.Context , obj client.Object , patch client.Patch , opts ... client.PatchOption ) error {
89104 // Ignore CAPIProvider spec patch
90- if _ , ok := obj .(* turtlesv1.CAPIProvider ); ok && obj .GetDeletionTimestamp ().IsZero () && len ( obj . GetFinalizers ()) > 0 {
105+ if _ , ok := obj .(* turtlesv1.CAPIProvider ); ok && obj .GetDeletionTimestamp ().IsZero () {
91106 return nil
92107 }
93108
@@ -97,6 +112,7 @@ func (c *ClientWrapper) Patch(ctx context.Context, obj client.Object, patch clie
97112//+kubebuilder:rbac:groups=turtles-capi.cattle.io,resources=capiproviders,verbs=get;list;watch;create;update;patch;delete
98113//+kubebuilder:rbac:groups=turtles-capi.cattle.io,resources=capiproviders/status,verbs=get;update;patch
99114//+kubebuilder:rbac:groups=turtles-capi.cattle.io,resources=capiproviders/finalizers,verbs=update
115+ // +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch;create;update;patch;delete
100116
101117// CAPIProviderReconciler wraps the upstream CAPIProviderReconciler.
102118type CAPIProviderReconciler struct {
@@ -106,20 +122,15 @@ type CAPIProviderReconciler struct {
106122
107123// BuildWithManager builds the CAPIProviderReconciler.
108124func (r * CAPIProviderReconciler ) BuildWithManager (ctx context.Context , mgr ctrl.Manager ) (* ctrl.Builder , error ) {
109- return r .GenericProviderReconciler .BuildWithManager (ctx , mgr )
110- }
111-
112- // SetupWithManager sets up the controller with the Manager.
113- func (r * CAPIProviderReconciler ) SetupWithManager (ctx context.Context , mgr ctrl.Manager , options ctr.Options ) error {
114- builder , err := r .BuildWithManager (ctx , mgr )
125+ builder , err := r .GenericProviderReconciler .BuildWithManager (ctx , mgr )
115126 if err != nil {
116- return err
127+ return nil , err
117128 }
118129
119130 builder = builder .Named ("ProviderReconciler" )
120131
121132 if err := indexFields (ctx , & turtlesv1.CAPIProvider {}, mgr ); err != nil {
122- return err
133+ return nil , err
123134 }
124135
125136 builder .Watches (
@@ -142,7 +153,8 @@ func (r *CAPIProviderReconciler) SetupWithManager(ctx context.Context, mgr ctrl.
142153
143154 r .ReconcilePhases = []controller.PhaseFn {
144155 r .waitForClusterctlConfigUpdate ,
145- r .setDefaultProviderSpec ,
156+ r .setProviderSpec ,
157+ r .syncSecrets ,
146158 rec .ApplyFromCache ,
147159 rec .PreflightChecks ,
148160 rec .InitializePhaseReconciler ,
@@ -159,14 +171,24 @@ func (r *CAPIProviderReconciler) SetupWithManager(ctx context.Context, mgr ctrl.
159171
160172 r .DeletePhases = []controller.PhaseFn {
161173 r .waitForClusterctlConfigUpdate ,
162- r .setDefaultProviderSpec ,
174+ r .setProviderSpec ,
163175 rec .Delete ,
164176 }
165177
166178 for i , phase := range r .ReconcilePhases {
167179 r .ReconcilePhases [i ] = finalizePhase (phase , r .setConditions )
168180 }
169181
182+ return builder , nil
183+ }
184+
185+ // SetupWithManager sets up the controller with the Manager.
186+ func (r * CAPIProviderReconciler ) SetupWithManager (ctx context.Context , mgr ctrl.Manager , options ctr.Options ) error {
187+ builder , err := r .BuildWithManager (ctx , mgr )
188+ if err != nil {
189+ return err
190+ }
191+
170192 return builder .WithOptions (options ).Complete (reconcile .AsReconciler (r .Client , r ))
171193}
172194
@@ -271,13 +293,13 @@ func setProviderSpec(ctx context.Context, cl client.Client, provider *turtlesv1.
271293 }
272294
273295 switch provider .ProviderName () {
274- case "azure" :
296+ case azureProvider :
275297 if provider .Status .Variables == nil {
276298 provider .Status .Variables = map [string ]string {}
277299 }
278300
279301 provider .Status .Variables ["EXP_AKS_RESOURCE_HEALTH" ] = "true"
280- case "gcp" :
302+ case gcpProvider :
281303 if provider .Status .Variables == nil {
282304 provider .Status .Variables = map [string ]string {}
283305 }
@@ -288,7 +310,7 @@ func setProviderSpec(ctx context.Context, cl client.Client, provider *turtlesv1.
288310 return nil
289311}
290312
291- func (r * CAPIProviderReconciler ) setDefaultProviderSpec (ctx context.Context ) (* controller.Result , error ) {
313+ func (r * CAPIProviderReconciler ) setProviderSpec (ctx context.Context ) (* controller.Result , error ) {
292314 if capiProvider , ok := r .Provider .(* turtlesv1.CAPIProvider ); ok {
293315 return & controller.Result {}, setProviderSpec (ctx , r .Client , capiProvider )
294316 }
@@ -342,7 +364,7 @@ func finalizePhase(phase controller.PhaseFn, finalizePhase controller.PhaseFn) c
342364 }
343365
344366 // Perform finalization step after early completion
345- if res .Completed {
367+ if res != nil && res .Completed {
346368 return finalizePhase (ctx )
347369 }
348370
@@ -545,6 +567,25 @@ func setConditions(provider *turtlesv1.CAPIProvider) {
545567 }
546568}
547569
570+ func (r * CAPIProviderReconciler ) syncSecrets (ctx context.Context ) (* controller.Result , error ) {
571+ var err error
572+
573+ if capiProvider , ok := r .Provider .(* turtlesv1.CAPIProvider ); ok {
574+ s := sync .NewList (
575+ sync .NewSecretSync (r .Client , capiProvider ),
576+ sync .NewSecretMapperSync (ctx , r .Client , capiProvider ),
577+ )
578+
579+ if err := s .Sync (ctx ); client .IgnoreNotFound (err ) != nil {
580+ return & controller.Result {}, err
581+ }
582+
583+ s .Apply (ctx , & err )
584+ }
585+
586+ return & controller.Result {}, err
587+ }
588+
548589func setLatestVersion (ctx context.Context , cl client.Client , provider * turtlesv1.CAPIProvider ) error {
549590 log := log .FromContext (ctx )
550591
@@ -627,7 +668,7 @@ func (r *CAPIProviderReconciler) waitForClusterctlConfigUpdate(ctx context.Conte
627668
628669 if ! synced {
629670 logger .Info ("ClusterctlConfig is not synced yet, waiting for mounted ConfigMap to be updated." )
630- return & controller.Result {RequeueAfter : defaultRequeueDuration }, nil
671+ return & controller.Result {RequeueAfter : 5 * time . Second }, nil
631672 }
632673
633674 return & controller.Result {}, nil
0 commit comments