@@ -104,10 +104,9 @@ func (r *DRPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
104
104
u .validatedSetFalse ("NamespaceCreateFailed" , err ))
105
105
}
106
106
107
- drclusters := & ramen.DRClusterList {}
108
-
109
- if err := r .Client .List (ctx , drclusters ); err != nil {
110
- return ctrl.Result {}, fmt .Errorf ("drclusters list: %w" , u .validatedSetFalse ("drClusterListFailed" , err ))
107
+ drclusters , drClusterIDsToNames , err := r .getDRClusterDetails (ctx )
108
+ if err != nil {
109
+ return ctrl.Result {}, fmt .Errorf ("drclusters details: %w" , u .validatedSetFalse ("drClusterDetailsFailed" , err ))
111
110
}
112
111
113
112
secretsUtil := & util.SecretsUtil {Client : r .Client , APIReader : r .APIReader , Ctx : ctx , Log : log }
@@ -119,7 +118,7 @@ func (r *DRPolicyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
119
118
120
119
log .Info ("create/update" )
121
120
122
- reason , err := validateDRPolicy (ctx , drpolicy , drclusters , r .APIReader )
121
+ reason , err := validateDRPolicy (ctx , drpolicy , drclusters , r .APIReader , drClusterIDsToNames )
123
122
if err != nil {
124
123
statusErr := u .validatedSetFalse (reason , err )
125
124
if ! errors .Is (statusErr , err ) || reason != ReasonDRClusterNotFound {
@@ -166,7 +165,7 @@ func (r *DRPolicyReconciler) reconcile(
166
165
}
167
166
168
167
func (r * DRPolicyReconciler ) initiateDRPolicyMetrics (drpolicy * ramen.DRPolicy , drclusters * ramen.DRClusterList ) error {
169
- isMetro , _ := dRPolicySupportsMetro (drpolicy , drclusters .Items )
168
+ isMetro , _ := dRPolicySupportsMetro (drpolicy , drclusters .Items , nil )
170
169
171
170
// Do not set metric for metro-dr
172
171
if ! isMetro {
@@ -178,10 +177,36 @@ func (r *DRPolicyReconciler) initiateDRPolicyMetrics(drpolicy *ramen.DRPolicy, d
178
177
return nil
179
178
}
180
179
180
+ func (r * DRPolicyReconciler ) getDRClusterDetails (ctx context.Context ) (* ramen.DRClusterList , map [string ]string , error ) {
181
+ drClusters := & ramen.DRClusterList {}
182
+ if err := r .Client .List (ctx , drClusters ); err != nil {
183
+ return nil , nil , fmt .Errorf ("drclusters list: %w" , err )
184
+ }
185
+
186
+ drClusterIDsToNames := map [string ]string {}
187
+
188
+ for idx := range drClusters .Items {
189
+ mc , err := util .NewManagedClusterInstance (ctx , r .Client , drClusters .Items [idx ].GetName ())
190
+ if err != nil {
191
+ return nil , nil , fmt .Errorf ("drclusters ManagedCluster (%s): %w" , drClusters .Items [idx ].GetName (), err )
192
+ }
193
+
194
+ clID , err := mc .ClusterID ()
195
+ if err != nil {
196
+ return nil , nil , fmt .Errorf ("drclusters cluster ID (%s): %w" , drClusters .Items [idx ].GetName (), err )
197
+ }
198
+
199
+ drClusterIDsToNames [clID ] = drClusters .Items [idx ].GetName ()
200
+ }
201
+
202
+ return drClusters , drClusterIDsToNames , nil
203
+ }
204
+
181
205
func validateDRPolicy (ctx context.Context ,
182
206
drpolicy * ramen.DRPolicy ,
183
207
drclusters * ramen.DRClusterList ,
184
208
apiReader client.Reader ,
209
+ drClusterIDsToNames map [string ]string ,
185
210
) (string , error ) {
186
211
// DRPolicy does not support both Sync and Async configurations in one single DRPolicy
187
212
if len (drpolicy .Status .Sync .PeerClasses ) > 0 && len (drpolicy .Status .Async .PeerClasses ) > 0 {
@@ -200,7 +225,7 @@ func validateDRPolicy(ctx context.Context,
200
225
return reason , err
201
226
}
202
227
203
- err = validatePolicyConflicts (ctx , apiReader , drpolicy , drclusters )
228
+ err = validatePolicyConflicts (ctx , apiReader , drpolicy , drclusters , drClusterIDsToNames )
204
229
if err != nil {
205
230
return ReasonValidationFailed , err
206
231
}
@@ -258,13 +283,14 @@ func validatePolicyConflicts(ctx context.Context,
258
283
apiReader client.Reader ,
259
284
drpolicy * ramen.DRPolicy ,
260
285
drclusters * ramen.DRClusterList ,
286
+ drClusterIDsToNames map [string ]string ,
261
287
) error {
262
288
drpolicies , err := util .GetAllDRPolicies (ctx , apiReader )
263
289
if err != nil {
264
290
return fmt .Errorf ("validate managed cluster in drpolicy %v failed: %w" , drpolicy .Name , err )
265
291
}
266
292
267
- err = hasConflictingDRPolicy (drpolicy , drclusters , drpolicies )
293
+ err = hasConflictingDRPolicy (drpolicy , drclusters , drpolicies , drClusterIDsToNames )
268
294
if err != nil {
269
295
return fmt .Errorf ("validate managed cluster in drpolicy failed: %w" , err )
270
296
}
@@ -274,7 +300,12 @@ func validatePolicyConflicts(ctx context.Context,
274
300
275
301
// If two drpolicies have common managed cluster(s) and at least one of them is
276
302
// a metro supported drpolicy, then fail.
277
- func hasConflictingDRPolicy (match * ramen.DRPolicy , drclusters * ramen.DRClusterList , list ramen.DRPolicyList ) error {
303
+ func hasConflictingDRPolicy (
304
+ match * ramen.DRPolicy ,
305
+ drclusters * ramen.DRClusterList ,
306
+ list ramen.DRPolicyList ,
307
+ drClusterIDsToNames map [string ]string ,
308
+ ) error {
278
309
// Valid cases
279
310
// [e1,w1] [e1,c1]
280
311
// [e1,w1] [e1,w1]
@@ -294,80 +325,47 @@ func hasConflictingDRPolicy(match *ramen.DRPolicy, drclusters *ramen.DRClusterLi
294
325
continue
295
326
}
296
327
297
- // None of the common managed clusters should belong to Metro Regions in either of the drpolicies.
298
- if haveOverlappingMetroZones (match , drp , drclusters ) {
328
+ // None of the common managed clusters should belong to Metro clusters in either of the drpolicies.
329
+ if haveOverlappingMetroZones (match , drp , drclusters , drClusterIDsToNames ) {
299
330
return fmt .Errorf ("drpolicy: %v has overlapping metro region with another drpolicy %v" , match .Name , drp .Name )
300
331
}
301
332
}
302
333
303
334
return nil
304
335
}
305
336
306
- func getClusterIDSFromPolicy (drpolicy * ramen.DRPolicy ) []string {
307
- cids := []string {}
308
-
309
- if len (drpolicy .Status .Sync .PeerClasses ) > 0 {
310
- for _ , pc := range drpolicy .Status .Sync .PeerClasses {
311
- cids = append (cids , pc .ClusterIDs ... )
312
- }
313
-
314
- return cids
315
- }
316
-
317
- if len (drpolicy .Status .Async .PeerClasses ) > 0 {
318
- for _ , pc := range drpolicy .Status .Async .PeerClasses {
319
- cids = append (cids , pc .ClusterIDs ... )
320
- }
321
-
322
- return cids
323
- }
324
-
325
- return cids
326
- }
327
-
328
- func hasOverlapWithMetro (metroMap map [string ][]string , commonClusterIDs , commonClusters []string ) bool {
329
- for _ , v := range metroMap {
330
- if sets .NewString (v ... ).HasAny (commonClusterIDs ... ) {
331
- return true
332
- }
333
-
334
- if sets .NewString (v ... ).HasAny (commonClusters ... ) {
335
- return true
336
- }
337
- }
338
-
339
- return false
340
- }
341
-
342
- func haveOverlappingMetroZones (d1 * ramen.DRPolicy , d2 * ramen.DRPolicy , drclusters * ramen.DRClusterList ) bool {
337
+ func haveOverlappingMetroZones (
338
+ d1 , d2 * ramen.DRPolicy ,
339
+ drclusters * ramen.DRClusterList ,
340
+ drClusterIDsToNames map [string ]string ,
341
+ ) bool {
343
342
d1ClusterNames := sets .NewString (util .DRPolicyClusterNames (d1 )... )
344
- d1ClusterIDs := sets .NewString (getClusterIDSFromPolicy (d1 )... )
345
- d1SupportsMetro , d1MetroMap := dRPolicySupportsMetro (d1 , drclusters .Items )
346
-
343
+ d1SupportsMetro , d1MetroClusters := dRPolicySupportsMetro (d1 , drclusters .Items , drClusterIDsToNames )
347
344
d2ClusterNames := sets .NewString (util .DRPolicyClusterNames (d2 )... )
348
- d2ClusterIDs := sets .NewString (getClusterIDSFromPolicy (d2 )... )
349
- d2SupportsMetro , d2MetroMap := dRPolicySupportsMetro (d2 , drclusters .Items )
350
-
345
+ d2SupportsMetro , d2MetroClusters := dRPolicySupportsMetro (d2 , drclusters .Items , drClusterIDsToNames )
351
346
commonClusters := d1ClusterNames .Intersection (d2ClusterNames )
352
- commonClusterIDs := d1ClusterIDs .Intersection (d2ClusterIDs )
353
347
354
348
// No common managed clusters, so we are good
355
- if commonClusterIDs . Len () == 0 && commonClusters .Len () == 0 {
349
+ if commonClusters .Len () == 0 {
356
350
return false
357
351
}
358
352
359
353
// Lets check if the metro clusters in DRPolicy d2 belong to common managed clusters list
360
354
if d2SupportsMetro {
361
- return hasOverlapWithMetro (d2MetroMap ,
362
- commonClusterIDs .List (),
363
- commonClusters .List ())
355
+ for _ , v := range d2MetroClusters {
356
+ if sets .NewString (v ... ).HasAny (commonClusters .List ()... ) {
357
+ return true
358
+ }
359
+ }
364
360
}
365
361
366
362
// Lets check if the metro clusters in DRPolicy d1 belong to common managed clusters list
367
363
if d1SupportsMetro {
368
- return hasOverlapWithMetro (d1MetroMap ,
369
- commonClusterIDs .List (),
370
- commonClusters .List ())
364
+ for _ , v := range d1MetroClusters {
365
+ if sets .NewString (v ... ).HasAny (commonClusters .List ()... ) {
366
+ return true
367
+ }
368
+ }
371
369
}
372
370
373
371
return false
@@ -407,7 +405,7 @@ func (u *drpolicyUpdater) deleteDRPolicy(drclusters *ramen.DRClusterList,
407
405
}
408
406
409
407
// proceed to delete metrics if non-metro-dr
410
- isMetro , _ := dRPolicySupportsMetro (u .object , drclusters .Items )
408
+ isMetro , _ := dRPolicySupportsMetro (u .object , drclusters .Items , nil )
411
409
if ! isMetro {
412
410
// delete metrics if matching labels are found
413
411
metricLabels := DRPolicySyncIntervalMetricLabels (u .object )
0 commit comments