@@ -622,8 +622,103 @@ func (d *Driver) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequ
622
622
return nil , status .Error (codes .Unimplemented , "" )
623
623
}
624
624
625
- // ListSnapshots is part of implementing Snapshot & Restore functionality, but we don't support that
626
- func (d * Driver ) ListSnapshots (context.Context , * csi.ListSnapshotsRequest ) (* csi.ListSnapshotsResponse , error ) {
625
+ // ListSnapshots retrieves a list of existing snapshots as part of the Snapshot & Restore functionality.
626
+ func (d * Driver ) ListSnapshots (ctx context.Context , req * csi.ListSnapshotsRequest ) (* csi.ListSnapshotsResponse , error ) {
627
+ log .Info ().Msg ("Request: ListSnapshots" )
628
+
629
+ snapshotID := req .GetSnapshotId ()
630
+ sourceVolumeID := req .GetSourceVolumeId ()
631
+
632
+ if req .GetStartingToken () != "" {
633
+ log .Error ().
634
+ Msg ("ListSnapshots RPC received a Starting token, but pagination is not supported. Ensure the request does not include a starting token." )
635
+ return nil , status .Error (codes .Aborted , "starting-token not supported" )
636
+ }
637
+
638
+ // case 1: SnapshotId is not empty, return snapshots that match the snapshot id
639
+ if len (snapshotID ) != 0 {
640
+ log .Debug ().
641
+ Str ("snapshot_id" , snapshotID ).
642
+ Msg ("Fetching snapshot" )
643
+
644
+ // Retrieve a specific snapshot by ID
645
+ // Todo: GetSnapshot to be implemented in civogo
646
+ // Todo: Un-comment post client implementation
647
+ // snapshot, err := d.CivoClient.GetSnapshot(snapshotID)
648
+ // if err != nil {
649
+ // Todo: DatabaseSnapshotNotFoundError & DiskSnapshotNotFoundError are placeholders, it's still not clear what error will be returned by API (awaiting implementation - WIP)
650
+ // if strings.Contains(err.Error(), "DatabaseSnapshotNotFoundError") ||
651
+ // strings.Contains(err.Error(), "DiskSnapshotNotFoundError") {
652
+ // log.Info().
653
+ // Str("snapshot_id", snapshotID).
654
+ // Msg("ListSnapshots: no snapshot found, returning with success")
655
+ // return &csi.ListSnapshotsResponse{}, nil
656
+ // }
657
+ // log.Error().
658
+ // Err(err).
659
+ // Str("snapshot_id", snapshotID).
660
+ // Msg("Failed to list snapshot from Civo API")
661
+ // return nil, status.Errorf(codes.Internal, "failed to list snapshot %q: %v", snapshotID, err)
662
+ // }
663
+ // return &csi.ListSnapshotsResponse{
664
+ // Entries: []*csi.ListSnapshotsResponse_Entry{convertSnapshot(snapshot)},
665
+ // }, nil
666
+ }
667
+
668
+ // case 2: Retrieve snapshots by source volume ID
669
+ if len (sourceVolumeID ) != 0 {
670
+ log .Debug ().
671
+ Str ("operation" , "list_snapshots" ).
672
+ Str ("source_volume_id" , sourceVolumeID ).
673
+ Msg ("Fetching volume snapshots" )
674
+
675
+ // snapshots, err := d.CivoClient.ListSnapshots() // Todo: ListSnapshots to be implemented in civogo
676
+ // if err != nil{
677
+ // log.Error().
678
+ // Err(err).
679
+ // Str("source_volume_id", sourceVolumeID).
680
+ // Msg("Failed to list snapshots for volume")
681
+ // return nil, status.Errorf(codes.Internal, "failed to list snapshots for volume %q: %v", sourceVolumeID, err)
682
+ // }
683
+
684
+ // entries := []*csi.ListSnapshotsResponse_Entry{}
685
+ // for _, snapshot := range snapshots {
686
+ // if snapshot.VolID == sourceVolumeID {
687
+ // entries = append(entries, convertSnapshot(snapshot))
688
+ // }
689
+ // }
690
+
691
+ // return &csi.ListSnapshotsResponse{
692
+ // Entries: entries,
693
+ // }, nil
694
+ }
695
+
696
+ log .Debug ().Msg ("Fetching all snapshots" )
697
+
698
+ // case 3: Retrieve all snapshots if no filters are provided
699
+ // Todo: un-comment post client(civogo) implementation
700
+ // snapshots, err := d.CivoClient.ListSnapshots() // Todo: ListSnapshots to be implemented in civogo
701
+ // if err != nil{
702
+ // log.Error().Err(err).Msg("Failed to list snapshots from Civo API")
703
+ // return nil, status.Errorf(codes.Internal, "failed to list snapshots from Civo API: %v", err)
704
+ // }
705
+
706
+ // sort.Slice(snapshots, func(i, j int) bool {
707
+ // return snapshots[i].Id < snapshots[j].Id
708
+ // })
709
+
710
+ // entries := []*csi.ListSnapshotsResponse_Entry{}
711
+ // for _, snap := range snapshots {
712
+ // entries = append(entries, convertSnapshot(snap))
713
+ // }
714
+
715
+ // log.Info().
716
+ // Int("total_snapshots", len(entries)).
717
+ // Msg("Snapshots listed successfully")
718
+
719
+ // return &csi.ListSnapshotsResponse{
720
+ // Entries: entries,
721
+ // }, nil
627
722
return nil , status .Error (codes .Unimplemented , "" )
628
723
}
629
724
@@ -640,3 +735,18 @@ func getVolSizeInBytes(capRange *csi.CapacityRange) (int64, error) {
640
735
641
736
return bytes , nil
642
737
}
738
+
739
+ // Todo: Un-comment post client implementation is complete
740
+ // Todo: Snapshot to be defined in civogo
741
+ // convertSnapshot function converts a civogo.Snapshot object(API response) into a CSI ListSnapshotsResponse_Entry
742
+ // func convertSnapshot(snap *civogo.Snapshot) *csi.ListSnapshotsResponse_Entry {
743
+ // return &csi.ListSnapshotsResponse_Entry{
744
+ // Snapshot: &csi.Snapshot{
745
+ // SnapshotId: snap.Id,
746
+ // SourceVolumeId: snap.VolID,
747
+ // CreationTime: snap.CreationTime,
748
+ // SizeBytes: snap.SizeBytes,
749
+ // ReadyToUse: snap.ReadyToUse,
750
+ // },
751
+ // }
752
+ // }
0 commit comments