@@ -586,8 +586,8 @@ func (d *Driver) ControllerGetCapabilities(context.Context, *csi.ControllerGetCa
586
586
csi .ControllerServiceCapability_RPC_LIST_VOLUMES ,
587
587
csi .ControllerServiceCapability_RPC_GET_CAPACITY ,
588
588
csi .ControllerServiceCapability_RPC_EXPAND_VOLUME ,
589
- // csi.ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT, TODO: Uncomment after client implementation is complete.
590
- // csi.ControllerServiceCapability_RPC_LIST_SNAPSHOTS, TODO: Uncomment after client implementation is complete.
589
+ csi .ControllerServiceCapability_RPC_CREATE_DELETE_SNAPSHOT ,
590
+ csi .ControllerServiceCapability_RPC_LIST_SNAPSHOTS ,
591
591
}
592
592
593
593
var csc []* csi.ControllerServiceCapability
@@ -651,13 +651,16 @@ func (d *Driver) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequ
651
651
if err != nil {
652
652
return nil , status .Error (codes .Internal , fmt .Sprintf ("failed to parse creation time: %v" , err ))
653
653
}
654
+
655
+ isReady := isSnapshotReady (snapshot .State )
656
+
654
657
return & csi.CreateSnapshotResponse {
655
658
Snapshot : & csi.Snapshot {
656
659
SnapshotId : snapshot .SnapshotID ,
657
660
SourceVolumeId : snapshot .VolumeID ,
658
- CreationTime : creationTime , // TODO
659
- SizeBytes : int64 (snapshot .RestoreSize ),
660
- ReadyToUse : true , // TODO
661
+ CreationTime : creationTime ,
662
+ SizeBytes : int64 (snapshot .RestoreSize ),
663
+ ReadyToUse : isReady ,
661
664
},
662
665
}, nil
663
666
}
@@ -705,13 +708,16 @@ func (d *Driver) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequ
705
708
if err != nil {
706
709
return nil , status .Error (codes .Internal , fmt .Sprintf ("failed to parse creation time: %v" , err ))
707
710
}
711
+
712
+ isReady := isSnapshotReady (snapshot .State )
713
+
708
714
return & csi.CreateSnapshotResponse {
709
715
Snapshot : & csi.Snapshot {
710
716
SnapshotId : snapshot .SnapshotID ,
711
717
SourceVolumeId : snapshot .VolumeID ,
712
- CreationTime : creationTime , // TODO:
713
- SizeBytes : int64 (snapshot .RestoreSize ),
714
- // ReadyToUse: true, // TODO:
718
+ CreationTime : creationTime ,
719
+ SizeBytes : int64 (snapshot .RestoreSize ),
720
+ ReadyToUse : isReady ,
715
721
},
716
722
}, nil
717
723
}
@@ -768,9 +774,7 @@ func (d *Driver) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsReques
768
774
769
775
snapshot , err := d .CivoClient .GetVolumeSnapshotByVolumeID (sourceVolumeID , snapshotID )
770
776
if err != nil {
771
- // Todo: DatabaseSnapshotNotFoundError & DiskSnapshotNotFoundError are placeholders, it's still not clear what error will be returned by API (awaiting implementation - WIP)
772
- if strings .Contains (err .Error (), "DatabaseSnapshotNotFoundError" ) ||
773
- strings .Contains (err .Error (), "DiskSnapshotNotFoundError" ) {
777
+ if strings .Contains (err .Error (), "DatabaseSnapshotNotFoundError" ) {
774
778
log .Info ().
775
779
Str ("snapshot_id" , snapshotID ).
776
780
Str ("source_volume_id" , sourceVolumeID ).
@@ -784,9 +788,19 @@ func (d *Driver) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsReques
784
788
Msg ("Failed to list snapshot from Civo API" )
785
789
return nil , status .Errorf (codes .Internal , "failed to list snapshot %q: %v" , snapshotID , err )
786
790
}
791
+ entry , err := convertSnapshot (snapshot )
792
+ if err != nil {
793
+ log .Error ().
794
+ Err (err ).
795
+ Str ("SnapshotID" , snapshot .SnapshotID ).
796
+ Str ("VolumeID" , snapshot .VolumeID ).
797
+ Msg ("Failed to convert civo snapshot to CSI snapshot" )
798
+ return nil , status .Errorf (codes .Internal , "failed to convert civo snapshot to CSI snapshot %s: %v" , snapshot .SnapshotID , err )
799
+ }
800
+
787
801
return & csi.ListSnapshotsResponse {
788
802
Entries : []* csi.ListSnapshotsResponse_Entry {
789
- convertSnapshot ( snapshot ) ,
803
+ entry ,
790
804
},
791
805
}, nil
792
806
}
@@ -798,9 +812,7 @@ func (d *Driver) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsReques
798
812
799
813
snapshot , err := d .CivoClient .GetVolumeSnapshot (snapshotID )
800
814
if err != nil {
801
- // Todo: DatabaseSnapshotNotFoundError & DiskSnapshotNotFoundError are placeholders, it's still not clear what error will be returned by API (awaiting implementation - WIP)
802
- if strings .Contains (err .Error (), "DatabaseSnapshotNotFoundError" ) ||
803
- strings .Contains (err .Error (), "DiskSnapshotNotFoundError" ) {
815
+ if strings .Contains (err .Error (), "DatabaseSnapshotNotFoundError" ) {
804
816
log .Info ().
805
817
Str ("snapshot_id" , snapshotID ).
806
818
Msg ("ListSnapshots: no snapshot found, returning with success" )
@@ -812,9 +824,19 @@ func (d *Driver) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsReques
812
824
Msg ("Failed to list snapshot from Civo API" )
813
825
return nil , status .Errorf (codes .Internal , "failed to list snapshot %q: %v" , snapshotID , err )
814
826
}
827
+
828
+ entry , err := convertSnapshot (snapshot )
829
+ if err != nil {
830
+ log .Error ().
831
+ Err (err ).
832
+ Str ("SnapshotID" , snapshot .SnapshotID ).
833
+ Str ("VolumeID" , snapshot .VolumeID ).
834
+ Msg ("Failed to convert civo snapshot to CSI snapshot" )
835
+ return nil , status .Errorf (codes .Internal , "failed to convert civo snapshot to CSI snapshot %s: %v" , snapshot .SnapshotID , err )
836
+ }
815
837
return & csi.ListSnapshotsResponse {
816
838
Entries : []* csi.ListSnapshotsResponse_Entry {
817
- convertSnapshot ( snapshot ) ,
839
+ entry ,
818
840
},
819
841
}, nil
820
842
}
@@ -837,7 +859,16 @@ func (d *Driver) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsReques
837
859
entries := []* csi.ListSnapshotsResponse_Entry {}
838
860
for _ , snapshot := range snapshots {
839
861
if snapshot .VolumeID == sourceVolumeID {
840
- entries = append (entries , convertSnapshot (& snapshot ))
862
+ entry , err := convertSnapshot (& snapshot )
863
+ if err != nil {
864
+ log .Error ().
865
+ Err (err ).
866
+ Str ("SnapshotID" , snapshot .SnapshotID ).
867
+ Str ("VolumeID" , snapshot .VolumeID ).
868
+ Msg ("Failed to convert civo snapshot to CSI snapshot" )
869
+ return nil , status .Errorf (codes .Internal , "failed to convert civo snapshot to CSI snapshot %s: %v" , snapshot .SnapshotID , err )
870
+ }
871
+ entries = append (entries , entry )
841
872
}
842
873
}
843
874
sort .Slice (entries , func (i , j int ) bool {
@@ -862,8 +893,19 @@ func (d *Driver) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsReques
862
893
})
863
894
864
895
entries := []* csi.ListSnapshotsResponse_Entry {}
896
+
865
897
for _ , snap := range snapshots {
866
- entries = append (entries , convertSnapshot (& snap ))
898
+ entry , err := convertSnapshot (& snap )
899
+ if err != nil {
900
+ log .Error ().
901
+ Err (err ).
902
+ Str ("SnapshotID" , snap .SnapshotID ).
903
+ Str ("VolumeID" , snap .VolumeID ).
904
+ Msg ("Failed to convert civo snapshot to CSI snapshot" )
905
+ return nil , status .Errorf (codes .Internal , "failed to convert civo snapshot to CSI snapshot %s: %v" , snap .SnapshotID , err )
906
+ }
907
+ entries = append (entries , entry )
908
+
867
909
}
868
910
869
911
log .Info ().
@@ -890,26 +932,41 @@ func getVolSizeInBytes(capRange *csi.CapacityRange) (int64, error) {
890
932
}
891
933
892
934
// convertSnapshot function converts a civogo.Snapshot object(API response) into a CSI ListSnapshotsResponse_Entry
893
- func convertSnapshot (in * civogo.VolumeSnapshot ) * csi.ListSnapshotsResponse_Entry {
894
- // creationTime, err := ParseTimeToProtoTimestamp(in.CreationTime)
895
- // if err != nil {
896
- // return nil, status.Error(codes.Internal, fmt.Sprintf("failed to parse creation time: %v", err))
897
- // }
935
+ func convertSnapshot (in * civogo.VolumeSnapshot ) (* csi.ListSnapshotsResponse_Entry , error ) {
936
+ creationTime , err := ParseTimeToProtoTimestamp (in .CreationTime )
937
+ if err != nil {
938
+ return nil , fmt .Errorf ("failed to parse creation time for snapshot %s: %w" , in .SnapshotID , err )
939
+ }
940
+
941
+ // Explicitly define which state indicates the snapshot is ready for use
942
+ isReady := isSnapshotReady (in .State )
943
+
898
944
return & csi.ListSnapshotsResponse_Entry {
899
945
Snapshot : & csi.Snapshot {
900
946
SnapshotId : in .SnapshotID ,
901
947
SourceVolumeId : in .VolumeID ,
902
- // CreationTime: snap.CreationTime ,
903
- SizeBytes : int64 (in .RestoreSize ),
904
- // ReadyToUse: snap.ReadyToUse ,
948
+ CreationTime : creationTime ,
949
+ SizeBytes : int64 (in .RestoreSize ),
950
+ ReadyToUse : isReady ,
905
951
},
906
- }
952
+ }, nil
907
953
}
908
954
955
+ // ParseTimeToProtoTimestamp parses a time string in RFC3339 format to *timestamppb.Timestamp.
909
956
func ParseTimeToProtoTimestamp (timeStr string ) (* timestamppb.Timestamp , error ) {
910
- t , err := time .Parse (time .RFC3339 , timeStr )
911
- if err != nil {
912
- return nil , err
913
- }
914
- return timestamppb .New (t ), nil
915
- }
957
+ t , err := time .Parse (time .RFC3339 , timeStr )
958
+ if err != nil {
959
+ return nil , err
960
+ }
961
+ return timestamppb .New (t ), nil
962
+ }
963
+
964
+ // isSnapshotReady determines if a snapshot is ready for use
965
+ func isSnapshotReady (state string ) bool {
966
+ // Define the states that indicate the snapshot is ready
967
+ readyStates := map [string ]bool {
968
+ "Ready" : true ,
969
+ "Available" : true , // Add other states if applicable
970
+ }
971
+ return readyStates [state ]
972
+ }
0 commit comments