Skip to content

Commit 98c6540

Browse files
Merge pull request #1580 from Danil-Grigorev/refactor-syncer
Add operator_reconciler tests and simplify syncer implementation
2 parents 48b1408 + 916a001 commit 98c6540

12 files changed

+416
-223
lines changed

internal/controllers/operator_reconciler.go

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

5254
const (
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.
88103
func (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.
102118
type CAPIProviderReconciler struct {
@@ -106,20 +122,15 @@ type CAPIProviderReconciler struct {
106122

107123
// BuildWithManager builds the CAPIProviderReconciler.
108124
func (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+
548589
func 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

Comments
 (0)