Skip to content

Commit 0a4e842

Browse files
authored
Merge pull request #36 from civo/listSnapshotRPC
feat: add ListSnapshots RPC
2 parents 5c71fef + 2b5199c commit 0a4e842

File tree

1 file changed

+112
-2
lines changed

1 file changed

+112
-2
lines changed

pkg/driver/controller_server.go

+112-2
Original file line numberDiff line numberDiff line change
@@ -622,8 +622,103 @@ func (d *Driver) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequ
622622
return nil, status.Error(codes.Unimplemented, "")
623623
}
624624

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
627722
return nil, status.Error(codes.Unimplemented, "")
628723
}
629724

@@ -640,3 +735,18 @@ func getVolSizeInBytes(capRange *csi.CapacityRange) (int64, error) {
640735

641736
return bytes, nil
642737
}
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

Comments
 (0)