Skip to content

Commit 83f1000

Browse files
Merge pull request #279 from sabre1041/refactor-pruning
Refactored pruning and error handling logic
2 parents efd060b + 0656728 commit 83f1000

File tree

1 file changed

+53
-45
lines changed

1 file changed

+53
-45
lines changed

controllers/groupsync_controller.go

Lines changed: 53 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package controllers
1818

1919
import (
2020
"context"
21-
"errors"
2221
"fmt"
2322
"time"
2423

@@ -32,7 +31,8 @@ import (
3231
apierrors "k8s.io/apimachinery/pkg/api/errors"
3332
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3433
"k8s.io/apimachinery/pkg/types"
35-
kubeclock "k8s.io/apimachinery/pkg/util/clock"
34+
utilerrors "k8s.io/apimachinery/pkg/util/errors"
35+
kubeclock "k8s.io/utils/clock"
3636
ctrl "sigs.k8s.io/controller-runtime"
3737
"sigs.k8s.io/controller-runtime/pkg/client"
3838
"sigs.k8s.io/controller-runtime/pkg/reconcile"
@@ -93,6 +93,8 @@ func (r *GroupSyncReconciler) Reconcile(context context.Context, req ctrl.Reques
9393
return r.ManageError(context, instance, err)
9494
}
9595

96+
syncErrors := []error{}
97+
9698
// Execute Each Provider Syncer
9799
for _, groupSyncer := range groupSyncMgr.GroupSyncers {
98100

@@ -105,22 +107,23 @@ func (r *GroupSyncReconciler) Reconcile(context context.Context, req ctrl.Reques
105107

106108
// Initialize Connection
107109
if err := groupSyncer.Bind(); err != nil {
108-
return r.wrapMetricsErrorWithMetrics(prometheusLabels, context, instance, err)
110+
r.manageSyncError(prometheusLabels, &syncErrors, err)
111+
continue
109112
}
110113

111-
syncStartTime := time.Now().Format(time.RFC3339)
112114
// Perform Sync
113115
groups, err := groupSyncer.Sync()
114116

115117
if err != nil {
116118
logger.Error(err, "Failed to Complete Sync", "Provider", groupSyncer.GetProviderName())
117-
return r.wrapMetricsErrorWithMetrics(prometheusLabels, context, instance, err)
119+
r.manageSyncError(prometheusLabels, &syncErrors, err)
120+
continue
118121
}
119122

120123
updatedGroups := 0
121124
prunedGroups := 0
122125

123-
for _, group := range groups {
126+
for i, group := range groups {
124127

125128
ocpGroup := &userv1.Group{}
126129
err := r.GetClient().Get(context, types.NamespacedName{Name: group.Name, Namespace: ""}, ocpGroup)
@@ -136,11 +139,12 @@ func (r *GroupSyncReconciler) Reconcile(context context.Context, req ctrl.Reques
136139
ocpGroup.Name = group.Name
137140

138141
} else if err != nil {
139-
return r.wrapMetricsErrorWithMetrics(prometheusLabels, context, instance, err)
142+
r.manageSyncError(prometheusLabels, &syncErrors, err)
143+
continue
140144
} else {
141145
// Verify this group is not managed by another provider
142146
if groupProviderLabel, exists := ocpGroup.Labels[constants.SyncProvider]; !exists || (groupProviderLabel != providerLabel) {
143-
r.Log.Info("Group Provider Label Did Not Match Expected Provider Label", "Group Name", ocpGroup.Name, "Expected Label", providerLabel, "Found Label", groupProviderLabel)
147+
r.Log.Info("Group Provider Label Did Not Match Expected Provider Label", "Provider", groupSyncer.GetProviderName(), "Group Name", ocpGroup.Name, "Expected Label", providerLabel, "Found Label", groupProviderLabel)
144148
continue
145149
}
146150
}
@@ -163,34 +167,38 @@ func (r *GroupSyncReconciler) Reconcile(context context.Context, req ctrl.Reques
163167
ocpGroup.Labels[constants.SyncProvider] = providerLabel
164168

165169
// Add Gloabl Annotations/Labels
166-
ocpGroup.Annotations[constants.SyncTimestamp] = time.Now().UTC().Format(time.RFC3339)
170+
now := time.Now().UTC().Format(time.RFC3339)
171+
ocpGroup.Annotations[constants.SyncTimestamp] = now
167172

168173
ocpGroup.Users = group.Users
169174

170175
err = r.CreateOrUpdateResource(context, nil, "", ocpGroup)
171176

177+
group.UID = ocpGroup.UID
178+
groups[i] = group
179+
172180
if err != nil {
173-
r.Log.Error(err, "Failed to Create or Update OpenShift Group")
174-
return r.wrapMetricsErrorWithMetrics(prometheusLabels, context, instance, err)
181+
r.Log.Error(err, "Failed to Create or Update OpenShift Group", "Provider", groupSyncer.GetProviderName())
182+
r.manageSyncError(prometheusLabels, &syncErrors, err)
183+
continue
175184
}
176185

177186
updatedGroups++
178187
}
179188

180189
if groupSyncer.GetPrune() {
181-
logger.Info("Start Pruning Groups")
182-
prunedGroups, err = r.pruneGroups(context, instance, providerLabel, syncStartTime, logger)
190+
logger.Info("Start Pruning Groups", "Provider", groupSyncer.GetProviderName())
191+
prunedGroups, err = r.pruneGroups(context, instance, groups, groupSyncer.GetProviderName(), providerLabel, logger)
183192
if err != nil {
184-
r.Log.Error(err, "Failed to Prune Group")
185-
return r.wrapMetricsErrorWithMetrics(prometheusLabels, context, instance, err)
193+
r.Log.Error(err, "Failed to Prune Group", "Provider", groupSyncer.GetProviderName())
194+
r.manageSyncError(prometheusLabels, &syncErrors, err)
186195
}
187-
logger.Info("Pruning Completed")
196+
logger.Info("Pruning Completed", "Provider", groupSyncer.GetProviderName())
188197
}
189198

190199
logger.Info("Sync Completed Successfully", "Provider", groupSyncer.GetProviderName(), "Groups Created or Updated", updatedGroups, "Groups Pruned", prunedGroups)
191200

192201
// Add Metrics
193-
194202
successfulGroupSyncs.With(prometheusLabels).Inc()
195203
groupsSynchronized.With(prometheusLabels).Set(float64(updatedGroups))
196204
groupSyncError.With(prometheusLabels).Set(0)
@@ -199,6 +207,11 @@ func (r *GroupSyncReconciler) Reconcile(context context.Context, req ctrl.Reques
199207
}
200208
}
201209

210+
// Throw error if error occurred during sync
211+
if len(syncErrors) > 0 {
212+
return r.ManageError(context, instance, utilerrors.NewAggregate(syncErrors))
213+
}
214+
202215
instance.Status.LastSyncSuccessTime = &metav1.Time{Time: clock.Now()}
203216

204217
successResult, err := r.ManageSuccess(context, instance)
@@ -222,24 +235,18 @@ func (r *GroupSyncReconciler) SetupWithManager(mgr ctrl.Manager) error {
222235
Complete(r)
223236
}
224237

225-
func (r *GroupSyncReconciler) wrapMetricsErrorWithMetrics(prometheusLabels prometheus.Labels, context context.Context, obj client.Object, issue error) (ctrl.Result, error) {
238+
func (r *GroupSyncReconciler) manageSyncError(prometheusLabels prometheus.Labels, syncErrors *[]error, err error) {
226239

227240
unsuccessfulGroupSyncs.With(prometheusLabels).Inc()
228241
groupSyncError.With(prometheusLabels).Set(1)
229242

230-
return r.ManageError(context, obj, issue)
243+
*syncErrors = append(*syncErrors, err)
244+
231245
}
232246

233-
func (r *GroupSyncReconciler) pruneGroups(context context.Context, instance *redhatcopv1alpha1.GroupSync, providerLabel string, syncStartTime string, logger logr.Logger) (int, error) {
247+
func (r *GroupSyncReconciler) pruneGroups(context context.Context, instance *redhatcopv1alpha1.GroupSync, syncedGroups []userv1.Group, providerName, providerLabel string, logger logr.Logger) (int, error) {
234248
prunedGroups := 0
235249

236-
syncStartDatetime, syncStartParseError := time.Parse(time.RFC3339, syncStartTime)
237-
238-
// Should not occur
239-
if syncStartParseError != nil {
240-
return prunedGroups, syncStartParseError
241-
}
242-
243250
ocpGroups := &userv1.GroupList{}
244251
opts := []client.ListOption{
245252
client.InNamespace(""),
@@ -252,31 +259,32 @@ func (r *GroupSyncReconciler) pruneGroups(context context.Context, instance *red
252259

253260
for _, group := range ocpGroups.Items {
254261

255-
if groupSyncTime, ok := group.Annotations[constants.SyncTimestamp]; ok {
256-
257-
groupSyncDatetime, groupSyncTimeParseErr := time.Parse(time.RFC3339, groupSyncTime)
262+
// Remove group if not found in the list of synchronized groups
263+
groupFound := isGroupFound(group, syncedGroups)
258264

259-
if groupSyncTimeParseErr == nil {
260-
if groupSyncDatetime.Before(syncStartDatetime) {
261-
logger.Info("pruneGroups", "Delete Group", group.Name)
262-
err = r.GetClient().Delete(context, &group)
263-
prunedGroups++
264-
if err != nil {
265-
return prunedGroups, err
266-
}
267-
}
268-
} else {
269-
if groupSyncTimeParseErr != nil {
270-
logger.Error(groupSyncTimeParseErr, "Error parsing group start time annotation", "Group Name", group.Name, "Time", syncStartTime)
271-
}
265+
if !groupFound {
266+
logger.Info("Pruning Group", "Provider", providerName, "Group", group.Name)
267+
err = r.GetClient().Delete(context, &group)
268+
prunedGroups++
269+
if err != nil {
270+
return prunedGroups, err
272271
}
273-
} else {
274-
logger.Error(errors.New("unable to locate sync timestamp annotation"), "Group Name", group.Name)
275272
}
276273
}
277274
return prunedGroups, nil
278275
}
279276

277+
func isGroupFound(canidateGroup userv1.Group, baseGroups []userv1.Group) bool {
278+
279+
for _, baseGroup := range baseGroups {
280+
if baseGroup.UID == canidateGroup.UID {
281+
return true
282+
}
283+
}
284+
285+
return false
286+
}
287+
280288
func mergeMap(m1, m2 map[string]string) map[string]string {
281289

282290
if m1 != nil {

0 commit comments

Comments
 (0)