diff --git a/e2e/rbd.go b/e2e/rbd.go index 57d0c1b7996a..954014f72681 100644 --- a/e2e/rbd.go +++ b/e2e/rbd.go @@ -3099,6 +3099,64 @@ var _ = Describe("RBD", func() { validateOmapCount(f, 0, rbdType, defaultRBDPool, volumesType) }) + By("creating an app with a PVC, using a topology constrained StorageClass with volumenameprefix", func() { + By("checking node has required CSI topology labels set", func() { + err := checkNodeHasLabel(f.ClientSet, nodeCSIRegionLabel, regionValue) + if err != nil { + framework.Failf("failed to check node label: %v", err) + } + err = checkNodeHasLabel(f.ClientSet, nodeCSIZoneLabel, zoneValue) + if err != nil { + framework.Failf("failed to check node label: %v", err) + } + }) + + By("creating a StorageClass with delayed binding mode and CSI topology parameter") + err := deleteResource(rbdExamplePath + "storageclass.yaml") + if err != nil { + framework.Failf("failed to delete storageclass: %v", err) + } + topologyConstraint := "[{\"poolName\":\"" + rbdTopologyPool + "\",\"domainSegments\":" + + "[{\"domainLabel\":\"region\",\"value\":\"" + regionValue + "\"}," + + "{\"domainLabel\":\"zone\",\"value\":\"" + zoneValue + "\"}]}]" + err = createRBDStorageClass(f.ClientSet, f, defaultSCName, + map[string]string{"volumeBindingMode": "WaitForFirstConsumer"}, + map[string]string{ + "topologyConstrainedPools": topologyConstraint, + "volumeNamePrefix": "foo-bar-", + }, deletePolicy) + if err != nil { + framework.Failf("failed to create storageclass: %v", err) + } + + By("creating an app using a PV from the delayed binding mode StorageClass") + pvc, app, err := createPVCAndAppBinding(pvcPath, appPath, f, 0) + if err != nil { + framework.Failf("failed to create PVC and application: %v", err) + } + + // validate created backend rbd images + validateRBDImageCount(f, 1, defaultRBDPool) + + // cleanup and undo changes made by the test + err = deletePVCAndApp("", f, pvc, app) + if err != nil { + framework.Failf("failed to delete PVC and application: %v", err) + } + // validate created backend rbd images + validateRBDImageCount(f, 0, defaultRBDPool) + + err = deleteResource(rbdExamplePath + "storageclass.yaml") + if err != nil { + framework.Failf("failed to delete storageclass: %v", err) + } + + err = createRBDStorageClass(f.ClientSet, f, defaultSCName, nil, nil, deletePolicy) + if err != nil { + framework.Failf("failed to create storageclass: %v", err) + } + }) + // Mount pvc to pod with invalid mount option,expected that // mounting will fail By("Mount pvc to pod with invalid mount option", func() { diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index bd00d148f6b0..5757b466a3d5 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -215,6 +215,10 @@ func (cs *ControllerServer) parseVolCreateRequest( // store topology information from the request rbdVol.TopologyPools, rbdVol.TopologyRequirement, err = util.GetTopologyFromRequest(req) + volOp := req.GetParameters() + if namePrefix, ok := volOp["volumeNamePrefix"]; ok { + rbdVol.NamePrefix = namePrefix + } if err != nil { return nil, status.Error(codes.InvalidArgument, err.Error()) } @@ -317,6 +321,10 @@ func (cs *ControllerServer) CreateVolume( } defer cr.DeleteCredentials() rbdVol, err := cs.parseVolCreateRequest(ctx, req) + volOp := req.GetParameters() + if namePrefix, ok := volOp["volumeNamePrefix"]; ok { + rbdVol.NamePrefix = namePrefix + } if err != nil { return nil, err }