1
16
17 package auth
18
19 import (
20 "context"
21 "fmt"
22 "os"
23 "strings"
24 "testing"
25 "time"
26
27 coordination "k8s.io/api/coordination/v1"
28 corev1 "k8s.io/api/core/v1"
29 policy "k8s.io/api/policy/v1"
30 "k8s.io/api/resource/v1alpha2"
31 storagev1 "k8s.io/api/storage/v1"
32 apierrors "k8s.io/apimachinery/pkg/api/errors"
33 "k8s.io/apimachinery/pkg/api/resource"
34 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
35 "k8s.io/apimachinery/pkg/types"
36 "k8s.io/apimachinery/pkg/util/wait"
37 utilfeature "k8s.io/apiserver/pkg/util/feature"
38 clientset "k8s.io/client-go/kubernetes"
39 featuregatetesting "k8s.io/component-base/featuregate/testing"
40 kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
41 "k8s.io/kubernetes/pkg/features"
42 "k8s.io/kubernetes/test/integration/framework"
43 "k8s.io/utils/pointer"
44 )
45
46 func TestNodeAuthorizer(t *testing.T) {
47 const (
48
49
50 tokenMaster = "master-token"
51 tokenNodeUnknown = "unknown-token"
52 tokenNode1 = "node1-token"
53 tokenNode2 = "node2-token"
54 )
55
56 tokenFile, err := os.CreateTemp("", "kubeconfig")
57 if err != nil {
58 t.Fatal(err)
59 }
60 tokenFile.WriteString(strings.Join([]string{
61 fmt.Sprintf(`%s,admin,uid1,"system:masters"`, tokenMaster),
62 fmt.Sprintf(`%s,unknown,uid2,"system:nodes"`, tokenNodeUnknown),
63 fmt.Sprintf(`%s,system:node:node1,uid3,"system:nodes"`, tokenNode1),
64 fmt.Sprintf(`%s,system:node:node2,uid4,"system:nodes"`, tokenNode2),
65 }, "\n"))
66 tokenFile.Close()
67
68 defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DynamicResourceAllocation, true)()
69
70 server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{
71 "--runtime-config=api/all=true",
72 "--authorization-mode", "Node,RBAC",
73 "--token-auth-file", tokenFile.Name(),
74 "--enable-admission-plugins", "NodeRestriction",
75
76
77 "--disable-admission-plugins", "ServiceAccount,TaintNodesByCondition",
78 }, framework.SharedEtcd())
79 defer server.TearDownFn()
80
81
82 clientConfig := server.ClientConfig
83 superuserClient, superuserClientExternal := clientsetForToken(tokenMaster, clientConfig)
84
85
86 for {
87 result := superuserClient.CoreV1().RESTClient().Get().AbsPath("/healthz").Do(context.TODO())
88 _, err := result.Raw()
89 if err == nil {
90 break
91 }
92 t.Log(err)
93 time.Sleep(time.Second)
94 }
95
96
97 if _, err := superuserClient.CoreV1().Namespaces().Create(context.TODO(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "ns"}}, metav1.CreateOptions{}); err != nil {
98 t.Fatal(err)
99 }
100
101 if _, err := superuserClient.CoreV1().Secrets("ns").Create(context.TODO(), &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "mysecret"}}, metav1.CreateOptions{}); err != nil {
102 t.Fatal(err)
103 }
104 if _, err := superuserClient.CoreV1().Secrets("ns").Create(context.TODO(), &corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "mypvsecret"}}, metav1.CreateOptions{}); err != nil {
105 t.Fatal(err)
106 }
107 if _, err := superuserClient.CoreV1().ConfigMaps("ns").Create(context.TODO(), &corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "myconfigmap"}}, metav1.CreateOptions{}); err != nil {
108 t.Fatal(err)
109 }
110 if _, err := superuserClient.ResourceV1alpha2().ResourceClaims("ns").Create(context.TODO(), &v1alpha2.ResourceClaim{ObjectMeta: metav1.ObjectMeta{Name: "mynamedresourceclaim"}, Spec: v1alpha2.ResourceClaimSpec{ResourceClassName: "example.com"}}, metav1.CreateOptions{}); err != nil {
111 t.Fatal(err)
112 }
113 if _, err := superuserClient.ResourceV1alpha2().ResourceClaims("ns").Create(context.TODO(), &v1alpha2.ResourceClaim{ObjectMeta: metav1.ObjectMeta{Name: "mytemplatizedresourceclaim"}, Spec: v1alpha2.ResourceClaimSpec{ResourceClassName: "example.com"}}, metav1.CreateOptions{}); err != nil {
114 t.Fatal(err)
115 }
116
117 pvName := "mypv"
118 if _, err := superuserClientExternal.StorageV1().VolumeAttachments().Create(context.TODO(), &storagev1.VolumeAttachment{
119 ObjectMeta: metav1.ObjectMeta{Name: "myattachment"},
120 Spec: storagev1.VolumeAttachmentSpec{
121 Attacher: "foo",
122 Source: storagev1.VolumeAttachmentSource{PersistentVolumeName: &pvName},
123 NodeName: "node2",
124 },
125 }, metav1.CreateOptions{}); err != nil {
126 t.Fatal(err)
127 }
128 if _, err := superuserClient.CoreV1().PersistentVolumeClaims("ns").Create(context.TODO(), &corev1.PersistentVolumeClaim{
129 ObjectMeta: metav1.ObjectMeta{Name: "mypvc"},
130 Spec: corev1.PersistentVolumeClaimSpec{
131 AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadOnlyMany},
132 Resources: corev1.VolumeResourceRequirements{Requests: corev1.ResourceList{corev1.ResourceStorage: resource.MustParse("1")}},
133 },
134 }, metav1.CreateOptions{}); err != nil {
135 t.Fatal(err)
136 }
137
138 if _, err := superuserClient.CoreV1().PersistentVolumes().Create(context.TODO(), &corev1.PersistentVolume{
139 ObjectMeta: metav1.ObjectMeta{Name: "mypv"},
140 Spec: corev1.PersistentVolumeSpec{
141 AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadOnlyMany},
142 Capacity: corev1.ResourceList{corev1.ResourceStorage: resource.MustParse("1")},
143 ClaimRef: &corev1.ObjectReference{Namespace: "ns", Name: "mypvc"},
144 PersistentVolumeSource: corev1.PersistentVolumeSource{AzureFile: &corev1.AzureFilePersistentVolumeSource{ShareName: "default", SecretName: "mypvsecret"}},
145 },
146 }, metav1.CreateOptions{}); err != nil {
147 t.Fatal(err)
148 }
149
150 getSecret := func(client clientset.Interface) func() error {
151 return func() error {
152 _, err := client.CoreV1().Secrets("ns").Get(context.TODO(), "mysecret", metav1.GetOptions{})
153 return err
154 }
155 }
156 getPVSecret := func(client clientset.Interface) func() error {
157 return func() error {
158 _, err := client.CoreV1().Secrets("ns").Get(context.TODO(), "mypvsecret", metav1.GetOptions{})
159 return err
160 }
161 }
162 getConfigMap := func(client clientset.Interface) func() error {
163 return func() error {
164 _, err := client.CoreV1().ConfigMaps("ns").Get(context.TODO(), "myconfigmap", metav1.GetOptions{})
165 return err
166 }
167 }
168 getPVC := func(client clientset.Interface) func() error {
169 return func() error {
170 _, err := client.CoreV1().PersistentVolumeClaims("ns").Get(context.TODO(), "mypvc", metav1.GetOptions{})
171 return err
172 }
173 }
174 getPV := func(client clientset.Interface) func() error {
175 return func() error {
176 _, err := client.CoreV1().PersistentVolumes().Get(context.TODO(), "mypv", metav1.GetOptions{})
177 return err
178 }
179 }
180 getVolumeAttachment := func(client clientset.Interface) func() error {
181 return func() error {
182 _, err := client.StorageV1().VolumeAttachments().Get(context.TODO(), "myattachment", metav1.GetOptions{})
183 return err
184 }
185 }
186 getResourceClaim := func(client clientset.Interface) func() error {
187 return func() error {
188 _, err := client.ResourceV1alpha2().ResourceClaims("ns").Get(context.TODO(), "mynamedresourceclaim", metav1.GetOptions{})
189 return err
190 }
191 }
192 getResourceClaimTemplate := func(client clientset.Interface) func() error {
193 return func() error {
194 _, err := client.ResourceV1alpha2().ResourceClaims("ns").Get(context.TODO(), "mytemplatizedresourceclaim", metav1.GetOptions{})
195 return err
196 }
197 }
198 addResourceClaimTemplateReference := func(client clientset.Interface) func() error {
199 return func() error {
200 _, err := client.CoreV1().Pods("ns").Patch(context.TODO(), "node2normalpod", types.MergePatchType,
201 []byte(`{"status":{"resourceClaimStatuses":[{"name":"templateclaim","resourceClaimName":"mytemplatizedresourceclaim"}]}}`),
202 metav1.PatchOptions{}, "status")
203 return err
204 }
205 }
206 removeResourceClaimReference := func(client clientset.Interface) func() error {
207 return func() error {
208 _, err := client.CoreV1().Pods("ns").Patch(context.TODO(), "node2normalpod", types.MergePatchType,
209 []byte(`{"status":{"resourceClaimStatuses":null}}`),
210 metav1.PatchOptions{}, "status")
211 return err
212 }
213 }
214
215 createNode2NormalPod := func(client clientset.Interface) func() error {
216 return func() error {
217 _, err := client.CoreV1().Pods("ns").Create(context.TODO(), &corev1.Pod{
218 ObjectMeta: metav1.ObjectMeta{Name: "node2normalpod"},
219 Spec: corev1.PodSpec{
220 NodeName: "node2",
221 Containers: []corev1.Container{{Name: "image", Image: "busybox"}},
222 Volumes: []corev1.Volume{
223 {Name: "secret", VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "mysecret"}}},
224 {Name: "cm", VolumeSource: corev1.VolumeSource{ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: "myconfigmap"}}}},
225 {Name: "pvc", VolumeSource: corev1.VolumeSource{PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: "mypvc"}}},
226 },
227 ResourceClaims: []corev1.PodResourceClaim{
228 {Name: "namedclaim", Source: corev1.ClaimSource{ResourceClaimName: pointer.String("mynamedresourceclaim")}},
229 {Name: "templateclaim", Source: corev1.ClaimSource{ResourceClaimTemplateName: pointer.String("myresourceclaimtemplate")}},
230 },
231 },
232 }, metav1.CreateOptions{})
233 return err
234 }
235 }
236 updateNode2NormalPodStatus := func(client clientset.Interface) func() error {
237 return func() error {
238 startTime := metav1.NewTime(time.Now())
239 _, err := client.CoreV1().Pods("ns").UpdateStatus(context.TODO(), &corev1.Pod{
240 ObjectMeta: metav1.ObjectMeta{Name: "node2normalpod"},
241 Status: corev1.PodStatus{StartTime: &startTime},
242 }, metav1.UpdateOptions{})
243 return err
244 }
245 }
246 deleteNode2NormalPod := func(client clientset.Interface) func() error {
247 return func() error {
248 zero := int64(0)
249 return client.CoreV1().Pods("ns").Delete(context.TODO(), "node2normalpod", metav1.DeleteOptions{GracePeriodSeconds: &zero})
250 }
251 }
252
253 createNode2MirrorPod := func(client clientset.Interface) func() error {
254 return func() error {
255 const nodeName = "node2"
256 node, err := client.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{})
257 if err != nil {
258 return err
259 }
260 controller := true
261 _, err = client.CoreV1().Pods("ns").Create(context.TODO(), &corev1.Pod{
262 ObjectMeta: metav1.ObjectMeta{
263 Name: "node2mirrorpod",
264 Annotations: map[string]string{corev1.MirrorPodAnnotationKey: "true"},
265 OwnerReferences: []metav1.OwnerReference{{
266 APIVersion: corev1.SchemeGroupVersion.String(),
267 Kind: "Node",
268 Name: nodeName,
269 UID: node.UID,
270 Controller: &controller,
271 }},
272 },
273 Spec: corev1.PodSpec{
274 NodeName: nodeName,
275 Containers: []corev1.Container{{Name: "image", Image: "busybox"}},
276 },
277 }, metav1.CreateOptions{})
278 return err
279 }
280 }
281 deleteNode2MirrorPod := func(client clientset.Interface) func() error {
282 return func() error {
283 zero := int64(0)
284 return client.CoreV1().Pods("ns").Delete(context.TODO(), "node2mirrorpod", metav1.DeleteOptions{GracePeriodSeconds: &zero})
285 }
286 }
287
288 createNode2 := func(client clientset.Interface) func() error {
289 return func() error {
290 _, err := client.CoreV1().Nodes().Create(context.TODO(), &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: "node2"}}, metav1.CreateOptions{})
291 return err
292 }
293 }
294 updateNode2Status := func(client clientset.Interface) func() error {
295 return func() error {
296 _, err := client.CoreV1().Nodes().UpdateStatus(context.TODO(), &corev1.Node{
297 ObjectMeta: metav1.ObjectMeta{Name: "node2"},
298 Status: corev1.NodeStatus{},
299 }, metav1.UpdateOptions{})
300 return err
301 }
302 }
303 deleteNode2 := func(client clientset.Interface) func() error {
304 return func() error {
305 return client.CoreV1().Nodes().Delete(context.TODO(), "node2", metav1.DeleteOptions{})
306 }
307 }
308 createNode2NormalPodEviction := func(client clientset.Interface) func() error {
309 return func() error {
310 zero := int64(0)
311 return client.PolicyV1().Evictions("ns").Evict(context.TODO(), &policy.Eviction{
312 TypeMeta: metav1.TypeMeta{
313 APIVersion: "policy/v1",
314 Kind: "Eviction",
315 },
316 ObjectMeta: metav1.ObjectMeta{
317 Name: "node2normalpod",
318 Namespace: "ns",
319 },
320 DeleteOptions: &metav1.DeleteOptions{GracePeriodSeconds: &zero},
321 })
322 }
323 }
324 createNode2MirrorPodEviction := func(client clientset.Interface) func() error {
325 return func() error {
326 zero := int64(0)
327 return client.PolicyV1().Evictions("ns").Evict(context.TODO(), &policy.Eviction{
328 TypeMeta: metav1.TypeMeta{
329 APIVersion: "policy/v1",
330 Kind: "Eviction",
331 },
332 ObjectMeta: metav1.ObjectMeta{
333 Name: "node2mirrorpod",
334 Namespace: "ns",
335 },
336 DeleteOptions: &metav1.DeleteOptions{GracePeriodSeconds: &zero},
337 })
338 }
339 }
340
341 capacity := 50
342 updatePVCCapacity := func(client clientset.Interface) func() error {
343 return func() error {
344 capacity++
345 statusString := fmt.Sprintf("{\"status\": {\"capacity\": {\"storage\": \"%dG\"}}}", capacity)
346 patchBytes := []byte(statusString)
347 _, err := client.CoreV1().PersistentVolumeClaims("ns").Patch(context.TODO(), "mypvc", types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status")
348 return err
349 }
350 }
351
352 updatePVCPhase := func(client clientset.Interface) func() error {
353 return func() error {
354 patchBytes := []byte(`{"status":{"phase": "Bound"}}`)
355 _, err := client.CoreV1().PersistentVolumeClaims("ns").Patch(context.TODO(), "mypvc", types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status")
356 return err
357 }
358 }
359
360 getNode1Lease := func(client clientset.Interface) func() error {
361 return func() error {
362 _, err := client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Get(context.TODO(), "node1", metav1.GetOptions{})
363 return err
364 }
365 }
366 node1LeaseDurationSeconds := int32(40)
367 createNode1Lease := func(client clientset.Interface) func() error {
368 return func() error {
369 lease := &coordination.Lease{
370 ObjectMeta: metav1.ObjectMeta{
371 Name: "node1",
372 },
373 Spec: coordination.LeaseSpec{
374 HolderIdentity: pointer.String("node1"),
375 LeaseDurationSeconds: pointer.Int32(node1LeaseDurationSeconds),
376 RenewTime: &metav1.MicroTime{Time: time.Now()},
377 },
378 }
379 _, err := client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Create(context.TODO(), lease, metav1.CreateOptions{})
380 return err
381 }
382 }
383 updateNode1Lease := func(client clientset.Interface) func() error {
384 return func() error {
385 lease, err := client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Get(context.TODO(), "node1", metav1.GetOptions{})
386 if err != nil {
387 return err
388 }
389 lease.Spec.RenewTime = &metav1.MicroTime{Time: time.Now()}
390 _, err = client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Update(context.TODO(), lease, metav1.UpdateOptions{})
391 return err
392 }
393 }
394 patchNode1Lease := func(client clientset.Interface) func() error {
395 return func() error {
396 node1LeaseDurationSeconds++
397 bs := []byte(fmt.Sprintf(`{"spec": {"leaseDurationSeconds": %d}}`, node1LeaseDurationSeconds))
398 _, err := client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Patch(context.TODO(), "node1", types.StrategicMergePatchType, bs, metav1.PatchOptions{})
399 return err
400 }
401 }
402 deleteNode1Lease := func(client clientset.Interface) func() error {
403 return func() error {
404 return client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Delete(context.TODO(), "node1", metav1.DeleteOptions{})
405 }
406 }
407
408 getNode1CSINode := func(client clientset.Interface) func() error {
409 return func() error {
410 _, err := client.StorageV1().CSINodes().Get(context.TODO(), "node1", metav1.GetOptions{})
411 return err
412 }
413 }
414 createNode1CSINode := func(client clientset.Interface) func() error {
415 return func() error {
416 nodeInfo := &storagev1.CSINode{
417 ObjectMeta: metav1.ObjectMeta{
418 Name: "node1",
419 },
420 Spec: storagev1.CSINodeSpec{
421 Drivers: []storagev1.CSINodeDriver{
422 {
423 Name: "com.example.csi.driver1",
424 NodeID: "com.example.csi/node1",
425 TopologyKeys: []string{"com.example.csi/zone"},
426 },
427 },
428 },
429 }
430 _, err := client.StorageV1().CSINodes().Create(context.TODO(), nodeInfo, metav1.CreateOptions{})
431 return err
432 }
433 }
434 updateNode1CSINode := func(client clientset.Interface) func() error {
435 return func() error {
436 nodeInfo, err := client.StorageV1().CSINodes().Get(context.TODO(), "node1", metav1.GetOptions{})
437 if err != nil {
438 return err
439 }
440 nodeInfo.Spec.Drivers = []storagev1.CSINodeDriver{
441 {
442 Name: "com.example.csi.driver2",
443 NodeID: "com.example.csi/node1",
444 TopologyKeys: []string{"com.example.csi/rack"},
445 },
446 }
447 _, err = client.StorageV1().CSINodes().Update(context.TODO(), nodeInfo, metav1.UpdateOptions{})
448 return err
449 }
450 }
451 patchNode1CSINode := func(client clientset.Interface) func() error {
452 return func() error {
453 bs := []byte(fmt.Sprintf(`{"csiDrivers": [ { "driver": "net.example.storage.driver2", "nodeID": "net.example.storage/node1", "topologyKeys": [ "net.example.storage/region" ] } ] }`))
454
455 _, err := client.StorageV1().CSINodes().Patch(context.TODO(), "node1", types.MergePatchType, bs, metav1.PatchOptions{})
456 return err
457 }
458 }
459 deleteNode1CSINode := func(client clientset.Interface) func() error {
460 return func() error {
461 return client.StorageV1().CSINodes().Delete(context.TODO(), "node1", metav1.DeleteOptions{})
462 }
463 }
464
465 nodeanonClient, _ := clientsetForToken(tokenNodeUnknown, clientConfig)
466 node1Client, node1ClientExternal := clientsetForToken(tokenNode1, clientConfig)
467 node2Client, node2ClientExternal := clientsetForToken(tokenNode2, clientConfig)
468 _, csiNode1Client := clientsetForToken(tokenNode1, clientConfig)
469 _, csiNode2Client := clientsetForToken(tokenNode2, clientConfig)
470
471
472 expectForbidden(t, getSecret(nodeanonClient))
473 expectForbidden(t, getPVSecret(nodeanonClient))
474 expectForbidden(t, getConfigMap(nodeanonClient))
475 expectForbidden(t, getPVC(nodeanonClient))
476 expectForbidden(t, getPV(nodeanonClient))
477 expectForbidden(t, getResourceClaim(nodeanonClient))
478 expectForbidden(t, getResourceClaimTemplate(nodeanonClient))
479 expectForbidden(t, createNode2NormalPod(nodeanonClient))
480 expectForbidden(t, deleteNode2NormalPod(nodeanonClient))
481 expectForbidden(t, createNode2MirrorPodEviction(nodeanonClient))
482 expectForbidden(t, createNode2(nodeanonClient))
483 expectForbidden(t, updateNode2Status(nodeanonClient))
484 expectForbidden(t, deleteNode2(nodeanonClient))
485
486 expectForbidden(t, getSecret(node1Client))
487 expectForbidden(t, getPVSecret(node1Client))
488 expectForbidden(t, getConfigMap(node1Client))
489 expectForbidden(t, getPVC(node1Client))
490 expectForbidden(t, getPV(node1Client))
491 expectForbidden(t, getResourceClaim(node1Client))
492 expectForbidden(t, getResourceClaimTemplate(node1Client))
493 expectForbidden(t, createNode2NormalPod(nodeanonClient))
494 expectNotFound(t, createNode2MirrorPodEviction(node1Client))
495 expectForbidden(t, createNode2(node1Client))
496 expectNotFound(t, updateNode2Status(node1Client))
497 expectForbidden(t, deleteNode2(node1Client))
498
499
500 expectForbidden(t, getSecret(node2Client))
501 expectForbidden(t, getPVSecret(node2Client))
502 expectForbidden(t, getConfigMap(node2Client))
503 expectForbidden(t, getPVC(node2Client))
504 expectForbidden(t, getPV(node2Client))
505 expectForbidden(t, getResourceClaim(node2Client))
506 expectForbidden(t, getResourceClaimTemplate(node2Client))
507
508 expectForbidden(t, createNode2NormalPod(nodeanonClient))
509
510 expectAllowed(t, createNode2(node2Client))
511 expectAllowed(t, updateNode2Status(node2Client))
512 expectForbidden(t, createNode2MirrorPod(nodeanonClient))
513 expectForbidden(t, deleteNode2MirrorPod(nodeanonClient))
514 expectForbidden(t, createNode2MirrorPod(node1Client))
515 expectNotFound(t, deleteNode2MirrorPod(node1Client))
516
517 expectAllowed(t, createNode2NormalPod(superuserClient))
518
519 expectAllowed(t, createNode2MirrorPod(node2Client))
520 expectAllowed(t, deleteNode2MirrorPod(node2Client))
521 expectAllowed(t, createNode2MirrorPod(node2Client))
522 expectAllowed(t, createNode2MirrorPodEviction(node2Client))
523
524 expectForbidden(t, deleteNode2(node2Client))
525
526 expectForbidden(t, updateNode2Status(node1Client))
527
528
529 expectForbidden(t, getSecret(nodeanonClient))
530 expectForbidden(t, getPVSecret(nodeanonClient))
531 expectForbidden(t, getConfigMap(nodeanonClient))
532 expectForbidden(t, getPVC(nodeanonClient))
533 expectForbidden(t, getPV(nodeanonClient))
534 expectForbidden(t, getResourceClaim(nodeanonClient))
535 expectForbidden(t, getResourceClaimTemplate(nodeanonClient))
536 expectForbidden(t, createNode2NormalPod(nodeanonClient))
537 expectForbidden(t, updateNode2NormalPodStatus(nodeanonClient))
538 expectForbidden(t, deleteNode2NormalPod(nodeanonClient))
539 expectForbidden(t, createNode2NormalPodEviction(nodeanonClient))
540 expectForbidden(t, createNode2MirrorPod(nodeanonClient))
541 expectForbidden(t, deleteNode2MirrorPod(nodeanonClient))
542 expectForbidden(t, createNode2MirrorPodEviction(nodeanonClient))
543
544 expectForbidden(t, getSecret(node1Client))
545 expectForbidden(t, getPVSecret(node1Client))
546 expectForbidden(t, getConfigMap(node1Client))
547 expectForbidden(t, getPVC(node1Client))
548 expectForbidden(t, getPV(node1Client))
549 expectForbidden(t, getResourceClaim(node1Client))
550 expectForbidden(t, getResourceClaimTemplate(node1Client))
551 expectForbidden(t, createNode2NormalPod(node1Client))
552 expectForbidden(t, updateNode2NormalPodStatus(node1Client))
553 expectForbidden(t, deleteNode2NormalPod(node1Client))
554 expectForbidden(t, createNode2NormalPodEviction(node1Client))
555 expectForbidden(t, createNode2MirrorPod(node1Client))
556 expectNotFound(t, deleteNode2MirrorPod(node1Client))
557 expectNotFound(t, createNode2MirrorPodEviction(node1Client))
558
559
560 expectAllowed(t, getSecret(node2Client))
561 expectAllowed(t, getPVSecret(node2Client))
562 expectAllowed(t, getConfigMap(node2Client))
563 expectAllowed(t, getPVC(node2Client))
564 expectAllowed(t, getPV(node2Client))
565
566
567 expectAllowed(t, getResourceClaim(node2Client))
568 expectForbidden(t, getResourceClaimTemplate(node2Client))
569
570
571 expectForbidden(t, addResourceClaimTemplateReference(node2Client))
572
573 expectAllowed(t, addResourceClaimTemplateReference(superuserClient))
574
575 expectAllowed(t, getResourceClaim(node2Client))
576 expectAllowed(t, getResourceClaimTemplate(node2Client))
577
578
579 expectForbidden(t, removeResourceClaimReference(node2Client))
580
581 expectAllowed(t, removeResourceClaimReference(superuserClient))
582
583 expectAllowed(t, getResourceClaim(node2Client))
584 expectForbidden(t, getResourceClaimTemplate(node2Client))
585
586 expectForbidden(t, createNode2NormalPod(node2Client))
587 expectAllowed(t, updateNode2NormalPodStatus(node2Client))
588 expectAllowed(t, deleteNode2NormalPod(node2Client))
589 expectAllowed(t, createNode2MirrorPod(node2Client))
590 expectAllowed(t, deleteNode2MirrorPod(node2Client))
591
592
593 expectAllowed(t, createNode2NormalPod(superuserClient))
594 expectAllowed(t, createNode2MirrorPod(superuserClient))
595 expectAllowed(t, createNode2NormalPodEviction(node2Client))
596 expectAllowed(t, createNode2MirrorPodEviction(node2Client))
597
598 expectAllowed(t, deleteNode2(superuserClient))
599
600
601 expectAllowed(t, createNode2NormalPod(superuserClient))
602
603 expectForbidden(t, updatePVCCapacity(node1Client))
604 expectAllowed(t, updatePVCCapacity(node2Client))
605 expectForbidden(t, updatePVCPhase(node2Client))
606
607
608 expectForbidden(t, getVolumeAttachment(node1ClientExternal))
609 expectAllowed(t, getVolumeAttachment(node2ClientExternal))
610
611
612 expectAllowed(t, createNode2(node2Client))
613
614 expectAllowed(t, deleteNode2(superuserClient))
615
616
617
618
619 expectAllowed(t, createNode1Lease(node1Client))
620 expectAllowed(t, getNode1Lease(node1Client))
621 expectAllowed(t, updateNode1Lease(node1Client))
622 expectAllowed(t, patchNode1Lease(node1Client))
623 expectAllowed(t, deleteNode1Lease(node1Client))
624
625 expectForbidden(t, createNode1Lease(node2Client))
626 expectForbidden(t, getNode1Lease(node2Client))
627 expectForbidden(t, updateNode1Lease(node2Client))
628 expectForbidden(t, patchNode1Lease(node2Client))
629 expectForbidden(t, deleteNode1Lease(node2Client))
630
631
632 expectAllowed(t, createNode1CSINode(csiNode1Client))
633 expectAllowed(t, getNode1CSINode(csiNode1Client))
634 expectAllowed(t, updateNode1CSINode(csiNode1Client))
635 expectAllowed(t, patchNode1CSINode(csiNode1Client))
636 expectAllowed(t, deleteNode1CSINode(csiNode1Client))
637
638 expectForbidden(t, createNode1CSINode(csiNode2Client))
639 expectForbidden(t, getNode1CSINode(csiNode2Client))
640 expectForbidden(t, updateNode1CSINode(csiNode2Client))
641 expectForbidden(t, patchNode1CSINode(csiNode2Client))
642 expectForbidden(t, deleteNode1CSINode(csiNode2Client))
643 }
644
645
646
647
648 func expect(t *testing.T, f func() error, wantErr func(error) bool) (timeout bool, lastErr error) {
649 t.Helper()
650 err := wait.PollImmediate(time.Second, 30*time.Second, func() (bool, error) {
651 t.Helper()
652 lastErr = f()
653 if wantErr(lastErr) {
654 return true, nil
655 }
656 t.Logf("unexpected response, will retry: %v", lastErr)
657 return false, nil
658 })
659 return err == nil, lastErr
660 }
661
662 func expectForbidden(t *testing.T, f func() error) {
663 t.Helper()
664 if ok, err := expect(t, f, apierrors.IsForbidden); !ok {
665 t.Errorf("Expected forbidden error, got %v", err)
666 }
667 }
668
669 func expectNotFound(t *testing.T, f func() error) {
670 t.Helper()
671 if ok, err := expect(t, f, apierrors.IsNotFound); !ok {
672 t.Errorf("Expected notfound error, got %v", err)
673 }
674 }
675
676 func expectAllowed(t *testing.T, f func() error) {
677 t.Helper()
678 if ok, err := expect(t, f, func(e error) bool { return e == nil }); !ok {
679 t.Errorf("Expected no error, got %v", err)
680 }
681 }
682
View as plain text