sigs.k8s.io/blob-csi-driver@v1.24.1/test/e2e/pre_provisioning_test.go (about)

     1  /*
     2  Copyright 2019 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 e2e
    18  
    19  import (
    20  	"fmt"
    21  	"math/rand"
    22  	"strconv"
    23  
    24  	"sigs.k8s.io/blob-csi-driver/test/e2e/driver"
    25  	"sigs.k8s.io/blob-csi-driver/test/e2e/testsuites"
    26  
    27  	"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
    28  	"github.com/container-storage-interface/spec/lib/go/csi"
    29  	"github.com/onsi/ginkgo/v2"
    30  	v1 "k8s.io/api/core/v1"
    31  	storagev1 "k8s.io/api/storage/v1"
    32  	clientset "k8s.io/client-go/kubernetes"
    33  	"k8s.io/kubernetes/test/e2e/framework"
    34  	admissionapi "k8s.io/pod-security-admission/api"
    35  )
    36  
    37  const (
    38  	defaultVolumeSize = 10
    39  )
    40  
    41  var (
    42  	defaultVolumeSizeBytes int64 = defaultVolumeSize * 1024 * 1024 * 1024
    43  )
    44  
    45  var _ = ginkgo.Describe("[blob-csi-e2e] Pre-Provisioned", func() {
    46  	f := framework.NewDefaultFramework("blob")
    47  	f.NamespacePodSecurityEnforceLevel = admissionapi.LevelPrivileged
    48  
    49  	var (
    50  		cs         clientset.Interface
    51  		ns         *v1.Namespace
    52  		testDriver driver.PreProvisionedVolumeTestDriver
    53  		volumeID   string
    54  	)
    55  
    56  	ginkgo.BeforeEach(func(ctx ginkgo.SpecContext) {
    57  		checkPodsRestart := testCmd{
    58  			command:  "sh",
    59  			args:     []string{"test/utils/check_driver_pods_restart.sh"},
    60  			startLog: "Check driver pods if restarts ...",
    61  			endLog:   "Check successfully",
    62  		}
    63  		execTestCmd([]testCmd{checkPodsRestart})
    64  
    65  		cs = f.ClientSet
    66  		ns = f.Namespace
    67  		testDriver = driver.InitBlobCSIDriver()
    68  
    69  		volName := fmt.Sprintf("pre-provisioned-%d-%v", ginkgo.GinkgoParallelProcess(), strconv.Itoa(rand.Intn(10000)))
    70  		resp, err := blobDriver.CreateVolume(ctx, makeCreateVolumeReq(volName, ns.Name))
    71  		framework.ExpectNoError(err, "create volume error")
    72  		volumeID = resp.Volume.VolumeId
    73  
    74  		ginkgo.DeferCleanup(func(ctx ginkgo.SpecContext) {
    75  			_, err := blobDriver.DeleteVolume(
    76  				ctx,
    77  				&csi.DeleteVolumeRequest{
    78  					VolumeId: volumeID,
    79  				})
    80  			framework.ExpectNoError(err, "delete volume %s error", volumeID)
    81  		})
    82  	})
    83  
    84  	ginkgo.It("[env] should use a pre-provisioned volume and mount it as readOnly in a pod", func(ctx ginkgo.SpecContext) {
    85  		volumeSize := fmt.Sprintf("%dGi", defaultVolumeSize)
    86  		pods := []testsuites.PodDetails{
    87  			{
    88  				Cmd: "echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data",
    89  				Volumes: []testsuites.VolumeDetails{
    90  					{
    91  						VolumeID:  volumeID,
    92  						FSType:    "ext4",
    93  						ClaimSize: volumeSize,
    94  						VolumeMount: testsuites.VolumeMountDetails{
    95  							NameGenerate:      "test-volume-",
    96  							MountPathGenerate: "/mnt/test-",
    97  							ReadOnly:          true,
    98  						},
    99  					},
   100  				},
   101  			},
   102  		}
   103  		test := testsuites.PreProvisionedReadOnlyVolumeTest{
   104  			CSIDriver: testDriver,
   105  			Pods:      pods,
   106  		}
   107  		test.Run(ctx, cs, ns)
   108  	})
   109  
   110  	ginkgo.It(fmt.Sprintf("[env] should use a pre-provisioned volume and retain PV with reclaimPolicy %q", v1.PersistentVolumeReclaimRetain), func(ctx ginkgo.SpecContext) {
   111  		volumeSize := fmt.Sprintf("%dGi", defaultVolumeSize)
   112  		reclaimPolicy := v1.PersistentVolumeReclaimRetain
   113  		volumes := []testsuites.VolumeDetails{
   114  			{
   115  				VolumeID:      volumeID,
   116  				FSType:        "ext4",
   117  				ClaimSize:     volumeSize,
   118  				ReclaimPolicy: &reclaimPolicy,
   119  			},
   120  		}
   121  		test := testsuites.PreProvisionedReclaimPolicyTest{
   122  			CSIDriver: testDriver,
   123  			Volumes:   volumes,
   124  		}
   125  		test.Run(ctx, cs, ns)
   126  	})
   127  
   128  	ginkgo.It("should use a pre-provisioned volume and mount it by multiple pods", func(ctx ginkgo.SpecContext) {
   129  		volumeSize := fmt.Sprintf("%dGi", defaultVolumeSize)
   130  		pods := []testsuites.PodDetails{}
   131  		for i := 1; i <= 6; i++ {
   132  			pod := testsuites.PodDetails{
   133  				Cmd: "echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data",
   134  				Volumes: []testsuites.VolumeDetails{
   135  					{
   136  						// make VolumeID unique in test
   137  						// to workaround the issue: https://github.com/kubernetes/kubernetes/pull/107065
   138  						// which was fixed in k8s 1.24
   139  						VolumeID:  fmt.Sprintf("%s%d", volumeID, i),
   140  						ClaimSize: volumeSize,
   141  						VolumeMount: testsuites.VolumeMountDetails{
   142  							NameGenerate:      "test-volume-",
   143  							MountPathGenerate: "/mnt/test-",
   144  						},
   145  					},
   146  				},
   147  			}
   148  			pods = append(pods, pod)
   149  		}
   150  
   151  		test := testsuites.PreProvisionedMultiplePods{
   152  			CSIDriver: testDriver,
   153  			Pods:      pods,
   154  		}
   155  		test.Run(ctx, cs, ns)
   156  	})
   157  
   158  	ginkgo.It("should use existing credentials in k8s cluster", func(ctx ginkgo.SpecContext) {
   159  		volumeSize := fmt.Sprintf("%dGi", defaultVolumeSize)
   160  		reclaimPolicy := v1.PersistentVolumeReclaimRetain
   161  		volumeBindingMode := storagev1.VolumeBindingImmediate
   162  
   163  		pods := []testsuites.PodDetails{
   164  			{
   165  				Cmd: "echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data",
   166  				Volumes: []testsuites.VolumeDetails{
   167  					{
   168  						VolumeID:          volumeID,
   169  						FSType:            "ext4",
   170  						ClaimSize:         volumeSize,
   171  						ReclaimPolicy:     &reclaimPolicy,
   172  						VolumeBindingMode: &volumeBindingMode,
   173  						VolumeMount: testsuites.VolumeMountDetails{
   174  							NameGenerate:      "test-volume-",
   175  							MountPathGenerate: "/mnt/test-",
   176  						},
   177  					},
   178  				},
   179  			},
   180  		}
   181  		test := testsuites.PreProvisionedExistingCredentialsTest{
   182  			CSIDriver: testDriver,
   183  			Pods:      pods,
   184  		}
   185  		test.Run(ctx, cs, ns)
   186  	})
   187  
   188  	ginkgo.It("should use provided credentials", ginkgo.Label("flaky"), func(ctx ginkgo.SpecContext) {
   189  		volumeSize := fmt.Sprintf("%dGi", defaultVolumeSize)
   190  		reclaimPolicy := v1.PersistentVolumeReclaimRetain
   191  		volumeBindingMode := storagev1.VolumeBindingImmediate
   192  
   193  		pods := []testsuites.PodDetails{
   194  			{
   195  				Cmd: "echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data",
   196  				Volumes: []testsuites.VolumeDetails{
   197  					{
   198  						VolumeID:          volumeID,
   199  						FSType:            "ext4",
   200  						ClaimSize:         volumeSize,
   201  						ReclaimPolicy:     &reclaimPolicy,
   202  						VolumeBindingMode: &volumeBindingMode,
   203  						VolumeMount: testsuites.VolumeMountDetails{
   204  							NameGenerate:      "test-volume-",
   205  							MountPathGenerate: "/mnt/test-",
   206  						},
   207  						NodeStageSecretRef: "azure-secret",
   208  						Attrib:             make(map[string]string),
   209  					},
   210  				},
   211  			},
   212  		}
   213  		test := testsuites.PreProvisionedProvidedCredentiasTest{
   214  			CSIDriver: testDriver,
   215  			Pods:      pods,
   216  			Driver:    blobDriver,
   217  		}
   218  		test.Run(ctx, cs, ns)
   219  	})
   220  
   221  	ginkgo.It("should use Key Vault", func(ctx ginkgo.SpecContext) {
   222  		volumeSize := fmt.Sprintf("%dGi", defaultVolumeSize)
   223  		reclaimPolicy := v1.PersistentVolumeReclaimRetain
   224  		volumeBindingMode := storagev1.VolumeBindingImmediate
   225  
   226  		pods := []testsuites.PodDetails{
   227  			{
   228  				Cmd: "echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data",
   229  				Volumes: []testsuites.VolumeDetails{
   230  					{
   231  						VolumeID:          volumeID,
   232  						FSType:            "ext4",
   233  						ClaimSize:         volumeSize,
   234  						ReclaimPolicy:     &reclaimPolicy,
   235  						VolumeBindingMode: &volumeBindingMode,
   236  						VolumeMount: testsuites.VolumeMountDetails{
   237  							NameGenerate:      "test-volume-",
   238  							MountPathGenerate: "/mnt/test-",
   239  						},
   240  						Attrib: make(map[string]string),
   241  					},
   242  				},
   243  			},
   244  		}
   245  
   246  		test := testsuites.PreProvisionedKeyVaultTest{
   247  			CSIDriver: testDriver,
   248  			Pods:      pods,
   249  			Driver:    blobDriver,
   250  		}
   251  		test.Run(ctx, cs, ns)
   252  	})
   253  
   254  	ginkgo.It("should use SAS token", func(ctx ginkgo.SpecContext) {
   255  		pods := []testsuites.PodDetails{
   256  			{
   257  				Cmd: "echo 'hello world' > /mnt/test-1/data && grep 'hello world' /mnt/test-1/data",
   258  				Volumes: []testsuites.VolumeDetails{
   259  					{
   260  						VolumeID:          volumeID,
   261  						FSType:            "ext4",
   262  						ClaimSize:         fmt.Sprintf("%dGi", defaultVolumeSize),
   263  						ReclaimPolicy:     to.Ptr(v1.PersistentVolumeReclaimRetain),
   264  						VolumeBindingMode: to.Ptr(storagev1.VolumeBindingImmediate),
   265  						VolumeMount: testsuites.VolumeMountDetails{
   266  							NameGenerate:      "test-volume-",
   267  							MountPathGenerate: "/mnt/test-",
   268  						},
   269  						Attrib: make(map[string]string),
   270  					},
   271  				},
   272  			},
   273  		}
   274  
   275  		test := testsuites.PreProvisionedSASTokenTest{
   276  			CSIDriver: testDriver,
   277  			Pods:      pods,
   278  			Driver:    blobDriver,
   279  		}
   280  		test.Run(ctx, cs, ns)
   281  	})
   282  })
   283  
   284  func makeCreateVolumeReq(volumeName, secretNamespace string) *csi.CreateVolumeRequest {
   285  	req := &csi.CreateVolumeRequest{
   286  		Name: volumeName,
   287  		VolumeCapabilities: []*csi.VolumeCapability{
   288  			{
   289  				AccessType: &csi.VolumeCapability_Mount{
   290  					Mount: &csi.VolumeCapability_MountVolume{},
   291  				},
   292  				AccessMode: &csi.VolumeCapability_AccessMode{
   293  					Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
   294  				},
   295  			},
   296  		},
   297  		CapacityRange: &csi.CapacityRange{
   298  			RequiredBytes: defaultVolumeSizeBytes,
   299  			LimitBytes:    defaultVolumeSizeBytes,
   300  		},
   301  		Parameters: map[string]string{
   302  			"skuname":         "Standard_LRS",
   303  			"containerName":   volumeName,
   304  			"secretNamespace": secretNamespace,
   305  		},
   306  	}
   307  
   308  	return req
   309  }