@@ -18,6 +18,7 @@ package v4
18
18
19
19
import (
20
20
"fmt"
21
+ "os"
21
22
"path/filepath"
22
23
"strings"
23
24
@@ -55,6 +56,8 @@ func GenerateV4(kbc *utils.TestContext) {
55
56
err = utils .ImplementWebhooks (webhookFilePath , strings .ToLower (kbc .Kind ))
56
57
ExpectWithOffset (1 , err ).NotTo (HaveOccurred ())
57
58
59
+ scaffoldConversionWebhook (kbc )
60
+
58
61
ExpectWithOffset (1 , pluginutil .UncommentCode (
59
62
filepath .Join (kbc .Dir , "config" , "default" , "kustomization.yaml" ),
60
63
"#- ../certmanager" , "#" )).To (Succeed ())
@@ -92,6 +95,8 @@ func GenerateV4WithoutMetrics(kbc *utils.TestContext) {
92
95
err = utils .ImplementWebhooks (webhookFilePath , strings .ToLower (kbc .Kind ))
93
96
ExpectWithOffset (1 , err ).NotTo (HaveOccurred ())
94
97
98
+ scaffoldConversionWebhook (kbc )
99
+
95
100
ExpectWithOffset (1 , pluginutil .UncommentCode (
96
101
filepath .Join (kbc .Dir , "config" , "default" , "kustomization.yaml" ),
97
102
"#- ../certmanager" , "#" )).To (Succeed ())
@@ -153,6 +158,8 @@ func GenerateV4WithNetworkPolicies(kbc *utils.TestContext) {
153
158
err = utils .ImplementWebhooks (webhookFilePath , strings .ToLower (kbc .Kind ))
154
159
ExpectWithOffset (1 , err ).NotTo (HaveOccurred ())
155
160
161
+ scaffoldConversionWebhook (kbc )
162
+
156
163
ExpectWithOffset (1 , pluginutil .UncommentCode (
157
164
filepath .Join (kbc .Dir , "config" , "default" , "kustomization.yaml" ),
158
165
"#- ../certmanager" , "#" )).To (Succeed ())
@@ -368,3 +375,114 @@ func uncommentPodStandards(kbc *utils.TestContext) {
368
375
ExpectWithOffset (1 , err ).NotTo (HaveOccurred ())
369
376
}
370
377
}
378
+
379
+ // scaffoldConversionWebhook sets up conversion webhooks for testing the ConversionTest API
380
+ func scaffoldConversionWebhook (kbc * utils.TestContext ) {
381
+ By ("scaffolding conversion webhooks for testing ConversionTest v1 to v2 conversion" )
382
+
383
+ // Create API for v1 (hub) with conversion enabled
384
+ err := kbc .CreateAPI (
385
+ "--group" , kbc .Group ,
386
+ "--version" , "v1" ,
387
+ "--kind" , "ConversionTest" ,
388
+ "--controller=true" ,
389
+ "--resource=true" ,
390
+ "--make=false" ,
391
+ )
392
+ ExpectWithOffset (1 , err ).NotTo (HaveOccurred (), "failed to create v1 API for conversion testing" )
393
+
394
+ // Create API for v2 (spoke) without a controller
395
+ err = kbc .CreateAPI (
396
+ "--group" , kbc .Group ,
397
+ "--version" , "v2" ,
398
+ "--kind" , "ConversionTest" ,
399
+ "--controller=false" ,
400
+ "--resource=true" ,
401
+ "--make=false" ,
402
+ )
403
+ ExpectWithOffset (1 , err ).NotTo (HaveOccurred (), "failed to create v2 API for conversion testing" )
404
+
405
+ // Create the conversion webhook for v1
406
+ By ("setting up the conversion webhook for v1" )
407
+ err = kbc .CreateWebhook (
408
+ "--group" , kbc .Group ,
409
+ "--version" , "v1" ,
410
+ "--kind" , "ConversionTest" ,
411
+ "--conversion" ,
412
+ "--make=false" ,
413
+ )
414
+ ExpectWithOffset (1 , err ).NotTo (HaveOccurred (), "failed to create conversion webhook for v1" )
415
+
416
+ // Insert Size field in v1
417
+ By ("implementing the size spec in v1" )
418
+ ExpectWithOffset (1 , pluginutil .InsertCode (
419
+ filepath .Join (kbc .Dir , "api" , "v1" , "conversiontest_types.go" ),
420
+ "Foo string `json:\" foo,omitempty\" `" ,
421
+ "\n \t Size int `json:\" size,omitempty\" ` // Number of desired instances" ,
422
+ )).NotTo (HaveOccurred (), "failed to add size spec to conversiontest_types v1" )
423
+
424
+ // Insert Replicas field in v2
425
+ By ("implementing the replicas spec in v2" )
426
+ ExpectWithOffset (1 , pluginutil .InsertCode (
427
+ filepath .Join (kbc .Dir , "api" , "v2" , "conversiontest_types.go" ),
428
+ "Foo string `json:\" foo,omitempty\" `" ,
429
+ "\n \t Replicas int `json:\" replicas,omitempty\" ` // Number of replicas" ,
430
+ )).NotTo (HaveOccurred (), "failed to add replicas spec to conversiontest_types v2" )
431
+
432
+ // TODO: Remove the code bellow when we have hub and spoke scaffolded by
433
+ // Kubebuilder. Intead of create the file we will replace the TODO(user)
434
+ // with the code implementation.
435
+ By ("implementing markers" )
436
+ ExpectWithOffset (1 , pluginutil .InsertCode (
437
+ filepath .Join (kbc .Dir , "api" , "v1" , "conversiontest_types.go" ),
438
+ "// +kubebuilder:object:root=true\n // +kubebuilder:subresource:status" ,
439
+ "\n // +kubebuilder:storageversion\n // +kubebuilder:conversion:hub\n " ,
440
+ )).NotTo (HaveOccurred (), "failed to add markers to conversiontest_types v1" )
441
+
442
+ // Create the hub conversion file in v1
443
+ By ("creating the conversion implementation in v1 as hub" )
444
+ err = os .WriteFile (filepath .Join (kbc .Dir , "api" , "v1" , "conversiontest_conversion.go" ), []byte (`
445
+ package v1
446
+
447
+ // ConversionTest defines the hub conversion logic.
448
+ // Implement the Hub interface to signal that v1 is the hub version.
449
+ func (*ConversionTest) Hub() {}
450
+ ` ), 0644 )
451
+ ExpectWithOffset (1 , err ).NotTo (HaveOccurred (), "failed to create hub conversion file in v1" )
452
+
453
+ // Create the conversion file in v2
454
+ By ("creating the conversion implementation in v2" )
455
+ err = os .WriteFile (filepath .Join (kbc .Dir , "api" , "v2" , "conversiontest_conversion.go" ), []byte (`
456
+ package v2
457
+
458
+ import (
459
+ "log"
460
+
461
+ "sigs.k8s.io/controller-runtime/pkg/conversion"
462
+ v1 "sigs.k8s.io/kubebuilder/v4/api/v1"
463
+ )
464
+
465
+ // ConvertTo converts this ConversionTest to the Hub version (v1).
466
+ func (src *ConversionTest) ConvertTo(dstRaw conversion.Hub) error {
467
+ dst := dstRaw.(*v1.ConversionTest)
468
+ log.Printf("Converting from %T to %T", src.APIVersion, dst.APIVersion)
469
+
470
+ // Implement conversion logic from v2 to v1
471
+ dst.Spec.Size = src.Spec.Replicas // Convert replicas in v2 to size in v1
472
+
473
+ return nil
474
+ }
475
+
476
+ // ConvertFrom converts the Hub version (v1) to this ConversionTest (v2).
477
+ func (dst *ConversionTest) ConvertFrom(srcRaw conversion.Hub) error {
478
+ src := srcRaw.(*v1.ConversionTest)
479
+ log.Printf("Converting from %T to %T", src.APIVersion, dst.APIVersion)
480
+
481
+ // Implement conversion logic from v1 to v2
482
+ dst.Spec.Replicas = src.Spec.Size // Convert size in v1 to replicas in v2
483
+
484
+ return nil
485
+ }
486
+ ` ), 0644 )
487
+ ExpectWithOffset (1 , err ).NotTo (HaveOccurred (), "failed to create conversion file in v2" )
488
+ }
0 commit comments