node_test.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package auth
  14. import (
  15. "fmt"
  16. "io/ioutil"
  17. "strings"
  18. "testing"
  19. "time"
  20. coordination "k8s.io/api/coordination/v1"
  21. corev1 "k8s.io/api/core/v1"
  22. policy "k8s.io/api/policy/v1beta1"
  23. storagev1 "k8s.io/api/storage/v1"
  24. storagev1beta1 "k8s.io/api/storage/v1beta1"
  25. apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
  26. "k8s.io/apimachinery/pkg/api/errors"
  27. "k8s.io/apimachinery/pkg/api/resource"
  28. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  29. "k8s.io/apimachinery/pkg/runtime"
  30. "k8s.io/apimachinery/pkg/types"
  31. "k8s.io/apimachinery/pkg/util/wait"
  32. utilfeature "k8s.io/apiserver/pkg/util/feature"
  33. clientset "k8s.io/client-go/kubernetes"
  34. "k8s.io/client-go/kubernetes/scheme"
  35. featuregatetesting "k8s.io/component-base/featuregate/testing"
  36. kubeapiservertesting "k8s.io/kubernetes/cmd/kube-apiserver/app/testing"
  37. "k8s.io/kubernetes/pkg/features"
  38. "k8s.io/kubernetes/test/integration/framework"
  39. "k8s.io/utils/pointer"
  40. )
  41. func TestNodeAuthorizer(t *testing.T) {
  42. const (
  43. // Define credentials
  44. tokenMaster = "master-token"
  45. tokenNodeUnknown = "unknown-token"
  46. tokenNode1 = "node1-token"
  47. tokenNode2 = "node2-token"
  48. )
  49. // Enable DynamicKubeletConfig feature so that Node.Spec.ConfigSource can be set
  50. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.DynamicKubeletConfig, true)()
  51. // Enable NodeLease feature so that nodes can create leases
  52. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeLease, true)()
  53. // Enable CSINodeInfo feature so that nodes can create CSINode objects.
  54. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSINodeInfo, true)()
  55. tokenFile, err := ioutil.TempFile("", "kubeconfig")
  56. if err != nil {
  57. t.Fatal(err)
  58. }
  59. tokenFile.WriteString(strings.Join([]string{
  60. fmt.Sprintf(`%s,admin,uid1,"system:masters"`, tokenMaster),
  61. fmt.Sprintf(`%s,unknown,uid2,"system:nodes"`, tokenNodeUnknown),
  62. fmt.Sprintf(`%s,system:node:node1,uid3,"system:nodes"`, tokenNode1),
  63. fmt.Sprintf(`%s,system:node:node2,uid4,"system:nodes"`, tokenNode2),
  64. }, "\n"))
  65. tokenFile.Close()
  66. server := kubeapiservertesting.StartTestServerOrDie(t, nil, []string{
  67. "--authorization-mode", "Node,RBAC",
  68. "--token-auth-file", tokenFile.Name(),
  69. "--enable-admission-plugins", "NodeRestriction",
  70. // The "default" SA is not installed, causing the ServiceAccount plugin to retry for ~1s per
  71. // API request.
  72. "--disable-admission-plugins", "ServiceAccount,TaintNodesByCondition",
  73. }, framework.SharedEtcd())
  74. defer server.TearDownFn()
  75. // Build client config and superuser clientset
  76. clientConfig := server.ClientConfig
  77. superuserClient, superuserClientExternal := clientsetForToken(tokenMaster, clientConfig)
  78. // Wait for a healthy server
  79. for {
  80. result := superuserClient.CoreV1().RESTClient().Get().AbsPath("/healthz").Do()
  81. _, err := result.Raw()
  82. if err == nil {
  83. break
  84. }
  85. t.Log(err)
  86. time.Sleep(time.Second)
  87. }
  88. // Create objects
  89. if _, err := superuserClient.CoreV1().Namespaces().Create(&corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "ns"}}); err != nil {
  90. t.Fatal(err)
  91. }
  92. if _, err := superuserClient.CoreV1().Secrets("ns").Create(&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "mysecret"}}); err != nil {
  93. t.Fatal(err)
  94. }
  95. if _, err := superuserClient.CoreV1().Secrets("ns").Create(&corev1.Secret{ObjectMeta: metav1.ObjectMeta{Name: "mypvsecret"}}); err != nil {
  96. t.Fatal(err)
  97. }
  98. if _, err := superuserClient.CoreV1().ConfigMaps("ns").Create(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "myconfigmap"}}); err != nil {
  99. t.Fatal(err)
  100. }
  101. if _, err := superuserClient.CoreV1().ConfigMaps("ns").Create(&corev1.ConfigMap{ObjectMeta: metav1.ObjectMeta{Name: "myconfigmapconfigsource"}}); err != nil {
  102. t.Fatal(err)
  103. }
  104. pvName := "mypv"
  105. if _, err := superuserClientExternal.StorageV1().VolumeAttachments().Create(&storagev1.VolumeAttachment{
  106. ObjectMeta: metav1.ObjectMeta{Name: "myattachment"},
  107. Spec: storagev1.VolumeAttachmentSpec{
  108. Attacher: "foo",
  109. Source: storagev1.VolumeAttachmentSource{PersistentVolumeName: &pvName},
  110. NodeName: "node2",
  111. },
  112. }); err != nil {
  113. t.Fatal(err)
  114. }
  115. if _, err := superuserClient.CoreV1().PersistentVolumeClaims("ns").Create(&corev1.PersistentVolumeClaim{
  116. ObjectMeta: metav1.ObjectMeta{Name: "mypvc"},
  117. Spec: corev1.PersistentVolumeClaimSpec{
  118. AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadOnlyMany},
  119. Resources: corev1.ResourceRequirements{Requests: corev1.ResourceList{corev1.ResourceStorage: resource.MustParse("1")}},
  120. },
  121. }); err != nil {
  122. t.Fatal(err)
  123. }
  124. if _, err := superuserClient.CoreV1().PersistentVolumes().Create(&corev1.PersistentVolume{
  125. ObjectMeta: metav1.ObjectMeta{Name: "mypv"},
  126. Spec: corev1.PersistentVolumeSpec{
  127. AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadOnlyMany},
  128. Capacity: corev1.ResourceList{corev1.ResourceStorage: resource.MustParse("1")},
  129. ClaimRef: &corev1.ObjectReference{Namespace: "ns", Name: "mypvc"},
  130. PersistentVolumeSource: corev1.PersistentVolumeSource{AzureFile: &corev1.AzureFilePersistentVolumeSource{ShareName: "default", SecretName: "mypvsecret"}},
  131. },
  132. }); err != nil {
  133. t.Fatal(err)
  134. }
  135. getSecret := func(client clientset.Interface) func() error {
  136. return func() error {
  137. _, err := client.CoreV1().Secrets("ns").Get("mysecret", metav1.GetOptions{})
  138. return err
  139. }
  140. }
  141. getPVSecret := func(client clientset.Interface) func() error {
  142. return func() error {
  143. _, err := client.CoreV1().Secrets("ns").Get("mypvsecret", metav1.GetOptions{})
  144. return err
  145. }
  146. }
  147. getConfigMap := func(client clientset.Interface) func() error {
  148. return func() error {
  149. _, err := client.CoreV1().ConfigMaps("ns").Get("myconfigmap", metav1.GetOptions{})
  150. return err
  151. }
  152. }
  153. getConfigMapConfigSource := func(client clientset.Interface) func() error {
  154. return func() error {
  155. _, err := client.CoreV1().ConfigMaps("ns").Get("myconfigmapconfigsource", metav1.GetOptions{})
  156. return err
  157. }
  158. }
  159. getPVC := func(client clientset.Interface) func() error {
  160. return func() error {
  161. _, err := client.CoreV1().PersistentVolumeClaims("ns").Get("mypvc", metav1.GetOptions{})
  162. return err
  163. }
  164. }
  165. getPV := func(client clientset.Interface) func() error {
  166. return func() error {
  167. _, err := client.CoreV1().PersistentVolumes().Get("mypv", metav1.GetOptions{})
  168. return err
  169. }
  170. }
  171. getVolumeAttachment := func(client clientset.Interface) func() error {
  172. return func() error {
  173. _, err := client.StorageV1().VolumeAttachments().Get("myattachment", metav1.GetOptions{})
  174. return err
  175. }
  176. }
  177. createNode2NormalPod := func(client clientset.Interface) func() error {
  178. return func() error {
  179. _, err := client.CoreV1().Pods("ns").Create(&corev1.Pod{
  180. ObjectMeta: metav1.ObjectMeta{Name: "node2normalpod"},
  181. Spec: corev1.PodSpec{
  182. NodeName: "node2",
  183. Containers: []corev1.Container{{Name: "image", Image: "busybox"}},
  184. Volumes: []corev1.Volume{
  185. {Name: "secret", VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{SecretName: "mysecret"}}},
  186. {Name: "cm", VolumeSource: corev1.VolumeSource{ConfigMap: &corev1.ConfigMapVolumeSource{LocalObjectReference: corev1.LocalObjectReference{Name: "myconfigmap"}}}},
  187. {Name: "pvc", VolumeSource: corev1.VolumeSource{PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ClaimName: "mypvc"}}},
  188. },
  189. },
  190. })
  191. return err
  192. }
  193. }
  194. updateNode2NormalPodStatus := func(client clientset.Interface) func() error {
  195. return func() error {
  196. startTime := metav1.NewTime(time.Now())
  197. _, err := client.CoreV1().Pods("ns").UpdateStatus(&corev1.Pod{
  198. ObjectMeta: metav1.ObjectMeta{Name: "node2normalpod"},
  199. Status: corev1.PodStatus{StartTime: &startTime},
  200. })
  201. return err
  202. }
  203. }
  204. deleteNode2NormalPod := func(client clientset.Interface) func() error {
  205. return func() error {
  206. zero := int64(0)
  207. return client.CoreV1().Pods("ns").Delete("node2normalpod", &metav1.DeleteOptions{GracePeriodSeconds: &zero})
  208. }
  209. }
  210. createNode2MirrorPod := func(client clientset.Interface) func() error {
  211. return func() error {
  212. _, err := client.CoreV1().Pods("ns").Create(&corev1.Pod{
  213. ObjectMeta: metav1.ObjectMeta{
  214. Name: "node2mirrorpod",
  215. Annotations: map[string]string{corev1.MirrorPodAnnotationKey: "true"},
  216. },
  217. Spec: corev1.PodSpec{
  218. NodeName: "node2",
  219. Containers: []corev1.Container{{Name: "image", Image: "busybox"}},
  220. },
  221. })
  222. return err
  223. }
  224. }
  225. deleteNode2MirrorPod := func(client clientset.Interface) func() error {
  226. return func() error {
  227. zero := int64(0)
  228. return client.CoreV1().Pods("ns").Delete("node2mirrorpod", &metav1.DeleteOptions{GracePeriodSeconds: &zero})
  229. }
  230. }
  231. createNode2 := func(client clientset.Interface) func() error {
  232. return func() error {
  233. _, err := client.CoreV1().Nodes().Create(&corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: "node2"}})
  234. return err
  235. }
  236. }
  237. setNode2ConfigSource := func(client clientset.Interface) func() error {
  238. return func() error {
  239. node2, err := client.CoreV1().Nodes().Get("node2", metav1.GetOptions{})
  240. if err != nil {
  241. return err
  242. }
  243. node2.Spec.ConfigSource = &corev1.NodeConfigSource{
  244. ConfigMap: &corev1.ConfigMapNodeConfigSource{
  245. Namespace: "ns",
  246. Name: "myconfigmapconfigsource",
  247. KubeletConfigKey: "kubelet",
  248. },
  249. }
  250. _, err = client.CoreV1().Nodes().Update(node2)
  251. return err
  252. }
  253. }
  254. unsetNode2ConfigSource := func(client clientset.Interface) func() error {
  255. return func() error {
  256. node2, err := client.CoreV1().Nodes().Get("node2", metav1.GetOptions{})
  257. if err != nil {
  258. return err
  259. }
  260. node2.Spec.ConfigSource = nil
  261. _, err = client.CoreV1().Nodes().Update(node2)
  262. return err
  263. }
  264. }
  265. updateNode2Status := func(client clientset.Interface) func() error {
  266. return func() error {
  267. _, err := client.CoreV1().Nodes().UpdateStatus(&corev1.Node{
  268. ObjectMeta: metav1.ObjectMeta{Name: "node2"},
  269. Status: corev1.NodeStatus{},
  270. })
  271. return err
  272. }
  273. }
  274. deleteNode2 := func(client clientset.Interface) func() error {
  275. return func() error {
  276. return client.CoreV1().Nodes().Delete("node2", nil)
  277. }
  278. }
  279. createNode2NormalPodEviction := func(client clientset.Interface) func() error {
  280. return func() error {
  281. zero := int64(0)
  282. return client.PolicyV1beta1().Evictions("ns").Evict(&policy.Eviction{
  283. TypeMeta: metav1.TypeMeta{
  284. APIVersion: "policy/v1beta1",
  285. Kind: "Eviction",
  286. },
  287. ObjectMeta: metav1.ObjectMeta{
  288. Name: "node2normalpod",
  289. Namespace: "ns",
  290. },
  291. DeleteOptions: &metav1.DeleteOptions{GracePeriodSeconds: &zero},
  292. })
  293. }
  294. }
  295. createNode2MirrorPodEviction := func(client clientset.Interface) func() error {
  296. return func() error {
  297. zero := int64(0)
  298. return client.PolicyV1beta1().Evictions("ns").Evict(&policy.Eviction{
  299. TypeMeta: metav1.TypeMeta{
  300. APIVersion: "policy/v1beta1",
  301. Kind: "Eviction",
  302. },
  303. ObjectMeta: metav1.ObjectMeta{
  304. Name: "node2mirrorpod",
  305. Namespace: "ns",
  306. },
  307. DeleteOptions: &metav1.DeleteOptions{GracePeriodSeconds: &zero},
  308. })
  309. }
  310. }
  311. capacity := 50
  312. updatePVCCapacity := func(client clientset.Interface) func() error {
  313. return func() error {
  314. capacity++
  315. statusString := fmt.Sprintf("{\"status\": {\"capacity\": {\"storage\": \"%dG\"}}}", capacity)
  316. patchBytes := []byte(statusString)
  317. _, err := client.CoreV1().PersistentVolumeClaims("ns").Patch("mypvc", types.StrategicMergePatchType, patchBytes, "status")
  318. return err
  319. }
  320. }
  321. updatePVCPhase := func(client clientset.Interface) func() error {
  322. return func() error {
  323. patchBytes := []byte(`{"status":{"phase": "Bound"}}`)
  324. _, err := client.CoreV1().PersistentVolumeClaims("ns").Patch("mypvc", types.StrategicMergePatchType, patchBytes, "status")
  325. return err
  326. }
  327. }
  328. getNode1Lease := func(client clientset.Interface) func() error {
  329. return func() error {
  330. _, err := client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Get("node1", metav1.GetOptions{})
  331. return err
  332. }
  333. }
  334. node1LeaseDurationSeconds := int32(40)
  335. createNode1Lease := func(client clientset.Interface) func() error {
  336. return func() error {
  337. lease := &coordination.Lease{
  338. ObjectMeta: metav1.ObjectMeta{
  339. Name: "node1",
  340. },
  341. Spec: coordination.LeaseSpec{
  342. HolderIdentity: pointer.StringPtr("node1"),
  343. LeaseDurationSeconds: pointer.Int32Ptr(node1LeaseDurationSeconds),
  344. RenewTime: &metav1.MicroTime{Time: time.Now()},
  345. },
  346. }
  347. _, err := client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Create(lease)
  348. return err
  349. }
  350. }
  351. updateNode1Lease := func(client clientset.Interface) func() error {
  352. return func() error {
  353. lease, err := client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Get("node1", metav1.GetOptions{})
  354. if err != nil {
  355. return err
  356. }
  357. lease.Spec.RenewTime = &metav1.MicroTime{Time: time.Now()}
  358. _, err = client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Update(lease)
  359. return err
  360. }
  361. }
  362. patchNode1Lease := func(client clientset.Interface) func() error {
  363. return func() error {
  364. node1LeaseDurationSeconds++
  365. bs := []byte(fmt.Sprintf(`{"spec": {"leaseDurationSeconds": %d}}`, node1LeaseDurationSeconds))
  366. _, err := client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Patch("node1", types.StrategicMergePatchType, bs)
  367. return err
  368. }
  369. }
  370. deleteNode1Lease := func(client clientset.Interface) func() error {
  371. return func() error {
  372. return client.CoordinationV1().Leases(corev1.NamespaceNodeLease).Delete("node1", &metav1.DeleteOptions{})
  373. }
  374. }
  375. getNode1CSINode := func(client clientset.Interface) func() error {
  376. return func() error {
  377. _, err := client.StorageV1beta1().CSINodes().Get("node1", metav1.GetOptions{})
  378. return err
  379. }
  380. }
  381. createNode1CSINode := func(client clientset.Interface) func() error {
  382. return func() error {
  383. nodeInfo := &storagev1beta1.CSINode{
  384. ObjectMeta: metav1.ObjectMeta{
  385. Name: "node1",
  386. },
  387. Spec: storagev1beta1.CSINodeSpec{
  388. Drivers: []storagev1beta1.CSINodeDriver{
  389. {
  390. Name: "com.example.csi.driver1",
  391. NodeID: "com.example.csi/node1",
  392. TopologyKeys: []string{"com.example.csi/zone"},
  393. },
  394. },
  395. },
  396. }
  397. _, err := client.StorageV1beta1().CSINodes().Create(nodeInfo)
  398. return err
  399. }
  400. }
  401. updateNode1CSINode := func(client clientset.Interface) func() error {
  402. return func() error {
  403. nodeInfo, err := client.StorageV1beta1().CSINodes().Get("node1", metav1.GetOptions{})
  404. if err != nil {
  405. return err
  406. }
  407. nodeInfo.Spec.Drivers = []storagev1beta1.CSINodeDriver{
  408. {
  409. Name: "com.example.csi.driver2",
  410. NodeID: "com.example.csi/node1",
  411. TopologyKeys: []string{"com.example.csi/rack"},
  412. },
  413. }
  414. _, err = client.StorageV1beta1().CSINodes().Update(nodeInfo)
  415. return err
  416. }
  417. }
  418. patchNode1CSINode := func(client clientset.Interface) func() error {
  419. return func() error {
  420. bs := []byte(fmt.Sprintf(`{"csiDrivers": [ { "driver": "net.example.storage.driver2", "nodeID": "net.example.storage/node1", "topologyKeys": [ "net.example.storage/region" ] } ] }`))
  421. // StrategicMergePatch is unsupported by CRs. Falling back to MergePatch
  422. _, err := client.StorageV1beta1().CSINodes().Patch("node1", types.MergePatchType, bs)
  423. return err
  424. }
  425. }
  426. deleteNode1CSINode := func(client clientset.Interface) func() error {
  427. return func() error {
  428. return client.StorageV1beta1().CSINodes().Delete("node1", &metav1.DeleteOptions{})
  429. }
  430. }
  431. nodeanonClient, _ := clientsetForToken(tokenNodeUnknown, clientConfig)
  432. node1Client, node1ClientExternal := clientsetForToken(tokenNode1, clientConfig)
  433. node2Client, node2ClientExternal := clientsetForToken(tokenNode2, clientConfig)
  434. _, csiNode1Client := clientsetForToken(tokenNode1, clientConfig)
  435. _, csiNode2Client := clientsetForToken(tokenNode2, clientConfig)
  436. // all node requests from node1 and unknown node fail
  437. expectForbidden(t, getSecret(nodeanonClient))
  438. expectForbidden(t, getPVSecret(nodeanonClient))
  439. expectForbidden(t, getConfigMap(nodeanonClient))
  440. expectForbidden(t, getPVC(nodeanonClient))
  441. expectForbidden(t, getPV(nodeanonClient))
  442. expectForbidden(t, createNode2NormalPod(nodeanonClient))
  443. expectForbidden(t, createNode2MirrorPod(nodeanonClient))
  444. expectForbidden(t, deleteNode2NormalPod(nodeanonClient))
  445. expectForbidden(t, deleteNode2MirrorPod(nodeanonClient))
  446. expectForbidden(t, createNode2MirrorPodEviction(nodeanonClient))
  447. expectForbidden(t, createNode2(nodeanonClient))
  448. expectForbidden(t, updateNode2Status(nodeanonClient))
  449. expectForbidden(t, deleteNode2(nodeanonClient))
  450. expectForbidden(t, getSecret(node1Client))
  451. expectForbidden(t, getPVSecret(node1Client))
  452. expectForbidden(t, getConfigMap(node1Client))
  453. expectForbidden(t, getPVC(node1Client))
  454. expectForbidden(t, getPV(node1Client))
  455. expectForbidden(t, createNode2NormalPod(nodeanonClient))
  456. expectForbidden(t, createNode2MirrorPod(node1Client))
  457. expectNotFound(t, deleteNode2MirrorPod(node1Client))
  458. expectNotFound(t, createNode2MirrorPodEviction(node1Client))
  459. expectForbidden(t, createNode2(node1Client))
  460. expectForbidden(t, updateNode2Status(node1Client))
  461. expectForbidden(t, deleteNode2(node1Client))
  462. // related object requests from node2 fail
  463. expectForbidden(t, getSecret(node2Client))
  464. expectForbidden(t, getPVSecret(node2Client))
  465. expectForbidden(t, getConfigMap(node2Client))
  466. expectForbidden(t, getPVC(node2Client))
  467. expectForbidden(t, getPV(node2Client))
  468. expectForbidden(t, createNode2NormalPod(nodeanonClient))
  469. // mirror pod and self node lifecycle is allowed
  470. expectAllowed(t, createNode2MirrorPod(node2Client))
  471. expectAllowed(t, deleteNode2MirrorPod(node2Client))
  472. expectAllowed(t, createNode2MirrorPod(node2Client))
  473. expectAllowed(t, createNode2MirrorPodEviction(node2Client))
  474. expectAllowed(t, createNode2(node2Client))
  475. expectAllowed(t, updateNode2Status(node2Client))
  476. // self deletion is not allowed
  477. expectForbidden(t, deleteNode2(node2Client))
  478. // clean up node2
  479. expectAllowed(t, deleteNode2(superuserClient))
  480. // create a pod as an admin to add object references
  481. expectAllowed(t, createNode2NormalPod(superuserClient))
  482. // unidentifiable node and node1 are still forbidden
  483. expectForbidden(t, getSecret(nodeanonClient))
  484. expectForbidden(t, getPVSecret(nodeanonClient))
  485. expectForbidden(t, getConfigMap(nodeanonClient))
  486. expectForbidden(t, getPVC(nodeanonClient))
  487. expectForbidden(t, getPV(nodeanonClient))
  488. expectForbidden(t, createNode2NormalPod(nodeanonClient))
  489. expectForbidden(t, updateNode2NormalPodStatus(nodeanonClient))
  490. expectForbidden(t, deleteNode2NormalPod(nodeanonClient))
  491. expectForbidden(t, createNode2NormalPodEviction(nodeanonClient))
  492. expectForbidden(t, createNode2MirrorPod(nodeanonClient))
  493. expectForbidden(t, deleteNode2MirrorPod(nodeanonClient))
  494. expectForbidden(t, createNode2MirrorPodEviction(nodeanonClient))
  495. expectForbidden(t, getSecret(node1Client))
  496. expectForbidden(t, getPVSecret(node1Client))
  497. expectForbidden(t, getConfigMap(node1Client))
  498. expectForbidden(t, getPVC(node1Client))
  499. expectForbidden(t, getPV(node1Client))
  500. expectForbidden(t, createNode2NormalPod(node1Client))
  501. expectForbidden(t, updateNode2NormalPodStatus(node1Client))
  502. expectForbidden(t, deleteNode2NormalPod(node1Client))
  503. expectForbidden(t, createNode2NormalPodEviction(node1Client))
  504. expectForbidden(t, createNode2MirrorPod(node1Client))
  505. expectNotFound(t, deleteNode2MirrorPod(node1Client))
  506. expectNotFound(t, createNode2MirrorPodEviction(node1Client))
  507. // node2 can get referenced objects now
  508. expectAllowed(t, getSecret(node2Client))
  509. expectAllowed(t, getPVSecret(node2Client))
  510. expectAllowed(t, getConfigMap(node2Client))
  511. expectAllowed(t, getPVC(node2Client))
  512. expectAllowed(t, getPV(node2Client))
  513. expectForbidden(t, createNode2NormalPod(node2Client))
  514. expectAllowed(t, updateNode2NormalPodStatus(node2Client))
  515. expectAllowed(t, deleteNode2NormalPod(node2Client))
  516. expectAllowed(t, createNode2MirrorPod(node2Client))
  517. expectAllowed(t, deleteNode2MirrorPod(node2Client))
  518. // recreate as an admin to test eviction
  519. expectAllowed(t, createNode2NormalPod(superuserClient))
  520. expectAllowed(t, createNode2MirrorPod(superuserClient))
  521. expectAllowed(t, createNode2NormalPodEviction(node2Client))
  522. expectAllowed(t, createNode2MirrorPodEviction(node2Client))
  523. // re-create a pod as an admin to add object references
  524. expectAllowed(t, createNode2NormalPod(superuserClient))
  525. // ExpandPersistentVolumes feature disabled
  526. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, false)()
  527. expectForbidden(t, updatePVCCapacity(node1Client))
  528. expectForbidden(t, updatePVCCapacity(node2Client))
  529. // ExpandPersistentVolumes feature enabled
  530. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExpandPersistentVolumes, true)()
  531. expectForbidden(t, updatePVCCapacity(node1Client))
  532. expectAllowed(t, updatePVCCapacity(node2Client))
  533. expectForbidden(t, updatePVCPhase(node2Client))
  534. // Enabled CSIPersistentVolume feature
  535. expectForbidden(t, getVolumeAttachment(node1ClientExternal))
  536. expectAllowed(t, getVolumeAttachment(node2ClientExternal))
  537. // create node2 again
  538. expectAllowed(t, createNode2(node2Client))
  539. // node2 can not set its own config source
  540. expectForbidden(t, setNode2ConfigSource(node2Client))
  541. // node2 can not access the configmap config source yet
  542. expectForbidden(t, getConfigMapConfigSource(node2Client))
  543. // superuser can access the configmap config source
  544. expectAllowed(t, getConfigMapConfigSource(superuserClient))
  545. // superuser can set node2's config source
  546. expectAllowed(t, setNode2ConfigSource(superuserClient))
  547. // node2 can now get the configmap assigned as its config source
  548. expectAllowed(t, getConfigMapConfigSource(node2Client))
  549. // superuser can unset node2's config source
  550. expectAllowed(t, unsetNode2ConfigSource(superuserClient))
  551. // node2 can no longer get the configmap after it is unassigned as its config source
  552. expectForbidden(t, getConfigMapConfigSource(node2Client))
  553. // clean up node2
  554. expectAllowed(t, deleteNode2(superuserClient))
  555. //TODO(mikedanese): integration test node restriction of TokenRequest
  556. // node1 allowed to operate on its own lease
  557. expectAllowed(t, createNode1Lease(node1Client))
  558. expectAllowed(t, getNode1Lease(node1Client))
  559. expectAllowed(t, updateNode1Lease(node1Client))
  560. expectAllowed(t, patchNode1Lease(node1Client))
  561. expectAllowed(t, deleteNode1Lease(node1Client))
  562. // node2 not allowed to operate on another node's lease
  563. expectForbidden(t, createNode1Lease(node2Client))
  564. expectForbidden(t, getNode1Lease(node2Client))
  565. expectForbidden(t, updateNode1Lease(node2Client))
  566. expectForbidden(t, patchNode1Lease(node2Client))
  567. expectForbidden(t, deleteNode1Lease(node2Client))
  568. // node1 allowed to operate on its own CSINode
  569. expectAllowed(t, createNode1CSINode(csiNode1Client))
  570. expectAllowed(t, getNode1CSINode(csiNode1Client))
  571. expectAllowed(t, updateNode1CSINode(csiNode1Client))
  572. expectAllowed(t, patchNode1CSINode(csiNode1Client))
  573. expectAllowed(t, deleteNode1CSINode(csiNode1Client))
  574. // node2 not allowed to operate on another node's CSINode
  575. expectForbidden(t, createNode1CSINode(csiNode2Client))
  576. expectForbidden(t, getNode1CSINode(csiNode2Client))
  577. expectForbidden(t, updateNode1CSINode(csiNode2Client))
  578. expectForbidden(t, patchNode1CSINode(csiNode2Client))
  579. expectForbidden(t, deleteNode1CSINode(csiNode2Client))
  580. }
  581. // expect executes a function a set number of times until it either returns the
  582. // expected error or executes too many times. It returns if the retries timed
  583. // out and the last error returned by the method.
  584. func expect(t *testing.T, f func() error, wantErr func(error) bool) (timeout bool, lastErr error) {
  585. t.Helper()
  586. err := wait.PollImmediate(time.Second, 30*time.Second, func() (bool, error) {
  587. t.Helper()
  588. lastErr = f()
  589. if wantErr(lastErr) {
  590. return true, nil
  591. }
  592. t.Logf("unexpected response, will retry: %v", lastErr)
  593. return false, nil
  594. })
  595. return err == nil, lastErr
  596. }
  597. func expectForbidden(t *testing.T, f func() error) {
  598. t.Helper()
  599. if ok, err := expect(t, f, errors.IsForbidden); !ok {
  600. t.Errorf("Expected forbidden error, got %v", err)
  601. }
  602. }
  603. func expectNotFound(t *testing.T, f func() error) {
  604. t.Helper()
  605. if ok, err := expect(t, f, errors.IsNotFound); !ok {
  606. t.Errorf("Expected notfound error, got %v", err)
  607. }
  608. }
  609. func expectAllowed(t *testing.T, f func() error) {
  610. t.Helper()
  611. if ok, err := expect(t, f, func(e error) bool { return e == nil }); !ok {
  612. t.Errorf("Expected no error, got %v", err)
  613. }
  614. }
  615. // crdFromManifest reads a .json/yaml file and returns the CRD in it.
  616. func crdFromManifest(filename string) (*apiextensionsv1beta1.CustomResourceDefinition, error) {
  617. var crd apiextensionsv1beta1.CustomResourceDefinition
  618. data, err := ioutil.ReadFile(filename)
  619. if err != nil {
  620. return nil, err
  621. }
  622. if err := runtime.DecodeInto(scheme.Codecs.UniversalDecoder(), data, &crd); err != nil {
  623. return nil, err
  624. }
  625. return &crd, nil
  626. }