volumes_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  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 controlplane
  14. import (
  15. "fmt"
  16. "io/ioutil"
  17. "os"
  18. "reflect"
  19. "testing"
  20. "k8s.io/api/core/v1"
  21. kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
  22. kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
  23. )
  24. func TestGetEtcdCertVolumes(t *testing.T) {
  25. hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate
  26. k8sCertificatesDir := "/etc/kubernetes/pki"
  27. var tests = []struct {
  28. name, ca, cert, key string
  29. vol []v1.Volume
  30. volMount []v1.VolumeMount
  31. }{
  32. {
  33. name: "Should ignore files in /etc/ssl/certs",
  34. ca: "/etc/ssl/certs/my-etcd-ca.crt",
  35. cert: "/etc/ssl/certs/my-etcd.crt",
  36. key: "/etc/ssl/certs/my-etcd.key",
  37. vol: []v1.Volume{},
  38. volMount: []v1.VolumeMount{},
  39. },
  40. {
  41. name: "Should ignore files in subdirs of /etc/ssl/certs",
  42. ca: "/etc/ssl/certs/etcd/my-etcd-ca.crt",
  43. cert: "/etc/ssl/certs/etcd/my-etcd.crt",
  44. key: "/etc/ssl/certs/etcd/my-etcd.key",
  45. vol: []v1.Volume{},
  46. volMount: []v1.VolumeMount{},
  47. },
  48. {
  49. name: "Should ignore files in /etc/pki",
  50. ca: "/etc/pki/my-etcd-ca.crt",
  51. cert: "/etc/pki/my-etcd.crt",
  52. key: "/etc/pki/my-etcd.key",
  53. vol: []v1.Volume{},
  54. volMount: []v1.VolumeMount{},
  55. },
  56. {
  57. name: "Should ignore files in Kubernetes PKI directory (and subdirs)",
  58. ca: k8sCertificatesDir + "/ca/my-etcd-ca.crt",
  59. cert: k8sCertificatesDir + "/my-etcd.crt",
  60. key: k8sCertificatesDir + "/my-etcd.key",
  61. vol: []v1.Volume{},
  62. volMount: []v1.VolumeMount{},
  63. },
  64. {
  65. name: "All certs are in the same dir",
  66. ca: "/var/lib/certs/etcd/my-etcd-ca.crt",
  67. cert: "/var/lib/certs/etcd/my-etcd.crt",
  68. key: "/var/lib/certs/etcd/my-etcd.key",
  69. vol: []v1.Volume{
  70. {
  71. Name: "etcd-certs-0",
  72. VolumeSource: v1.VolumeSource{
  73. HostPath: &v1.HostPathVolumeSource{
  74. Path: "/var/lib/certs/etcd",
  75. Type: &hostPathDirectoryOrCreate,
  76. },
  77. },
  78. },
  79. },
  80. volMount: []v1.VolumeMount{
  81. {
  82. Name: "etcd-certs-0",
  83. MountPath: "/var/lib/certs/etcd",
  84. ReadOnly: true,
  85. },
  86. },
  87. },
  88. {
  89. name: "One file + two files in separate dirs",
  90. ca: "/etc/certs/etcd/my-etcd-ca.crt",
  91. cert: "/var/lib/certs/etcd/my-etcd.crt",
  92. key: "/var/lib/certs/etcd/my-etcd.key",
  93. vol: []v1.Volume{
  94. {
  95. Name: "etcd-certs-0",
  96. VolumeSource: v1.VolumeSource{
  97. HostPath: &v1.HostPathVolumeSource{
  98. Path: "/etc/certs/etcd",
  99. Type: &hostPathDirectoryOrCreate,
  100. },
  101. },
  102. },
  103. {
  104. Name: "etcd-certs-1",
  105. VolumeSource: v1.VolumeSource{
  106. HostPath: &v1.HostPathVolumeSource{
  107. Path: "/var/lib/certs/etcd",
  108. Type: &hostPathDirectoryOrCreate,
  109. },
  110. },
  111. },
  112. },
  113. volMount: []v1.VolumeMount{
  114. {
  115. Name: "etcd-certs-0",
  116. MountPath: "/etc/certs/etcd",
  117. ReadOnly: true,
  118. },
  119. {
  120. Name: "etcd-certs-1",
  121. MountPath: "/var/lib/certs/etcd",
  122. ReadOnly: true,
  123. },
  124. },
  125. },
  126. {
  127. name: "All three files in different directories",
  128. ca: "/etc/certs/etcd/my-etcd-ca.crt",
  129. cert: "/var/lib/certs/etcd/my-etcd.crt",
  130. key: "/var/lib/certs/private/my-etcd.key",
  131. vol: []v1.Volume{
  132. {
  133. Name: "etcd-certs-0",
  134. VolumeSource: v1.VolumeSource{
  135. HostPath: &v1.HostPathVolumeSource{
  136. Path: "/etc/certs/etcd",
  137. Type: &hostPathDirectoryOrCreate,
  138. },
  139. },
  140. },
  141. {
  142. Name: "etcd-certs-1",
  143. VolumeSource: v1.VolumeSource{
  144. HostPath: &v1.HostPathVolumeSource{
  145. Path: "/var/lib/certs/etcd",
  146. Type: &hostPathDirectoryOrCreate,
  147. },
  148. },
  149. },
  150. {
  151. Name: "etcd-certs-2",
  152. VolumeSource: v1.VolumeSource{
  153. HostPath: &v1.HostPathVolumeSource{
  154. Path: "/var/lib/certs/private",
  155. Type: &hostPathDirectoryOrCreate,
  156. },
  157. },
  158. },
  159. },
  160. volMount: []v1.VolumeMount{
  161. {
  162. Name: "etcd-certs-0",
  163. MountPath: "/etc/certs/etcd",
  164. ReadOnly: true,
  165. },
  166. {
  167. Name: "etcd-certs-1",
  168. MountPath: "/var/lib/certs/etcd",
  169. ReadOnly: true,
  170. },
  171. {
  172. Name: "etcd-certs-2",
  173. MountPath: "/var/lib/certs/private",
  174. ReadOnly: true,
  175. },
  176. },
  177. },
  178. {
  179. name: "The most top-level dir should be used",
  180. ca: "/etc/certs/etcd/my-etcd-ca.crt",
  181. cert: "/etc/certs/etcd/serving/my-etcd.crt",
  182. key: "/etc/certs/etcd/serving/my-etcd.key",
  183. vol: []v1.Volume{
  184. {
  185. Name: "etcd-certs-0",
  186. VolumeSource: v1.VolumeSource{
  187. HostPath: &v1.HostPathVolumeSource{
  188. Path: "/etc/certs/etcd",
  189. Type: &hostPathDirectoryOrCreate,
  190. },
  191. },
  192. },
  193. },
  194. volMount: []v1.VolumeMount{
  195. {
  196. Name: "etcd-certs-0",
  197. MountPath: "/etc/certs/etcd",
  198. ReadOnly: true,
  199. },
  200. },
  201. },
  202. {
  203. name: "The most top-level dir should be used, regardless of order",
  204. ca: "/etc/certs/etcd/ca/my-etcd-ca.crt",
  205. cert: "/etc/certs/etcd/my-etcd.crt",
  206. key: "/etc/certs/etcd/my-etcd.key",
  207. vol: []v1.Volume{
  208. {
  209. Name: "etcd-certs-0",
  210. VolumeSource: v1.VolumeSource{
  211. HostPath: &v1.HostPathVolumeSource{
  212. Path: "/etc/certs/etcd",
  213. Type: &hostPathDirectoryOrCreate,
  214. },
  215. },
  216. },
  217. },
  218. volMount: []v1.VolumeMount{
  219. {
  220. Name: "etcd-certs-0",
  221. MountPath: "/etc/certs/etcd",
  222. ReadOnly: true,
  223. },
  224. },
  225. },
  226. }
  227. for _, rt := range tests {
  228. t.Run(rt.name, func(t *testing.T) {
  229. actualVol, actualVolMount := getEtcdCertVolumes(&kubeadmapi.ExternalEtcd{
  230. CAFile: rt.ca,
  231. CertFile: rt.cert,
  232. KeyFile: rt.key,
  233. }, k8sCertificatesDir)
  234. if !reflect.DeepEqual(actualVol, rt.vol) {
  235. t.Errorf(
  236. "failed getEtcdCertVolumes:\n\texpected: %v\n\t actual: %v",
  237. rt.vol,
  238. actualVol,
  239. )
  240. }
  241. if !reflect.DeepEqual(actualVolMount, rt.volMount) {
  242. t.Errorf(
  243. "failed getEtcdCertVolumes:\n\texpected: %v\n\t actual: %v",
  244. rt.volMount,
  245. actualVolMount,
  246. )
  247. }
  248. })
  249. }
  250. }
  251. func TestGetHostPathVolumesForTheControlPlane(t *testing.T) {
  252. hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate
  253. hostPathFileOrCreate := v1.HostPathFileOrCreate
  254. volMap := make(map[string]map[string]v1.Volume)
  255. volMap[kubeadmconstants.KubeAPIServer] = map[string]v1.Volume{}
  256. volMap[kubeadmconstants.KubeAPIServer]["k8s-certs"] = v1.Volume{
  257. Name: "k8s-certs",
  258. VolumeSource: v1.VolumeSource{
  259. HostPath: &v1.HostPathVolumeSource{
  260. Path: testCertsDir,
  261. Type: &hostPathDirectoryOrCreate,
  262. },
  263. },
  264. }
  265. volMap[kubeadmconstants.KubeAPIServer]["ca-certs"] = v1.Volume{
  266. Name: "ca-certs",
  267. VolumeSource: v1.VolumeSource{
  268. HostPath: &v1.HostPathVolumeSource{
  269. Path: "/etc/ssl/certs",
  270. Type: &hostPathDirectoryOrCreate,
  271. },
  272. },
  273. }
  274. volMap[kubeadmconstants.KubeControllerManager] = map[string]v1.Volume{}
  275. volMap[kubeadmconstants.KubeControllerManager]["k8s-certs"] = v1.Volume{
  276. Name: "k8s-certs",
  277. VolumeSource: v1.VolumeSource{
  278. HostPath: &v1.HostPathVolumeSource{
  279. Path: testCertsDir,
  280. Type: &hostPathDirectoryOrCreate,
  281. },
  282. },
  283. }
  284. volMap[kubeadmconstants.KubeControllerManager]["ca-certs"] = v1.Volume{
  285. Name: "ca-certs",
  286. VolumeSource: v1.VolumeSource{
  287. HostPath: &v1.HostPathVolumeSource{
  288. Path: "/etc/ssl/certs",
  289. Type: &hostPathDirectoryOrCreate,
  290. },
  291. },
  292. }
  293. volMap[kubeadmconstants.KubeControllerManager]["kubeconfig"] = v1.Volume{
  294. Name: "kubeconfig",
  295. VolumeSource: v1.VolumeSource{
  296. HostPath: &v1.HostPathVolumeSource{
  297. Path: "/etc/kubernetes/controller-manager.conf",
  298. Type: &hostPathFileOrCreate,
  299. },
  300. },
  301. }
  302. volMap[kubeadmconstants.KubeScheduler] = map[string]v1.Volume{}
  303. volMap[kubeadmconstants.KubeScheduler]["kubeconfig"] = v1.Volume{
  304. Name: "kubeconfig",
  305. VolumeSource: v1.VolumeSource{
  306. HostPath: &v1.HostPathVolumeSource{
  307. Path: "/etc/kubernetes/scheduler.conf",
  308. Type: &hostPathFileOrCreate,
  309. },
  310. },
  311. }
  312. volMountMap := make(map[string]map[string]v1.VolumeMount)
  313. volMountMap[kubeadmconstants.KubeAPIServer] = map[string]v1.VolumeMount{}
  314. volMountMap[kubeadmconstants.KubeAPIServer]["k8s-certs"] = v1.VolumeMount{
  315. Name: "k8s-certs",
  316. MountPath: testCertsDir,
  317. ReadOnly: true,
  318. }
  319. volMountMap[kubeadmconstants.KubeAPIServer]["ca-certs"] = v1.VolumeMount{
  320. Name: "ca-certs",
  321. MountPath: "/etc/ssl/certs",
  322. ReadOnly: true,
  323. }
  324. volMountMap[kubeadmconstants.KubeControllerManager] = map[string]v1.VolumeMount{}
  325. volMountMap[kubeadmconstants.KubeControllerManager]["k8s-certs"] = v1.VolumeMount{
  326. Name: "k8s-certs",
  327. MountPath: testCertsDir,
  328. ReadOnly: true,
  329. }
  330. volMountMap[kubeadmconstants.KubeControllerManager]["ca-certs"] = v1.VolumeMount{
  331. Name: "ca-certs",
  332. MountPath: "/etc/ssl/certs",
  333. ReadOnly: true,
  334. }
  335. volMountMap[kubeadmconstants.KubeControllerManager]["kubeconfig"] = v1.VolumeMount{
  336. Name: "kubeconfig",
  337. MountPath: "/etc/kubernetes/controller-manager.conf",
  338. ReadOnly: true,
  339. }
  340. volMountMap[kubeadmconstants.KubeScheduler] = map[string]v1.VolumeMount{}
  341. volMountMap[kubeadmconstants.KubeScheduler]["kubeconfig"] = v1.VolumeMount{
  342. Name: "kubeconfig",
  343. MountPath: "/etc/kubernetes/scheduler.conf",
  344. ReadOnly: true,
  345. }
  346. volMap2 := make(map[string]map[string]v1.Volume)
  347. volMap2[kubeadmconstants.KubeAPIServer] = map[string]v1.Volume{}
  348. volMap2[kubeadmconstants.KubeAPIServer]["k8s-certs"] = v1.Volume{
  349. Name: "k8s-certs",
  350. VolumeSource: v1.VolumeSource{
  351. HostPath: &v1.HostPathVolumeSource{
  352. Path: testCertsDir,
  353. Type: &hostPathDirectoryOrCreate,
  354. },
  355. },
  356. }
  357. volMap2[kubeadmconstants.KubeAPIServer]["ca-certs"] = v1.Volume{
  358. Name: "ca-certs",
  359. VolumeSource: v1.VolumeSource{
  360. HostPath: &v1.HostPathVolumeSource{
  361. Path: "/etc/ssl/certs",
  362. Type: &hostPathDirectoryOrCreate,
  363. },
  364. },
  365. }
  366. volMap2[kubeadmconstants.KubeAPIServer]["etcd-certs-0"] = v1.Volume{
  367. Name: "etcd-certs-0",
  368. VolumeSource: v1.VolumeSource{
  369. HostPath: &v1.HostPathVolumeSource{
  370. Path: "/etc/certs/etcd",
  371. Type: &hostPathDirectoryOrCreate,
  372. },
  373. },
  374. }
  375. volMap2[kubeadmconstants.KubeAPIServer]["etcd-certs-1"] = v1.Volume{
  376. Name: "etcd-certs-1",
  377. VolumeSource: v1.VolumeSource{
  378. HostPath: &v1.HostPathVolumeSource{
  379. Path: "/var/lib/etcd/certs",
  380. Type: &hostPathDirectoryOrCreate,
  381. },
  382. },
  383. }
  384. volMap2[kubeadmconstants.KubeControllerManager] = map[string]v1.Volume{}
  385. volMap2[kubeadmconstants.KubeControllerManager]["k8s-certs"] = v1.Volume{
  386. Name: "k8s-certs",
  387. VolumeSource: v1.VolumeSource{
  388. HostPath: &v1.HostPathVolumeSource{
  389. Path: testCertsDir,
  390. Type: &hostPathDirectoryOrCreate,
  391. },
  392. },
  393. }
  394. volMap2[kubeadmconstants.KubeControllerManager]["ca-certs"] = v1.Volume{
  395. Name: "ca-certs",
  396. VolumeSource: v1.VolumeSource{
  397. HostPath: &v1.HostPathVolumeSource{
  398. Path: "/etc/ssl/certs",
  399. Type: &hostPathDirectoryOrCreate,
  400. },
  401. },
  402. }
  403. volMap2[kubeadmconstants.KubeControllerManager]["kubeconfig"] = v1.Volume{
  404. Name: "kubeconfig",
  405. VolumeSource: v1.VolumeSource{
  406. HostPath: &v1.HostPathVolumeSource{
  407. Path: "/etc/kubernetes/controller-manager.conf",
  408. Type: &hostPathFileOrCreate,
  409. },
  410. },
  411. }
  412. volMap2[kubeadmconstants.KubeScheduler] = map[string]v1.Volume{}
  413. volMap2[kubeadmconstants.KubeScheduler]["kubeconfig"] = v1.Volume{
  414. Name: "kubeconfig",
  415. VolumeSource: v1.VolumeSource{
  416. HostPath: &v1.HostPathVolumeSource{
  417. Path: "/etc/kubernetes/scheduler.conf",
  418. Type: &hostPathFileOrCreate,
  419. },
  420. },
  421. }
  422. volMountMap2 := make(map[string]map[string]v1.VolumeMount)
  423. volMountMap2[kubeadmconstants.KubeAPIServer] = map[string]v1.VolumeMount{}
  424. volMountMap2[kubeadmconstants.KubeAPIServer]["k8s-certs"] = v1.VolumeMount{
  425. Name: "k8s-certs",
  426. MountPath: testCertsDir,
  427. ReadOnly: true,
  428. }
  429. volMountMap2[kubeadmconstants.KubeAPIServer]["ca-certs"] = v1.VolumeMount{
  430. Name: "ca-certs",
  431. MountPath: "/etc/ssl/certs",
  432. ReadOnly: true,
  433. }
  434. volMountMap2[kubeadmconstants.KubeAPIServer]["etcd-certs-0"] = v1.VolumeMount{
  435. Name: "etcd-certs-0",
  436. MountPath: "/etc/certs/etcd",
  437. ReadOnly: true,
  438. }
  439. volMountMap2[kubeadmconstants.KubeAPIServer]["etcd-certs-1"] = v1.VolumeMount{
  440. Name: "etcd-certs-1",
  441. MountPath: "/var/lib/etcd/certs",
  442. ReadOnly: true,
  443. }
  444. volMountMap2[kubeadmconstants.KubeControllerManager] = map[string]v1.VolumeMount{}
  445. volMountMap2[kubeadmconstants.KubeControllerManager]["k8s-certs"] = v1.VolumeMount{
  446. Name: "k8s-certs",
  447. MountPath: testCertsDir,
  448. ReadOnly: true,
  449. }
  450. volMountMap2[kubeadmconstants.KubeControllerManager]["ca-certs"] = v1.VolumeMount{
  451. Name: "ca-certs",
  452. MountPath: "/etc/ssl/certs",
  453. ReadOnly: true,
  454. }
  455. volMountMap2[kubeadmconstants.KubeControllerManager]["kubeconfig"] = v1.VolumeMount{
  456. Name: "kubeconfig",
  457. MountPath: "/etc/kubernetes/controller-manager.conf",
  458. ReadOnly: true,
  459. }
  460. volMountMap2[kubeadmconstants.KubeScheduler] = map[string]v1.VolumeMount{}
  461. volMountMap2[kubeadmconstants.KubeScheduler]["kubeconfig"] = v1.VolumeMount{
  462. Name: "kubeconfig",
  463. MountPath: "/etc/kubernetes/scheduler.conf",
  464. ReadOnly: true,
  465. }
  466. var tests = []struct {
  467. name string
  468. cfg *kubeadmapi.ClusterConfiguration
  469. vol map[string]map[string]v1.Volume
  470. volMount map[string]map[string]v1.VolumeMount
  471. }{
  472. {
  473. name: "Should ignore files in /etc/ssl/certs",
  474. cfg: &kubeadmapi.ClusterConfiguration{
  475. CertificatesDir: testCertsDir,
  476. Etcd: kubeadmapi.Etcd{},
  477. },
  478. vol: volMap,
  479. volMount: volMountMap,
  480. },
  481. {
  482. name: "Should ignore files in /etc/ssl/certs and in CertificatesDir",
  483. cfg: &kubeadmapi.ClusterConfiguration{
  484. CertificatesDir: testCertsDir,
  485. Etcd: kubeadmapi.Etcd{
  486. External: &kubeadmapi.ExternalEtcd{
  487. Endpoints: []string{"foo"},
  488. CAFile: "/etc/certs/etcd/my-etcd-ca.crt",
  489. CertFile: testCertsDir + "/etcd/my-etcd.crt",
  490. KeyFile: "/var/lib/etcd/certs/my-etcd.key",
  491. },
  492. },
  493. },
  494. vol: volMap2,
  495. volMount: volMountMap2,
  496. },
  497. }
  498. tmpdir, err := ioutil.TempDir("", "")
  499. if err != nil {
  500. t.Fatalf("Couldn't create tmpdir")
  501. }
  502. defer os.RemoveAll(tmpdir)
  503. // set up tmp caCertsExtraVolumePaths for testing
  504. caCertsExtraVolumePaths = []string{fmt.Sprintf("%s/etc/pki", tmpdir), fmt.Sprintf("%s/usr/share/ca-certificates", tmpdir)}
  505. defer func() { caCertsExtraVolumePaths = []string{"/etc/pki", "/usr/share/ca-certificates"} }()
  506. for _, rt := range tests {
  507. t.Run(rt.name, func(t *testing.T) {
  508. mounts := getHostPathVolumesForTheControlPlane(rt.cfg)
  509. // Avoid unit test errors when the flexvolume is mounted
  510. delete(mounts.volumes[kubeadmconstants.KubeControllerManager], flexvolumeDirVolumeName)
  511. delete(mounts.volumeMounts[kubeadmconstants.KubeControllerManager], flexvolumeDirVolumeName)
  512. if !reflect.DeepEqual(mounts.volumes, rt.vol) {
  513. t.Errorf(
  514. "failed getHostPathVolumesForTheControlPlane:\n\texpected: %v\n\t actual: %v",
  515. rt.vol,
  516. mounts.volumes,
  517. )
  518. }
  519. if !reflect.DeepEqual(mounts.volumeMounts, rt.volMount) {
  520. t.Errorf(
  521. "failed getHostPathVolumesForTheControlPlane:\n\texpected: %v\n\t actual: %v",
  522. rt.volMount,
  523. mounts.volumeMounts,
  524. )
  525. }
  526. })
  527. }
  528. }
  529. func TestAddExtraHostPathMounts(t *testing.T) {
  530. mounts := newControlPlaneHostPathMounts()
  531. hostPathDirectoryOrCreate := v1.HostPathDirectoryOrCreate
  532. hostPathFileOrCreate := v1.HostPathFileOrCreate
  533. vols := []v1.Volume{
  534. {
  535. Name: "foo",
  536. VolumeSource: v1.VolumeSource{
  537. HostPath: &v1.HostPathVolumeSource{
  538. Path: "/tmp/foo",
  539. Type: &hostPathDirectoryOrCreate,
  540. },
  541. },
  542. },
  543. {
  544. Name: "bar",
  545. VolumeSource: v1.VolumeSource{
  546. HostPath: &v1.HostPathVolumeSource{
  547. Path: "/tmp/bar",
  548. Type: &hostPathFileOrCreate,
  549. },
  550. },
  551. },
  552. }
  553. volMounts := []v1.VolumeMount{
  554. {
  555. Name: "foo",
  556. MountPath: "/tmp/foo",
  557. ReadOnly: true,
  558. },
  559. {
  560. Name: "bar",
  561. MountPath: "/tmp/bar",
  562. ReadOnly: true,
  563. },
  564. }
  565. mounts.AddHostPathMounts("component", vols, volMounts)
  566. hostPathMounts := []kubeadmapi.HostPathMount{
  567. {
  568. Name: "foo-0",
  569. HostPath: "/tmp/qux-0",
  570. MountPath: "/tmp/qux-0",
  571. ReadOnly: true,
  572. PathType: v1.HostPathFile,
  573. },
  574. {
  575. Name: "bar-0",
  576. HostPath: "/tmp/asd-0",
  577. MountPath: "/tmp/asd-0",
  578. ReadOnly: false,
  579. PathType: v1.HostPathDirectory,
  580. },
  581. {
  582. Name: "foo-1",
  583. HostPath: "/tmp/qux-1",
  584. MountPath: "/tmp/qux-1",
  585. ReadOnly: true,
  586. PathType: v1.HostPathFileOrCreate,
  587. },
  588. {
  589. Name: "bar-1",
  590. HostPath: "/tmp/asd-1",
  591. MountPath: "/tmp/asd-1",
  592. ReadOnly: false,
  593. PathType: v1.HostPathDirectoryOrCreate,
  594. },
  595. }
  596. mounts.AddExtraHostPathMounts("component", hostPathMounts)
  597. for _, hostMount := range hostPathMounts {
  598. t.Run(hostMount.Name, func(t *testing.T) {
  599. volumeName := hostMount.Name
  600. if _, ok := mounts.volumes["component"][volumeName]; !ok {
  601. t.Errorf("Expected to find volume %q", volumeName)
  602. }
  603. vol := mounts.volumes["component"][volumeName]
  604. if vol.Name != volumeName {
  605. t.Errorf("Expected volume name %q", volumeName)
  606. }
  607. if vol.HostPath.Path != hostMount.HostPath {
  608. t.Errorf("Expected host path %q", hostMount.HostPath)
  609. }
  610. if _, ok := mounts.volumeMounts["component"][volumeName]; !ok {
  611. t.Errorf("Expected to find volume mount %q", volumeName)
  612. }
  613. if *vol.HostPath.Type != v1.HostPathType(hostMount.PathType) {
  614. t.Errorf("Expected to host path type %q", hostMount.PathType)
  615. }
  616. volMount := mounts.volumeMounts["component"][volumeName]
  617. if volMount.Name != volumeName {
  618. t.Errorf("Expected volume mount name %q", volumeName)
  619. }
  620. if volMount.MountPath != hostMount.MountPath {
  621. t.Errorf("Expected container path %q", hostMount.MountPath)
  622. }
  623. if volMount.ReadOnly != hostMount.ReadOnly {
  624. t.Errorf("Expected volume readOnly setting %t", hostMount.ReadOnly)
  625. }
  626. })
  627. }
  628. }