@@ -18,7 +18,6 @@ package controllers
1818
1919import (
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+
280288func mergeMap (m1 , m2 map [string ]string ) map [string ]string {
281289
282290 if m1 != nil {
0 commit comments