knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/webhook/psbinding/controller.go (about) 1 /* 2 Copyright 2019 The Knative 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 psbinding 18 19 import ( 20 "context" 21 22 // Injection stuff 23 kubeclient "knative.dev/pkg/client/injection/kube/client" 24 mwhinformer "knative.dev/pkg/client/injection/kube/informers/admissionregistration/v1/mutatingwebhookconfiguration" 25 secretinformer "knative.dev/pkg/injection/clients/namespacedkube/informers/core/v1/secret" 26 27 "k8s.io/apimachinery/pkg/types" 28 "k8s.io/client-go/tools/cache" 29 "knative.dev/pkg/apis/duck" 30 duckv1 "knative.dev/pkg/apis/duck/v1" 31 "knative.dev/pkg/controller" 32 "knative.dev/pkg/logging" 33 pkgreconciler "knative.dev/pkg/reconciler" 34 "knative.dev/pkg/system" 35 "knative.dev/pkg/webhook" 36 ) 37 38 // Bindable is implemented by Binding resources whose subjects are PodSpecable 39 // and that want to leverage this shared logic to simplify binding authorship. 40 type Bindable interface { 41 duck.Bindable 42 43 // Do performs this binding's mutation with the specified context on the 44 // provided PodSpecable. The provided context may be decorated by 45 // passing a BindableContext to both NewAdmissionController and 46 // BaseReconciler. 47 Do(context.Context, *duckv1.WithPod) 48 49 // Undo is the dual of Do, it undoes the binding. 50 Undo(context.Context, *duckv1.WithPod) 51 } 52 53 // Mutation is the type of the Do/Undo methods. 54 type Mutation func(context.Context, *duckv1.WithPod) 55 56 // ListAll is the type of methods for enumerating all of the Bindables on the 57 // cluster in order to index the covered types to program the admission webhook. 58 type ListAll func() ([]Bindable, error) 59 60 // GetListAll is a factory method for the ListAll method, which may also be 61 // supplied with a ResourceEventHandler to register a callback with the Informer 62 // that sits behind the returned ListAll so that the handler can queue work 63 // whenever the result of ListAll changes. 64 type GetListAll func(context.Context, cache.ResourceEventHandler) ListAll 65 66 // BindableContext is the type of context decorator methods that may be supplied 67 // to NewAdmissionController and BaseReconciler. 68 type BindableContext func(context.Context, Bindable) (context.Context, error) 69 70 var sentinel = types.NamespacedName{} 71 72 // NewAdmissionController constructs the webhook portion of the pair of 73 // reconcilers that implement the semantics of our Binding. 74 func NewAdmissionController( 75 ctx context.Context, 76 name, path string, 77 gla GetListAll, 78 withContext BindableContext, 79 reconcilerOptions ...ReconcilerOption, 80 ) *controller.Impl { 81 // Extract the assorted things from our context. 82 client := kubeclient.Get(ctx) 83 mwhInformer := mwhinformer.Get(ctx) 84 secretInformer := secretinformer.Get(ctx) 85 options := webhook.GetOptions(ctx) 86 87 // Construct the reconciler for the mutating webhook configuration. 88 wh := NewReconciler(name, path, options.SecretName, client, mwhInformer.Lister(), secretInformer.Lister(), withContext, reconcilerOptions...) 89 c := controller.NewContext(ctx, wh, controller.ControllerOptions{WorkQueueName: name, Logger: logging.FromContext(ctx).Named(name)}) 90 91 // Enqueue a sentinel when we become leader. 92 wh.PromoteFunc = func(bkt pkgreconciler.Bucket, enq func(pkgreconciler.Bucket, types.NamespacedName)) error { 93 enq(bkt, sentinel) 94 return nil 95 } 96 97 // It doesn't matter what we enqueue because we will always Reconcile 98 // the named MWH resource. 99 handler := controller.HandleAll(c.EnqueueSentinel(sentinel)) 100 101 // Reconcile when the named MutatingWebhookConfiguration changes. 102 mwhInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ 103 FilterFunc: controller.FilterWithName(name), 104 Handler: handler, 105 }) 106 107 // Reconcile when the cert bundle changes. 108 secretInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ 109 FilterFunc: controller.FilterWithNameAndNamespace(system.Namespace(), wh.SecretName), 110 Handler: handler, 111 }) 112 113 // Give the reconciler a way to list all of the Bindable resources, 114 // and configure the controller to handle changes to those resources. 115 wh.ListAll = gla(ctx, handler) 116 117 return c 118 }