@@ -80,14 +80,17 @@ func (cs *ControllerServer) validateVolumeReq(ctx context.Context, req *csi.Crea
8080 }
8181 options := req .GetParameters ()
8282 if value , ok := options ["clusterID" ]; ! ok || value == "" {
83- return status .Error (codes .InvalidArgument , "empty cluster ID to provision volume from" )
83+ if _ , ok := options ["clusterTopologyConfigMap" ]; ! ok {
84+ return status .Error (codes .InvalidArgument , "empty cluster ID to provision volume from" )
85+ }
8486 }
8587 poolValue , poolOK := options ["pool" ]
8688 topologyConstrainedPoolsValue , topologyOK := options ["topologyConstrainedPools" ]
89+ _ , clusterTopologyOK := options ["clusterTopologyConfigMap" ]
8790 if ! poolOK {
8891 if topologyOK && topologyConstrainedPoolsValue == "" {
8992 return status .Error (codes .InvalidArgument , "empty pool name or topologyConstrainedPools to provision volume" )
90- } else if ! topologyOK {
93+ } else if ! topologyOK && ! clusterTopologyOK {
9194 return status .Error (codes .InvalidArgument , "missing or empty pool name to provision volume from" )
9295 }
9396 } else if poolValue == "" {
@@ -154,7 +157,6 @@ func validateStriping(parameters map[string]string) error {
154157func (cs * ControllerServer ) parseVolCreateRequest (
155158 ctx context.Context ,
156159 req * csi.CreateVolumeRequest ,
157- cr * util.Credentials ,
158160) (* rbdVolume , error ) {
159161 // TODO (sbezverk) Last check for not exceeding total storage capacity
160162
@@ -229,17 +231,22 @@ func (cs *ControllerServer) parseVolCreateRequest(
229231 return nil , status .Error (codes .InvalidArgument , err .Error ())
230232 }
231233
234+ // store cluster topology information from the request if present
235+ rbdVol .ClusterTopologies , _ , err = util .GetClusterTopologiesFromRequest (req )
236+ if err != nil {
237+ return nil , status .Error (codes .InvalidArgument , err .Error ())
238+ }
239+
232240 // parse QOS parameters from mutable parameters
233241 err = rbdVol .SetQOS (ctx , req .GetMutableParameters ())
234242 if err != nil {
235243 return nil , status .Error (codes .InvalidArgument , err .Error ())
236244 }
237245
238- err = rbdVol .Connect (cr )
246+ // Get QosParameters from SC if qos configuration existing in SC
247+ err = rbdVol .SetQOS (ctx , req .GetParameters ())
239248 if err != nil {
240- log .ErrorLog (ctx , "failed to connect to volume %v: %v" , rbdVol .RbdImageName , err )
241-
242- return nil , status .Error (codes .Internal , err .Error ())
249+ return nil , status .Error (codes .InvalidArgument , err .Error ())
243250 }
244251
245252 // NOTE: rbdVol does not contain VolID and RbdImageName populated, everything
@@ -277,6 +284,10 @@ func (rbdVol *rbdVolume) ToCSI(ctx context.Context) (*csi.Volume, error) {
277284 vol .VolumeContext ["dataPool" ] = rbdVol .DataPool
278285 }
279286
287+ if rbdVol .ClusterSecretName != "" {
288+ vol .VolumeContext ["clusterSecretName" ] = rbdVol .ClusterSecretName
289+ }
290+
280291 if rbdVol .Topology != nil {
281292 vol .AccessibleTopology = []* csi.Topology {
282293 {
@@ -363,19 +374,48 @@ func (cs *ControllerServer) CreateVolume(
363374 return nil , err
364375 }
365376
377+ rbdVol , err := cs .parseVolCreateRequest (ctx , req )
378+ if err != nil {
379+ return nil , err
380+ }
381+ defer rbdVol .Destroy (ctx )
382+
383+ selectedCluster := util.ClusterTopology {}
384+ if rbdVol .ClusterTopologies != nil {
385+ selectedCluster , _ , err = util .FindClusterAndTopology (rbdVol .ClusterTopologies , rbdVol .TopologyRequirement )
386+ if err != nil {
387+ return nil , status .Error (codes .InvalidArgument , err .Error ())
388+ }
389+ if selectedCluster .ClusterID == "" {
390+ return nil , status .Error (codes .InvalidArgument , "no matching cluster found for provided topology requirements" )
391+ }
392+ // persist selected secret for volume context
393+ rbdVol .ClusterSecretName = selectedCluster .SecretName
394+ }
395+
396+ secrets := req .GetSecrets ()
397+ if len (secrets ) == 0 && selectedCluster .SecretName != "" {
398+ namespace , nsErr := util .GetPodNamespace ()
399+ if nsErr != nil {
400+ return nil , status .Error (codes .InvalidArgument , nsErr .Error ())
401+ }
402+ secrets , err = k8s .GetSecret (selectedCluster .SecretName , namespace )
403+ if err != nil {
404+ return nil , status .Error (codes .InvalidArgument , err .Error ())
405+ }
406+ }
407+ if len (secrets ) == 0 {
408+ return nil , status .Error (codes .InvalidArgument , "missing credentials for provisioning" )
409+ }
410+
366411 // TODO: create/get a connection from the ConnPool, and do not pass the
367412 // credentials to any of the utility functions.
368413
369- cr , err := util .NewUserCredentialsWithMigration (req . GetSecrets () )
414+ cr , err := util .NewUserCredentialsWithMigration (secrets )
370415 if err != nil {
371416 return nil , status .Error (codes .InvalidArgument , err .Error ())
372417 }
373418 defer cr .DeleteCredentials ()
374- rbdVol , err := cs .parseVolCreateRequest (ctx , req , cr )
375- if err != nil {
376- return nil , err
377- }
378- defer rbdVol .Destroy (ctx )
379419 // Existence and conflict checks
380420 if acquired := cs .VolumeLocks .TryAcquire (req .GetName ()); ! acquired {
381421 log .ErrorLog (ctx , util .VolumeOperationAlreadyExistsFmt , req .GetName ())
@@ -400,6 +440,13 @@ func (cs *ControllerServer) CreateVolume(
400440 return nil , status .Error (codes .Internal , err .Error ())
401441 }
402442
443+ err = rbdVol .Connect (cr )
444+ if err != nil {
445+ log .ErrorLog (ctx , "failed to connect to volume %v: %v" , rbdVol .RbdImageName , err )
446+
447+ return nil , status .Error (codes .Internal , err .Error ())
448+ }
449+
403450 found , err := rbdVol .Exists (ctx , parentVol )
404451 if err != nil {
405452 return nil , getGRPCErrorForCreateVolume (err )
@@ -869,8 +916,8 @@ func checkContentSource(
869916 return nil , nil , status .Error (codes .NotFound , "volume cannot be empty" )
870917 }
871918 volID := vol .GetVolumeId ()
872- if err := util . ValidateVolumeID ( volID , true ); err != nil {
873- return nil , nil , status .Error (codes .InvalidArgument , err . Error () )
919+ if volID == "" {
920+ return nil , nil , status .Errorf (codes .NotFound , "volume ID cannot be empty" )
874921 }
875922 rbdvol , err := GenVolFromVolID (ctx , volID , cr , req .GetSecrets ())
876923 if err != nil {
@@ -958,8 +1005,8 @@ func (cs *ControllerServer) DeleteVolume(
9581005
9591006 // For now the image get unconditionally deleted, but here retention policy can be checked
9601007 volumeID := req .GetVolumeId ()
961- if err := util . ValidateVolumeID ( volumeID , true ); err != nil {
962- return nil , status .Error (codes .InvalidArgument , err . Error () )
1008+ if volumeID == "" {
1009+ return nil , status .Error (codes .InvalidArgument , "empty volume ID in request" )
9631010 }
9641011
9651012 cr , err := util .NewUserCredentialsWithMigration (req .GetSecrets ())
@@ -1122,8 +1169,8 @@ func (cs *ControllerServer) ValidateVolumeCapabilities(
11221169 ctx context.Context ,
11231170 req * csi.ValidateVolumeCapabilitiesRequest ,
11241171) (* csi.ValidateVolumeCapabilitiesResponse , error ) {
1125- if err := util . ValidateVolumeID ( req .GetVolumeId (), util . IsStaticVol ( req . GetVolumeContext ())); err != nil {
1126- return nil , status .Error (codes .InvalidArgument , err . Error () )
1172+ if req .GetVolumeId () == "" {
1173+ return nil , status .Error (codes .InvalidArgument , "empty volume ID in request" )
11271174 }
11281175
11291176 if len (req .GetVolumeCapabilities ()) == 0 {
@@ -1596,8 +1643,8 @@ func (cs *ControllerServer) ControllerExpandVolume(
15961643 }
15971644
15981645 volID := req .GetVolumeId ()
1599- if err := util . ValidateVolumeID ( volID , true ); err != nil {
1600- return nil , status .Error (codes .InvalidArgument , err . Error () )
1646+ if volID == "" {
1647+ return nil , status .Error (codes .InvalidArgument , "volume ID cannot be empty" )
16011648 }
16021649
16031650 capRange := req .GetCapacityRange ()
@@ -1778,8 +1825,8 @@ func (cs *ControllerServer) ControllerUnpublishVolume(
17781825 if ! k8s .RunsOnKubernetes () {
17791826 return & csi.ControllerUnpublishVolumeResponse {}, nil
17801827 }
1781- if err := util . ValidateVolumeID ( req .GetVolumeId (), true ); err != nil {
1782- return nil , status .Error (codes .InvalidArgument , err . Error () )
1828+ if req .GetVolumeId () == "" {
1829+ return nil , status .Error (codes .InvalidArgument , "Volume ID cannot be empty" )
17831830 }
17841831
17851832 volumeId := req .GetVolumeId ()
0 commit comments