1
16
17 package storage
18
19 import (
20 "context"
21 "fmt"
22 "strings"
23 "time"
24
25 v1 "k8s.io/api/core/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/apimachinery/pkg/util/rand"
28 clientset "k8s.io/client-go/kubernetes"
29 "k8s.io/kubernetes/test/e2e/framework"
30 e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
31 "k8s.io/kubernetes/test/e2e/storage/utils"
32 imageutils "k8s.io/kubernetes/test/utils/image"
33 admissionapi "k8s.io/pod-security-admission/api"
34
35 "github.com/onsi/ginkgo/v2"
36 )
37
38 var (
39 volumePath = "/test-volume"
40 volumeName = "test-volume"
41 )
42
43 var _ = utils.SIGDescribe("Ephemeralstorage", func() {
44 var (
45 c clientset.Interface
46 )
47
48 f := framework.NewDefaultFramework("pv")
49 f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
50
51 ginkgo.BeforeEach(func() {
52 c = f.ClientSet
53 })
54
55 ginkgo.Describe("When pod refers to non-existent ephemeral storage", func() {
56 for _, testSource := range invalidEphemeralSource("pod-ephm-test") {
57 testSource := testSource
58 ginkgo.It(fmt.Sprintf("should allow deletion of pod with invalid volume : %s", testSource.volumeType), func(ctx context.Context) {
59 pod := testEphemeralVolumePod(f, testSource.volumeType, testSource.source)
60 pod, err := c.CoreV1().Pods(f.Namespace.Name).Create(ctx, pod, metav1.CreateOptions{})
61 framework.ExpectNoError(err)
62
63
64 time.Sleep(30 * time.Second)
65 framework.Logf("Deleting pod %q/%q", pod.Namespace, pod.Name)
66 framework.ExpectNoError(e2epod.DeletePodWithWait(ctx, c, pod))
67 })
68 }
69 })
70 })
71
72 type ephemeralTestInfo struct {
73 volumeType string
74 source *v1.VolumeSource
75 }
76
77 func testEphemeralVolumePod(f *framework.Framework, volumeType string, source *v1.VolumeSource) *v1.Pod {
78 var (
79 suffix = strings.ToLower(fmt.Sprintf("%s-%s", volumeType, rand.String(4)))
80 )
81 return &v1.Pod{
82 ObjectMeta: metav1.ObjectMeta{
83 Name: fmt.Sprintf("pod-ephm-test-%s", suffix),
84 Namespace: f.Namespace.Name,
85 },
86 Spec: v1.PodSpec{
87 Containers: []v1.Container{
88 {
89 Name: fmt.Sprintf("test-container-subpath-%s", suffix),
90 Image: imageutils.GetE2EImage(imageutils.Agnhost),
91 VolumeMounts: []v1.VolumeMount{
92 {
93 Name: volumeName,
94 MountPath: volumePath,
95 },
96 },
97 },
98 },
99 RestartPolicy: v1.RestartPolicyNever,
100 Volumes: []v1.Volume{
101 {
102 Name: volumeName,
103 VolumeSource: *source,
104 },
105 },
106 },
107 }
108 }
109
110 func invalidEphemeralSource(suffix string) []ephemeralTestInfo {
111 testInfo := []ephemeralTestInfo{
112 {
113 volumeType: "secret",
114 source: &v1.VolumeSource{
115 Secret: &v1.SecretVolumeSource{
116 SecretName: fmt.Sprintf("secert-%s", suffix),
117 },
118 },
119 },
120 {
121 volumeType: "configmap",
122 source: &v1.VolumeSource{
123 ConfigMap: &v1.ConfigMapVolumeSource{
124 LocalObjectReference: v1.LocalObjectReference{
125 Name: fmt.Sprintf("configmap-%s", suffix),
126 },
127 },
128 },
129 },
130 {
131 volumeType: "projected",
132 source: &v1.VolumeSource{
133 Projected: &v1.ProjectedVolumeSource{
134 Sources: []v1.VolumeProjection{
135 {
136 Secret: &v1.SecretProjection{
137 LocalObjectReference: v1.LocalObjectReference{
138 Name: fmt.Sprintf("secret-%s", suffix),
139 },
140 },
141 },
142 },
143 },
144 },
145 },
146 }
147 return testInfo
148 }
149
View as plain text