1
2
3
4 package krusty_test
5
6 import (
7 "os"
8 "testing"
9
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/require"
12 kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
13 "sigs.k8s.io/kustomize/kyaml/openapi"
14 "sigs.k8s.io/kustomize/kyaml/openapi/kubernetesapi"
15 )
16
17 func writeTestSchema(th kusttest_test.Harness, filepath string) {
18 bytes, _ := os.ReadFile("./testdata/customschema.json")
19 th.WriteF(filepath+"mycrd_schema.json", string(bytes))
20 }
21
22 func writeTestSchemaYaml(th kusttest_test.Harness, filepath string) {
23 bytes, _ := os.ReadFile("./testdata/customschema.yaml")
24 th.WriteF(filepath+"mycrd_schema.yaml", string(bytes))
25 }
26
27 func writeCustomResource(th kusttest_test.Harness, filepath string) {
28 th.WriteF(filepath, `
29 apiVersion: example.com/v1alpha1
30 kind: MyCRD
31 metadata:
32 name: service
33 spec:
34 template:
35 spec:
36 containers:
37 - name: server
38 image: server
39 command: example
40 ports:
41 - name: grpc
42 protocol: TCP
43 containerPort: 8080
44 `)
45 }
46
47 func writeOtherCustomResource(th kusttest_test.Harness, filepath string) {
48 th.WriteF(filepath, `
49 apiVersion: v1alpha1
50 kind: MyCRD
51 metadata:
52 name: service
53 spec:
54 template:
55 spec:
56 containers:
57 - name: server
58 image: server
59 command: example
60 ports:
61 - name: grpc
62 protocol: TCP
63 containerPort: 8080
64 `)
65 }
66
67 func writeTestComponentWithCustomSchema(th kusttest_test.Harness) {
68 writeTestSchema(th, "comp/")
69 openapi.ResetOpenAPI()
70 th.WriteC("comp", `
71 openapi:
72 path: mycrd_schema.json
73 `)
74 th.WriteF("comp/stub.yaml", `
75 apiVersion: v1
76 kind: Deployment
77 metadata:
78 name: stub
79 spec:
80 replicas: 1
81 `)
82 }
83
84 const customSchemaPatch = `
85 patchesStrategicMerge:
86 - |-
87 apiVersion: example.com/v1alpha1
88 kind: MyCRD
89 metadata:
90 name: service
91 spec:
92 template:
93 spec:
94 containers:
95 - name: server
96 image: nginx
97 `
98
99 const customSchemaPatchMultipleGvks = `
100 patchesStrategicMerge:
101 - |-
102 apiVersion: example.com/v1alpha1
103 kind: MyCRD
104 metadata:
105 name: service
106 spec:
107 template:
108 spec:
109 containers:
110 - name: server
111 image: nginx
112 - |-
113 apiVersion: v1alpha1
114 kind: MyCRD
115 metadata:
116 name: service
117 spec:
118 template:
119 spec:
120 containers:
121 - name: server
122 image: nginx
123 `
124
125 const patchedCustomResource = `
126 apiVersion: example.com/v1alpha1
127 kind: MyCRD
128 metadata:
129 name: service
130 spec:
131 template:
132 spec:
133 containers:
134 - command: example
135 image: nginx
136 name: server
137 ports:
138 - containerPort: 8080
139 name: grpc
140 protocol: TCP
141 `
142
143 func runOpenApiTest(t *testing.T, test func(t *testing.T)) {
144 t.Helper()
145 openapi.ResetOpenAPI()
146 test(t)
147 openapi.ResetOpenAPI()
148 }
149
150
151 func TestCustomOpenApiFieldBasicUsage(t *testing.T) {
152 runOpenApiTest(t, func(t *testing.T) {
153 t.Helper()
154 th := kusttest_test.MakeHarness(t)
155 th.WriteK(".", `
156 resources:
157 - mycrd.yaml
158 openapi:
159 path: mycrd_schema.json
160 `+customSchemaPatch)
161 writeCustomResource(th, "mycrd.yaml")
162 writeTestSchema(th, "./")
163 m := th.Run(".", th.MakeDefaultOptions())
164 th.AssertActualEqualsExpected(m, patchedCustomResource)
165 })
166 }
167
168 func TestCustomOpenApiFieldBasicUsageWithRemoteSchema(t *testing.T) {
169 runOpenApiTest(t, func(t *testing.T) {
170 t.Helper()
171 th := kusttest_test.MakeHarness(t)
172 th.WriteK(".", `
173 resources:
174 - mycrd.yaml
175 openapi:
176 path: https://github.com/kubernetes-sigs/kustomize/raw/master/api/krusty/testdata/customschema.json
177 `+customSchemaPatch)
178 writeCustomResource(th, "mycrd.yaml")
179 writeTestSchema(th, "./")
180 m := th.Run(".", th.MakeDefaultOptions())
181 th.AssertActualEqualsExpected(m, patchedCustomResource)
182 })
183 }
184
185 func TestCustomOpenApiFieldWithTwoGvks(t *testing.T) {
186 runOpenApiTest(t, func(t *testing.T) {
187 t.Helper()
188 th := kusttest_test.MakeHarness(t)
189 th.WriteK(".", `
190 resources:
191 - mycrd.yaml
192 - myothercrd.yaml
193 openapi:
194 path: mycrd_schema.json
195 `+customSchemaPatchMultipleGvks)
196 writeCustomResource(th, "mycrd.yaml")
197 writeOtherCustomResource(th, "myothercrd.yaml")
198 writeTestSchema(th, "./")
199 m := th.Run(".", th.MakeDefaultOptions())
200 th.AssertActualEqualsExpected(m, `apiVersion: example.com/v1alpha1
201 kind: MyCRD
202 metadata:
203 name: service
204 spec:
205 template:
206 spec:
207 containers:
208 - command: example
209 image: nginx
210 name: server
211 ports:
212 - containerPort: 8080
213 name: grpc
214 protocol: TCP
215 ---
216 apiVersion: v1alpha1
217 kind: MyCRD
218 metadata:
219 name: service
220 spec:
221 template:
222 spec:
223 containers:
224 - command: example
225 image: nginx
226 name: server
227 ports:
228 - containerPort: 8080
229 name: grpc
230 protocol: TCP
231 `)
232 })
233 }
234
235 func TestCustomOpenApiFieldYaml(t *testing.T) {
236 runOpenApiTest(t, func(t *testing.T) {
237 t.Helper()
238 th := kusttest_test.MakeHarness(t)
239 th.WriteK(".", `
240 resources:
241 - mycrd.yaml
242 openapi:
243 path: mycrd_schema.yaml
244 `+customSchemaPatch)
245 writeCustomResource(th, "mycrd.yaml")
246 writeTestSchemaYaml(th, "./")
247 m := th.Run(".", th.MakeDefaultOptions())
248 th.AssertActualEqualsExpected(m, patchedCustomResource)
249 })
250 }
251
252
253
254 func TestCustomOpenApiFieldBothPathAndVersion(t *testing.T) {
255 runOpenApiTest(t, func(t *testing.T) {
256 t.Helper()
257 th := kusttest_test.MakeHarness(t)
258 th.WriteK(".", `
259 resources:
260 - mycrd.yaml
261 openapi:
262 version: v1.21.2
263 path: mycrd_schema.json
264 `+customSchemaPatch)
265 writeCustomResource(th, "mycrd.yaml")
266 writeTestSchema(th, "./")
267 err := th.RunWithErr(".", th.MakeDefaultOptions())
268 require.Error(t, err)
269 assert.Equal(t,
270 "builtin version and custom schema provided, cannot use both",
271 err.Error())
272 })
273 }
274
275
276 func TestCustomOpenApiFieldFileNotFound(t *testing.T) {
277 runOpenApiTest(t, func(t *testing.T) {
278 t.Helper()
279 th := kusttest_test.MakeHarness(t)
280 th.WriteK(".", `
281 resources:
282 - mycrd.yaml
283 openapi:
284 path: mycrd_schema.json
285 `+customSchemaPatch)
286 writeCustomResource(th, "mycrd.yaml")
287 err := th.RunWithErr(".", th.MakeDefaultOptions())
288 require.Error(t, err)
289 assert.Equal(t,
290 "'/mycrd_schema.json' doesn't exist",
291 err.Error())
292 })
293 }
294
295 func TestCustomOpenApiFieldFromBase(t *testing.T) {
296 runOpenApiTest(t, func(t *testing.T) {
297 t.Helper()
298 th := kusttest_test.MakeHarness(t)
299 th.WriteK("base", `
300 resources:
301 - mycrd.yaml
302 openapi:
303 path: mycrd_schema.json
304 `)
305 th.WriteK("overlay", `
306 resources:
307 - ../base
308 `+customSchemaPatch)
309 writeCustomResource(th, "base/mycrd.yaml")
310 writeTestSchema(th, "base/")
311 m := th.Run("overlay", th.MakeDefaultOptions())
312 th.AssertActualEqualsExpected(m, patchedCustomResource)
313 assert.Equal(t, "using custom schema from file provided",
314 openapi.GetSchemaVersion())
315 })
316 }
317
318 func TestCustomOpenApiFieldFromBaseWithRemoteSchema(t *testing.T) {
319 runOpenApiTest(t, func(t *testing.T) {
320 t.Helper()
321 th := kusttest_test.MakeHarness(t)
322 th.WriteK("base", `
323 resources:
324 - mycrd.yaml
325 openapi:
326 path: https://github.com/kubernetes-sigs/kustomize/raw/master/api/krusty/testdata/customschema.json
327 `)
328 th.WriteK("overlay", `
329 resources:
330 - ../base
331 `+customSchemaPatch)
332 writeCustomResource(th, "base/mycrd.yaml")
333 writeTestSchema(th, "base/")
334 m := th.Run("overlay", th.MakeDefaultOptions())
335 th.AssertActualEqualsExpected(m, patchedCustomResource)
336 assert.Equal(t, "using custom schema from file provided",
337 openapi.GetSchemaVersion())
338 })
339 }
340
341 func TestCustomOpenApiFieldFromOverlay(t *testing.T) {
342 runOpenApiTest(t, func(t *testing.T) {
343 t.Helper()
344 th := kusttest_test.MakeHarness(t)
345 th.WriteK("base", `
346 resources:
347 - mycrd.yaml
348 `)
349 th.WriteK("overlay", `
350 resources:
351 - ../base
352 openapi:
353 path: mycrd_schema.json
354 `+customSchemaPatch)
355 writeCustomResource(th, "base/mycrd.yaml")
356 writeTestSchema(th, "overlay/")
357 m := th.Run("overlay", th.MakeDefaultOptions())
358 th.AssertActualEqualsExpected(m, patchedCustomResource)
359 assert.Equal(t, "using custom schema from file provided",
360 openapi.GetSchemaVersion())
361 })
362 }
363
364 func TestCustomOpenApiFieldFromOverlayWithRemoteSchema(t *testing.T) {
365 runOpenApiTest(t, func(t *testing.T) {
366 t.Helper()
367 th := kusttest_test.MakeHarness(t)
368 th.WriteK("base", `
369 resources:
370 - mycrd.yaml
371 `)
372 th.WriteK("overlay", `
373 resources:
374 - ../base
375 openapi:
376 path: https://github.com/kubernetes-sigs/kustomize/raw/master/api/krusty/testdata/customschema.json
377 `+customSchemaPatch)
378 writeCustomResource(th, "base/mycrd.yaml")
379 writeTestSchema(th, "overlay/")
380 m := th.Run("overlay", th.MakeDefaultOptions())
381 th.AssertActualEqualsExpected(m, patchedCustomResource)
382 assert.Equal(t, "using custom schema from file provided",
383 openapi.GetSchemaVersion())
384 })
385 }
386
387 func TestCustomOpenApiFieldOverlayTakesPrecedence(t *testing.T) {
388 runOpenApiTest(t, func(t *testing.T) {
389 t.Helper()
390 th := kusttest_test.MakeHarness(t)
391 openapi.ResetOpenAPI()
392 th.WriteK("base", `
393 resources:
394 - mycrd.yaml
395 openapi:
396 path: mycrd_schema.json
397 `)
398 th.WriteK("overlay", `
399 resources:
400 - ../base
401 openapi:
402 version: v1.21.2
403 `+customSchemaPatch)
404 writeCustomResource(th, "base/mycrd.yaml")
405 writeTestSchema(th, "base/")
406 m := th.Run("overlay", th.MakeDefaultOptions())
407 th.AssertActualEqualsExpected(m, `
408 apiVersion: example.com/v1alpha1
409 kind: MyCRD
410 metadata:
411 name: service
412 spec:
413 template:
414 spec:
415 containers:
416 - image: nginx
417 name: server
418 `)
419 assert.Equal(t, "v1.21.2", openapi.GetSchemaVersion())
420 })
421 }
422
423 func TestCustomOpenApiFieldFromComponent(t *testing.T) {
424 runOpenApiTest(t, func(t *testing.T) {
425 t.Helper()
426 input := []FileGen{
427 writeTestBase,
428 writeTestComponentWithCustomSchema,
429 writeOverlayProd}
430
431 th := kusttest_test.MakeHarness(t)
432 for _, f := range input {
433 f(th)
434 }
435 th.Run("prod", th.MakeDefaultOptions())
436 assert.Equal(t, "using custom schema from file provided", openapi.GetSchemaVersion())
437 })
438 }
439
440
441
442 func TestCustomOpenApiFieldFromComponentWithOverlays(t *testing.T) {
443 runOpenApiTest(t, func(t *testing.T) {
444 t.Helper()
445 th := kusttest_test.MakeHarness(t)
446
447
448 th.WriteK("overlays/overlay-component-openapi", `resources:
449 - ../base/
450 components:
451 - ../../components/dc-openapi
452 `)
453
454
455 th.WriteK("overlays/base", `resources:
456 - dc.yml
457 `)
458
459
460 th.WriteF("overlays/base/dc.yml", `apiVersion: apps.openshift.io/v1
461 kind: DeploymentConfig
462 metadata:
463 name: my-dc
464 spec:
465 template:
466 spec:
467 initContainers:
468 - name: init
469 containers:
470 - name: container
471 env:
472 - name: foo
473 value: bar
474 volumeMounts:
475 - name: cm
476 mountPath: /opt/cm
477 volumes:
478 - name: cm
479 configMap:
480 name: cm
481 `)
482
483
484 bytes, _ := os.ReadFile("./testdata/openshiftschema.json")
485 th.WriteF("components/dc-openapi/openapi.json", string(bytes))
486
487
488 th.WriteF("components/dc-openapi/patch.yml", `apiVersion: apps.openshift.io/v1
489 kind: DeploymentConfig
490 metadata:
491 name: my-dc
492 spec:
493 template:
494 spec:
495 containers:
496 - name: container
497 volumeMounts:
498 - name: additional-cm
499 mountPath: /mnt
500 volumes:
501 - name: additional-cm
502 configMap:
503 name: additional-cm
504 `)
505
506
507 th.WriteC("components/dc-openapi", `patchesStrategicMerge:
508 - patch.yml
509 openapi:
510 path: openapi.json
511 `)
512
513 m := th.Run("overlays/overlay-component-openapi", th.MakeDefaultOptions())
514 th.AssertActualEqualsExpected(m, `apiVersion: apps.openshift.io/v1
515 kind: DeploymentConfig
516 metadata:
517 name: my-dc
518 spec:
519 template:
520 spec:
521 containers:
522 - env:
523 - name: foo
524 value: bar
525 name: container
526 volumeMounts:
527 - mountPath: /mnt
528 name: additional-cm
529 - mountPath: /opt/cm
530 name: cm
531 initContainers:
532 - name: init
533 volumes:
534 - configMap:
535 name: additional-cm
536 name: additional-cm
537 - configMap:
538 name: cm
539 name: cm
540 `)
541 })
542 }
543
544 func TestCustomOpenApiFieldVersion(t *testing.T) {
545 runOpenApiTest(t, func(t *testing.T) {
546 t.Helper()
547 th := kusttest_test.MakeHarness(t)
548 th.WriteK(".", `
549 openapi:
550 version: v1.21.2
551 resources:
552 - deployment.yaml
553 `)
554 th.WriteF("deployment.yaml", `
555 apiVersion: apps/v1
556 kind: Deployment
557 metadata:
558 name: myDeployment
559 spec:
560 template:
561 spec:
562 containers:
563 - image: whatever
564 `)
565
566 m := th.Run(".", th.MakeDefaultOptions())
567 th.AssertActualEqualsExpected(m, `
568 apiVersion: apps/v1
569 kind: Deployment
570 metadata:
571 name: myDeployment
572 spec:
573 template:
574 spec:
575 containers:
576 - image: whatever
577 `)
578 assert.Equal(t, "v1.21.2", openapi.GetSchemaVersion())
579 })
580 }
581
582 func TestCustomOpenApiFieldNotBuiltin(t *testing.T) {
583 runOpenApiTest(t, func(t *testing.T) {
584 t.Helper()
585 th := kusttest_test.MakeHarness(t)
586 th.WriteK(".", `
587 openapi:
588 version: v1.14.1
589 resources:
590 - deployment.yaml
591 `)
592 th.WriteF("deployment.yaml", `
593 apiVersion: apps/v1
594 kind: Deployment
595 metadata:
596 name: myDeployment
597 spec:
598 template:
599 spec:
600 containers:
601 - image: whatever
602 `)
603
604 err := th.RunWithErr(".", th.MakeDefaultOptions())
605 if err == nil {
606 t.Fatalf("expected an error")
607 }
608 })
609 }
610
611 func TestCustomOpenApiFieldDefaultVersion(t *testing.T) {
612 runOpenApiTest(t, func(t *testing.T) {
613 t.Helper()
614 th := kusttest_test.MakeHarness(t)
615 th.WriteK(".", `
616 resources:
617 - deployment.yaml
618 `)
619 th.WriteF("deployment.yaml", `
620 apiVersion: apps/v1
621 kind: Deployment
622 metadata:
623 name: myDeployment
624 spec:
625 template:
626 spec:
627 containers:
628 - image: whatever
629 `)
630
631 m := th.Run(".", th.MakeDefaultOptions())
632 th.AssertActualEqualsExpected(m, `
633 apiVersion: apps/v1
634 kind: Deployment
635 metadata:
636 name: myDeployment
637 spec:
638 template:
639 spec:
640 containers:
641 - image: whatever
642 `)
643 assert.Equal(t, kubernetesapi.DefaultOpenAPI, openapi.GetSchemaVersion())
644 })
645 }
646
View as plain text