@@ -88,17 +88,20 @@ func (s *controllerService) CreateVolume(pctx lctx.Context, preq *lcsi.CreateVol
8888 return nil , err
8989 }
9090
91+ volName := preq .GetName () // get the name of the volume, always in the format of pvc-<random-uuid>
92+ volCap := preq .GetVolumeCapabilities () // get volume capabilities
93+ multiAttach := isMultiAttach (volCap ) // check if the volume is multi-attach, true if multi-attach, false otherwise
94+ zone := lsutil .ConvertVMZoneToPortalZone (pickAvailabilityZone (preq .GetAccessibilityRequirements ()))
95+
96+ llog .V (5 ).InfoS ("[INFO] - CreateVolume: zone info" , "zone" , zone )
97+
9198 // Validate volume size, if volume size is less than the default volume size of cloud provider, set it to the default volume size
92- volSizeBytes , err := s .getVolSizeBytes (preq )
99+ volumeTypeId , volSizeBytes , err := s .getVolSizeBytes (zone , preq )
93100 if err != nil {
94101 llog .ErrorS (err , "[ERROR] - CreateVolume: Failed to get volume size" )
95102 return nil , ErrFailedToValidateVolumeSize (preq .GetName (), err )
96103 }
97104
98- volName := preq .GetName () // get the name of the volume, always in the format of pvc-<random-uuid>
99- volCap := preq .GetVolumeCapabilities () // get volume capabilities
100- multiAttach := isMultiAttach (volCap ) // check if the volume is multi-attach, true if multi-attach, false otherwise
101-
102105 // check if a request is already in-flight
103106 if ok := s .inFlight .Insert (volName ); ! ok {
104107 llog .InfoS ("[INFO] - CreateVolume: Operation is already in-flight" , "volumeName" , volName , "inflightKey" , volName )
@@ -118,13 +121,11 @@ func (s *controllerService) CreateVolume(pctx lctx.Context, preq *lcsi.CreateVol
118121 }
119122 }
120123
121- cvr := NewCreateVolumeRequest ().WithDriverOptions (s .driverOptions )
124+ cvr := NewCreateVolumeRequest ().WithDriverOptions (s .driverOptions ). WithZone ( zone ). WithVolumeTypeID ( volumeTypeId )
122125 parser , _ := ljoat .GetParser ()
123126 for pk , pv := range preq .GetParameters () {
124127 llog .InfoS ("[INFO] - CreateVolume: Parsing request parameters" , "key" , pk , "value" , pv )
125128 switch lstr .ToLower (pk ) {
126- case VolumeTypeKey :
127- cvr = cvr .WithVolumeTypeID (pv )
128129 case EncryptedKey :
129130 cvr = cvr .WithEncrypted (pv )
130131 case PVCNameKey :
@@ -237,6 +238,36 @@ func (s *controllerService) CreateVolume(pctx lctx.Context, preq *lcsi.CreateVol
237238 return newCreateVolumeResponse (newVol , cvr , respCtx ), nil
238239}
239240
241+ // pickAvailabilityZone selects 1 zone given topology requirement.
242+ // if not found, empty string is returned.
243+ func pickAvailabilityZone (requirement * lcsi.TopologyRequirement ) string {
244+ if requirement == nil {
245+ return ""
246+ }
247+ for _ , topology := range requirement .GetPreferred () {
248+ zone , exists := topology .GetSegments ()[WellKnownZoneTopologyKey ]
249+ if exists {
250+ return zone
251+ }
252+
253+ zone , exists = topology .GetSegments ()[ZoneTopologyKey ]
254+ if exists {
255+ return zone
256+ }
257+ }
258+ for _ , topology := range requirement .GetRequisite () {
259+ zone , exists := topology .GetSegments ()[WellKnownZoneTopologyKey ]
260+ if exists {
261+ return zone
262+ }
263+ zone , exists = topology .GetSegments ()[ZoneTopologyKey ]
264+ if exists {
265+ return zone
266+ }
267+ }
268+ return ""
269+ }
270+
240271func (s * controllerService ) DeleteVolume (pctx lctx.Context , preq * lcsi.DeleteVolumeRequest ) (* lcsi.DeleteVolumeResponse , error ) {
241272 llog .InfoS ("[INFO] - DeleteVolume: called" , "request" , * preq )
242273
@@ -599,13 +630,19 @@ func (s *controllerService) ModifyVolumeProperties(pctx lctx.Context, preq *lvmr
599630 return nil , ErrFailedToGetVolume (volumeID )
600631 }
601632
602- if volume .VolumeTypeID == options .VolumeType {
633+ volumeTypeId , sdkErr := s .cloud .GetVolumeTypeIdByName (volume .ZoneId , options .VolumeType )
634+ if sdkErr != nil {
635+ llog .ErrorS (sdkErr .GetError (), "[ERROR] - ModifyVolumeProperties: Failed to get the volume type ID by name" , sdkErr .GetListParameters ()... )
636+ return nil , ErrFailedToGetVolume (volumeID )
637+ }
638+
639+ if volume .VolumeTypeID == options .VolumeType || volumeTypeId == volume .VolumeTypeID {
603640 llog .V (2 ).Infof ("[INFO] - ModifyVolumeProperties: Volume %s already has volume type %s" , volumeID , options .VolumeType )
604641 return & lvmrpc.ModifyVolumePropertiesResponse {}, nil
605642 }
606643
607644 llog .InfoS ("[INFO] - ModifyVolumeProperties: Modifying volume" , "volumeID" , volumeID , "newVolumeType" , options .VolumeType , "oldVolumeType" , volume .VolumeTypeID , "newSize" , volume .Size )
608- ierr := s .cloud .ModifyVolumeType (volumeID , options . VolumeType , int (volume .Size ))
645+ ierr := s .cloud .ModifyVolumeType (volumeID , volumeTypeId , int (volume .Size ))
609646 if ierr != nil {
610647 llog .ErrorS (ierr .GetError (), "ModifyVolumeProperties: failed to modify volume" , "volumeID" , volumeID )
611648 return nil , ierr .GetError ()
@@ -636,7 +673,7 @@ func (s *controllerService) getClusterID() string {
636673 return s .driverOptions .clusterID
637674}
638675
639- func (s * controllerService ) getVolSizeBytes (preq * lcsi.CreateVolumeRequest ) (volSizeBytes int64 , err error ) {
676+ func (s * controllerService ) getVolSizeBytes (zoneID string , preq * lcsi.CreateVolumeRequest ) (volumeTypeId string , volSizeBytes int64 , err error ) {
640677 // get the volume size that user provided
641678 if preq .GetCapacityRange () != nil {
642679 volSizeBytes = preq .GetCapacityRange ().GetRequiredBytes ()
@@ -648,25 +685,29 @@ func (s *controllerService) getVolSizeBytes(preq *lcsi.CreateVolumeRequest) (vol
648685 // If the user forget to specify the volume type, get the default volume type
649686 tmpVolType , sdkErr := s .cloud .GetDefaultVolumeType ()
650687 if sdkErr != nil {
651- return 0 , sdkErr .GetError ()
688+ return "" , 0 , sdkErr .GetError ()
652689 }
653690
654691 volType = tmpVolType .Id
655692 }
693+ volumeTypeId , sdkErr := s .cloud .GetVolumeTypeIdByName (zoneID , volType )
694+ if sdkErr != nil {
695+ return "" , 0 , sdkErr .GetError ()
696+ }
656697
657698 // Get the minimum volume size allowed by the volume type
658- volTypeEntity , sdkErr := s .cloud .GetVolumeTypeById (volType )
699+ volTypeEntity , sdkErr := s .cloud .GetVolumeTypeById (volumeTypeId )
659700 if sdkErr != nil {
660- return 0 , sdkErr .GetError ()
701+ return "" , 0 , sdkErr .GetError ()
661702 }
662703
663704 // Calculate the bytes that cloud provider allowing to create the volume
664705 cvs := lsutil .GiBToBytes (int64 (volTypeEntity .MinSize ))
665706 if volSizeBytes < cvs {
666- return 0 , ErrVolumeSizeTooSmall (preq .GetName (), volSizeBytes )
707+ return volumeTypeId , 0 , ErrVolumeSizeTooSmall (preq .GetName (), volSizeBytes )
667708 }
668709
669- return volSizeBytes , nil
710+ return volumeTypeId , volSizeBytes , nil
670711}
671712
672713func newCreateVolumeResponse (disk * lsentity.Volume , pcvr * CreateVolumeRequest , prespCtx map [string ]string ) * lcsi.CreateVolumeResponse {
@@ -680,12 +721,18 @@ func newCreateVolumeResponse(disk *lsentity.Volume, pcvr *CreateVolumeRequest, p
680721 },
681722 }
682723 }
724+ segments := map [string ]string {WellKnownZoneTopologyKey : lsutil .ConvertPortalZoneToVMZone (disk .ZoneId )}
683725
684726 return & lcsi.CreateVolumeResponse {
685727 Volume : & lcsi.Volume {
686728 VolumeId : disk .Id ,
687729 CapacityBytes : int64 (disk .Size * 1024 * 1024 * 1024 ),
688730 VolumeContext : prespCtx ,
731+ AccessibleTopology : []* lcsi.Topology {
732+ {
733+ Segments : segments ,
734+ },
735+ },
689736 ContentSource : vcs ,
690737 },
691738 }
0 commit comments