This is an automated email from the ASF dual-hosted git repository.

ronething pushed a commit to branch feat/gateway_ingressclass_webhook
in repository https://gitbox.apache.org/repos/asf/apisix-ingress-controller.git

commit 13438f94f8e6c254bce185b7ecbafb0c661a0c27
Author: Ashing Zheng <[email protected]>
AuthorDate: Mon Sep 22 17:30:28 2025 +0800

    feat: add webhook for ingressclass and gateway
    
    Signed-off-by: Ashing Zheng <[email protected]>
---
 PROJECT                                     | 17 +++++
 internal/webhook/v1/gateway_webhook.go      | 96 +++++++++++++++++++++++++++++
 internal/webhook/v1/ingressclass_webhook.go | 96 +++++++++++++++++++++++++++++
 3 files changed, 209 insertions(+)

diff --git a/PROJECT b/PROJECT
index a9b4a155..cb21ee36 100644
--- a/PROJECT
+++ b/PROJECT
@@ -78,4 +78,21 @@ resources:
   webhooks:
     validation: true
     webhookVersion: v1
+- core: true
+  domain: k8s.io
+  group: networking
+  kind: IngressClass
+  path: k8s.io/api/networking/v1
+  version: v1
+  webhooks:
+    validation: true
+    webhookVersion: v1
+- external: true
+  group: gateway.networking.k8s.io
+  kind: Gateway
+  path: sigs.k8s.io/gateway-api/apis/v1
+  version: v1
+  webhooks:
+    validation: true
+    webhookVersion: v1
 version: "3"
diff --git a/internal/webhook/v1/gateway_webhook.go 
b/internal/webhook/v1/gateway_webhook.go
new file mode 100644
index 00000000..799754b9
--- /dev/null
+++ b/internal/webhook/v1/gateway_webhook.go
@@ -0,0 +1,96 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package v1
+
+import (
+       "context"
+       "fmt"
+
+       "k8s.io/apimachinery/pkg/runtime"
+       ctrl "sigs.k8s.io/controller-runtime"
+       logf "sigs.k8s.io/controller-runtime/pkg/log"
+       "sigs.k8s.io/controller-runtime/pkg/webhook"
+       "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
+       gatewaynetworkingk8siov1 "sigs.k8s.io/gateway-api/apis/v1"
+)
+
+// nolint:unused
+// log is for logging in this package.
+var gatewaylog = logf.Log.WithName("gateway-resource")
+
+// SetupGatewayWebhookWithManager registers the webhook for Gateway in the 
manager.
+func SetupGatewayWebhookWithManager(mgr ctrl.Manager) error {
+       return 
ctrl.NewWebhookManagedBy(mgr).For(&gatewaynetworkingk8siov1.Gateway{}).
+               WithValidator(&GatewayCustomValidator{}).
+               Complete()
+}
+
+// TODO(user): EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
+
+// TODO(user): change verbs to "verbs=create;update;delete" if you want to 
enable deletion validation.
+// NOTE: The 'path' attribute must follow a specific pattern and should not be 
modified directly here.
+// Modifying the path for an invalid path can cause API server errors; failing 
to locate the webhook.
+// 
+kubebuilder:webhook:path=/validate-gateway-networking-k8s-io-v1-gateway,mutating=false,failurePolicy=fail,sideEffects=None,groups=gateway.networking.k8s.io,resources=gateways,verbs=create;update,versions=v1,name=vgateway-v1.kb.io,admissionReviewVersions=v1
+
+// GatewayCustomValidator struct is responsible for validating the Gateway 
resource
+// when it is created, updated, or deleted.
+//
+// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen 
from generating DeepCopy methods,
+// as this struct is used only for temporary operations and does not need to 
be deeply copied.
+type GatewayCustomValidator struct {
+       // TODO(user): Add more fields as needed for validation
+}
+
+var _ webhook.CustomValidator = &GatewayCustomValidator{}
+
+// ValidateCreate implements webhook.CustomValidator so a webhook will be 
registered for the type Gateway.
+func (v *GatewayCustomValidator) ValidateCreate(_ context.Context, obj 
runtime.Object) (admission.Warnings, error) {
+       gateway, ok := obj.(*gatewaynetworkingk8siov1.Gateway)
+       if !ok {
+               return nil, fmt.Errorf("expected a Gateway object but got %T", 
obj)
+       }
+       gatewaylog.Info("Validation for Gateway upon creation", "name", 
gateway.GetName())
+
+       // TODO(user): fill in your validation logic upon object creation.
+
+       return nil, nil
+}
+
+// ValidateUpdate implements webhook.CustomValidator so a webhook will be 
registered for the type Gateway.
+func (v *GatewayCustomValidator) ValidateUpdate(_ context.Context, oldObj, 
newObj runtime.Object) (admission.Warnings, error) {
+       gateway, ok := newObj.(*gatewaynetworkingk8siov1.Gateway)
+       if !ok {
+               return nil, fmt.Errorf("expected a Gateway object for the 
newObj but got %T", newObj)
+       }
+       gatewaylog.Info("Validation for Gateway upon update", "name", 
gateway.GetName())
+
+       // TODO(user): fill in your validation logic upon object update.
+
+       return nil, nil
+}
+
+// ValidateDelete implements webhook.CustomValidator so a webhook will be 
registered for the type Gateway.
+func (v *GatewayCustomValidator) ValidateDelete(ctx context.Context, obj 
runtime.Object) (admission.Warnings, error) {
+       gateway, ok := obj.(*gatewaynetworkingk8siov1.Gateway)
+       if !ok {
+               return nil, fmt.Errorf("expected a Gateway object but got %T", 
obj)
+       }
+       gatewaylog.Info("Validation for Gateway upon deletion", "name", 
gateway.GetName())
+
+       // TODO(user): fill in your validation logic upon object deletion.
+
+       return nil, nil
+}
diff --git a/internal/webhook/v1/ingressclass_webhook.go 
b/internal/webhook/v1/ingressclass_webhook.go
new file mode 100644
index 00000000..2712666a
--- /dev/null
+++ b/internal/webhook/v1/ingressclass_webhook.go
@@ -0,0 +1,96 @@
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements.  See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to You under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package v1
+
+import (
+       "context"
+       "fmt"
+
+       networkingv1 "k8s.io/api/networking/v1"
+       "k8s.io/apimachinery/pkg/runtime"
+       ctrl "sigs.k8s.io/controller-runtime"
+       logf "sigs.k8s.io/controller-runtime/pkg/log"
+       "sigs.k8s.io/controller-runtime/pkg/webhook"
+       "sigs.k8s.io/controller-runtime/pkg/webhook/admission"
+)
+
+// nolint:unused
+// log is for logging in this package.
+var ingressclasslog = logf.Log.WithName("ingressclass-resource")
+
+// SetupIngressClassWebhookWithManager registers the webhook for IngressClass 
in the manager.
+func SetupIngressClassWebhookWithManager(mgr ctrl.Manager) error {
+       return ctrl.NewWebhookManagedBy(mgr).For(&networkingv1.IngressClass{}).
+               WithValidator(&IngressClassCustomValidator{}).
+               Complete()
+}
+
+// TODO(user): EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
+
+// TODO(user): change verbs to "verbs=create;update;delete" if you want to 
enable deletion validation.
+// NOTE: The 'path' attribute must follow a specific pattern and should not be 
modified directly here.
+// Modifying the path for an invalid path can cause API server errors; failing 
to locate the webhook.
+// 
+kubebuilder:webhook:path=/validate-networking-k8s-io-v1-ingressclass,mutating=false,failurePolicy=fail,sideEffects=None,groups=networking.k8s.io,resources=ingressclasses,verbs=create;update,versions=v1,name=vingressclass-v1.kb.io,admissionReviewVersions=v1
+
+// IngressClassCustomValidator struct is responsible for validating the 
IngressClass resource
+// when it is created, updated, or deleted.
+//
+// NOTE: The +kubebuilder:object:generate=false marker prevents controller-gen 
from generating DeepCopy methods,
+// as this struct is used only for temporary operations and does not need to 
be deeply copied.
+type IngressClassCustomValidator struct {
+       // TODO(user): Add more fields as needed for validation
+}
+
+var _ webhook.CustomValidator = &IngressClassCustomValidator{}
+
+// ValidateCreate implements webhook.CustomValidator so a webhook will be 
registered for the type IngressClass.
+func (v *IngressClassCustomValidator) ValidateCreate(_ context.Context, obj 
runtime.Object) (admission.Warnings, error) {
+       ingressclass, ok := obj.(*networkingv1.IngressClass)
+       if !ok {
+               return nil, fmt.Errorf("expected a IngressClass object but got 
%T", obj)
+       }
+       ingressclasslog.Info("Validation for IngressClass upon creation", 
"name", ingressclass.GetName())
+
+       // TODO(user): fill in your validation logic upon object creation.
+
+       return nil, nil
+}
+
+// ValidateUpdate implements webhook.CustomValidator so a webhook will be 
registered for the type IngressClass.
+func (v *IngressClassCustomValidator) ValidateUpdate(_ context.Context, 
oldObj, newObj runtime.Object) (admission.Warnings, error) {
+       ingressclass, ok := newObj.(*networkingv1.IngressClass)
+       if !ok {
+               return nil, fmt.Errorf("expected a IngressClass object for the 
newObj but got %T", newObj)
+       }
+       ingressclasslog.Info("Validation for IngressClass upon update", "name", 
ingressclass.GetName())
+
+       // TODO(user): fill in your validation logic upon object update.
+
+       return nil, nil
+}
+
+// ValidateDelete implements webhook.CustomValidator so a webhook will be 
registered for the type IngressClass.
+func (v *IngressClassCustomValidator) ValidateDelete(ctx context.Context, obj 
runtime.Object) (admission.Warnings, error) {
+       ingressclass, ok := obj.(*networkingv1.IngressClass)
+       if !ok {
+               return nil, fmt.Errorf("expected a IngressClass object but got 
%T", obj)
+       }
+       ingressclasslog.Info("Validation for IngressClass upon deletion", 
"name", ingressclass.GetName())
+
+       // TODO(user): fill in your validation logic upon object deletion.
+
+       return nil, nil
+}

Reply via email to