Merge pull request #106611 from verult/delegate-fsgroup-disable-onrootmismatch-e2e

Delegate FSGroup CSI driver e2e: verify fsgroup is passed to CSI calls
This commit is contained in:
Kubernetes Prow Robot 2021-11-23 17:52:20 -08:00 committed by GitHub
commit e53cf07724
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 147 additions and 56 deletions

View File

@ -27,6 +27,7 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
csipbv1 "github.com/container-storage-interface/spec/lib/go/csi"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/status" "google.golang.org/grpc/status"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
@ -107,6 +108,7 @@ var _ = utils.SIGDescribe("CSI mock volume", func() {
// just disable resizing on driver it overrides enableResizing flag for CSI mock driver // just disable resizing on driver it overrides enableResizing flag for CSI mock driver
disableResizingOnDriver bool disableResizingOnDriver bool
enableSnapshot bool enableSnapshot bool
enableVolumeMountGroup bool // enable the VOLUME_MOUNT_GROUP node capability in the CSI mock driver.
hooks *drivers.Hooks hooks *drivers.Hooks
tokenRequests []storagev1.TokenRequest tokenRequests []storagev1.TokenRequest
requiresRepublish *bool requiresRepublish *bool
@ -140,18 +142,19 @@ var _ = utils.SIGDescribe("CSI mock volume", func() {
cs := f.ClientSet cs := f.ClientSet
var err error var err error
driverOpts := drivers.CSIMockDriverOpts{ driverOpts := drivers.CSIMockDriverOpts{
RegisterDriver: tp.registerDriver, RegisterDriver: tp.registerDriver,
PodInfo: tp.podInfo, PodInfo: tp.podInfo,
StorageCapacity: tp.storageCapacity, StorageCapacity: tp.storageCapacity,
EnableTopology: tp.enableTopology, EnableTopology: tp.enableTopology,
AttachLimit: tp.attachLimit, AttachLimit: tp.attachLimit,
DisableAttach: tp.disableAttach, DisableAttach: tp.disableAttach,
EnableResizing: tp.enableResizing, EnableResizing: tp.enableResizing,
EnableNodeExpansion: tp.enableNodeExpansion, EnableNodeExpansion: tp.enableNodeExpansion,
EnableSnapshot: tp.enableSnapshot, EnableSnapshot: tp.enableSnapshot,
TokenRequests: tp.tokenRequests, EnableVolumeMountGroup: tp.enableVolumeMountGroup,
RequiresRepublish: tp.requiresRepublish, TokenRequests: tp.tokenRequests,
FSGroupPolicy: tp.fsGroupPolicy, RequiresRepublish: tp.requiresRepublish,
FSGroupPolicy: tp.fsGroupPolicy,
} }
// At the moment, only tests which need hooks are // At the moment, only tests which need hooks are
@ -1715,6 +1718,55 @@ var _ = utils.SIGDescribe("CSI mock volume", func() {
} }
}) })
ginkgo.Context("Delegate FSGroup to CSI driver [LinuxOnly]", func() {
tests := []struct {
name string
enableVolumeMountGroup bool
}{
{
name: "should pass FSGroup to CSI driver if it is set in pod and driver supports VOLUME_MOUNT_GROUP",
enableVolumeMountGroup: true,
},
{
name: "should not pass FSGroup to CSI driver if it is set in pod and driver supports VOLUME_MOUNT_GROUP",
enableVolumeMountGroup: false,
},
}
for _, t := range tests {
test := t
ginkgo.It(test.name, func() {
var nodeStageFsGroup, nodePublishFsGroup string
if framework.NodeOSDistroIs("windows") {
e2eskipper.Skipf("FSGroupPolicy is only applied on linux nodes -- skipping")
}
init(testParameters{
disableAttach: true,
registerDriver: true,
enableVolumeMountGroup: t.enableVolumeMountGroup,
hooks: createFSGroupRequestPreHook(&nodeStageFsGroup, &nodePublishFsGroup),
})
defer cleanup()
fsGroupVal := int64(rand.Int63n(20000) + 1024)
fsGroup := &fsGroupVal
fsGroupStr := strconv.FormatInt(fsGroupVal, 10 /* base */)
_, _, pod := createPodWithFSGroup(fsGroup) /* persistent volume */
err := e2epod.WaitForPodNameRunningInNamespace(m.cs, pod.Name, pod.Namespace)
framework.ExpectNoError(err, "failed to start pod")
if t.enableVolumeMountGroup {
framework.ExpectEqual(nodeStageFsGroup, fsGroupStr, "Expect NodeStageVolumeRequest.VolumeCapability.MountVolume.VolumeMountGroup to equal %q; got: %q", fsGroupStr, nodeStageFsGroup)
framework.ExpectEqual(nodePublishFsGroup, fsGroupStr, "Expect NodePublishVolumeRequest.VolumeCapability.MountVolume.VolumeMountGroup to equal %q; got: %q", fsGroupStr, nodePublishFsGroup)
} else {
framework.ExpectEmpty(nodeStageFsGroup, "Expect NodeStageVolumeRequest.VolumeCapability.MountVolume.VolumeMountGroup to be empty; got: %q", nodeStageFsGroup)
framework.ExpectEmpty(nodePublishFsGroup, "Expect NodePublishVolumeRequest.VolumeCapability.MountVolume.VolumeMountGroup to empty; got: %q", nodePublishFsGroup)
}
})
}
})
ginkgo.Context("CSI Volume Snapshots secrets [Feature:VolumeSnapshotDataSource]", func() { ginkgo.Context("CSI Volume Snapshots secrets [Feature:VolumeSnapshotDataSource]", func() {
var ( var (
@ -2460,6 +2512,30 @@ func createPreHook(method string, callback func(counter int64) error) *drivers.H
} }
} }
// createFSGroupRequestPreHook creates a hook that records the fsGroup passed in
// through NodeStageVolume and NodePublishVolume calls.
func createFSGroupRequestPreHook(nodeStageFsGroup, nodePublishFsGroup *string) *drivers.Hooks {
return &drivers.Hooks{
Pre: func(ctx context.Context, fullMethod string, request interface{}) (reply interface{}, err error) {
nodeStageRequest, ok := request.(csipbv1.NodeStageVolumeRequest)
if ok {
mountVolume := nodeStageRequest.GetVolumeCapability().GetMount()
if mountVolume != nil {
*nodeStageFsGroup = mountVolume.VolumeMountGroup
}
}
nodePublishRequest, ok := request.(csipbv1.NodePublishVolumeRequest)
if ok {
mountVolume := nodePublishRequest.GetVolumeCapability().GetMount()
if mountVolume != nil {
*nodePublishFsGroup = mountVolume.VolumeMountGroup
}
}
return nil, nil
},
}
}
type snapshotMetricsTestConfig struct { type snapshotMetricsTestConfig struct {
// expected values // expected values
metricName string metricName string

View File

@ -377,6 +377,16 @@ func (s *service) NodeGetCapabilities(
}) })
} }
if s.config.VolumeMountGroupRequired {
capabilities = append(capabilities, &csi.NodeServiceCapability{
Type: &csi.NodeServiceCapability_Rpc{
Rpc: &csi.NodeServiceCapability_RPC{
Type: csi.NodeServiceCapability_RPC_VOLUME_MOUNT_GROUP,
},
},
})
}
return &csi.NodeGetCapabilitiesResponse{ return &csi.NodeGetCapabilitiesResponse{
Capabilities: capabilities, Capabilities: capabilities,
}, nil }, nil

View File

@ -55,6 +55,7 @@ type Config struct {
DriverName string DriverName string
AttachLimit int64 AttachLimit int64
NodeExpansionRequired bool NodeExpansionRequired bool
VolumeMountGroupRequired bool
DisableControllerExpansion bool DisableControllerExpansion bool
DisableOnlineExpansion bool DisableOnlineExpansion bool
PermissiveTargetPath bool PermissiveTargetPath bool

View File

@ -299,21 +299,22 @@ func (h *hostpathCSIDriver) PrepareTest(f *framework.Framework) (*storageframewo
// mockCSI // mockCSI
type mockCSIDriver struct { type mockCSIDriver struct {
driverInfo storageframework.DriverInfo driverInfo storageframework.DriverInfo
manifests []string manifests []string
podInfo *bool podInfo *bool
storageCapacity *bool storageCapacity *bool
attachable bool attachable bool
attachLimit int attachLimit int
enableTopology bool enableTopology bool
enableNodeExpansion bool enableNodeExpansion bool
hooks Hooks hooks Hooks
tokenRequests []storagev1.TokenRequest tokenRequests []storagev1.TokenRequest
requiresRepublish *bool requiresRepublish *bool
fsGroupPolicy *storagev1.FSGroupPolicy fsGroupPolicy *storagev1.FSGroupPolicy
embedded bool enableVolumeMountGroup bool
calls MockCSICalls embedded bool
embeddedCSIDriver *mockdriver.CSIDriver calls MockCSICalls
embeddedCSIDriver *mockdriver.CSIDriver
// Additional values set during PrepareTest // Additional values set during PrepareTest
clientSet kubernetes.Interface clientSet kubernetes.Interface
@ -347,18 +348,19 @@ type MockCSITestDriver interface {
// CSIMockDriverOpts defines options used for csi driver // CSIMockDriverOpts defines options used for csi driver
type CSIMockDriverOpts struct { type CSIMockDriverOpts struct {
RegisterDriver bool RegisterDriver bool
DisableAttach bool DisableAttach bool
PodInfo *bool PodInfo *bool
StorageCapacity *bool StorageCapacity *bool
AttachLimit int AttachLimit int
EnableTopology bool EnableTopology bool
EnableResizing bool EnableResizing bool
EnableNodeExpansion bool EnableNodeExpansion bool
EnableSnapshot bool EnableSnapshot bool
TokenRequests []storagev1.TokenRequest EnableVolumeMountGroup bool
RequiresRepublish *bool TokenRequests []storagev1.TokenRequest
FSGroupPolicy *storagev1.FSGroupPolicy RequiresRepublish *bool
FSGroupPolicy *storagev1.FSGroupPolicy
// Embedded defines whether the CSI mock driver runs // Embedded defines whether the CSI mock driver runs
// inside the cluster (false, the default) or just a proxy // inside the cluster (false, the default) or just a proxy
@ -499,18 +501,19 @@ func InitMockCSIDriver(driverOpts CSIMockDriverOpts) MockCSITestDriver {
storageframework.CapVolumeLimits: true, storageframework.CapVolumeLimits: true,
}, },
}, },
manifests: driverManifests, manifests: driverManifests,
podInfo: driverOpts.PodInfo, podInfo: driverOpts.PodInfo,
storageCapacity: driverOpts.StorageCapacity, storageCapacity: driverOpts.StorageCapacity,
enableTopology: driverOpts.EnableTopology, enableTopology: driverOpts.EnableTopology,
attachable: !driverOpts.DisableAttach, attachable: !driverOpts.DisableAttach,
attachLimit: driverOpts.AttachLimit, attachLimit: driverOpts.AttachLimit,
enableNodeExpansion: driverOpts.EnableNodeExpansion, enableNodeExpansion: driverOpts.EnableNodeExpansion,
tokenRequests: driverOpts.TokenRequests, tokenRequests: driverOpts.TokenRequests,
requiresRepublish: driverOpts.RequiresRepublish, requiresRepublish: driverOpts.RequiresRepublish,
fsGroupPolicy: driverOpts.FSGroupPolicy, fsGroupPolicy: driverOpts.FSGroupPolicy,
embedded: driverOpts.Embedded, enableVolumeMountGroup: driverOpts.EnableVolumeMountGroup,
hooks: driverOpts.Hooks, embedded: driverOpts.Embedded,
hooks: driverOpts.Hooks,
} }
} }
@ -573,11 +576,12 @@ func (m *mockCSIDriver) PrepareTest(f *framework.Framework) (*storageframework.P
containername := "mock" containername := "mock"
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
serviceConfig := mockservice.Config{ serviceConfig := mockservice.Config{
DisableAttach: !m.attachable, DisableAttach: !m.attachable,
DriverName: "csi-mock-" + f.UniqueName, DriverName: "csi-mock-" + f.UniqueName,
AttachLimit: int64(m.attachLimit), AttachLimit: int64(m.attachLimit),
NodeExpansionRequired: m.enableNodeExpansion, NodeExpansionRequired: m.enableNodeExpansion,
EnableTopology: m.enableTopology, VolumeMountGroupRequired: m.enableVolumeMountGroup,
EnableTopology: m.enableTopology,
IO: proxy.PodDirIO{ IO: proxy.PodDirIO{
F: f, F: f,
Namespace: m.driverNamespace.Name, Namespace: m.driverNamespace.Name,