Skip to content

Commit a2b4fde

Browse files
committed
fix csi tests
1 parent e5b1277 commit a2b4fde

File tree

4 files changed

+98
-11
lines changed

4 files changed

+98
-11
lines changed

pkg/cloud/cloud.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ type Interface interface {
2626

2727
CreateVolumeFromSnapshot(ctx context.Context, zoneID, name, domainID, projectID, snapshotID string, sizeInGB int64) (*Volume, error)
2828
GetSnapshotByID(ctx context.Context, snapshotID string) (*Snapshot, error)
29+
GetSnapshotByName(ctx context.Context, name string) (*Snapshot, error)
2930
CreateSnapshot(ctx context.Context, volumeID string) (*Snapshot, error)
3031
DeleteSnapshot(ctx context.Context, snapshotID string) error
3132
}

pkg/cloud/fake/fake.go

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package fake
44

55
import (
66
"context"
7+
"fmt"
78

89
"github.com/hashicorp/go-uuid"
910

@@ -15,10 +16,11 @@ const zoneID = "a1887604-237c-4212-a9cd-94620b7880fa"
1516
const snapshotID = "9d076136-657b-4c84-b279-455da3ea484c"
1617

1718
type fakeConnector struct {
18-
node *cloud.VM
19-
snapshot *cloud.Snapshot
20-
volumesByID map[string]cloud.Volume
21-
volumesByName map[string]cloud.Volume
19+
node *cloud.VM
20+
snapshot *cloud.Snapshot
21+
volumesByID map[string]cloud.Volume
22+
volumesByName map[string]cloud.Volume
23+
snapshotsByName map[string]*cloud.Snapshot
2224
}
2325

2426
// New returns a new fake implementation of the
@@ -47,11 +49,16 @@ func New() cloud.Interface {
4749
CreatedAt: "2025-07-07T16:13:06-0700",
4850
}
4951

52+
snapshotsByName := map[string]*cloud.Snapshot{
53+
snapshot.Name: snapshot,
54+
}
55+
5056
return &fakeConnector{
51-
node: node,
52-
snapshot: snapshot,
53-
volumesByID: map[string]cloud.Volume{volume.ID: volume},
54-
volumesByName: map[string]cloud.Volume{volume.Name: volume},
57+
node: node,
58+
snapshot: snapshot,
59+
volumesByID: map[string]cloud.Volume{volume.ID: volume},
60+
volumesByName: map[string]cloud.Volume{volume.Name: volume},
61+
snapshotsByName: snapshotsByName,
5562
}
5663
}
5764

@@ -72,6 +79,9 @@ func (f *fakeConnector) ListZonesID(_ context.Context) ([]string, error) {
7279
}
7380

7481
func (f *fakeConnector) GetVolumeByID(_ context.Context, volumeID string) (*cloud.Volume, error) {
82+
if volumeID == "" {
83+
return nil, fmt.Errorf("invalid volume ID: empty string")
84+
}
7585
vol, ok := f.volumesByID[volumeID]
7686
if ok {
7787
return &vol, nil
@@ -81,6 +91,9 @@ func (f *fakeConnector) GetVolumeByID(_ context.Context, volumeID string) (*clou
8191
}
8292

8393
func (f *fakeConnector) GetVolumeByName(_ context.Context, name string) (*cloud.Volume, error) {
94+
if name == "" {
95+
return nil, fmt.Errorf("invalid volume name: empty string")
96+
}
8497
vol, ok := f.volumesByName[name]
8598
if ok {
8699
return &vol, nil
@@ -152,3 +165,13 @@ func (f *fakeConnector) CreateSnapshot(ctx context.Context, volumeID string) (*c
152165
func (f *fakeConnector) DeleteSnapshot(ctx context.Context, snapshotID string) error {
153166
return nil
154167
}
168+
169+
func (f *fakeConnector) GetSnapshotByName(_ context.Context, name string) (*cloud.Snapshot, error) {
170+
if name == "" {
171+
return nil, fmt.Errorf("invalid snapshot name: empty string")
172+
}
173+
if snap, ok := f.snapshotsByName[name]; ok {
174+
return snap, nil
175+
}
176+
return nil, cloud.ErrNotFound
177+
}

pkg/cloud/snapshots.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,40 @@ func (c *client) DeleteSnapshot(ctx context.Context, snapshotID string) error {
8181

8282
return err
8383
}
84+
85+
func (c *client) GetSnapshotByName(ctx context.Context, name string) (*Snapshot, error) {
86+
logger := klog.FromContext(ctx)
87+
if name == "" {
88+
return nil, ErrNotFound
89+
}
90+
p := c.Snapshot.NewListSnapshotsParams()
91+
p.SetName(name)
92+
if c.projectID != "" {
93+
p.SetProjectid(c.projectID)
94+
}
95+
logger.V(2).Info("CloudStack API call", "command", "ListSnapshots", "params", map[string]string{
96+
"name": name,
97+
"projectid": c.projectID,
98+
})
99+
l, err := c.Snapshot.ListSnapshots(p)
100+
if err != nil {
101+
return nil, err
102+
}
103+
if l.Count == 0 {
104+
return nil, ErrNotFound
105+
}
106+
if l.Count > 1 {
107+
return nil, ErrTooManyResults
108+
}
109+
snapshot := l.Snapshots[0]
110+
s := Snapshot{
111+
ID: snapshot.Id,
112+
Name: snapshot.Name,
113+
DomainID: snapshot.Domainid,
114+
ProjectID: snapshot.Projectid,
115+
ZoneID: snapshot.Zoneid,
116+
VolumeID: snapshot.Volumeid,
117+
CreatedAt: snapshot.Created,
118+
}
119+
return &s, nil
120+
}

pkg/driver/controller.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -328,11 +328,32 @@ func (cs *controllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol
328328
func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequest) (*csi.CreateSnapshotResponse, error) {
329329
klog.V(4).Infof("CreateSnapshot")
330330

331+
if req.GetName() == "" {
332+
return nil, status.Error(codes.InvalidArgument, "Snapshot name missing in request")
333+
}
334+
331335
volumeID := req.GetSourceVolumeId()
336+
if volumeID == "" {
337+
return nil, status.Error(codes.InvalidArgument, "SourceVolumeId missing in request")
338+
}
339+
340+
// Check for existing snapshot with same name but different source volume ID
341+
if req.GetName() != "" {
342+
// check if the name matches and volumeID differs
343+
existingSnap, err := cs.connector.GetSnapshotByName(ctx, req.GetName())
344+
if err == nil && existingSnap.VolumeID != volumeID {
345+
return nil, status.Errorf(codes.AlreadyExists, "Snapshot with name %s already exists for a different source volume", req.GetName())
346+
}
347+
}
348+
332349
volume, err := cs.connector.GetVolumeByID(ctx, volumeID)
333-
if errors.Is(err, cloud.ErrNotFound) {
334-
return nil, status.Errorf(codes.NotFound, "Volume %v not found", volumeID)
335-
} else if err != nil {
350+
if err != nil {
351+
if err.Error() == "invalid volume ID: empty string" {
352+
return nil, status.Error(codes.InvalidArgument, "Invalid volume ID")
353+
}
354+
if errors.Is(err, cloud.ErrNotFound) {
355+
return nil, status.Errorf(codes.NotFound, "Volume %v not found", volumeID)
356+
}
336357
// Error with CloudStack
337358
return nil, status.Errorf(codes.Internal, "Error %v", err)
338359
}
@@ -363,6 +384,11 @@ func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateS
363384

364385
}
365386

387+
func (cs *controllerServer) ListSnapshots(ctx context.Context, req *csi.ListSnapshotsRequest) (*csi.ListSnapshotsResponse, error) {
388+
// Stub implementation: returns an empty list
389+
return &csi.ListSnapshotsResponse{Entries: []*csi.ListSnapshotsResponse_Entry{}}, nil
390+
}
391+
366392
func (cs *controllerServer) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequest) (*csi.DeleteSnapshotResponse, error) {
367393
snapshotID := req.GetSnapshotId()
368394

0 commit comments

Comments
 (0)