diff --git a/docs/book/src/cronjob-tutorial/testdata/project/test/e2e/e2e_test.go b/docs/book/src/cronjob-tutorial/testdata/project/test/e2e/e2e_test.go index ff3834edc2f..2916bacdc57 100644 --- a/docs/book/src/cronjob-tutorial/testdata/project/test/e2e/e2e_test.go +++ b/docs/book/src/cronjob-tutorial/testdata/project/test/e2e/e2e_test.go @@ -216,6 +216,41 @@ var _ = Describe("Manager", Ordered, func() { } Eventually(verifyMetricsServerStarted).Should(Succeed()) + By("waiting for webhook service to be ready") + verifyWebhookServiceReady := func(g Gomega) { + const webhookServiceName = "project-webhook-service" + + // Webhook service should exist since webhooks are configured + cmd := exec.Command("kubectl", "get", "service", webhookServiceName, "-n", namespace) + _, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred(), "Webhook service should exist but was not found") + + // Check if webhook server is ready by verifying pod readiness + cmd = exec.Command("kubectl", "get", "pods", "-l", "control-plane=controller-manager", + "-n", namespace, "-o", "jsonpath={.items[0].status.conditions[?(@.type=='Ready')].status}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(output).To(Equal("True"), + "Controller manager pod not ready (webhook server may not be accepting connections)") + + // Check if webhook service endpoints are available + cmd = exec.Command("kubectl", "get", "endpoints", webhookServiceName, + "-n", namespace, "-o", "jsonpath={.subsets[*].addresses[*].ip}") + output, err = utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(output).NotTo(BeEmpty(), "Webhook service endpoints are not ready") + + // Test webhook connectivity by checking if webhook server port is responding + cmd = exec.Command("kubectl", "run", "webhook-test", "--rm", "-i", "--restart=Never", + "--image=curlimages/curl:latest", "--", + "curl", "-k", "--connect-timeout", "5", + "https://"+webhookServiceName+"."+namespace+".svc:443/readyz") + _, err = utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred(), "Webhook server not responding on port 443") + } + Eventually(verifyWebhookServiceReady, 2*time.Minute).Should(Succeed()) + // +kubebuilder:scaffold:e2e-webhooks-readiness + By("creating the curl-metrics pod to access the metrics endpoint") cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never", "--namespace", namespace, diff --git a/docs/book/src/getting-started/testdata/project/test/e2e/e2e_test.go b/docs/book/src/getting-started/testdata/project/test/e2e/e2e_test.go index adc9eda7e3f..e7451d9ebd1 100644 --- a/docs/book/src/getting-started/testdata/project/test/e2e/e2e_test.go +++ b/docs/book/src/getting-started/testdata/project/test/e2e/e2e_test.go @@ -211,6 +211,8 @@ var _ = Describe("Manager", Ordered, func() { } Eventually(verifyMetricsServerStarted).Should(Succeed()) + // +kubebuilder:scaffold:e2e-webhooks-readiness + By("creating the curl-metrics pod to access the metrics endpoint") cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never", "--namespace", namespace, diff --git a/docs/book/src/multiversion-tutorial/testdata/project/test/e2e/e2e_test.go b/docs/book/src/multiversion-tutorial/testdata/project/test/e2e/e2e_test.go index 29300e0e4d0..f224895c2e3 100644 --- a/docs/book/src/multiversion-tutorial/testdata/project/test/e2e/e2e_test.go +++ b/docs/book/src/multiversion-tutorial/testdata/project/test/e2e/e2e_test.go @@ -216,6 +216,41 @@ var _ = Describe("Manager", Ordered, func() { } Eventually(verifyMetricsServerStarted).Should(Succeed()) + By("waiting for webhook service to be ready") + verifyWebhookServiceReady := func(g Gomega) { + const webhookServiceName = "project-webhook-service" + + // Webhook service should exist since webhooks are configured + cmd := exec.Command("kubectl", "get", "service", webhookServiceName, "-n", namespace) + _, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred(), "Webhook service should exist but was not found") + + // Check if webhook server is ready by verifying pod readiness + cmd = exec.Command("kubectl", "get", "pods", "-l", "control-plane=controller-manager", + "-n", namespace, "-o", "jsonpath={.items[0].status.conditions[?(@.type=='Ready')].status}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(output).To(Equal("True"), + "Controller manager pod not ready (webhook server may not be accepting connections)") + + // Check if webhook service endpoints are available + cmd = exec.Command("kubectl", "get", "endpoints", webhookServiceName, + "-n", namespace, "-o", "jsonpath={.subsets[*].addresses[*].ip}") + output, err = utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred()) + g.Expect(output).NotTo(BeEmpty(), "Webhook service endpoints are not ready") + + // Test webhook connectivity by checking if webhook server port is responding + cmd = exec.Command("kubectl", "run", "webhook-test", "--rm", "-i", "--restart=Never", + "--image=curlimages/curl:latest", "--", + "curl", "-k", "--connect-timeout", "5", + "https://"+webhookServiceName+"."+namespace+".svc:443/readyz") + _, err = utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred(), "Webhook server not responding on port 443") + } + Eventually(verifyWebhookServiceReady, 2*time.Minute).Should(Succeed()) + // +kubebuilder:scaffold:e2e-webhooks-readiness + By("creating the curl-metrics pod to access the metrics endpoint") cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never", "--namespace", namespace, diff --git a/docs/book/src/reference/markers/scaffold.md b/docs/book/src/reference/markers/scaffold.md index ab68f4f02db..9d26aae080b 100644 --- a/docs/book/src/reference/markers/scaffold.md +++ b/docs/book/src/reference/markers/scaffold.md @@ -107,6 +107,7 @@ properly registered with the manager, so that the controller can reconcile the r | `+kubebuilder:scaffold:crdkustomizecainjectioname` | `config/default` | Marks where CA injection patches are added for the conversion webhooks. | | **(No longer supported)** `+kubebuilder:scaffold:crdkustomizecainjectionpatch` | `config/crd` | Marks where CA injection patches are added for the webhooks. Replaced by `+kubebuilder:scaffold:crdkustomizecainjectionns` and `+kubebuilder:scaffold:crdkustomizecainjectioname` | | `+kubebuilder:scaffold:manifestskustomizesamples` | `config/samples` | Marks where Kustomize sample manifests are injected. | +| `+kubebuilder:scaffold:e2e-webhooks-readiness` | `test/e2e` | Adds webhooks readiness checks in e2e tests before metrics collection. | | `+kubebuilder:scaffold:e2e-webhooks-checks` | `test/e2e` | Adds e2e checks for webhooks depending on the types of webhooks scaffolded. |