@@ -76,14 +76,14 @@ func (p *Plugin) CreateVolume(
7676
7777func checkInputParameters (params map [string ]string ) error {
7878 if params == nil {
79- return errors .New ("input parameters cannot be nil" )
79+ return errors .New ("volume creation parameters cannot be nil" )
8080 }
8181
8282 keyList := []string {ParamProfile , ParamEnableReplication , ParamSecondaryAZ , PublishAttachMode , StorageType }
8383
8484 for k , _ := range params {
8585 if ! util .Contained (k , keyList ) {
86- return fmt .Errorf ("invalid input paramter key: %s. It should be one of %s,%s,%s,%s,%s" ,
86+ return fmt .Errorf ("invalid volume creation paramter key: %s. It should be one of %s,%s,%s,%s,%s" ,
8787 k , ParamProfile , ParamEnableReplication , ParamSecondaryAZ , PublishAttachMode , StorageType )
8888 }
8989 }
@@ -148,12 +148,22 @@ func (p *Plugin) ControllerPublishVolume(ctx context.Context,
148148 return nil , status .Error (codes .InvalidArgument , msg )
149149 }
150150
151- if req .NodeId == "" {
151+ if req .GetNodeId () == "" {
152152 msg := "node ID must be provided"
153153 glog .Error (msg )
154154 return nil , status .Error (codes .InvalidArgument , msg )
155155 }
156156
157+ if req .GetVolumeCapability () == nil {
158+ msg := "volume capability must be provided"
159+ glog .Error (msg )
160+ return nil , status .Error (codes .InvalidArgument , msg )
161+ }
162+
163+ if req .GetReadonly () {
164+ return nil , status .Error (codes .AlreadyExists , "read only volumes are not supported" )
165+ }
166+
157167 glog .V (5 ).Infof ("plugin information %#v" , p )
158168 glog .V (5 ).Infof ("current storage type: %s" , p .PluginStorageType )
159169
@@ -193,11 +203,29 @@ func (p *Plugin) ControllerUnpublishVolume(
193203}
194204
195205// ValidateVolumeCapabilities implementation
196- func (p * Plugin ) ValidateVolumeCapabilities (
197- ctx context.Context ,
206+ func (p * Plugin ) ValidateVolumeCapabilities (ctx context.Context ,
198207 req * csi.ValidateVolumeCapabilitiesRequest ) (
199208 * csi.ValidateVolumeCapabilitiesResponse , error ) {
200- return nil , status .Error (codes .Unimplemented , "" )
209+
210+ volId := req .GetVolumeId ()
211+ if volId == "" {
212+ return nil , status .Error (codes .InvalidArgument , "" )
213+ }
214+
215+ if req .GetVolumeCapabilities () == nil {
216+ return nil , status .Error (codes .InvalidArgument , "" )
217+ }
218+
219+ vol , err := p .Client .GetVolume (volId )
220+ if vol == nil || err != nil {
221+ return nil , status .Error (codes .NotFound , err .Error ())
222+ }
223+
224+ return & csi.ValidateVolumeCapabilitiesResponse {
225+ Confirmed : & csi.ValidateVolumeCapabilitiesResponse_Confirmed {
226+ VolumeCapabilities : req .VolumeCapabilities ,
227+ },
228+ }, nil
201229}
202230
203231// ListVolumes implementation
@@ -296,6 +324,13 @@ func (p *Plugin) ControllerGetCapabilities(
296324 },
297325 },
298326 },
327+ & csi.ControllerServiceCapability {
328+ Type : & csi.ControllerServiceCapability_Rpc {
329+ Rpc : & csi.ControllerServiceCapability_RPC {
330+ Type : csi .ControllerServiceCapability_RPC_PUBLISH_READONLY ,
331+ },
332+ },
333+ },
299334 },
300335 }, nil
301336}
@@ -426,12 +461,17 @@ func (p *Plugin) DeleteSnapshot(
426461 glog .V (5 ).Infof ("start to delete snapshot, snapshot id: %v, delete snapshot secrets: %v!" ,
427462 req .SnapshotId , req .Secrets )
428463
429- if 0 == len (req .SnapshotId ) {
464+ snpId := req .GetSnapshotId ()
465+ if snpId == "" {
430466 return nil , status .Error (codes .InvalidArgument , "snapshot id cannot be empty" )
431467 }
432468
433- err := p .Client .DeleteVolumeSnapshot (req .SnapshotId , nil )
469+ snp , _ := p .Client .GetVolumeSnapshot (snpId )
470+ if snp == nil {
471+ return & csi.DeleteSnapshotResponse {}, nil
472+ }
434473
474+ err := p .Client .DeleteVolumeSnapshot (req .SnapshotId , nil )
435475 if nil != err {
436476 msg := fmt .Sprintf ("delete snapshot failed: %v" , err )
437477 glog .Error (msg )
@@ -488,18 +528,19 @@ func (p *Plugin) ListSnapshots(
488528 break
489529 case (0 == snapshotIDLen ) && (0 != sourceVolumeIdLen ):
490530 if len (snapshotsFilterByVolumeId ) <= 0 {
491- return nil , status . Error ( codes . NotFound , fmt . Sprintf ( "no snapshot with source volume id %s" , sourceVolumeId ))
531+ return & csi. ListSnapshotsResponse { Entries : [] * csi. ListSnapshotsResponse_Entry {}}, nil
492532 }
493533
494534 filterResult = snapshotsFilterByVolumeId
495535 break
496536 case (0 != snapshotIDLen ) && (0 == sourceVolumeIdLen ):
497537 if len (snapshotsFilterById ) <= 0 {
498- return nil , status . Error ( codes . NotFound , fmt . Sprintf ( "no snapshot with id %s" , snapshotId ))
538+ return & csi. ListSnapshotsResponse { Entries : [] * csi. ListSnapshotsResponse_Entry {}}, nil
499539 }
500540
501541 filterResult = snapshotsFilterById
502542 break
543+ case (0 != snapshotIDLen ) && (0 != sourceVolumeIdLen ):
503544 case (0 != snapshotIDLen ) && (0 != sourceVolumeIdLen ):
504545 for _ , snapshot := range snapshotsFilterById {
505546 if snapshot .VolumeId == sourceVolumeId {
@@ -687,28 +728,24 @@ func (p *Plugin) UnpublishRoutine() {
687728
688729 if err := p .Client .DeleteVolumeAttachment (act .Id , act ); err != nil {
689730 glog .Errorf ("%s failed to unpublish: %v" , act .Id , err )
690- } else {
691- waitAttachmentDeleted (act .Id , func (id string ) (interface {}, error ) {
692- return p .Client .GetVolumeAttachment (id )
693- }, e )
694731 }
695732
733+ waitAttachmentDeleted (act .Id , func (id string ) (interface {}, error ) {
734+ return p .Client .GetVolumeAttachment (id )
735+ }, e )
736+
696737 // delete fileshare access control list if storage type is file
697738 case * model.FileShareAclSpec :
698739 act := e .Value .(* model.FileShareAclSpec )
699740
700741 if err := p .Client .DeleteFileShareAcl (act .Id ); err != nil {
701- if strings .Contains (err .Error (), "Not Found" ) {
702- glog .Infof ("delete attachment %s successfully" , act .Id )
703- UnpublishAttachmentList .Delete (e )
704- } else {
705- glog .Errorf ("%s failed to unpublish: %v" , act .Id , err )
706- }
707- } else {
708- waitAttachmentDeleted (act .Id , func (id string ) (interface {}, error ) {
709- return p .Client .GetFileShareAcl (id )
710- }, e )
742+ glog .Errorf ("%s failed to unpublish: %v" , act .Id , err )
711743 }
744+
745+ waitAttachmentDeleted (act .Id , func (id string ) (interface {}, error ) {
746+ return p .Client .GetFileShareAcl (id )
747+ }, e )
748+
712749 }
713750
714751 time .Sleep (10 * time .Second )
@@ -726,16 +763,25 @@ func waitAttachmentDeleted(id string, f func(string) (interface{}, error), e *li
726763 for {
727764 select {
728765 case <- ticker .C :
729- _ , err := f (id )
730-
731- if err != nil && strings .Contains (err .Error (), "Not Found" ) {
732- glog .Infof ("delete attachment %s successfully" , id )
733- UnpublishAttachmentList .Delete (e )
734- return
735- } else {
736- glog .Errorf ("delete attachment failed: %v" , err )
766+ v , _ := f (id )
767+
768+ switch v .(type ) {
769+ case * model.VolumeAttachmentSpec :
770+ if v .(* model.VolumeAttachmentSpec ) == nil {
771+ glog .Infof ("delete attachment %s successfully" , id )
772+ UnpublishAttachmentList .Delete (e )
773+ return
774+ }
775+ case * model.FileShareAclSpec :
776+ if v .(* model.FileShareAclSpec ) == nil {
777+ glog .Infof ("delete attachment %s successfully" , id )
778+ UnpublishAttachmentList .Delete (e )
779+ return
780+ }
737781 }
738782
783+ glog .Errorf ("delete attachment %#v failed" , v )
784+
739785 case <- timeout :
740786 glog .Errorf ("waiting to delete %s timeout" , id )
741787 return
@@ -755,14 +801,14 @@ func extractISCSIInitiatorFromNodeInfo(nodeInfo string) (string, error) {
755801}
756802
757803func extractNvmeofInitiatorFromNodeInfo (nodeInfo string ) (string , error ) {
758- for _ , v := range strings .Split (nodeInfo , "," ) {
759- if strings .Contains (v , "nqn" ) {
760- glog .V (5 ).Info ("Nvmeof initiator is " , v )
761- return v , nil
762- }
763- }
764-
765- return "" , errors .New ("no Nvmeof initiators found" )
804+ for _ , v := range strings .Split (nodeInfo , "," ) {
805+ if strings .Contains (v , "nqn" ) {
806+ glog .V (5 ).Info ("Nvmeof initiator is " , v )
807+ return v , nil
808+ }
809+ }
810+
811+ return "" , errors .New ("no Nvmeof initiators found" )
766812}
767813
768814func extractFCInitiatorFromNodeInfo (nodeInfo string ) ([]string , error ) {
@@ -782,6 +828,17 @@ func extractFCInitiatorFromNodeInfo(nodeInfo string) ([]string, error) {
782828 return wwpns , nil
783829}
784830
831+ func extractIpFromNodeInfo (nodeInfo string ) (string , error ) {
832+ for _ , v := range strings .Split (nodeInfo , "," ) {
833+ ip := net .ParseIP (v )
834+ if ip != nil {
835+ return v , nil
836+ }
837+ }
838+
839+ return "" , errors .New ("cannot find valid ip address" )
840+ }
841+
785842func getZone (requirement * csi.TopologyRequirement ) string {
786843 if requirement == nil {
787844 return ""
0 commit comments