176 lines
7.4 KiB
Go
176 lines
7.4 KiB
Go
/*
|
|
Copyright 2020 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package testsuites
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/kubernetes-csi/csi-driver-nfs/test/e2e/driver"
|
|
"github.com/onsi/ginkgo/v2"
|
|
v1 "k8s.io/api/core/v1"
|
|
storagev1 "k8s.io/api/storage/v1"
|
|
clientset "k8s.io/client-go/kubernetes"
|
|
)
|
|
|
|
const (
|
|
FileSystem VolumeMode = iota
|
|
Block
|
|
)
|
|
|
|
const (
|
|
VolumePVCKind = "PersistentVolumeClaim"
|
|
APIVersionv1beta1 = "v1beta1"
|
|
)
|
|
|
|
type PodDetails struct {
|
|
Cmd string
|
|
Volumes []VolumeDetails
|
|
}
|
|
|
|
type VolumeMode int
|
|
|
|
type VolumeMountDetails struct {
|
|
NameGenerate string
|
|
MountPathGenerate string
|
|
ReadOnly bool
|
|
}
|
|
|
|
type VolumeDeviceDetails struct {
|
|
NameGenerate string
|
|
DevicePath string
|
|
}
|
|
|
|
type DataSource struct {
|
|
Name string
|
|
}
|
|
|
|
type VolumeDetails struct {
|
|
VolumeType string
|
|
FSType string
|
|
Encrypted bool
|
|
MountOptions []string
|
|
ClaimSize string
|
|
ReclaimPolicy *v1.PersistentVolumeReclaimPolicy
|
|
VolumeBindingMode *storagev1.VolumeBindingMode
|
|
AllowedTopologyValues []string
|
|
VolumeMode VolumeMode
|
|
VolumeMount VolumeMountDetails
|
|
VolumeDevice VolumeDeviceDetails
|
|
// Optional, used with pre-provisioned volumes
|
|
VolumeID string
|
|
// Optional, used with PVCs created from snapshots
|
|
DataSource *DataSource
|
|
ShareName string
|
|
NodeStageSecretRef string
|
|
}
|
|
|
|
func (volume *VolumeDetails) SetupDynamicPersistentVolumeClaim(client clientset.Interface, namespace *v1.Namespace, csiDriver driver.DynamicPVTestDriver, storageClassParameters map[string]string) (*TestPersistentVolumeClaim, []func()) {
|
|
cleanupFuncs := make([]func(), 0)
|
|
ginkgo.By("setting up the StorageClass")
|
|
storageClass := csiDriver.GetDynamicProvisionStorageClass(storageClassParameters, volume.MountOptions, volume.ReclaimPolicy, volume.VolumeBindingMode, volume.AllowedTopologyValues, namespace.Name)
|
|
tsc := NewTestStorageClass(client, namespace, storageClass)
|
|
createdStorageClass := tsc.Create()
|
|
cleanupFuncs = append(cleanupFuncs, tsc.Cleanup)
|
|
ginkgo.By("setting up the PVC and PV")
|
|
var tpvc *TestPersistentVolumeClaim
|
|
if volume.DataSource != nil {
|
|
dataSource := &v1.TypedLocalObjectReference{
|
|
Name: volume.DataSource.Name,
|
|
}
|
|
tpvc = NewTestPersistentVolumeClaimWithDataSource(client, namespace, volume.ClaimSize, volume.VolumeMode, &createdStorageClass, dataSource)
|
|
} else {
|
|
tpvc = NewTestPersistentVolumeClaim(client, namespace, volume.ClaimSize, volume.VolumeMode, &createdStorageClass)
|
|
}
|
|
tpvc.Create()
|
|
cleanupFuncs = append(cleanupFuncs, tpvc.Cleanup)
|
|
// PV will not be ready until PVC is used in a pod when volumeBindingMode: WaitForFirstConsumer
|
|
if volume.VolumeBindingMode == nil || *volume.VolumeBindingMode == storagev1.VolumeBindingImmediate {
|
|
tpvc.WaitForBound()
|
|
tpvc.ValidateProvisionedPersistentVolume()
|
|
}
|
|
|
|
return tpvc, cleanupFuncs
|
|
}
|
|
|
|
func (pod *PodDetails) SetupWithDynamicVolumes(client clientset.Interface, namespace *v1.Namespace, csiDriver driver.DynamicPVTestDriver, storageClassParameters map[string]string) (*TestPod, []func()) {
|
|
tpod := NewTestPod(client, namespace, pod.Cmd)
|
|
cleanupFuncs := make([]func(), 0)
|
|
for n, v := range pod.Volumes {
|
|
tpvc, funcs := v.SetupDynamicPersistentVolumeClaim(client, namespace, csiDriver, storageClassParameters)
|
|
cleanupFuncs = append(cleanupFuncs, funcs...)
|
|
tpod.SetupVolume(tpvc.persistentVolumeClaim, fmt.Sprintf("%s%d", v.VolumeMount.NameGenerate, n+1), fmt.Sprintf("%s%d", v.VolumeMount.MountPathGenerate, n+1), v.VolumeMount.ReadOnly)
|
|
}
|
|
return tpod, cleanupFuncs
|
|
}
|
|
|
|
func (pod *PodDetails) SetupWithCSIInlineVolumes(client clientset.Interface, namespace *v1.Namespace, _ driver.DynamicPVTestDriver, server, share, mountOptions string, readOnly bool) (*TestPod, []func()) {
|
|
tpod := NewTestPod(client, namespace, pod.Cmd)
|
|
cleanupFuncs := make([]func(), 0)
|
|
for n, v := range pod.Volumes {
|
|
tpod.SetupCSIInlineVolume(fmt.Sprintf("%s%d", v.VolumeMount.NameGenerate, n+1), fmt.Sprintf("%s%d", v.VolumeMount.MountPathGenerate, n+1), server, share, mountOptions, readOnly)
|
|
}
|
|
return tpod, cleanupFuncs
|
|
}
|
|
|
|
func (pod *PodDetails) SetupDeployment(client clientset.Interface, namespace *v1.Namespace, csiDriver driver.DynamicPVTestDriver, storageClassParameters map[string]string) (*TestDeployment, []func()) {
|
|
cleanupFuncs := make([]func(), 0)
|
|
volume := pod.Volumes[0]
|
|
ginkgo.By("setting up the StorageClass")
|
|
storageClass := csiDriver.GetDynamicProvisionStorageClass(storageClassParameters, volume.MountOptions, volume.ReclaimPolicy, volume.VolumeBindingMode, volume.AllowedTopologyValues, namespace.Name)
|
|
tsc := NewTestStorageClass(client, namespace, storageClass)
|
|
createdStorageClass := tsc.Create()
|
|
cleanupFuncs = append(cleanupFuncs, tsc.Cleanup)
|
|
ginkgo.By("setting up the PVC")
|
|
tpvc := NewTestPersistentVolumeClaim(client, namespace, volume.ClaimSize, volume.VolumeMode, &createdStorageClass)
|
|
tpvc.Create()
|
|
tpvc.WaitForBound()
|
|
tpvc.ValidateProvisionedPersistentVolume()
|
|
cleanupFuncs = append(cleanupFuncs, tpvc.Cleanup)
|
|
ginkgo.By("setting up the Deployment")
|
|
tDeployment := NewTestDeployment(client, namespace, pod.Cmd, tpvc.persistentVolumeClaim, fmt.Sprintf("%s%d", volume.VolumeMount.NameGenerate, 1), fmt.Sprintf("%s%d", volume.VolumeMount.MountPathGenerate, 1), volume.VolumeMount.ReadOnly)
|
|
|
|
cleanupFuncs = append(cleanupFuncs, tDeployment.Cleanup)
|
|
return tDeployment, cleanupFuncs
|
|
}
|
|
|
|
// SetupWithDynamicMultipleVolumes each pod will be mounted with multiple volumes
|
|
func (pod *PodDetails) SetupWithDynamicMultipleVolumes(client clientset.Interface, namespace *v1.Namespace, csiDriver driver.DynamicPVTestDriver, storageClassParameters map[string]string) (*TestPod, []func()) {
|
|
tpod := NewTestPod(client, namespace, pod.Cmd)
|
|
cleanupFuncs := make([]func(), 0)
|
|
for n, v := range pod.Volumes {
|
|
tpvc, funcs := v.SetupDynamicPersistentVolumeClaim(client, namespace, csiDriver, storageClassParameters)
|
|
cleanupFuncs = append(cleanupFuncs, funcs...)
|
|
if v.VolumeMode == Block {
|
|
tpod.SetupRawBlockVolume(tpvc.persistentVolumeClaim, fmt.Sprintf("%s%d", v.VolumeDevice.NameGenerate, n+1), v.VolumeDevice.DevicePath)
|
|
} else {
|
|
tpod.SetupVolume(tpvc.persistentVolumeClaim, fmt.Sprintf("%s%d", v.VolumeMount.NameGenerate, n+1), fmt.Sprintf("%s%d", v.VolumeMount.MountPathGenerate, n+1), v.VolumeMount.ReadOnly)
|
|
}
|
|
}
|
|
return tpod, cleanupFuncs
|
|
}
|
|
|
|
func (pod *PodDetails) SetupWithDynamicVolumesWithSubpath(client clientset.Interface, namespace *v1.Namespace, csiDriver driver.DynamicPVTestDriver, storageClassParameters map[string]string) (*TestPod, []func()) {
|
|
tpod := NewTestPod(client, namespace, pod.Cmd)
|
|
cleanupFuncs := make([]func(), 0)
|
|
for n, v := range pod.Volumes {
|
|
tpvc, funcs := v.SetupDynamicPersistentVolumeClaim(client, namespace, csiDriver, storageClassParameters)
|
|
cleanupFuncs = append(cleanupFuncs, funcs...)
|
|
tpod.SetupVolumeMountWithSubpath(tpvc.persistentVolumeClaim, fmt.Sprintf("%s%d", v.VolumeMount.NameGenerate, n+1), fmt.Sprintf("%s%d", v.VolumeMount.MountPathGenerate, n+1), "testSubpath", v.VolumeMount.ReadOnly)
|
|
}
|
|
return tpod, cleanupFuncs
|
|
}
|