Skip to content

Testing Webhooks locally

Adyanth Hosavalike edited this page May 2, 2025 · 6 revisions

Since webhooks need to be served with TLS, testing them while developing is a slight pain. Here are the steps I follow:

Apply this patch with the <ip-address-of-dev> replaced by the IP of the dev host reachable by the k8s server. The /path/to/dev/certs/ should be replaced by the path where the certificate (tls.crt/tls.key) generated later is stored.

diff --git a/cmd/main.go b/cmd/main.go
index cec59e7..52e45dd 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -35,6 +35,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/log/zap"
 	"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
 	metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
+	"sigs.k8s.io/controller-runtime/pkg/webhook"
 
 	networkingv1alpha1 "github.com/adyanth/cloudflare-operator/api/v1alpha1"
 	networkingv1alpha2 "github.com/adyanth/cloudflare-operator/api/v1alpha2"
@@ -100,6 +101,9 @@ func main() {
 		LeaderElection:          enableLeaderElection,
 		LeaderElectionID:        "9f193cf8.cfargotunnel.com",
 		LeaderElectionNamespace: clusterResourceNamespace,
+		WebhookServer: webhook.NewServer(webhook.Options{
+			CertDir: "/path/to/dev/certs/",
+		}),
 	})
 	if err != nil {
 		setupLog.Error(err, "unable to start manager")
diff --git a/config/crd/patches/webhook_in_clustertunnels.yaml b/config/crd/patches/webhook_in_clustertunnels.yaml
index 47fb964..799348f 100644
--- a/config/crd/patches/webhook_in_clustertunnels.yaml
+++ b/config/crd/patches/webhook_in_clustertunnels.yaml
@@ -8,9 +8,6 @@ spec:
     strategy: Webhook
     webhook:
       clientConfig:
-        service:
-          namespace: system
-          name: webhook-service
-          path: /convert
+        url: https://100.120.130.56:9443/convert
       conversionReviewVersions:
       - v1
diff --git a/config/crd/patches/webhook_in_tunnels.yaml b/config/crd/patches/webhook_in_tunnels.yaml
index ae3c304..3171929 100644
--- a/config/crd/patches/webhook_in_tunnels.yaml
+++ b/config/crd/patches/webhook_in_tunnels.yaml
@@ -8,9 +8,6 @@ spec:
     strategy: Webhook
     webhook:
       clientConfig:
-        service:
-          namespace: system
-          name: webhook-service
-          path: /convert
+        url: https://100.120.130.56:9443/convert
       conversionReviewVersions:
       - v1

To create certs (assuming an empty test cluster. If you already have one, feel free to use it), we'll make use of cert-manager. So, lets install that with

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yaml

Then, to create the couple of issuers and certs:

apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: selfsigned-issuer
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: test-ca
spec:
  isCA: true
  commonName: test-ca
  subject:
    organizations:
      - ACME Inc.
    organizationalUnits:
      - Widgets
  secretName: test-ca-secret
  privateKey:
    algorithm: ECDSA
    size: 256
  issuerRef:
    name: selfsigned-issuer
    kind: Issuer
    group: cert-manager.io
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: test-ca-issuer
spec:
  ca:
    secretName: test-ca-secret
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: webhook
spec:
  secretName: webhook-tls
  isCA: false
  usages:
    - server auth
    - client auth
  dnsNames:
  - "webhook.test.svc.cluster.local"
  - "*"
  ipAddresses:
  - "100.120.130.56"
  issuerRef:
    name: test-ca-issuer

Once these are applied, run the following to get the certs out to the path specified earlier.

kubectl get secrets test-ca-secret -o yaml | yq .data | yq '."tls.crt"' | base64 -d  > /path/to/dev/certs/ca.crt
kubectl get secrets webhook-tls -o yaml | yq .data | yq '."tls.crt"' | base64 -d  > /path/to/dev/certs/tls.crt
kubectl get secrets webhook-tls -o yaml | yq .data | yq '."tls.key"' | base64 -d  > /path/to/dev/certs/tls.key

Final step, on the dev host, trust the newly created CA cert ca.crt.

Clone this wiki locally