From 64e288d49410a687b4f6e03d2802522fd338d354 Mon Sep 17 00:00:00 2001 From: Malay Kumar Parida Date: Thu, 7 Mar 2024 18:59:14 +0530 Subject: [PATCH] Create replica-1 sc for external mode if topology details are provided In external mode if topology details are provided then create a storageClass for replica-1. We construct the TopologyConstrainedPools from the topology details provided in the external cluster secret. Signed-off-by: Malay Kumar Parida --- .../storagecluster/external_resources.go | 9 ++++ controllers/storagecluster/storageclasses.go | 41 +++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/controllers/storagecluster/external_resources.go b/controllers/storagecluster/external_resources.go index f8bdddc176..6bd029bc93 100644 --- a/controllers/storagecluster/external_resources.go +++ b/controllers/storagecluster/external_resources.go @@ -30,6 +30,7 @@ const ( cephFsStorageClassName = "cephfs" cephRbdStorageClassName = "ceph-rbd" cephRbdRadosNamespaceStorageClassName = "ceph-rbd-rados-namespace" + cephRbdTopologyStorageClassName = "ceph-rbd-topology" cephRgwStorageClassName = "ceph-rgw" externalCephRgwEndpointKey = "endpoint" cephRgwTLSSecretKey = "ceph-rgw-tls-cert" @@ -371,6 +372,7 @@ func (r *StorageClusterReconciler) createExternalStorageClusterResources(instanc case "StorageClass": var scc StorageClassConfiguration + var err error if d.Name == cephFsStorageClassName { scc = newCephFilesystemStorageClassConfiguration(instance) enableRookCSICephFS = true @@ -380,6 +382,13 @@ func (r *StorageClusterReconciler) createExternalStorageClusterResources(instanc scc = newCephBlockPoolStorageClassConfiguration(instance) // update the storageclass name to rados storagesclass name scc.storageClass.Name = fmt.Sprintf("%s-%s", instance.Name, d.Name) + } else if d.Name == cephRbdTopologyStorageClassName { + scc = newNonResilientCephBlockPoolStorageClassConfiguration(instance) + scc.storageClass.Parameters["topologyConstrainedPools"], err = getTopologyConstrainedPoolsExternalMode(d.Data) + if err != nil { + r.Log.Error(err, "Failed to get topologyConstrainedPools from external mode secret.", "StorageClass", klog.KRef(instance.Namespace, d.Name)) + return err + } } else if d.Name == cephRgwStorageClassName { rgwEndpoint := d.Data[externalCephRgwEndpointKey] if err := checkEndpointReachable(rgwEndpoint, 5*time.Second); err != nil { diff --git a/controllers/storagecluster/storageclasses.go b/controllers/storagecluster/storageclasses.go index aa2bc06d20..16e82d8b5c 100644 --- a/controllers/storagecluster/storageclasses.go +++ b/controllers/storagecluster/storageclasses.go @@ -528,3 +528,44 @@ func getTopologyConstrainedPools(initData *ocsv1.StorageCluster) string { } return string(topologyConstrainedPoolsStr) } + +// getTopologyConstrainedPoolsExternalMode constructs the topologyConstrainedPools string for external mode from the data map +func getTopologyConstrainedPoolsExternalMode(data map[string]string) (string, error) { + type topologySegment struct { + DomainLabel string `json:"domainLabel"` + DomainValue string `json:"value"` + } + // TopologyConstrainedPool stores the pool name and a list of its associated topology domain values. + type topologyConstrainedPool struct { + PoolName string `json:"poolName"` + DomainSegments []topologySegment `json:"domainSegments"` + } + var topologyConstrainedPools []topologyConstrainedPool + + domainLabel := data["topologyFailureDomainLabel"] + domainValues := strings.Split(data["topologyFailureDomainValues"], ",") + poolNames := strings.Split(data["topologyPools"], ",") + + // Check if the number of pool names and domain values are equal + if len(poolNames) != len(domainValues) { + return "", fmt.Errorf("number of pool names and domain values are not equal") + } + + for i, poolName := range poolNames { + topologyConstrainedPools = append(topologyConstrainedPools, topologyConstrainedPool{ + PoolName: poolName, + DomainSegments: []topologySegment{ + { + DomainLabel: domainLabel, + DomainValue: domainValues[i], + }, + }, + }) + } + // returning as string as parameters are of type map[string]string + topologyConstrainedPoolsStr, err := json.MarshalIndent(topologyConstrainedPools, "", " ") + if err != nil { + return "", err + } + return string(topologyConstrainedPoolsStr), nil +}