Skip to content

Commit 1bc6ea8

Browse files
authored
validate CNSRegistreVolume to disallow registering volume not accessible to active clusters on namespace (#3436)
1 parent e338da4 commit 1bc6ea8

File tree

2 files changed

+578
-12
lines changed

2 files changed

+578
-12
lines changed

pkg/syncer/cnsoperator/controller/cnsregistervolume/cnsregistervolume_controller.go

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ var (
7676
clusterComputeResourceMoIds []string
7777
// workloadDomainIsolationEnabled determines if the workload domain
7878
// isolation feature is available on a supervisor cluster.
79-
workloadDomainIsolationEnabled bool
79+
workloadDomainIsolationEnabled bool
80+
isTKGSHAEnabled bool
81+
isMultipleClustersPerVsphereZoneEnabled bool
8082
)
8183

8284
// Add creates a new CnsRegisterVolume Controller and adds it to the Manager,
@@ -91,6 +93,9 @@ func Add(mgr manager.Manager, clusterFlavor cnstypes.CnsClusterFlavor,
9193
}
9294
workloadDomainIsolationEnabled = commonco.ContainerOrchestratorUtility.IsFSSEnabled(ctx,
9395
common.WorkloadDomainIsolation)
96+
isTKGSHAEnabled = commonco.ContainerOrchestratorUtility.IsFSSEnabled(ctx, common.TKGsHA)
97+
isMultipleClustersPerVsphereZoneEnabled = commonco.ContainerOrchestratorUtility.IsFSSEnabled(ctx,
98+
common.MultipleClustersPerVsphereZone)
9499

95100
var volumeInfoService cnsvolumeinfo.VolumeInfoService
96101
if clusterFlavor == cnstypes.CnsClusterFlavorWorkload {
@@ -202,7 +207,6 @@ type ReconcileCnsRegisterVolume struct {
202207
func (r *ReconcileCnsRegisterVolume) Reconcile(ctx context.Context,
203208
request reconcile.Request) (reconcile.Result, error) {
204209
log := logger.GetLogger(ctx)
205-
isTKGSHAEnabled := commonco.ContainerOrchestratorUtility.IsFSSEnabled(ctx, common.TKGsHA)
206210
// Fetch the CnsRegisterVolume instance.
207211
instance := &cnsregistervolumev1alpha1.CnsRegisterVolume{}
208212
err := r.client.Get(ctx, request.NamespacedName, instance)
@@ -326,17 +330,55 @@ func (r *ReconcileCnsRegisterVolume) Reconcile(ctx context.Context,
326330

327331
if syncer.IsPodVMOnStretchSupervisorFSSEnabled {
328332
if workloadDomainIsolationEnabled || len(clusterComputeResourceMoIds) > 1 {
329-
azClustersMap := topologyMgr.GetAZClustersMap(ctx)
330-
isAccessible := isDatastoreAccessibleToAZClusters(ctx, vc, azClustersMap, volume.DatastoreUrl)
331-
if !isAccessible {
332-
log.Errorf("Volume: %s present on datastore: %s is not accessible to any of the AZ clusters: %v",
333-
volumeID, volume.DatastoreUrl, azClustersMap)
334-
setInstanceError(ctx, r, instance, "Volume in the spec is not accessible to any of the AZ clusters")
335-
_, err = common.DeleteVolumeUtil(ctx, r.volumeManager, volumeID, false)
333+
if isMultipleClustersPerVsphereZoneEnabled {
334+
// Get zones assigned to the namespace
335+
zoneMaps := commonco.ContainerOrchestratorUtility.GetZonesForNamespace(request.Namespace)
336+
337+
// Convert map keys to slice
338+
zones := make([]string, 0, len(zoneMaps))
339+
for zone := range zoneMaps {
340+
zones = append(zones, zone)
341+
}
342+
// Get active clusters in the requested zones
343+
activeClusters, err := commonco.ContainerOrchestratorUtility.
344+
GetActiveClustersForNamespaceInRequestedZones(ctx, request.Namespace, zones)
336345
if err != nil {
337-
log.Errorf("Failed to untag CNS volume: %s with error: %+v", volumeID, err)
346+
msg := fmt.Sprintf("Failed to get active clusters for CnsRegisterVolume request. error: %+v", err)
347+
log.Error(msg)
348+
setInstanceError(ctx, r, instance, msg)
349+
return reconcile.Result{RequeueAfter: timeout}, nil
350+
}
351+
// Check if volume is accessible in any of the active clusters
352+
if !isDatastoreAccessibleToAZClusters(ctx, vc,
353+
map[string][]string{"dummy-zone-key": activeClusters}, volume.DatastoreUrl) {
354+
log.Errorf("Volume: %s present on datastore: %s is not accessible to any of the active "+
355+
"cluster on the namespace: %v", volumeID, volume.DatastoreUrl, activeClusters)
356+
setInstanceError(ctx, r, instance, "Volume in the spec is not accessible to any of "+
357+
"the active cluster on the namespace")
358+
359+
// Attempt volume cleanup
360+
if _, err = common.DeleteVolumeUtil(ctx, r.volumeManager, volumeID, false); err != nil {
361+
log.Errorf("Failed to untag CNS volume: %s with error: %+v", volumeID, err)
362+
return reconcile.Result{RequeueAfter: timeout}, nil
363+
}
364+
// permanent failure and not requeue.
365+
return reconcile.Result{}, nil
366+
}
367+
} else {
368+
azClustersMap := topologyMgr.GetAZClustersMap(ctx)
369+
isAccessible := isDatastoreAccessibleToAZClusters(ctx, vc, azClustersMap, volume.DatastoreUrl)
370+
if !isAccessible {
371+
log.Errorf("Volume: %s present on datastore: %s is not accessible to any of the AZ clusters: %v",
372+
volumeID, volume.DatastoreUrl, azClustersMap)
373+
setInstanceError(ctx, r, instance, "Volume in the spec is not accessible to any of the AZ clusters")
374+
_, err = common.DeleteVolumeUtil(ctx, r.volumeManager, volumeID, false)
375+
if err != nil {
376+
log.Errorf("Failed to untag CNS volume: %s with error: %+v", volumeID, err)
377+
return reconcile.Result{RequeueAfter: timeout}, nil
378+
}
379+
// permanent failure and not requeue.
380+
return reconcile.Result{}, nil
338381
}
339-
return reconcile.Result{RequeueAfter: timeout}, nil
340382
}
341383
}
342384
} else {
@@ -350,8 +392,10 @@ func (r *ReconcileCnsRegisterVolume) Reconcile(ctx context.Context,
350392
_, err = common.DeleteVolumeUtil(ctx, r.volumeManager, volumeID, false)
351393
if err != nil {
352394
log.Errorf("Failed to untag CNS volume: %s with error: %+v", volumeID, err)
395+
return reconcile.Result{RequeueAfter: timeout}, nil
353396
}
354-
return reconcile.Result{RequeueAfter: timeout}, nil
397+
// permanent failure and not requeue.
398+
return reconcile.Result{}, nil
355399
}
356400
}
357401
// Verify if storage policy is empty.

0 commit comments

Comments
 (0)