diff --git a/cmd/stackit-csi-plugin/main.go b/cmd/stackit-csi-plugin/main.go index d952bd60..06933db6 100644 --- a/cmd/stackit-csi-plugin/main.go +++ b/cmd/stackit-csi-plugin/main.go @@ -24,6 +24,8 @@ var ( httpEndpoint string provideControllerService bool provideNodeService bool + legacyStorageMode bool + blockVolumeCreation bool ) func main() { @@ -72,6 +74,9 @@ func main() { "If set to true then the CSI driver does provide the controller service (default: true)") cmd.PersistentFlags().BoolVar(&provideNodeService, "provide-node-service", true, "If set to true then the CSI driver does provide the node service (default: true)") + cmd.PersistentFlags().BoolVar(&legacyStorageMode, "legacy-storage-mode", false, + "Configures the CSI to listen to the legacy storage driverName cinder.csi.openstack.org instead") + cmd.PersistentFlags().BoolVar(&blockVolumeCreation, "block-volume-creation", false, "Block volume creation") stackit.AddExtraFlags(pflag.CommandLine) @@ -81,11 +86,21 @@ func main() { func handle() { // Initialize cloud - d := blockstorage.NewDriver(&blockstorage.DriverOpts{ + driverOpts := &blockstorage.DriverOpts{ Endpoint: endpoint, ClusterID: cluster, PVCLister: csi.GetPVCLister(), - }) + } + + if legacyStorageMode { + driverOpts.LegacyDriverName = true + } + + if blockVolumeCreation { + driverOpts.BlockVolumeCreation = true + } + + d := blockstorage.NewDriver(driverOpts) if provideControllerService { var err error diff --git a/pkg/csi/blockstorage/controllerserver.go b/pkg/csi/blockstorage/controllerserver.go index 8de6237e..e71cfee2 100644 --- a/pkg/csi/blockstorage/controllerserver.go +++ b/pkg/csi/blockstorage/controllerserver.go @@ -77,6 +77,10 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol cloud := cs.Instance + if cs.Driver.blockVolumeCreation { + return nil, status.Errorf(codes.FailedPrecondition, "The %s driver is update/read-only mode please migrate to the new driver", legacyDriverName) + } + // Volume Name volName := req.GetName() volCapabilities := req.GetVolumeCapabilities() @@ -112,7 +116,11 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol accessibleTopologyReq := req.GetAccessibilityRequirements() // Check from topology if accessibleTopologyReq != nil { - volAvailability = sharedcsi.GetAZFromTopology(topologyKey, accessibleTopologyReq) + if cs.Driver.legacyDriver { + volAvailability = sharedcsi.GetAZFromTopology(legacyTopologyKey, accessibleTopologyReq) + } else { + volAvailability = sharedcsi.GetAZFromTopology(topologyKey, accessibleTopologyReq) + } } } @@ -131,7 +139,7 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol return nil, status.Error(codes.Internal, fmt.Sprintf("Volume %s is not in available state", *vols[0].Id)) } klog.V(4).Infof("Volume %s already exists in Availability Zone: %s of size %d GiB", *vols[0].Id, vols[0].AvailabilityZone, *vols[0].Size) - return getCreateVolumeResponse(&vols[0]), nil + return cs.getCreateVolumeResponse(&vols[0]), nil } else if len(vols) > 1 { klog.V(3).Infof("found multiple existing volumes with selected name (%s) during create", volName) return nil, status.Error(codes.Internal, "Multiple volumes reported by Cinder with same name") @@ -274,7 +282,7 @@ func (cs *controllerServer) CreateVolume(ctx context.Context, req *csi.CreateVol klog.V(4).Infof("CreateVolume: Successfully created volume %s in Availability Zone: %s of size %d GiB", *vol.Id, vol.AvailabilityZone, *vol.Size) - return getCreateVolumeResponse(vol), nil + return cs.getCreateVolumeResponse(vol), nil } func setVolumeEncryptionParameters(opts *iaas.CreateVolumePayload, volParams *stackitParameterConfig) error { @@ -472,6 +480,10 @@ func (cs *controllerServer) CreateSnapshot(ctx context.Context, req *csi.CreateS cloud := cs.Instance + if cs.Driver.blockVolumeCreation { + return nil, status.Errorf(codes.FailedPrecondition, "The %s driver is update/read-only mode please migrate to the new driver", legacyDriverName) + } + name := req.Name volumeID := req.GetSourceVolumeId() snapshotType := req.Parameters[stackit.SnapshotType] @@ -961,7 +973,7 @@ func (cs *controllerServer) ControllerExpandVolume(ctx context.Context, req *csi }, nil } -func getCreateVolumeResponse(vol *iaas.Volume) *csi.CreateVolumeResponse { +func (cs *controllerServer) getCreateVolumeResponse(vol *iaas.Volume) *csi.CreateVolumeResponse { var volsrc *csi.VolumeContentSource var volumeSourceType stackit.VolumeSourceTypes volCnx := map[string]string{} @@ -1002,9 +1014,14 @@ func getCreateVolumeResponse(vol *iaas.Volume) *csi.CreateVolumeResponse { } } + topoKey := topologyKey + if cs.Driver.legacyDriver { + topoKey = legacyTopologyKey + } + accessibleTopology := []*csi.Topology{ { - Segments: map[string]string{topologyKey: vol.AvailabilityZone}, + Segments: map[string]string{topoKey: vol.AvailabilityZone}, }, } diff --git a/pkg/csi/blockstorage/driver.go b/pkg/csi/blockstorage/driver.go index 56fd1818..73d92bb1 100644 --- a/pkg/csi/blockstorage/driver.go +++ b/pkg/csi/blockstorage/driver.go @@ -15,8 +15,10 @@ import ( ) const ( - driverName = "block-storage.csi.stackit.cloud" - topologyKey = "topology." + driverName + "/zone" + driverName = "block-storage.csi.stackit.cloud" + legacyDriverName = "cinder.csi.openstack.org" + topologyKey = "topology." + driverName + "/zone" + legacyTopologyKey = "topology." + legacyDriverName + "/zone" // ResizeRequired parameter, if set to true, will trigger a resize on mount operation ResizeRequired = driverName + "/resizeRequired" @@ -29,10 +31,12 @@ var ( ) type Driver struct { - name string - fqVersion string // Fully qualified version in format {Version}@{CPO version} - endpoint string - clusterID string + name string + fqVersion string // Fully qualified version in format {Version}@{CPO version} + endpoint string + clusterID string + legacyDriver bool + blockVolumeCreation bool ids *identityServer cs *controllerServer @@ -47,8 +51,10 @@ type Driver struct { } type DriverOpts struct { - ClusterID string - Endpoint string + ClusterID string + Endpoint string + LegacyDriverName bool + BlockVolumeCreation bool PVCLister corev1.PersistentVolumeClaimLister } @@ -62,6 +68,15 @@ func NewDriver(o *DriverOpts) *Driver { pvcLister: o.PVCLister, } + if o.LegacyDriverName { + d.name = legacyDriverName + d.legacyDriver = true + } + + if o.BlockVolumeCreation { + d.blockVolumeCreation = true + } + klog.Info("Driver: ", d.name) klog.Info("Driver version: ", d.fqVersion) klog.Info("CSI Spec version: ", specVersion) diff --git a/pkg/csi/blockstorage/nodeserver.go b/pkg/csi/blockstorage/nodeserver.go index 648e5df3..34625f6f 100644 --- a/pkg/csi/blockstorage/nodeserver.go +++ b/pkg/csi/blockstorage/nodeserver.go @@ -322,9 +322,14 @@ func (ns *nodeServer) NodeGetInfo(ctx context.Context, _ *csi.NodeGetInfoRequest return nil, status.Errorf(codes.Internal, "[NodeGetInfo] Unable to retrieve availability zone of node %v", err) } + topoKey := topologyKey + if ns.Driver.legacyDriver { + topoKey = legacyTopologyKey + } + //TODO: support well-known topology key "topology.kubernetes.io/zone" segments := map[string]string{ - topologyKey: zone, + topoKey: zone, } nodeInfo.AccessibleTopology = &csi.Topology{Segments: segments}