sigs.k8s.io/controller-runtime@v0.18.2/pkg/envtest/webhook_test.go (about) 1 /* 2 Copyright 2021 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 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 }) // we need manager here just to leverage manager.SetFields 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 }