...

Source file src/k8s.io/kubernetes/test/integration/auth/node_test.go

Documentation: k8s.io/kubernetes/test/integration/auth

     1  /*
     2  Copyright 2017 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 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  		// Define credentials
    49  		// Fake values for testing.
    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  		// The "default" SA is not installed, causing the ServiceAccount plugin to retry for ~1s per
    76  		// API request.
    77  		"--disable-admission-plugins", "ServiceAccount,TaintNodesByCondition",
    78  	}, framework.SharedEtcd())
    79  	defer server.TearDownFn()
    80  
    81  	// Build client config and superuser clientset
    82  	clientConfig := server.ClientConfig
    83  	superuserClient, superuserClientExternal := clientsetForToken(tokenMaster, clientConfig)
    84  
    85  	// Wait for a healthy server
    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  	// Create objects
    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  			// StrategicMergePatch is unsupported by CRs. Falling back to MergePatch
   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  	// all node requests from node1 and unknown node fail
   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  	// related object requests from node2 fail
   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  	// mirror pod and self node lifecycle is allowed
   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  	// create a pod as an admin to add object references
   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  	// self deletion is not allowed
   524  	expectForbidden(t, deleteNode2(node2Client))
   525  	// modification of another node's status is not allowed
   526  	expectForbidden(t, updateNode2Status(node1Client))
   527  
   528  	// unidentifiable node and node1 are still forbidden
   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  	// node2 can get referenced objects now
   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  	// node2 can only get direct claim references
   567  	expectAllowed(t, getResourceClaim(node2Client))
   568  	expectForbidden(t, getResourceClaimTemplate(node2Client))
   569  
   570  	// node cannot add a claim reference
   571  	expectForbidden(t, addResourceClaimTemplateReference(node2Client))
   572  	// superuser can add a claim reference
   573  	expectAllowed(t, addResourceClaimTemplateReference(superuserClient))
   574  	// node can get direct and template claim references
   575  	expectAllowed(t, getResourceClaim(node2Client))
   576  	expectAllowed(t, getResourceClaimTemplate(node2Client))
   577  
   578  	// node cannot remove a claim reference
   579  	expectForbidden(t, removeResourceClaimReference(node2Client))
   580  	// superuser can remove a claim reference
   581  	expectAllowed(t, removeResourceClaimReference(superuserClient))
   582  	// node2 can only get direct claim references
   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  	// recreate as an admin to test eviction
   593  	expectAllowed(t, createNode2NormalPod(superuserClient))
   594  	expectAllowed(t, createNode2MirrorPod(superuserClient))
   595  	expectAllowed(t, createNode2NormalPodEviction(node2Client))
   596  	expectAllowed(t, createNode2MirrorPodEviction(node2Client))
   597  	// clean up node2
   598  	expectAllowed(t, deleteNode2(superuserClient))
   599  
   600  	// re-create a pod as an admin to add object references
   601  	expectAllowed(t, createNode2NormalPod(superuserClient))
   602  
   603  	expectForbidden(t, updatePVCCapacity(node1Client))
   604  	expectAllowed(t, updatePVCCapacity(node2Client))
   605  	expectForbidden(t, updatePVCPhase(node2Client))
   606  
   607  	// Enabled CSIPersistentVolume feature
   608  	expectForbidden(t, getVolumeAttachment(node1ClientExternal))
   609  	expectAllowed(t, getVolumeAttachment(node2ClientExternal))
   610  
   611  	// create node2 again
   612  	expectAllowed(t, createNode2(node2Client))
   613  	// clean up node2
   614  	expectAllowed(t, deleteNode2(superuserClient))
   615  
   616  	//TODO(mikedanese): integration test node restriction of TokenRequest
   617  
   618  	// node1 allowed to operate on its own lease
   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  	// node2 not allowed to operate on another node's lease
   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  	// node1 allowed to operate on its own CSINode
   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  	// node2 not allowed to operate on another node's CSINode
   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  // expect executes a function a set number of times until it either returns the
   646  // expected error or executes too many times. It returns if the retries timed
   647  // out and the last error returned by the method.
   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