From 8183d3aec1ecaa96569e92f7057427e84e9d0c8e Mon Sep 17 00:00:00 2001 From: Niclas Schad Date: Wed, 12 Nov 2025 10:04:53 +0100 Subject: [PATCH] Add support for legacy storage operations Signed-off-by: Niclas Schad --- cmd/stackit-csi-plugin/main.go | 13 ++++++++++-- pkg/csi/blockstorage/controllerserver.go | 19 +++++++++++++----- pkg/csi/blockstorage/driver.go | 25 ++++++++++++++++-------- pkg/csi/blockstorage/nodeserver.go | 7 ++++++- 4 files changed, 48 insertions(+), 16 deletions(-) diff --git a/cmd/stackit-csi-plugin/main.go b/cmd/stackit-csi-plugin/main.go index d952bd60..3290b7de 100644 --- a/cmd/stackit-csi-plugin/main.go +++ b/cmd/stackit-csi-plugin/main.go @@ -24,6 +24,7 @@ var ( httpEndpoint string provideControllerService bool provideNodeService bool + legacyStorageMode bool ) func main() { @@ -72,6 +73,8 @@ 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") stackit.AddExtraFlags(pflag.CommandLine) @@ -81,11 +84,17 @@ 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 + } + + d := blockstorage.NewDriver(driverOpts) if provideControllerService { var err error diff --git a/pkg/csi/blockstorage/controllerserver.go b/pkg/csi/blockstorage/controllerserver.go index d9af791d..20829434 100644 --- a/pkg/csi/blockstorage/controllerserver.go +++ b/pkg/csi/blockstorage/controllerserver.go @@ -112,7 +112,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 +135,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 +278,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 { @@ -957,7 +961,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{} @@ -998,9 +1002,14 @@ func getCreateVolumeResponse(vol *iaas.Volume) *csi.CreateVolumeResponse { } } + topoKey := topologyKey + if cs.Driver.legacyDriver { + topoKey = legacyTopologyKey + } + accessibleTopology := []*csi.Topology{ { - Segments: map[string]string{topologyKey: ptr.Deref(vol.AvailabilityZone, "")}, + Segments: map[string]string{topoKey: ptr.Deref(vol.AvailabilityZone, "")}, }, } diff --git a/pkg/csi/blockstorage/driver.go b/pkg/csi/blockstorage/driver.go index 1effd50c..a3933153 100644 --- a/pkg/csi/blockstorage/driver.go +++ b/pkg/csi/blockstorage/driver.go @@ -14,8 +14,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" @@ -28,10 +30,11 @@ 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 ids *identityServer cs *controllerServer @@ -46,8 +49,9 @@ type Driver struct { } type DriverOpts struct { - ClusterID string - Endpoint string + ClusterID string + Endpoint string + LegacyDriverName bool PVCLister corev1.PersistentVolumeClaimLister } @@ -61,6 +65,11 @@ func NewDriver(o *DriverOpts) *Driver { pvcLister: o.PVCLister, } + if o.LegacyDriverName { + d.name = legacyDriverName + d.legacyDriver = 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 514830bb..7d935913 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}