...
1
16
17 package envtest
18
19 import (
20 "context"
21 "crypto/tls"
22 "path/filepath"
23 "strings"
24 "time"
25
26 . "github.com/onsi/ginkgo/v2"
27 . "github.com/onsi/gomega"
28 appsv1 "k8s.io/api/apps/v1"
29 corev1 "k8s.io/api/core/v1"
30 apierrors "k8s.io/apimachinery/pkg/api/errors"
31 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32
33 "sigs.k8s.io/controller-runtime/pkg/client"
34 "sigs.k8s.io/controller-runtime/pkg/manager"
35 "sigs.k8s.io/controller-runtime/pkg/webhook"
36 "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
37 )
38
39 var _ = Describe("Test", func() {
40
41 Describe("Webhook", func() {
42 It("should reject create request for webhook that rejects all requests", func() {
43 m, err := manager.New(env.Config, manager.Options{
44 WebhookServer: webhook.NewServer(webhook.Options{
45 Port: env.WebhookInstallOptions.LocalServingPort,
46 Host: env.WebhookInstallOptions.LocalServingHost,
47 CertDir: env.WebhookInstallOptions.LocalServingCertDir,
48 TLSOpts: []func(*tls.Config){func(config *tls.Config) {}},
49 }),
50 })
51 Expect(err).NotTo(HaveOccurred())
52 server := m.GetWebhookServer()
53 server.Register("/failing", &webhook.Admission{Handler: &rejectingValidator{}})
54
55 ctx, cancel := context.WithCancel(context.Background())
56 go func() {
57 _ = server.Start(ctx)
58 }()
59
60 c, err := client.New(env.Config, client.Options{})
61 Expect(err).NotTo(HaveOccurred())
62
63 obj := &appsv1.Deployment{
64 TypeMeta: metav1.TypeMeta{
65 APIVersion: "apps/v1",
66 Kind: "Deployment",
67 },
68 ObjectMeta: metav1.ObjectMeta{
69 Name: "test-deployment",
70 Namespace: "default",
71 },
72 Spec: appsv1.DeploymentSpec{
73 Selector: &metav1.LabelSelector{
74 MatchLabels: map[string]string{"foo": "bar"},
75 },
76 Template: corev1.PodTemplateSpec{
77 ObjectMeta: metav1.ObjectMeta{Labels: map[string]string{"foo": "bar"}},
78 Spec: corev1.PodSpec{
79 Containers: []corev1.Container{
80 {
81 Name: "nginx",
82 Image: "nginx",
83 },
84 },
85 },
86 },
87 },
88 }
89
90 Eventually(func() bool {
91 err = c.Create(context.TODO(), obj)
92 return err != nil && strings.HasSuffix(err.Error(), "Always denied") && apierrors.ReasonForError(err) == metav1.StatusReasonForbidden
93 }, 1*time.Second).Should(BeTrue())
94
95 cancel()
96 })
97
98 It("should load webhooks from directory", func() {
99 installOptions := WebhookInstallOptions{
100 Paths: []string{filepath.Join("testdata", "webhooks")},
101 }
102 err := parseWebhook(&installOptions)
103 Expect(err).NotTo(HaveOccurred())
104 Expect(installOptions.MutatingWebhooks).To(HaveLen(2))
105 Expect(installOptions.ValidatingWebhooks).To(HaveLen(2))
106 })
107
108 It("should load webhooks from files", func() {
109 installOptions := WebhookInstallOptions{
110 Paths: []string{filepath.Join("testdata", "webhooks", "manifests.yaml")},
111 }
112 err := parseWebhook(&installOptions)
113 Expect(err).NotTo(HaveOccurred())
114 Expect(installOptions.MutatingWebhooks).To(HaveLen(2))
115 Expect(installOptions.ValidatingWebhooks).To(HaveLen(2))
116 })
117 })
118 })
119
120 type rejectingValidator struct {
121 }
122
123 func (v *rejectingValidator) Handle(_ context.Context, _ admission.Request) admission.Response {
124 return admission.Denied("Always denied")
125 }
126
View as plain text