k8s.io/kubernetes@v1.29.3/test/e2e/storage/csi_mock/csi_fsgroup_policy.go (about)

     1  /*
     2  Copyright 2022 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package csi_mock
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"math/rand"
    23  	"strconv"
    24  	"time"
    25  
    26  	"github.com/onsi/ginkgo/v2"
    27  	storagev1 "k8s.io/api/storage/v1"
    28  	"k8s.io/kubernetes/test/e2e/framework"
    29  	e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
    30  	e2eskipper "k8s.io/kubernetes/test/e2e/framework/skipper"
    31  	e2evolume "k8s.io/kubernetes/test/e2e/framework/volume"
    32  	"k8s.io/kubernetes/test/e2e/storage/utils"
    33  	admissionapi "k8s.io/pod-security-admission/api"
    34  )
    35  
    36  var _ = utils.SIGDescribe("CSI Mock volume fsgroup policies", func() {
    37  	f := framework.NewDefaultFramework("csi-mock-volumes-fsgroup-policy")
    38  	f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged
    39  	m := newMockDriverSetup(f)
    40  
    41  	// These tests *only* work on a cluster which has the CSIVolumeFSGroupPolicy feature enabled.
    42  	ginkgo.Context("CSI FSGroupPolicy [LinuxOnly]", func() {
    43  		tests := []struct {
    44  			name          string
    45  			fsGroupPolicy storagev1.FSGroupPolicy
    46  			modified      bool
    47  		}{
    48  			{
    49  				name:          "should modify fsGroup if fsGroupPolicy=default",
    50  				fsGroupPolicy: storagev1.ReadWriteOnceWithFSTypeFSGroupPolicy,
    51  				modified:      true,
    52  			},
    53  			{
    54  				name:          "should modify fsGroup if fsGroupPolicy=File",
    55  				fsGroupPolicy: storagev1.FileFSGroupPolicy,
    56  				modified:      true,
    57  			},
    58  			{
    59  				name:          "should not modify fsGroup if fsGroupPolicy=None",
    60  				fsGroupPolicy: storagev1.NoneFSGroupPolicy,
    61  				modified:      false,
    62  			},
    63  		}
    64  		for _, t := range tests {
    65  			test := t
    66  			ginkgo.It(test.name, func(ctx context.Context) {
    67  				if framework.NodeOSDistroIs("windows") {
    68  					e2eskipper.Skipf("FSGroupPolicy is only applied on linux nodes -- skipping")
    69  				}
    70  				m.init(ctx, testParameters{
    71  					disableAttach:  true,
    72  					registerDriver: true,
    73  					fsGroupPolicy:  &test.fsGroupPolicy,
    74  				})
    75  				ginkgo.DeferCleanup(m.cleanup)
    76  
    77  				// kube-scheduler may need some time before it gets the CSIDriver object.
    78  				// Without them, scheduling doesn't run as expected by the test.
    79  				syncDelay := 5 * time.Second
    80  				time.Sleep(syncDelay)
    81  
    82  				fsGroupVal := int64(rand.Int63n(20000) + 1024)
    83  				fsGroup := &fsGroupVal
    84  
    85  				_, _, pod := m.createPodWithFSGroup(ctx, fsGroup) /* persistent volume */
    86  
    87  				mountPath := pod.Spec.Containers[0].VolumeMounts[0].MountPath
    88  				dirName := mountPath + "/" + f.UniqueName
    89  				fileName := dirName + "/" + f.UniqueName
    90  
    91  				err := e2epod.WaitForPodNameRunningInNamespace(ctx, m.cs, pod.Name, pod.Namespace)
    92  				framework.ExpectNoError(err, "failed to start pod")
    93  
    94  				// Create the subdirectory to ensure that fsGroup propagates
    95  				createDirectory := fmt.Sprintf("mkdir %s", dirName)
    96  				_, _, err = e2evolume.PodExec(f, pod, createDirectory)
    97  				framework.ExpectNoError(err, "failed: creating the directory: %s", err)
    98  
    99  				// Inject the contents onto the mount
   100  				createFile := fmt.Sprintf("echo '%s' > '%s'; sync", "filecontents", fileName)
   101  				_, _, err = e2evolume.PodExec(f, pod, createFile)
   102  				framework.ExpectNoError(err, "failed: writing the contents: %s", err)
   103  
   104  				// Delete the created file. This step is mandatory, as the mock driver
   105  				// won't clean up the contents automatically.
   106  				defer func() {
   107  					deleteDir := fmt.Sprintf("rm -fr %s", dirName)
   108  					_, _, err = e2evolume.PodExec(f, pod, deleteDir)
   109  					framework.ExpectNoError(err, "failed: deleting the directory: %s", err)
   110  				}()
   111  
   112  				// Ensure that the fsGroup matches what we expect
   113  				if test.modified {
   114  					utils.VerifyFSGroupInPod(f, fileName, strconv.FormatInt(*fsGroup, 10), pod)
   115  				} else {
   116  					utils.VerifyFSGroupInPod(f, fileName, "root", pod)
   117  				}
   118  
   119  				// The created resources will be removed by the cleanup() function,
   120  				// so need to delete anything here.
   121  			})
   122  		}
   123  	})
   124  })