github.com/verrazzano/verrazzano@v1.7.0/application-operator/internal/operatorinit/run_webhook.go (about) 1 // Copyright (c) 2022, 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package operatorinit 5 6 import ( 7 vzapi "github.com/verrazzano/verrazzano/application-operator/apis/oam/v1alpha1" 8 "github.com/verrazzano/verrazzano/application-operator/controllers/webhooks" 9 "github.com/verrazzano/verrazzano/application-operator/internal/certificates" 10 "github.com/verrazzano/verrazzano/pkg/k8sutil" 11 "go.uber.org/zap" 12 istioversionedclient "istio.io/client-go/pkg/clientset/versioned" 13 "k8s.io/apimachinery/pkg/runtime" 14 "k8s.io/client-go/dynamic" 15 "k8s.io/client-go/kubernetes" 16 ctrl "sigs.k8s.io/controller-runtime" 17 "sigs.k8s.io/controller-runtime/pkg/webhook" 18 ) 19 20 const ( 21 failedToUpdate = "Failed to update %s: %v" 22 ) 23 24 // WebhookInit Webhook init container entry point 25 func WebhookInit(certDir string, log *zap.SugaredLogger) error { 26 log.Debug("Creating certificates used by webhooks") 27 28 conf, err := k8sutil.GetConfigFromController() 29 if err != nil { 30 log.Errorf("Failed to get config: %v", err) 31 return err 32 } 33 34 kubeClient, err := kubernetes.NewForConfig(conf) 35 if err != nil { 36 log.Errorf("Failed to get kubernetes client: %v", err) 37 return err 38 } 39 40 // Create the webhook certificates and secrets 41 if err := certificates.CreateWebhookCertificates(log, kubeClient, certDir); err != nil { 42 log.Errorf("Failed to create webhook certificates and secrets: %v", err) 43 return err 44 } 45 return nil 46 } 47 48 func StartWebhookServer(metricsAddr string, log *zap.SugaredLogger, enableLeaderElection bool, certDir string, scheme *runtime.Scheme) error { 49 config, err := k8sutil.GetConfigFromController() 50 if err != nil { 51 log.Errorf("Failed to get kubeconfig: %v", err) 52 return err 53 } 54 55 mgr, err := ctrl.NewManager(config, ctrl.Options{ 56 Scheme: scheme, 57 MetricsBindAddress: metricsAddr, 58 Port: 9443, 59 LeaderElection: enableLeaderElection, 60 LeaderElectionID: "5df248b4.verrazzano.io", 61 }) 62 if err != nil { 63 log.Errorf("Failed to start manager: %v", err) 64 return err 65 } 66 67 kubeClient, err := kubernetes.NewForConfig(config) 68 if err != nil { 69 log.Errorf("Failed to get clientset", err) 70 return err 71 } 72 73 log.Debug("Setting up certificates for webhook") 74 err = updateValidatingWebhookConfiguration(kubeClient, certificates.IngressTraitValidatingWebhookName) 75 if err != nil { 76 log.Errorf(failedToUpdate, certificates.IngressTraitValidatingWebhookName, err) 77 return err 78 } 79 80 err = updateValidatingWebhookConfiguration(kubeClient, certificates.MultiClusterSecretName) 81 if err != nil { 82 log.Errorf(failedToUpdate, certificates.MultiClusterSecretName, err) 83 return err 84 } 85 86 err = updateValidatingWebhookConfiguration(kubeClient, certificates.MultiClusterComponentName) 87 if err != nil { 88 log.Errorf(failedToUpdate, certificates.MultiClusterComponentName, err) 89 return err 90 } 91 92 err = updateValidatingWebhookConfiguration(kubeClient, certificates.MultiClusterConfigMapName) 93 if err != nil { 94 log.Errorf(failedToUpdate, certificates.MultiClusterConfigMapName, err) 95 return err 96 } 97 98 err = updateValidatingWebhookConfiguration(kubeClient, certificates.MultiClusterApplicationConfigurationName) 99 if err != nil { 100 log.Errorf(failedToUpdate, certificates.MultiClusterApplicationConfigurationName, err) 101 return err 102 } 103 104 err = updateValidatingWebhookConfiguration(kubeClient, certificates.VerrazzanoProjectValidatingWebhookName) 105 if err != nil { 106 log.Errorf(failedToUpdate, certificates.VerrazzanoProjectValidatingWebhookName, err) 107 return err 108 } 109 110 err = updateMutatingWebhookConfiguration(kubeClient, certificates.IstioMutatingWebhookName) 111 if err != nil { 112 log.Errorf(failedToUpdate, certificates.IstioMutatingWebhookName, err) 113 return err 114 } 115 116 err = updateMutatingWebhookConfiguration(kubeClient, certificates.AppConfigMutatingWebhookName) 117 if err != nil { 118 log.Errorf(failedToUpdate, certificates.AppConfigMutatingWebhookName, err) 119 return err 120 } 121 122 err = updateMutatingWebhookConfiguration(kubeClient, certificates.MetricsBindingWebhookName) 123 if err != nil { 124 log.Errorf(failedToUpdate, certificates.MetricsBindingWebhookName, err) 125 return err 126 } 127 128 if err = (&vzapi.IngressTrait{}).SetupWebhookWithManager(mgr); err != nil { 129 log.Errorf("Failed to create IngressTrait webhook: %v", err) 130 return err 131 } 132 133 // VerrazzanoProject validating webhook 134 mgr.GetWebhookServer().Register( 135 "/validate-clusters-verrazzano-io-v1alpha1-verrazzanoproject", 136 &webhook.Admission{Handler: &webhooks.VerrazzanoProjectValidator{}}) 137 138 dynamicClient, err := dynamic.NewForConfig(config) 139 if err != nil { 140 log.Errorf("Failed to create Kubernetes dynamic client: %v", err) 141 return err 142 } 143 144 istioClientSet, err := istioversionedclient.NewForConfig(config) 145 if err != nil { 146 log.Errorf("Failed to create istio client: %v", err) 147 return err 148 } 149 150 // Register a webhook that listens on pods that are running in a istio enabled namespace. 151 mgr.GetWebhookServer().Register( 152 webhooks.IstioDefaulterPath, 153 &webhook.Admission{ 154 Handler: &webhooks.IstioWebhook{ 155 Client: mgr.GetClient(), 156 KubeClient: kubeClient, 157 DynamicClient: dynamicClient, 158 IstioClient: istioClientSet, 159 }, 160 }, 161 ) 162 163 // Register the metrics binding mutating webhooks for plain old kubernetes objects workloads 164 // The webhooks handle legacy metrics template annotations on these workloads - newer 165 // workloads should rely on user-created monitor resources. 166 mgr.GetWebhookServer().Register( 167 webhooks.MetricsBindingGeneratorWorkloadPath, 168 &webhook.Admission{ 169 Handler: &webhooks.WorkloadWebhook{ 170 Client: mgr.GetClient(), 171 KubeClient: kubeClient, 172 }, 173 }, 174 ) 175 mgr.GetWebhookServer().Register( 176 webhooks.MetricsBindingLabelerPodPath, 177 &webhook.Admission{ 178 Handler: &webhooks.LabelerPodWebhook{ 179 Client: mgr.GetClient(), 180 DynamicClient: dynamicClient, 181 }, 182 }, 183 ) 184 185 mgr.GetWebhookServer().CertDir = certDir 186 appconfigWebhook := &webhooks.AppConfigWebhook{ 187 Client: mgr.GetClient(), 188 KubeClient: kubeClient, 189 IstioClient: istioClientSet, 190 Defaulters: []webhooks.AppConfigDefaulter{ 191 &webhooks.MetricsTraitDefaulter{ 192 Client: mgr.GetClient(), 193 }, 194 }, 195 } 196 mgr.GetWebhookServer().Register(webhooks.AppConfigDefaulterPath, &webhook.Admission{Handler: appconfigWebhook}) 197 198 // MultiClusterApplicationConfiguration validating webhook 199 mgr.GetWebhookServer().Register( 200 "/validate-clusters-verrazzano-io-v1alpha1-multiclusterapplicationconfiguration", 201 &webhook.Admission{Handler: &webhooks.MultiClusterApplicationConfigurationValidator{}}) 202 203 // MultiClusterComponent validating webhook 204 mgr.GetWebhookServer().Register( 205 "/validate-clusters-verrazzano-io-v1alpha1-multiclustercomponent", 206 &webhook.Admission{Handler: &webhooks.MultiClusterComponentValidator{}}) 207 208 // MultiClusterConfigMap validating webhook 209 mgr.GetWebhookServer().Register( 210 "/validate-clusters-verrazzano-io-v1alpha1-multiclusterconfigmap", 211 &webhook.Admission{Handler: &webhooks.MultiClusterConfigmapValidator{}}) 212 213 // MultiClusterSecret validating webhook 214 mgr.GetWebhookServer().Register( 215 "/validate-clusters-verrazzano-io-v1alpha1-multiclustersecret", 216 &webhook.Admission{Handler: &webhooks.MultiClusterSecretValidator{}}) 217 218 // +kubebuilder:scaffold:builder 219 220 log.Info("Starting manager") 221 if err = mgr.Start(ctrl.SetupSignalHandler()); err != nil { 222 log.Errorf("Failed to run manager: %v", err) 223 return err 224 } 225 return err 226 }