Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions pkg/csi/blockstorage/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,13 +179,8 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol
}
// Only continue checking if the Snapshot is found
if !stackiterrors.IsNotFound(err) {
// TODO: Remove cloud.GetVolume() once IaaS adds the AZ field in the response of GetSnapshotByID()
snapshotVolSrc, err := cloud.GetVolume(ctx, snap.GetVolumeId())
if err != nil {
return nil, status.Errorf(codes.Internal, "Failed to retrieve the source volume of snapshot %s: %v", sourceSnapshotID, err)
}
if snapshotVolSrc.AvailabilityZone != volAvailability {
return nil, status.Errorf(codes.ResourceExhausted, "Volume must be in the same availability zone as source Snapshot. Got %s Required: %s", volAvailability, snapshotVolSrc.AvailabilityZone)
if snap.GetAvailabilityZone() != volAvailability {
return nil, status.Errorf(codes.ResourceExhausted, "Volume must be in the same availability zone as source Snapshot. Got %s Required: %s", volAvailability, snap.GetAvailabilityZone())
}
}

Expand Down Expand Up @@ -361,7 +356,7 @@ func (cs *controllerServer) ControllerPublishVolume(ctx context.Context, req *cs
return nil, status.Error(codes.InvalidArgument, "[ControllerPublishVolume] Volume capability must be provided")
}

_, err := cloud.GetVolume(ctx, volumeID)
vol, err := cloud.GetVolume(ctx, volumeID)
if err != nil {
if stackiterrors.IsNotFound(err) {
return nil, status.Errorf(codes.NotFound, "[ControllerPublishVolume] Volume %s not found", volumeID)
Expand All @@ -377,6 +372,15 @@ func (cs *controllerServer) ControllerPublishVolume(ctx context.Context, req *cs
return nil, status.Errorf(codes.Internal, "[ControllerPublishVolume] GetInstanceByID failed with error %v", err)
}

// If Volume is already mounted to target instanceID, return OK
if vol.ServerId != nil && *vol.ServerId == instanceID {
return &csi.ControllerPublishVolumeResponse{}, nil
}

if vol.GetStatus() != stackitclient.VolumeAvailableStatus {
return nil, status.Errorf(codes.Internal, "[ControllerPublishVolume] Volume %s is not in an READY state. Got:%s Want:%s", volumeID, vol.GetStatus(), stackitclient.VolumeAvailableStatus)
}

payload := iaas.AddVolumeToServerPayload{
DeleteOnTermination: new(false),
}
Expand Down
25 changes: 9 additions & 16 deletions pkg/csi/blockstorage/controllerserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,13 +298,10 @@ var _ = Describe("ControllerServer test", Ordered, func() {
}

iaasClient.EXPECT().GetSnapshot(gomock.Any(), "snapshot-id").Return(&iaas.Snapshot{
Id: new("snapshot-id"),
Status: new("AVAILABLE"),
VolumeId: "snapshot-volume-id",
}, nil)
iaasClient.EXPECT().GetVolume(gomock.Any(), "snapshot-volume-id").Return(&iaas.Volume{
Id: new("snapshot-volume-id"),
AvailabilityZone: "eu01",
Id: new("snapshot-id"),
Status: new("AVAILABLE"),
VolumeId: "snapshot-volume-id",
AvailabilityZone: new("eu01"),
}, nil)
iaasClient.EXPECT().
CreateVolume(gomock.Any(), gomock.Any()).
Expand Down Expand Up @@ -420,14 +417,10 @@ var _ = Describe("ControllerServer test", Ordered, func() {
}

iaasClient.EXPECT().GetSnapshot(gomock.Any(), "snapshot-id").Return(&iaas.Snapshot{
Id: new("snapshot-id"),
VolumeId: "volume-id",
Status: new("AVAILABLE"),
}, nil)
iaasClient.EXPECT().GetVolume(gomock.Any(), "volume-id").Return(&iaas.Volume{
Id: new("snapshot-id"),
VolumeId: "volume-id",
Status: new("AVAILABLE"),
AvailabilityZone: "eu01",
Id: new("volume-id"),
AvailabilityZone: new("eu01"),
}, nil)

_, err := fakeCs.CreateVolume(context.Background(), req)
Expand Down Expand Up @@ -667,7 +660,7 @@ var _ = Describe("ControllerServer test", Ordered, func() {
NodeId: "fake",
VolumeCapability: stdVolCap,
}
iaasClient.EXPECT().GetVolume(gomock.Any(), req.VolumeId).Return(&iaas.Volume{}, nil)
iaasClient.EXPECT().GetVolume(gomock.Any(), req.VolumeId).Return(&iaas.Volume{Status: new("AVAILABLE")}, nil)
iaasClient.EXPECT().GetServer(gomock.Any(), "fake").Return(&iaas.Server{}, nil)
iaasClient.EXPECT().AttachVolume(gomock.Any(), req.NodeId, req.VolumeId, gomock.Any()).Return(req.VolumeId, nil)
iaasClient.EXPECT().WaitDiskAttached(gomock.Any(), req.NodeId, req.VolumeId).Return(nil)
Expand All @@ -681,7 +674,7 @@ var _ = Describe("ControllerServer test", Ordered, func() {
NodeId: "fake",
VolumeCapability: stdVolCap,
}
iaasClient.EXPECT().GetVolume(gomock.Any(), req.VolumeId).Return(&iaas.Volume{}, nil)
iaasClient.EXPECT().GetVolume(gomock.Any(), req.VolumeId).Return(&iaas.Volume{Status: new("AVAILABLE")}, nil)
iaasClient.EXPECT().GetServer(gomock.Any(), req.NodeId).Return(&iaas.Server{}, nil)
iaasClient.EXPECT().AttachVolume(gomock.Any(), req.NodeId, req.VolumeId, gomock.Any()).Return("", &oapierror.GenericOpenAPIError{
StatusCode: http.StatusForbidden,
Expand Down
14 changes: 11 additions & 3 deletions pkg/csi/blockstorage/sanity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ var _ = Describe("CSI sanity test", Ordered, func() {
newBackup := &iaas.Backup{
Id: new(uuid.New().String()),
Name: new(name),
Status: new("available"),
Status: new("AVAILABLE"),
VolumeId: new(volID),
SnapshotId: new(snapshotID),
CreatedAt: new(time.Now()),
Expand Down Expand Up @@ -329,7 +329,7 @@ var _ = Describe("CSI sanity test", Ordered, func() {
return "", &oapierror.GenericOpenAPIError{StatusCode: http.StatusNotFound}
}
vol.ServerId = new(instanceID)
vol.Status = new("attached")
vol.Status = new("ATTACHED")
return *vol.Id, nil
}).AnyTimes()

Expand All @@ -343,7 +343,15 @@ var _ = Describe("CSI sanity test", Ordered, func() {
gomock.Any(), // context
gomock.Any(), // instanceID
gomock.Any(), // volumeID
).Return(nil).AnyTimes()
).DoAndReturn(func(_ context.Context, _, volumeID string) error {
vol, ok := createdVolumes[volumeID]
if !ok {
return &oapierror.GenericOpenAPIError{StatusCode: http.StatusNotFound}
}
vol.ServerId = nil
vol.Status = new("AVAILABLE")
return nil
}).AnyTimes()

iaasClient.EXPECT().WaitDiskDetached(
gomock.Any(), // context
Expand Down
2 changes: 1 addition & 1 deletion pkg/stackit/client/iaas.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const (
BackupSource VolumeSourceTypes = "backup"
)

var volumeErrorStates = [...]string{"ERROR", "ERROR_RESIZING", "ERROR_DELETING"}
var volumeErrorStates = [...]string{"ERROR", "ERROR_BACKING-UP", "ERROR_DELETING", "ERROR_RESIZING", "ERROR_RESTORING-BACKUP", "ERROR_KMS-ENCRYPTION-PARAMS"}
Comment thread
xoxys marked this conversation as resolved.

func NewIaaSClient(region, projectID string, options []sdkconfig.ConfigurationOption) (IaaSClient, error) {
apiClient, err := iaas.NewAPIClient(options...)
Expand Down