Skip to content

Commit

Permalink
improve webhook setup (#2079)
Browse files Browse the repository at this point in the history
  • Loading branch information
rambohe-ch authored Jun 18, 2024
1 parent 8c7629a commit d02a949
Show file tree
Hide file tree
Showing 14 changed files with 46 additions and 145 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook"

yurtClient "github.com/openyurtio/openyurt/cmd/yurt-manager/app/client"
Expand All @@ -35,16 +34,7 @@ func (webhook *DeploymentRenderHandler) SetupWebhookWithManager(mgr ctrl.Manager
webhook.Client = yurtClient.GetClientByControllerNameOrDie(mgr, names.YurtAppOverriderController)
webhook.Scheme = mgr.GetScheme()

gvk, err := apiutil.GVKForObject(&v1.Deployment{}, mgr.GetScheme())
if err != nil {
return "", "", err
}
return util.GenerateMutatePath(gvk),
util.GenerateValidatePath(gvk),
ctrl.NewWebhookManagedBy(mgr).
For(&v1.Deployment{}).
WithDefaulter(webhook).
Complete()
return util.RegisterWebhook(mgr, &v1.Deployment{}, webhook)
}

// +kubebuilder:webhook:path=/mutate-apps-v1-deployment,mutating=true,failurePolicy=ignore,groups=apps,resources=deployments,verbs=create;update,versions=v1,name=mutate.apps.v1.deployment,sideEffects=None,admissionReviewVersions=v1
Expand Down
14 changes: 1 addition & 13 deletions pkg/yurtmanager/webhook/gateway/v1alpha1/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package v1alpha1

import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook"

"github.com/openyurtio/openyurt/pkg/apis/raven/v1alpha1"
Expand All @@ -27,18 +26,7 @@ import (

// SetupWebhookWithManager sets up Cluster webhooks. mutate path, validatepath, error
func (webhook *GatewayHandler) SetupWebhookWithManager(mgr ctrl.Manager) (string, string, error) {
// init
gvk, err := apiutil.GVKForObject(&v1alpha1.Gateway{}, mgr.GetScheme())
if err != nil {
return "", "", err
}
return util.GenerateMutatePath(gvk),
util.GenerateValidatePath(gvk),
ctrl.NewWebhookManagedBy(mgr).
For(&v1alpha1.Gateway{}).
WithDefaulter(webhook).
WithValidator(webhook).
Complete()
return util.RegisterWebhook(mgr, &v1alpha1.Gateway{}, webhook)
}

// Cluster implements a validating and defaulting webhook for Cluster.
Expand Down
15 changes: 1 addition & 14 deletions pkg/yurtmanager/webhook/gateway/v1beta1/gateway_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package v1beta1

import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook"

"github.com/openyurtio/openyurt/pkg/apis/raven/v1beta1"
Expand All @@ -27,19 +26,7 @@ import (

// SetupWebhookWithManager sets up Cluster webhooks. mutate path, validatepath, error
func (webhook *GatewayHandler) SetupWebhookWithManager(mgr ctrl.Manager) (string, string, error) {
// init

gvk, err := apiutil.GVKForObject(&v1beta1.Gateway{}, mgr.GetScheme())
if err != nil {
return "", "", err
}
return util.GenerateMutatePath(gvk),
util.GenerateValidatePath(gvk),
ctrl.NewWebhookManagedBy(mgr).
For(&v1beta1.Gateway{}).
WithDefaulter(webhook).
WithValidator(webhook).
Complete()
return util.RegisterWebhook(mgr, &v1beta1.Gateway{}, webhook)
}

// +kubebuilder:webhook:path=/validate-raven-openyurt-io-v1beta1-gateway,mutating=false,failurePolicy=fail,sideEffects=None,admissionReviewVersions=v1;v1beta1,groups=raven.openyurt.io,resources=gateways,verbs=create;update,versions=v1beta1,name=validate.gateway.v1beta1.raven.openyurt.io
Expand Down
2 changes: 1 addition & 1 deletion pkg/yurtmanager/webhook/node/v1/node_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func (webhook *NodeHandler) SetupWebhookWithManager(mgr ctrl.Manager) (string, s
// init
webhook.Client = yurtClient.GetClientByControllerNameOrDie(mgr, names.NodePoolController)

return util.RegisterIndependentWebhook(mgr, &v1.Node{}, webhook, webhook)
return util.RegisterWebhook(mgr, &v1.Node{}, webhook)
}

// +kubebuilder:webhook:path=/validate-core-openyurt-io-v1-node,mutating=false,failurePolicy=ignore,sideEffects=None,admissionReviewVersions=v1,groups="",resources=nodes,verbs=update,versions=v1,name=validate.core.v1.node.openyurt.io
Expand Down
13 changes: 1 addition & 12 deletions pkg/yurtmanager/webhook/nodepool/v1beta1/nodepool_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package v1beta1
import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook"

yurtClient "github.com/openyurtio/openyurt/cmd/yurt-manager/app/client"
Expand All @@ -33,17 +32,7 @@ func (webhook *NodePoolHandler) SetupWebhookWithManager(mgr ctrl.Manager) (strin
// init
webhook.Client = yurtClient.GetClientByControllerNameOrDie(mgr, names.NodePoolController)

gvk, err := apiutil.GVKForObject(&v1beta1.NodePool{}, mgr.GetScheme())
if err != nil {
return "", "", err
}
return util.GenerateMutatePath(gvk),
util.GenerateValidatePath(gvk),
ctrl.NewWebhookManagedBy(mgr).
For(&v1beta1.NodePool{}).
WithDefaulter(webhook).
WithValidator(webhook).
Complete()
return util.RegisterWebhook(mgr, &v1beta1.NodePool{}, webhook)
}

// +kubebuilder:webhook:path=/validate-apps-openyurt-io-v1beta1-nodepool,mutating=false,failurePolicy=fail,groups=apps.openyurt.io,resources=nodepools,verbs=create;update;delete,versions=v1beta1,name=v.v1beta1.nodepool.kb.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"k8s.io/klog/v2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook"

yurtClient "github.com/openyurtio/openyurt/cmd/yurt-manager/app/client"
Expand All @@ -36,22 +35,10 @@ func (webhook *PlatformAdminHandler) SetupWebhookWithManager(mgr ctrl.Manager) (
// init
webhook.Client = yurtClient.GetClientByControllerNameOrDie(mgr, names.PlatformAdminController)

gvk, err := apiutil.GVKForObject(&v1alpha1.PlatformAdmin{}, mgr.GetScheme())
if err != nil {
return "", "", err
}

if err := webhook.initManifest(); err != nil {
return "", "", err
}

return webhookutil.GenerateMutatePath(gvk),
webhookutil.GenerateValidatePath(gvk),
ctrl.NewWebhookManagedBy(mgr).
For(&v1alpha1.PlatformAdmin{}).
WithDefaulter(webhook).
WithValidator(webhook).
Complete()
return webhookutil.RegisterWebhook(mgr, &v1alpha1.PlatformAdmin{}, webhook)
}

func (webhook *PlatformAdminHandler) initManifest() error {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"k8s.io/klog/v2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook"

yurtClient "github.com/openyurtio/openyurt/cmd/yurt-manager/app/client"
Expand All @@ -36,22 +35,11 @@ func (webhook *PlatformAdminHandler) SetupWebhookWithManager(mgr ctrl.Manager) (
// init
webhook.Client = yurtClient.GetClientByControllerNameOrDie(mgr, names.PlatformAdminController)

gvk, err := apiutil.GVKForObject(&v1alpha2.PlatformAdmin{}, mgr.GetScheme())
if err != nil {
return "", "", err
}

if err := webhook.initManifest(); err != nil {
return "", "", err
}

return webhookutil.GenerateMutatePath(gvk),
webhookutil.GenerateValidatePath(gvk),
ctrl.NewWebhookManagedBy(mgr).
For(&v1alpha2.PlatformAdmin{}).
WithDefaulter(webhook).
WithValidator(webhook).
Complete()
return webhookutil.RegisterWebhook(mgr, &v1alpha2.PlatformAdmin{}, webhook)
}

func (webhook *PlatformAdminHandler) initManifest() error {
Expand Down
2 changes: 1 addition & 1 deletion pkg/yurtmanager/webhook/pod/v1alpha1/pod_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const (

// SetupWebhookWithManager sets up Cluster webhooks. mutate path, validate path, error
func (webhook *PodHandler) SetupWebhookWithManager(mgr ctrl.Manager) (string, string, error) {
return util.RegisterIndependentWebhook(mgr, &corev1.Pod{}, webhook, nil)
return util.RegisterWebhook(mgr, &corev1.Pod{}, webhook)
}

// +kubebuilder:webhook:path=/mutate-core-openyurt-io-v1-pod,mutating=true,failurePolicy=ignore,sideEffects=None,admissionReviewVersions=v1;v1beta1,groups="",resources=pods,verbs=create,versions=v1,name=mutate.core.v1.pod.openyurt.io
Expand Down
21 changes: 13 additions & 8 deletions pkg/yurtmanager/webhook/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,21 @@ func SetupWithManager(c *config.CompletedConfig, mgr manager.Manager) error {
if err != nil {
return fmt.Errorf("unable to create webhook %v", err)
}
if _, ok := WebhookHandlerPath[m]; ok {
panic(fmt.Errorf("webhook handler path %s duplicated", m))
if len(m) != 0 {
if _, ok := WebhookHandlerPath[m]; ok {
panic(fmt.Errorf("webhook handler path %s duplicated", m))
}
WebhookHandlerPath[m] = struct{}{}
klog.Infof("Add webhook mutate path %s", m)
}
WebhookHandlerPath[m] = struct{}{}
klog.Infof("Add webhook mutate path %s", m)
if _, ok := WebhookHandlerPath[v]; ok {
panic(fmt.Errorf("webhook handler path %s duplicated", v))

if len(v) != 0 {
if _, ok := WebhookHandlerPath[v]; ok {
panic(fmt.Errorf("webhook handler path %s duplicated", v))
}
WebhookHandlerPath[v] = struct{}{}
klog.Infof("Add webhook validate path %s", v)
}
WebhookHandlerPath[v] = struct{}{}
klog.Infof("Add webhook validate path %s", v)

return nil
}
Expand Down
30 changes: 21 additions & 9 deletions pkg/yurtmanager/webhook/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"

yurtutil "github.com/openyurtio/openyurt/pkg/util"
"sigs.k8s.io/controller-runtime/pkg/webhook/conversion"
)

const (
Expand Down Expand Up @@ -90,7 +89,7 @@ func GetCertWriter() string {
return os.Getenv("WEBHOOK_CERT_WRITER")
}

func GenerateMutatePath(gvk schema.GroupVersionKind) string {
func generateMutatePath(gvk schema.GroupVersionKind) string {
groupName := gvk.Group
if groupName == "" {
groupName = emptyGroupName
Expand All @@ -100,7 +99,7 @@ func GenerateMutatePath(gvk schema.GroupVersionKind) string {
gvk.Version + "-" + strings.ToLower(gvk.Kind)
}

func GenerateValidatePath(gvk schema.GroupVersionKind) string {
func generateValidatePath(gvk schema.GroupVersionKind) string {
groupName := gvk.Group
if groupName == "" {
groupName = emptyGroupName
Expand All @@ -109,31 +108,44 @@ func GenerateValidatePath(gvk schema.GroupVersionKind) string {
gvk.Version + "-" + strings.ToLower(gvk.Kind)
}

func RegisterIndependentWebhook(mgr ctrl.Manager, obj runtime.Object, defaulter admission.CustomDefaulter, validator admission.CustomValidator) (string, string, error) {
func RegisterWebhook(mgr ctrl.Manager, obj runtime.Object, webhook interface{}) (string, string, error) {
var mutatePath, validatorPath string
gvk, err := apiutil.GVKForObject(obj, mgr.GetScheme())
if err != nil {
return mutatePath, validatorPath, err
}

if !yurtutil.IsNil(defaulter) {
if defaulter, ok := webhook.(admission.CustomDefaulter); ok {
mutateWebhook := admission.WithCustomDefaulter(mgr.GetScheme(), obj, defaulter).WithRecoverPanic(true)
mutatePath = GenerateMutatePath(gvk)
mutatePath = generateMutatePath(gvk)
if !isAlreadyHandled(mgr, mutatePath) {
klog.Infof("Registering a mutating webhook, GVK: %s with path: %s", gvk.String(), mutatePath)
mgr.GetWebhookServer().Register(mutatePath, mutateWebhook)
}
}

if !yurtutil.IsNil(validator) {
if validator, ok := webhook.(admission.CustomValidator); ok {
validatorWebhook := admission.WithCustomValidator(mgr.GetScheme(), obj, validator).WithRecoverPanic(true)
validatorPath = GenerateValidatePath(gvk)
validatorPath = generateValidatePath(gvk)
if !isAlreadyHandled(mgr, validatorPath) {
klog.Infof("Registering a validating webhook, GVK: %s with path: %s", gvk.String(), validatorPath)
mgr.GetWebhookServer().Register(validatorPath, validatorWebhook)
}
}

ok, err := conversion.IsConvertible(mgr.GetScheme(), obj)
if err != nil {
klog.ErrorS(err, "conversion check error", "GVK", gvk)
return mutatePath, validatorPath, err
}

if ok {
if !isAlreadyHandled(mgr, "/convert") {
mgr.GetWebhookServer().Register("/convert", conversion.NewWebhookHandler(mgr.GetScheme()))
}
klog.InfoS("Conversion webhook enabled", "GVK", gvk)
}

return mutatePath, validatorPath, nil
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ package v1alpha1
import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook"

yurtClient "github.com/openyurtio/openyurt/cmd/yurt-manager/app/client"
"github.com/openyurtio/openyurt/cmd/yurt-manager/names"
"github.com/openyurtio/openyurt/pkg/apis/apps/v1alpha1"
appsv1alpha1 "github.com/openyurtio/openyurt/pkg/apis/apps/v1alpha1"
"github.com/openyurtio/openyurt/pkg/yurtmanager/webhook/util"
)
Expand All @@ -34,17 +32,7 @@ func (webhook *YurtAppDaemonHandler) SetupWebhookWithManager(mgr ctrl.Manager) (
// init
webhook.Client = yurtClient.GetClientByControllerNameOrDie(mgr, names.YurtAppDaemonController)

gvk, err := apiutil.GVKForObject(&appsv1alpha1.YurtAppDaemon{}, mgr.GetScheme())
if err != nil {
return "", "", err
}
return util.GenerateMutatePath(gvk),
util.GenerateValidatePath(gvk),
ctrl.NewWebhookManagedBy(mgr).
For(&v1alpha1.YurtAppDaemon{}).
WithDefaulter(webhook).
WithValidator(webhook).
Complete()
return util.RegisterWebhook(mgr, &appsv1alpha1.YurtAppDaemon{}, webhook)
}

// +kubebuilder:webhook:path=/validate-apps-openyurt-io-v1alpha1-yurtappdaemon,mutating=false,failurePolicy=fail,sideEffects=None,admissionReviewVersions=v1;v1beta1,groups=apps.openyurt.io,resources=yurtappdaemons,verbs=create;update,versions=v1alpha1,name=validate.apps.v1alpha1.yurtappdaemon.openyurt.io
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package v1alpha1
import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook"

yurtClient "github.com/openyurtio/openyurt/cmd/yurt-manager/app/client"
Expand All @@ -33,17 +32,7 @@ func (webhook *YurtAppOverriderHandler) SetupWebhookWithManager(mgr ctrl.Manager
// init
webhook.Client = yurtClient.GetClientByControllerNameOrDie(mgr, names.YurtAppOverriderController)

gvk, err := apiutil.GVKForObject(&v1alpha1.YurtAppOverrider{}, mgr.GetScheme())
if err != nil {
return "", "", err
}
return util.GenerateMutatePath(gvk),
util.GenerateValidatePath(gvk),
ctrl.NewWebhookManagedBy(mgr).
For(&v1alpha1.YurtAppOverrider{}).
WithDefaulter(webhook).
WithValidator(webhook).
Complete()
return util.RegisterWebhook(mgr, &v1alpha1.YurtAppOverrider{}, webhook)
}

// +kubebuilder:webhook:path=/validate-apps-openyurt-io-v1alpha1-yurtappoverrider,mutating=false,failurePolicy=fail,sideEffects=None,admissionReviewVersions=v1;v1beta1,groups=apps.openyurt.io,resources=yurtappoverriders,verbs=create;update;delete,versions=v1alpha1,name=validate.apps.v1alpha1.yurtappoverrider.openyurt.io
Expand Down
13 changes: 1 addition & 12 deletions pkg/yurtmanager/webhook/yurtappset/v1beta1/yurtappset_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package v1beta1
import (
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/webhook"

"github.com/openyurtio/openyurt/pkg/apis/apps/v1beta1"
Expand All @@ -31,17 +30,7 @@ func (webhook *YurtAppSetHandler) SetupWebhookWithManager(mgr ctrl.Manager) (str
// init
webhook.Scheme = mgr.GetScheme()

gvk, err := apiutil.GVKForObject(&v1beta1.YurtAppSet{}, mgr.GetScheme())
if err != nil {
return "", "", err
}
return util.GenerateMutatePath(gvk),
util.GenerateValidatePath(gvk),
ctrl.NewWebhookManagedBy(mgr).
For(&v1beta1.YurtAppSet{}).
WithDefaulter(webhook).
WithValidator(webhook).
Complete()
return util.RegisterWebhook(mgr, &v1beta1.YurtAppSet{}, webhook)
}

// +kubebuilder:webhook:path=/validate-apps-openyurt-io-v1beta1-yurtappset,mutating=false,failurePolicy=fail,groups=apps.openyurt.io,resources=yurtappsets,verbs=create;update,versions=v1beta1,name=vyurtappset.kb.io,sideEffects=None,admissionReviewVersions=v1;v1beta1
Expand Down
Loading

0 comments on commit d02a949

Please sign in to comment.