Skip to content

Commit

Permalink
Remove multizone and fix preprod
Browse files Browse the repository at this point in the history
Signed-off-by: Pierre-Emmanuel Jacquier <[email protected]>
  • Loading branch information
pierre-emmanuelJ committed Jan 25, 2024
1 parent fd62922 commit 7e8864a
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 95 deletions.
3 changes: 3 additions & 0 deletions cmd/exoscale-csi-driver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"os"

v3 "github.com/exoscale/egoscale/v3"
"github.com/exoscale/exoscale-csi-driver/cmd/exoscale-csi-driver/buildinfo"
"github.com/exoscale/exoscale-csi-driver/driver"

Expand Down Expand Up @@ -42,6 +43,7 @@ func main() {

apiKey := os.Getenv("EXOSCALE_API_KEY")
apiSecret := os.Getenv("EXOSCALE_API_SECRET")
apiURL := os.Getenv("EXOSCALE_API_URL")

// The node mode don't need secrets and do not interact with Exoscale API.
if *mode != string(driver.NodeMode) && (apiKey == "" || apiSecret == "") {
Expand All @@ -54,6 +56,7 @@ func main() {
Prefix: *prefix,
APIKey: apiKey,
APISecret: apiSecret,
Zone: v3.URL(apiURL),
})
if err != nil {
klog.Error(err)
Expand Down
100 changes: 43 additions & 57 deletions driver/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,33 +69,31 @@ var (

exoscaleVolumeID = DriverName + "/volume-id"
exoscaleVolumeName = DriverName + "/volume-name"
exoscaleVolumeZone = DriverName + "/volume-zone"
)

const (
MinimalVolumeSizeBytes = 100 * 1024 * 1024 * 1024
)

type controllerService struct {
client *v3.Client
zone v3.URL
client *v3.Client
zone v3.URL
zoneName string
}

func newControllerService(client *v3.Client, nodeMeta *nodeMetadata) controllerService {
return controllerService{
client: client,
zone: nodeMeta.zone,
client: client,
zone: nodeMeta.zone,
zoneName: nodeMeta.zoneName,
}
}

// CreateVolume creates a new volume from CreateVolumeRequest with blockstorage ProvisionVolume.
// This function is idempotent.
func (d *controllerService) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequest) (*csi.CreateVolumeResponse, error) {
klog.V(4).Infof("CreateVolume")
// TODO(multizone cluster) use req.AccessibilityRequirements,
// To create block storage volume in the right zone.

// TODO(multizone cluster) fetch all zone
volumes, err := d.client.ListBlockStorageVolumes(ctx)
if err != nil {
klog.Errorf("create block storage volume list: %v", err)
Expand All @@ -107,10 +105,10 @@ func (d *controllerService) CreateVolume(ctx context.Context, req *csi.CreateVol
if v.Name == req.Name {
return &csi.CreateVolumeResponse{
Volume: &csi.Volume{
VolumeId: exoscaleID(d.zone, v.ID),
VolumeId: v.ID.String(),
// API reply in bytes then send it without conversion
CapacityBytes: v.Size,
AccessibleTopology: newZoneTopology(d.zone),
AccessibleTopology: newZoneTopology(d.zoneName),
},
}, nil
}
Expand All @@ -127,14 +125,13 @@ func (d *controllerService) CreateVolume(ctx context.Context, req *csi.CreateVol
if srcSnapshot == nil {
return nil, status.Error(codes.Internal, "error retrieving snapshot from the volumeContentSource")
}
zone, snapshotID, err := getExoscaleID(srcSnapshot.SnapshotId)
snapshotID, err := v3.ParseUUID(srcSnapshot.SnapshotId)
if err != nil {
klog.Errorf("create volume from snapshot: %v", err)
return nil, err
}
client := d.client.WithURL(zone)

snapshot, err := client.GetBlockStorageSnapshot(ctx, snapshotID)
snapshot, err := d.client.GetBlockStorageSnapshot(ctx, snapshotID)
if err != nil {
if errors.Is(err, v3.ErrNotFound) {
klog.Errorf("create volume get snapshot not found: %v", err)
Expand Down Expand Up @@ -182,9 +179,9 @@ func (d *controllerService) CreateVolume(ctx context.Context, req *csi.CreateVol

return &csi.CreateVolumeResponse{
Volume: &csi.Volume{
VolumeId: exoscaleID(d.zone, opDone.Reference.ID),
VolumeId: opDone.Reference.ID.String(),
CapacityBytes: sizeInBytes,
AccessibleTopology: newZoneTopology(d.zone),
AccessibleTopology: newZoneTopology(d.zoneName),
ContentSource: req.GetVolumeContentSource(),
},
}, nil
Expand All @@ -195,14 +192,13 @@ func (d *controllerService) CreateVolume(ctx context.Context, req *csi.CreateVol
func (d *controllerService) DeleteVolume(ctx context.Context, req *csi.DeleteVolumeRequest) (*csi.DeleteVolumeResponse, error) {
klog.V(4).Infof("DeleteVolume")

zone, volumeID, err := getExoscaleID(req.VolumeId)
volumeID, err := v3.ParseUUID(req.VolumeId)
if err != nil {
klog.Errorf("parse exoscale volume ID %s: %v", req.VolumeId, err)
return nil, err
}
client := d.client.WithURL(zone)

op, err := client.DeleteBlockStorageVolume(ctx, volumeID)
op, err := d.client.DeleteBlockStorageVolume(ctx, volumeID)
if err != nil {
if errors.Is(err, v3.ErrNotFound) {
return &csi.DeleteVolumeResponse{}, nil
Expand All @@ -226,20 +222,19 @@ func (d *controllerService) DeleteVolume(ctx context.Context, req *csi.DeleteVol
func (d *controllerService) ControllerPublishVolume(ctx context.Context, req *csi.ControllerPublishVolumeRequest) (*csi.ControllerPublishVolumeResponse, error) {
klog.V(4).Infof("ControllerPublishVolume")

zone, instanceID, err := getExoscaleID(req.NodeId)
instanceID, err := v3.ParseUUID(req.NodeId)
if err != nil {
klog.Errorf("parse node ID %s: %v", req.NodeId, err)
return nil, err
}
client := d.client.WithURL(zone)

_, volumeID, err := getExoscaleID(req.VolumeId)
volumeID, err := v3.ParseUUID(req.VolumeId)
if err != nil {
klog.Errorf("parse exoscale volume ID %s: %v", req.VolumeId, err)
return nil, err
}

volume, err := client.GetBlockStorageVolume(ctx, volumeID)
volume, err := d.client.GetBlockStorageVolume(ctx, volumeID)
if err != nil {
if errors.Is(err, v3.ErrNotFound) {
return nil, status.Errorf(codes.NotFound, "volume %s not found", volumeID)
Expand All @@ -255,13 +250,12 @@ func (d *controllerService) ControllerPublishVolume(ctx context.Context, req *cs
PublishContext: map[string]string{
exoscaleVolumeName: volume.Name,
exoscaleVolumeID: volume.ID.String(),
exoscaleVolumeZone: string(zone),
},
}, nil
}
}

op, err := client.AttachBlockStorageVolumeToInstance(ctx, volumeID, v3.AttachBlockStorageVolumeToInstanceRequest{
op, err := d.client.AttachBlockStorageVolumeToInstance(ctx, volumeID, v3.AttachBlockStorageVolumeToInstanceRequest{
Instance: &v3.InstanceTarget{
ID: instanceID,
},
Expand All @@ -271,7 +265,7 @@ func (d *controllerService) ControllerPublishVolume(ctx context.Context, req *cs
return nil, err
}

_, err = client.Wait(ctx, op, v3.OperationStateSuccess)
_, err = d.client.Wait(ctx, op, v3.OperationStateSuccess)
if err != nil {
klog.Errorf("wait attach block storage volume %s to instance %s: %v", volumeID, instanceID, err)
return nil, err
Expand All @@ -281,7 +275,6 @@ func (d *controllerService) ControllerPublishVolume(ctx context.Context, req *cs
PublishContext: map[string]string{
exoscaleVolumeName: volume.Name,
exoscaleVolumeID: volume.ID.String(),
exoscaleVolumeZone: string(zone),
},
}, nil
}
Expand All @@ -292,14 +285,13 @@ func (d *controllerService) ControllerPublishVolume(ctx context.Context, req *cs
func (d *controllerService) ControllerUnpublishVolume(ctx context.Context, req *csi.ControllerUnpublishVolumeRequest) (*csi.ControllerUnpublishVolumeResponse, error) {
klog.V(4).Infof("ControllerUnpublishVolume")

zone, volumeID, err := getExoscaleID(req.VolumeId)
volumeID, err := v3.ParseUUID(req.VolumeId)
if err != nil {
klog.Errorf("parse exoscale volume ID %s: %v", req.VolumeId, err)
return nil, err
}
client := d.client.WithURL(zone)

op, err := client.DetachBlockStorageVolume(ctx, volumeID)
op, err := d.client.DetachBlockStorageVolume(ctx, volumeID)
if err != nil {
if errors.Is(err, v3.ErrNotFound) ||
(errors.Is(err, v3.ErrInvalidRequest) && strings.Contains(err.Error(), "Volume not attached")) {
Expand All @@ -325,14 +317,13 @@ func (d *controllerService) ControllerUnpublishVolume(ctx context.Context, req *
// This operation MUST be idempotent.
func (d *controllerService) ValidateVolumeCapabilities(ctx context.Context, req *csi.ValidateVolumeCapabilitiesRequest) (*csi.ValidateVolumeCapabilitiesResponse, error) {
klog.V(4).Infof("ValidateVolumeCapabilities")
zone, volumeID, err := getExoscaleID(req.VolumeId)
volumeID, err := v3.ParseUUID(req.VolumeId)
if err != nil {
klog.Errorf("parse exoscale ID %s: %v", req.VolumeId, err)
return nil, err
}
client := d.client.WithURL(zone)

_, err = client.GetBlockStorageVolume(ctx, volumeID)
_, err = d.client.GetBlockStorageVolume(ctx, volumeID)
if err != nil {
klog.Errorf("get block storage volume %s: %v", volumeID, err)
return nil, err
Expand Down Expand Up @@ -373,7 +364,6 @@ func (d *controllerService) ListVolumes(ctx context.Context, req *csi.ListVolume
}
}

// TODO(multizone cluster) list in all zones.
volumesResp, err := d.client.ListBlockStorageVolumes(ctx)
if err != nil {
klog.Errorf("list block storage volumes: %v", err)
Expand Down Expand Up @@ -402,15 +392,15 @@ func (d *controllerService) ListVolumes(ctx context.Context, req *csi.ListVolume
for _, v := range volumes {
var instancesID []string
if v.Instance != nil && v.Instance.ID != "" {
instancesID = append(instancesID, exoscaleID(d.zone, v.Instance.ID))
instancesID = append(instancesID, v.Instance.ID.String())
}

volumesEntries = append(volumesEntries, &csi.ListVolumesResponse_Entry{
Volume: &csi.Volume{
VolumeId: exoscaleID(d.zone, v.ID),
VolumeId: v.ID.String(),
// API reply in bytes then send it without conversion
CapacityBytes: v.Size,
AccessibleTopology: newZoneTopology(d.zone),
AccessibleTopology: newZoneTopology(d.zoneName),
},
Status: &csi.ListVolumesResponse_VolumeStatus{
PublishedNodeIds: instancesID,
Expand Down Expand Up @@ -451,29 +441,28 @@ func (d *controllerService) ControllerGetCapabilities(ctx context.Context, req *
func (d *controllerService) CreateSnapshot(ctx context.Context, req *csi.CreateSnapshotRequest) (*csi.CreateSnapshotResponse, error) {
klog.V(4).Infof("CreateSnapshot")

zone, volumeID, err := getExoscaleID(req.SourceVolumeId)
volumeID, err := v3.ParseUUID(req.SourceVolumeId)
if err != nil {
klog.Errorf("parse exoscale ID %s: %v", req.SourceVolumeId, err)
return nil, err
}
client := d.client.WithURL(zone)

volume, err := client.GetBlockStorageVolume(ctx, volumeID)
volume, err := d.client.GetBlockStorageVolume(ctx, volumeID)
if err != nil {
klog.Errorf("create snapshot get volume %s: %v", volumeID, err)
}

for _, s := range volume.BlockStorageSnapshots {
snapshot, err := client.GetBlockStorageSnapshot(ctx, s.ID)
snapshot, err := d.client.GetBlockStorageSnapshot(ctx, s.ID)
if err != nil {
klog.Errorf("create snapshot get snapshot %s: %v", s.ID, err)
}

if snapshot.Name == req.Name {
return &csi.CreateSnapshotResponse{
Snapshot: &csi.Snapshot{
SnapshotId: exoscaleID(zone, snapshot.ID),
SourceVolumeId: exoscaleID(zone, volume.ID),
SnapshotId: snapshot.ID.String(),
SourceVolumeId: volume.ID.String(),
CreationTime: timestamppb.New(snapshot.CreatedAT),
ReadyToUse: true,
SizeBytes: volume.Size,
Expand All @@ -482,7 +471,7 @@ func (d *controllerService) CreateSnapshot(ctx context.Context, req *csi.CreateS
}
}

op, err := client.CreateBlockStorageSnapshot(ctx, volume.ID, v3.CreateBlockStorageSnapshotRequest{
op, err := d.client.CreateBlockStorageSnapshot(ctx, volume.ID, v3.CreateBlockStorageSnapshotRequest{
Name: req.Name,
})
if err != nil {
Expand Down Expand Up @@ -510,8 +499,8 @@ func (d *controllerService) CreateSnapshot(ctx context.Context, req *csi.CreateS

return &csi.CreateSnapshotResponse{
Snapshot: &csi.Snapshot{
SnapshotId: exoscaleID(zone, snapshot.ID),
SourceVolumeId: exoscaleID(zone, volume.ID),
SnapshotId: snapshot.ID.String(),
SourceVolumeId: volume.ID.String(),
CreationTime: timestamppb.New(snapshot.CreatedAT),
ReadyToUse: true,
SizeBytes: volume.Size,
Expand All @@ -523,22 +512,21 @@ func (d *controllerService) CreateSnapshot(ctx context.Context, req *csi.CreateS
func (d *controllerService) DeleteSnapshot(ctx context.Context, req *csi.DeleteSnapshotRequest) (*csi.DeleteSnapshotResponse, error) {
klog.V(4).Infof("DeleteSnapshot")

zone, snapshotID, err := getExoscaleID(req.SnapshotId)
snapshotID, err := v3.ParseUUID(req.SnapshotId)
if err != nil {
klog.Errorf("parse exoscale snapshot ID %s: %v", req.SnapshotId, err)
return nil, err
}
client := d.client.WithURL(zone)

op, err := client.DeleteBlockStorageSnapshot(ctx, snapshotID)
op, err := d.client.DeleteBlockStorageSnapshot(ctx, snapshotID)
if err != nil {
if errors.Is(err, v3.ErrNotFound) {
return &csi.DeleteSnapshotResponse{}, nil
}
return nil, err
}

if _, err := client.Wait(ctx, op, v3.OperationStateSuccess); err != nil {
if _, err := d.client.Wait(ctx, op, v3.OperationStateSuccess); err != nil {
return nil, err
}

Expand All @@ -559,7 +547,6 @@ func (d *controllerService) ListSnapshots(ctx context.Context, req *csi.ListSnap
}
}

// TODO(multizone cluster) list in all zones.
snapResp, err := d.client.ListBlockStorageSnapshots(ctx)
if err != nil {
return nil, err
Expand Down Expand Up @@ -587,8 +574,8 @@ func (d *controllerService) ListSnapshots(ctx context.Context, req *csi.ListSnap
for _, s := range snapshots {
snapshotsEntries = append(snapshotsEntries, &csi.ListSnapshotsResponse_Entry{
Snapshot: &csi.Snapshot{
SourceVolumeId: exoscaleID(d.zone, s.BlockStorageVolume.ID),
SnapshotId: exoscaleID(d.zone, s.ID),
SourceVolumeId: s.BlockStorageVolume.ID.String(),
SnapshotId: s.ID.String(),
CreationTime: timestamppb.New(s.CreatedAT),
ReadyToUse: true,
// TODO SizeBytes
Expand All @@ -611,14 +598,13 @@ func (d *controllerService) ControllerExpandVolume(ctx context.Context, req *csi

// ControllerGetVolume gets a volume and return it.
func (d *controllerService) ControllerGetVolume(ctx context.Context, req *csi.ControllerGetVolumeRequest) (*csi.ControllerGetVolumeResponse, error) {
zone, volumeID, err := getExoscaleID(req.VolumeId)
volumeID, err := v3.ParseUUID(req.VolumeId)
if err != nil {
klog.Errorf("parse exoscale ID %s: %v", req.VolumeId, err)
return nil, err
}
client := d.client.WithURL(zone)

volume, err := client.GetBlockStorageVolume(ctx, volumeID)
volume, err := d.client.GetBlockStorageVolume(ctx, volumeID)
if err != nil {
if errors.Is(err, v3.ErrNotFound) {
return nil, status.Errorf(codes.NotFound, "volume %s not found", volumeID)
Expand All @@ -630,12 +616,12 @@ func (d *controllerService) ControllerGetVolume(ctx context.Context, req *csi.Co

var instancesID []string
if volume.Instance != nil && volume.Instance.ID != "" {
instancesID = append(instancesID, exoscaleID(d.zone, volume.Instance.ID))
instancesID = append(instancesID, volume.Instance.ID.String())
}

return &csi.ControllerGetVolumeResponse{
Volume: &csi.Volume{
VolumeId: exoscaleID(zone, volume.ID),
VolumeId: volume.ID.String(),
// API reply in bytes then send it without conversion
CapacityBytes: volume.Size,
},
Expand Down
Loading

0 comments on commit 7e8864a

Please sign in to comment.