@@ -25,6 +25,7 @@ import (
25
25
"os"
26
26
"os/exec"
27
27
"path/filepath"
28
+ "strings"
28
29
"time"
29
30
30
31
. "github.com/onsi/ginkgo/v2"
@@ -178,9 +179,14 @@ var _ = Describe("Manager", Ordered, func() {
178
179
cmd := exec .Command ("kubectl" , "create" , "clusterrolebinding" , metricsRoleBindingName ,
179
180
"--clusterrole=project-metrics-reader" ,
180
181
fmt .Sprintf ("--serviceaccount=%s:%s" , namespace , serviceAccountName ),
181
- )
182
- _ , err := utils .Run (cmd )
183
- Expect (err ).NotTo (HaveOccurred (), "Failed to create ClusterRoleBinding" )
182
+ "--dry-run=client" , "-o" , "yaml" )
183
+ output , err := utils .Run (cmd )
184
+ Expect (err ).NotTo (HaveOccurred (), "Failed to generate ClusterRoleBinding YAML" )
185
+
186
+ cmd = exec .Command ("kubectl" , "apply" , "-f" , "-" )
187
+ cmd .Stdin = strings .NewReader (output )
188
+ _ , err = utils .Run (cmd )
189
+ Expect (err ).NotTo (HaveOccurred (), "Failed to apply ClusterRoleBinding" )
184
190
185
191
By ("validating that the metrics service is available" )
186
192
cmd = exec .Command ("kubectl" , "get" , "service" , metricsServiceName , "-n" , namespace )
@@ -319,7 +325,74 @@ var _ = Describe("Manager", Ordered, func() {
319
325
320
326
// +kubebuilder:scaffold:e2e-webhooks-checks
321
327
322
- // TODO: Customize the e2e test suite with scenarios specific to your project.
328
+ It ("should validate webhook conversion between v1 and v2 CronJob versions" , func () {
329
+ By ("applying the v1 CronJob sample" )
330
+ cmd := exec .Command ("kubectl" , "apply" , "-f" , "config/samples/batch_v1_cronjob.yaml" , "-n" , namespace )
331
+ _ , err := utils .Run (cmd )
332
+ Expect (err ).NotTo (HaveOccurred (), "Failed to apply v1 CronJob sample" )
333
+
334
+ By ("verifying the v1 CronJob is stored properly" )
335
+ Eventually (func (g Gomega ) {
336
+ cmd := exec .Command ("kubectl" , "get" , "cronjob.batch.tutorial.kubebuilder.io" , "cronjob-sample" , "-n" , namespace , "-o" , "json" )
337
+ output , err := utils .Run (cmd )
338
+ g .Expect (err ).NotTo (HaveOccurred ())
339
+
340
+ var v1CronJob map [string ]interface {}
341
+ err = json .Unmarshal ([]byte (output ), & v1CronJob )
342
+ g .Expect (err ).NotTo (HaveOccurred ())
343
+
344
+ // Get spec and verify the schedule field exists
345
+ v1Spec , ok := v1CronJob ["spec" ].(map [string ]interface {})
346
+ g .Expect (ok ).To (BeTrue (), "Failed to get spec from v1 CronJob" )
347
+ g .Expect (v1Spec ["schedule" ]).NotTo (BeNil (), "Schedule field should exist in v1 CronJob" )
348
+ }).Should (Succeed ())
349
+
350
+ By ("deleting the v1 CronJob sample" )
351
+ cmd = exec .Command ("kubectl" , "delete" , "-f" , "config/samples/batch_v1_cronjob.yaml" , "-n" , namespace , "--ignore-not-found" )
352
+ _ , _ = utils .Run (cmd )
353
+
354
+ By ("applying the v2 CronJob sample" )
355
+ cmd = exec .Command ("kubectl" , "apply" , "-f" , "config/samples/batch_v2_cronjob.yaml" , "-n" , namespace )
356
+ _ , err = utils .Run (cmd )
357
+ Expect (err ).NotTo (HaveOccurred (), "Failed to apply v2 CronJob sample" )
358
+
359
+ By ("verifying the v2 CronJob is stored properly" )
360
+ Eventually (func (g Gomega ) {
361
+ cmd := exec .Command ("kubectl" , "get" , "cronjob.batch.tutorial.kubebuilder.io" , "cronjob-sample" , "-n" , namespace , "-o" , "json" )
362
+ output , err := utils .Run (cmd )
363
+ g .Expect (err ).NotTo (HaveOccurred ())
364
+
365
+ var v2CronJob map [string ]interface {}
366
+ err = json .Unmarshal ([]byte (output ), & v2CronJob )
367
+ g .Expect (err ).NotTo (HaveOccurred ())
368
+
369
+ // Get spec and verify the schedule field exists
370
+ v2Spec , ok := v2CronJob ["spec" ].(map [string ]interface {})
371
+ g .Expect (ok ).To (BeTrue (), "Failed to get spec from v2 CronJob" )
372
+ g .Expect (v2Spec ["schedule" ]).NotTo (BeNil (), "Schedule field should exist in v2 CronJob" )
373
+ }).Should (Succeed ())
374
+
375
+ By ("verifying conversion webhook was called by checking controller logs" )
376
+ Eventually (func (g Gomega ) {
377
+ cmd := exec .Command ("kubectl" , "logs" , controllerPodName , "-n" , namespace )
378
+ logs , err := utils .Run (cmd )
379
+ g .Expect (err ).NotTo (HaveOccurred ())
380
+
381
+ // Verify that conversion webhook was actually called
382
+ g .Expect (logs ).To (ContainSubstring ("ConvertTo:" ), "Expected to find ConvertTo log indicating conversion webhook was called" )
383
+ g .Expect (logs ).To (ContainSubstring ("ConvertFrom:" ), "Expected to find ConvertFrom log indicating conversion webhook was called" )
384
+
385
+ // Verify that conversion is happening between the versions
386
+ g .Expect (logs ).To (ContainSubstring ("Converting CronJob from Hub version v1 to Spoke version v2" ),
387
+ "Expected v1 to v2 conversion" )
388
+ g .Expect (logs ).To (ContainSubstring ("Converting CronJob from Spoke version v2 to Hub version v1" ),
389
+ "Expected v2 to v1 conversion" )
390
+ }).Should (Succeed ())
391
+
392
+ By ("cleaning up the v2 CronJob sample" )
393
+ cmd = exec .Command ("kubectl" , "delete" , "-f" , "config/samples/batch_v2_cronjob.yaml" , "-n" , namespace , "--ignore-not-found" )
394
+ _ , _ = utils .Run (cmd )
395
+ })
323
396
// Consider applying sample/CR(s) and check their status and/or verifying
324
397
// the reconciliation by using the metrics, i.e.:
325
398
// metricsOutput := getMetricsOutput()
0 commit comments