refactor: Re-use a lot of code and move to specific packages

This commit is contained in:
TheiLLeniumStudios
2025-12-28 08:47:55 +01:00
parent 3defc8bb29
commit c19058a66e
16 changed files with 251 additions and 717 deletions
@@ -62,9 +62,9 @@ func (r *ConfigMapReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
return ctrl.Result{}, nil
}
return r.reloadHandler().Process(ctx, cm.Namespace, cm.Name, "ConfigMap", reload.ResourceTypeConfigMap,
return r.reloadHandler().Process(ctx, cm.Namespace, cm.Name, reload.ResourceTypeConfigMap,
func(workloads []workload.WorkloadAccessor) []reload.ReloadDecision {
return r.ReloadService.ProcessConfigMap(reload.ConfigMapChange{
return r.ReloadService.Process(reload.ConfigMapChange{
ConfigMap: &cm,
EventType: reload.EventTypeUpdate,
}, workloads)
@@ -81,9 +81,9 @@ func (r *ConfigMapReconciler) handleDelete(ctx context.Context, req ctrl.Request
cm.Name = req.Name
cm.Namespace = req.Namespace
return r.reloadHandler().Process(ctx, req.Namespace, req.Name, "ConfigMap", reload.ResourceTypeConfigMap,
return r.reloadHandler().Process(ctx, req.Namespace, req.Name, reload.ResourceTypeConfigMap,
func(workloads []workload.WorkloadAccessor) []reload.ReloadDecision {
return r.ReloadService.ProcessConfigMap(reload.ConfigMapChange{
return r.ReloadService.Process(reload.ConfigMapChange{
ConfigMap: cm,
EventType: reload.EventTypeDelete,
}, workloads)
@@ -26,6 +26,7 @@ type DeploymentReconciler struct {
// Reconcile handles Deployment pause expiration.
func (r *DeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
log := r.Log.WithValues("deployment", req.NamespacedName)
log.Info("Deployment reconciling ", "namespace", req.Namespace, "name", req.Name)
var deploy appsv1.Deployment
if err := r.Get(ctx, req.NamespacedName, &deploy); err != nil {
@@ -76,14 +77,16 @@ func (r *DeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error {
// pausedByReloaderPredicate returns a predicate that only selects deployments
// that have been paused by Reloader (have the paused-at annotation).
func (r *DeploymentReconciler) pausedByReloaderPredicate() predicate.Predicate {
return predicate.NewPredicateFuncs(func(obj client.Object) bool {
annotations := obj.GetAnnotations()
if annotations == nil {
return false
}
return predicate.NewPredicateFuncs(
func(obj client.Object) bool {
annotations := obj.GetAnnotations()
if annotations == nil {
return false
}
// Only process if deployment has our paused-at annotation
_, hasPausedAt := annotations[r.Config.Annotations.PausedAt]
return hasPausedAt
})
// Only process if deployment has our paused-at annotation
_, hasPausedAt := annotations[r.Config.Annotations.PausedAt]
return hasPausedAt
},
)
}
+6 -6
View File
@@ -32,7 +32,7 @@ type ReloadHandler struct {
// Process handles the reload workflow: list workloads, get decisions, webhook or apply.
func (h *ReloadHandler) Process(
ctx context.Context,
namespace, resourceName, resourceKind string,
namespace, resourceName string,
resourceType reload.ResourceType,
getDecisions func([]workload.WorkloadAccessor) []reload.ReloadDecision,
log logr.Logger,
@@ -49,7 +49,7 @@ func (h *ReloadHandler) Process(
return h.sendWebhook(ctx, resourceName, namespace, resourceType, decisions, log)
}
h.applyReloads(ctx, resourceName, namespace, resourceKind, resourceType, decisions, log)
h.applyReloads(ctx, resourceName, namespace, resourceType, decisions, log)
return ctrl.Result{}, nil
}
@@ -99,7 +99,7 @@ func (h *ReloadHandler) sendWebhook(
func (h *ReloadHandler) applyReloads(
ctx context.Context,
resourceName, resourceNamespace, resourceKind string,
resourceName, resourceNamespace string,
resourceType reload.ResourceType,
decisions []reload.ReloadDecision,
log logr.Logger,
@@ -127,13 +127,13 @@ func (h *ReloadHandler) applyReloads(
"workload", decision.Workload.GetName(),
"kind", decision.Workload.Kind(),
)
h.EventRecorder.ReloadFailed(decision.Workload.GetObject(), resourceKind, resourceName, err)
h.EventRecorder.ReloadFailed(decision.Workload.GetObject(), resourceType.Kind(), resourceName, err)
h.Collectors.RecordReload(false, resourceNamespace)
continue
}
if updated {
h.EventRecorder.ReloadSuccess(decision.Workload.GetObject(), resourceKind, resourceName)
h.EventRecorder.ReloadSuccess(decision.Workload.GetObject(), resourceType.Kind(), resourceName)
h.Collectors.RecordReload(true, resourceNamespace)
log.Info("workload reloaded successfully",
"workload", decision.Workload.GetName(),
@@ -144,7 +144,7 @@ func (h *ReloadHandler) applyReloads(
WorkloadKind: string(decision.Workload.Kind()),
WorkloadName: decision.Workload.GetName(),
WorkloadNamespace: decision.Workload.GetNamespace(),
ResourceKind: resourceKind,
ResourceKind: resourceType.Kind(),
ResourceName: resourceName,
ResourceNamespace: resourceNamespace,
Timestamp: time.Now(),
+54 -84
View File
@@ -43,6 +43,52 @@ func UpdateWorkloadWithRetry(
}
}
// retryWithReload wraps the common retry logic for workload updates.
// It handles re-fetching on conflict, applying reload changes, and calling the update function.
func retryWithReload(
ctx context.Context,
c client.Client,
reloadService *reload.Service,
wl workload.WorkloadAccessor,
resourceName string,
resourceType reload.ResourceType,
namespace string,
hash string,
autoReload bool,
updateFn func() error,
) (bool, error) {
var updated bool
isFirstAttempt := true
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
if !isFirstAttempt {
obj := wl.GetObject()
key := client.ObjectKeyFromObject(obj)
if err := c.Get(ctx, key, obj); err != nil {
if errors.IsNotFound(err) {
return nil
}
return err
}
}
isFirstAttempt = false
var applyErr error
updated, applyErr = reloadService.ApplyReload(ctx, wl, resourceName, resourceType, namespace, hash, autoReload)
if applyErr != nil {
return applyErr
}
if !updated {
return nil
}
return updateFn()
})
return updated, err
}
// updateStandardWorkload updates Deployments, DaemonSets, StatefulSets, etc.
func updateStandardWorkload(
ctx context.Context,
@@ -55,48 +101,10 @@ func updateStandardWorkload(
hash string,
autoReload bool,
) (bool, error) {
var updated bool
isFirstAttempt := true
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
// On retry, re-fetch the object to get the latest ResourceVersion
if !isFirstAttempt {
obj := wl.GetObject()
key := client.ObjectKeyFromObject(obj)
if err := c.Get(ctx, key, obj); err != nil {
if errors.IsNotFound(err) {
// Object was deleted, nothing to update
return nil
}
return err
}
}
isFirstAttempt = false
// Apply reload changes (this modifies the workload in-place)
var applyErr error
updated, applyErr = reloadService.ApplyReload(
ctx,
wl,
resourceName,
resourceType,
namespace,
hash,
autoReload,
)
if applyErr != nil {
return applyErr
}
if !updated {
return nil
}
// Attempt update with field ownership
return c.Update(ctx, wl.GetObject(), client.FieldOwner(FieldManager))
})
return updated, err
return retryWithReload(ctx, c, reloadService, wl, resourceName, resourceType, namespace, hash, autoReload,
func() error {
return c.Update(ctx, wl.GetObject(), client.FieldOwner(FieldManager))
})
}
// updateJobWithRecreate deletes the Job and recreates it with the updated spec.
@@ -254,46 +262,8 @@ func updateArgoRollout(
return false, nil
}
var updated bool
isFirstAttempt := true
err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
// On retry, re-fetch the object to get the latest ResourceVersion
if !isFirstAttempt {
obj := rolloutWl.GetObject()
key := client.ObjectKeyFromObject(obj)
if err := c.Get(ctx, key, obj); err != nil {
if errors.IsNotFound(err) {
// Object was deleted, nothing to update
return nil
}
return err
}
}
isFirstAttempt = false
// Apply reload changes (this modifies the workload in-place)
var applyErr error
updated, applyErr = reloadService.ApplyReload(
ctx,
wl,
resourceName,
resourceType,
namespace,
hash,
autoReload,
)
if applyErr != nil {
return applyErr
}
if !updated {
return nil
}
// Use the RolloutWorkload's Update method which handles the rollout strategy
return rolloutWl.Update(ctx, c)
})
return updated, err
return retryWithReload(ctx, c, reloadService, wl, resourceName, resourceType, namespace, hash, autoReload,
func() error {
return rolloutWl.Update(ctx, c)
})
}
+4 -4
View File
@@ -62,9 +62,9 @@ func (r *SecretReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
return ctrl.Result{}, nil
}
return r.reloadHandler().Process(ctx, secret.Namespace, secret.Name, "Secret", reload.ResourceTypeSecret,
return r.reloadHandler().Process(ctx, secret.Namespace, secret.Name, reload.ResourceTypeSecret,
func(workloads []workload.WorkloadAccessor) []reload.ReloadDecision {
return r.ReloadService.ProcessSecret(reload.SecretChange{
return r.ReloadService.Process(reload.SecretChange{
Secret: &secret,
EventType: reload.EventTypeUpdate,
}, workloads)
@@ -78,9 +78,9 @@ func (r *SecretReconciler) handleDelete(ctx context.Context, req ctrl.Request, l
secret.Name = req.Name
secret.Namespace = req.Namespace
return r.reloadHandler().Process(ctx, req.Namespace, req.Name, "Secret", reload.ResourceTypeSecret,
return r.reloadHandler().Process(ctx, req.Namespace, req.Name, reload.ResourceTypeSecret,
func(workloads []workload.WorkloadAccessor) []reload.ReloadDecision {
return r.ReloadService.ProcessSecret(reload.SecretChange{
return r.ReloadService.Process(reload.SecretChange{
Secret: secret,
EventType: reload.EventTypeDelete,
}, workloads)