Skip to content

Commit 9fb4c06

Browse files
authored
Merge pull request #1295 from HaraldNordgren/sort_version_2
🐛 sort manifest webhooks
2 parents a51cd00 + 9f89b46 commit 9fb4c06

File tree

7 files changed

+140
-0
lines changed

7 files changed

+140
-0
lines changed

pkg/webhook/parser.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ package webhook
2424

2525
import (
2626
"fmt"
27+
"slices"
2728
"sort"
2829
"strings"
2930

@@ -514,8 +515,12 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
514515
}
515516

516517
versionedWebhooks := make(map[string][]interface{}, len(supportedWebhookVersions))
518+
//nolint:dupl
517519
for _, version := range supportedWebhookVersions {
518520
if cfgs, ok := mutatingCfgs[version]; ok {
521+
slices.SortFunc(cfgs, func(a, b admissionregv1.MutatingWebhook) int {
522+
return strings.Compare(a.Name, b.Name)
523+
})
519524
var objRaw *admissionregv1.MutatingWebhookConfiguration
520525
if mutatingWebhookCfgs.Name != "" {
521526
objRaw = &mutatingWebhookCfgs
@@ -553,6 +558,9 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
553558
}
554559

555560
if cfgs, ok := validatingCfgs[version]; ok {
561+
slices.SortFunc(cfgs, func(a, b admissionregv1.ValidatingWebhook) int {
562+
return strings.Compare(a.Name, b.Name)
563+
})
556564
var objRaw *admissionregv1.ValidatingWebhookConfiguration
557565
if validatingWebhookCfgs.Name != "" {
558566
objRaw = &validatingWebhookCfgs

pkg/webhook/parser_integration_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,76 @@ var _ = Describe("Webhook Generation From Parsing to CustomResourceDefinition",
426426
assertSame(actualValidating, expectedValidating)
427427
})
428428

429+
It("should keep webhook order stable across package traversal orders", func() {
430+
By("switching into testdata to appease go modules")
431+
cwd, err := os.Getwd()
432+
Expect(err).NotTo(HaveOccurred())
433+
Expect(os.Chdir("./testdata/valid-crosspkg-stable")).To(Succeed()) // go modules are directory-sensitive
434+
defer func() { Expect(os.Chdir(cwd)).To(Succeed()) }()
435+
436+
By("setting up the parser")
437+
reg := &markers.Registry{}
438+
Expect(reg.Register(webhook.ConfigDefinition)).To(Succeed())
439+
Expect(reg.Register(webhook.WebhookConfigDefinition)).To(Succeed())
440+
441+
By("loading the desired v1 YAML")
442+
expectedFile, err := os.ReadFile("manifests.yaml")
443+
Expect(err).NotTo(HaveOccurred())
444+
expectedManifest := &admissionregv1.ValidatingWebhookConfiguration{}
445+
Expect(yaml.UnmarshalStrict(expectedFile, expectedManifest)).To(Succeed())
446+
447+
rootsOrders := []struct {
448+
name string
449+
outputDir string
450+
roots []string
451+
}{
452+
{
453+
name: "v1 first",
454+
outputDir: "webhook-integration-test-order-a",
455+
roots: []string{
456+
"./v1",
457+
"./v1alpha1",
458+
}},
459+
{
460+
name: "v1alpha1 first",
461+
outputDir: "webhook-integration-test-order-b",
462+
roots: []string{
463+
"./v1alpha1",
464+
"./v1",
465+
}},
466+
}
467+
468+
for _, rootsOrder := range rootsOrders {
469+
By("loading the roots in order " + rootsOrder.name)
470+
pkgs, err := loader.LoadRoots(rootsOrder.roots...)
471+
Expect(err).NotTo(HaveOccurred())
472+
Expect(pkgs).To(HaveLen(2))
473+
474+
By("requesting that the manifest be generated for order " + rootsOrder.name)
475+
outputDir, err := os.MkdirTemp("", rootsOrder.outputDir)
476+
Expect(err).NotTo(HaveOccurred())
477+
defer os.RemoveAll(outputDir)
478+
genCtx := &genall.GenerationContext{
479+
Collector: &markers.Collector{Registry: reg},
480+
Roots: pkgs,
481+
OutputRule: genall.OutputToDirectory(outputDir),
482+
}
483+
Expect(webhook.Generator{}.Generate(genCtx)).To(Succeed())
484+
for _, r := range genCtx.Roots {
485+
Expect(r.Errors).To(HaveLen(0))
486+
}
487+
488+
By("loading the generated v1 YAML for order " + rootsOrder.name)
489+
actualFile, err := os.ReadFile(path.Join(outputDir, "manifests.yaml"))
490+
Expect(err).NotTo(HaveOccurred())
491+
actualManifest := &admissionregv1.ValidatingWebhookConfiguration{}
492+
Expect(yaml.UnmarshalStrict(actualFile, actualManifest)).To(Succeed())
493+
494+
By("comparing the manifest for order " + rootsOrder.name)
495+
assertSame(actualManifest, expectedManifest)
496+
}
497+
})
498+
429499
It("should fail to generate when there are multiple `kubebuilder:webhookconfiguration` markers of the same mutation type", func() {
430500
By("switching into testdata to appease go modules")
431501
cwd, err := os.Getwd()
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
apiVersion: admissionregistration.k8s.io/v1
3+
kind: ValidatingWebhookConfiguration
4+
metadata:
5+
name: validating-webhook-configuration
6+
webhooks:
7+
- admissionReviewVersions:
8+
- v1
9+
- v1beta1
10+
clientConfig:
11+
service:
12+
name: webhook-service
13+
namespace: system
14+
path: /validate-testdata-kubebuilder-io-v1alpha1-cronjob
15+
failurePolicy: Fail
16+
matchPolicy: Equivalent
17+
name: a.cronjob.testdata.kubebuilder.io
18+
rules:
19+
- apiGroups:
20+
- testdata.kubebuilder.io
21+
apiVersions:
22+
- v1alpha1
23+
operations:
24+
- CREATE
25+
- UPDATE
26+
resources:
27+
- cronjobs
28+
sideEffects: None
29+
- admissionReviewVersions:
30+
- v1
31+
- v1beta1
32+
clientConfig:
33+
service:
34+
name: webhook-service
35+
namespace: system
36+
path: /validate-testdata-kubebuilder-io-v1-cronjob
37+
failurePolicy: Fail
38+
matchPolicy: Equivalent
39+
name: validation.cronjob.testdata.kubebuilder.io
40+
rules:
41+
- apiGroups:
42+
- testdata.kubebuilder.io
43+
apiVersions:
44+
- v1
45+
operations:
46+
- CREATE
47+
- UPDATE
48+
resources:
49+
- cronjobs
50+
sideEffects: None
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package v1
2+
3+
type CronJob struct{}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package v1
2+
3+
// +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuilder.io,resources=cronjobs,versions=v1,name=validation.cronjob.testdata.kubebuilder.io,sideEffects=None,admissionReviewVersions=v1;v1beta1,path=/validate-testdata-kubebuilder-io-v1-cronjob
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package v1alpha1
2+
3+
type CronJob struct{}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package v1alpha1
2+
3+
// +kubebuilder:webhook:webhookVersions=v1,verbs=create;update,mutating=false,failurePolicy=fail,matchPolicy=Equivalent,groups=testdata.kubebuilder.io,resources=cronjobs,versions=v1alpha1,name=a.cronjob.testdata.kubebuilder.io,sideEffects=None,admissionReviewVersions=v1;v1beta1,path=/validate-testdata-kubebuilder-io-v1alpha1-cronjob

0 commit comments

Comments
 (0)