...

Source file src/sigs.k8s.io/controller-runtime/pkg/envtest/webhook_test.go

Documentation: sigs.k8s.io/controller-runtime/pkg/envtest

     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  }
   126  

View as plain text