diff --git a/controllers/storagecluster/external_resources.go b/controllers/storagecluster/external_resources.go index f8bdddc176..1b78ddbd7a 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" @@ -380,6 +381,9 @@ 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"] = getTopologyConstrainedPoolsExternalMode(d.Data) } 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..622f06ed07 100644 --- a/controllers/storagecluster/storageclasses.go +++ b/controllers/storagecluster/storageclasses.go @@ -528,3 +528,39 @@ 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 { + 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"], ",") + + 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 "" + } + return string(topologyConstrainedPoolsStr) +}