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..adff96390cc 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 @@ -197,24 +197,38 @@ var _ = Describe("Manager", Ordered, func() { Expect(err).NotTo(HaveOccurred()) Expect(token).NotTo(BeEmpty()) - By("waiting for the metrics endpoint to be ready") - verifyMetricsEndpointReady := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "endpoints", metricsServiceName, "-n", namespace) + By("ensuring the controller pod is ready") + verifyControllerPodReady := func(g Gomega) { + cmd := exec.Command("kubectl", "get", "pod", controllerPodName, "-n", namespace, + "-o", "jsonpath={.status.conditions[?(@.type=='Ready')].status}") output, err := utils.Run(cmd) g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("8443"), "Metrics endpoint is not ready") + g.Expect(output).To(Equal("True"), "Controller pod not ready") } - Eventually(verifyMetricsEndpointReady).Should(Succeed()) + Eventually(verifyControllerPodReady, 3*time.Minute, time.Second).Should(Succeed()) By("verifying that the controller manager is serving the metrics server") verifyMetricsServerStarted := func(g Gomega) { cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace) output, err := utils.Run(cmd) g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"), + g.Expect(output).To(ContainSubstring("Serving metrics server"), "Metrics server not yet started") } - Eventually(verifyMetricsServerStarted).Should(Succeed()) + Eventually(verifyMetricsServerStarted, 3*time.Minute, time.Second).Should(Succeed()) + + By("waiting for the webhook service endpoints to be ready") + verifyWebhookEndpointsReady := func(g Gomega) { + cmd := exec.Command("kubectl", "get", "endpointslices.discovery.k8s.io", "-n", namespace, + "-l", "kubernetes.io/service-name=project-webhook-service", + "-o", "jsonpath={range .items[*]}{range .endpoints[*]}{.addresses[*]}{end}{end}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred(), "Webhook endpoints should exist") + g.Expect(output).ShouldNot(BeEmpty(), "Webhook endpoints not yet ready") + } + Eventually(verifyWebhookEndpointsReady, 3*time.Minute, time.Second).Should(Succeed()) + + // +kubebuilder:scaffold:e2e-metrics-webhooks-readiness By("creating the curl-metrics pod to access the metrics endpoint") cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never", 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..d4b206e9618 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 @@ -192,24 +192,27 @@ var _ = Describe("Manager", Ordered, func() { Expect(err).NotTo(HaveOccurred()) Expect(token).NotTo(BeEmpty()) - By("waiting for the metrics endpoint to be ready") - verifyMetricsEndpointReady := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "endpoints", metricsServiceName, "-n", namespace) + By("ensuring the controller pod is ready") + verifyControllerPodReady := func(g Gomega) { + cmd := exec.Command("kubectl", "get", "pod", controllerPodName, "-n", namespace, + "-o", "jsonpath={.status.conditions[?(@.type=='Ready')].status}") output, err := utils.Run(cmd) g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("8443"), "Metrics endpoint is not ready") + g.Expect(output).To(Equal("True"), "Controller pod not ready") } - Eventually(verifyMetricsEndpointReady).Should(Succeed()) + Eventually(verifyControllerPodReady, 3*time.Minute, time.Second).Should(Succeed()) By("verifying that the controller manager is serving the metrics server") verifyMetricsServerStarted := func(g Gomega) { cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace) output, err := utils.Run(cmd) g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"), + g.Expect(output).To(ContainSubstring("Serving metrics server"), "Metrics server not yet started") } - Eventually(verifyMetricsServerStarted).Should(Succeed()) + Eventually(verifyMetricsServerStarted, 3*time.Minute, time.Second).Should(Succeed()) + + // +kubebuilder:scaffold:e2e-metrics-webhooks-readiness By("creating the curl-metrics pod to access the metrics endpoint") cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never", 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 8edcb41db53..d7f7aa49c12 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 @@ -204,24 +204,38 @@ var _ = Describe("Manager", Ordered, func() { Expect(err).NotTo(HaveOccurred()) Expect(token).NotTo(BeEmpty()) - By("waiting for the metrics endpoint to be ready") - verifyMetricsEndpointReady := func(g Gomega) { - cmd := exec.Command("kubectl", "get", "endpoints", metricsServiceName, "-n", namespace) + By("ensuring the controller pod is ready") + verifyControllerPodReady := func(g Gomega) { + cmd := exec.Command("kubectl", "get", "pod", controllerPodName, "-n", namespace, + "-o", "jsonpath={.status.conditions[?(@.type=='Ready')].status}") output, err := utils.Run(cmd) g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("8443"), "Metrics endpoint is not ready") + g.Expect(output).To(Equal("True"), "Controller pod not ready") } - Eventually(verifyMetricsEndpointReady).Should(Succeed()) + Eventually(verifyControllerPodReady, 3*time.Minute, time.Second).Should(Succeed()) By("verifying that the controller manager is serving the metrics server") verifyMetricsServerStarted := func(g Gomega) { cmd := exec.Command("kubectl", "logs", controllerPodName, "-n", namespace) output, err := utils.Run(cmd) g.Expect(err).NotTo(HaveOccurred()) - g.Expect(output).To(ContainSubstring("controller-runtime.metrics\tServing metrics server"), + g.Expect(output).To(ContainSubstring("Serving metrics server"), "Metrics server not yet started") } - Eventually(verifyMetricsServerStarted).Should(Succeed()) + Eventually(verifyMetricsServerStarted, 3*time.Minute, time.Second).Should(Succeed()) + + By("waiting for the webhook service endpoints to be ready") + verifyWebhookEndpointsReady := func(g Gomega) { + cmd := exec.Command("kubectl", "get", "endpointslices.discovery.k8s.io", "-n", namespace, + "-l", "kubernetes.io/service-name=project-webhook-service", + "-o", "jsonpath={range .items[*]}{range .endpoints[*]}{.addresses[*]}{end}{end}") + output, err := utils.Run(cmd) + g.Expect(err).NotTo(HaveOccurred(), "Webhook endpoints should exist") + g.Expect(output).ShouldNot(BeEmpty(), "Webhook endpoints not yet ready") + } + Eventually(verifyWebhookEndpointsReady, 3*time.Minute, time.Second).Should(Succeed()) + + // +kubebuilder:scaffold:e2e-metrics-webhooks-readiness By("creating the curl-metrics pod to access the metrics endpoint") cmd = exec.Command("kubectl", "run", "curl-metrics", "--restart=Never", diff --git a/docs/book/src/reference/markers/scaffold.md b/docs/book/src/reference/markers/scaffold.md index ffc7d06d000..2068a77b9d8 100644 --- a/docs/book/src/reference/markers/scaffold.md +++ b/docs/book/src/reference/markers/scaffold.md @@ -95,20 +95,20 @@ properly registered with the manager, so that the controller can reconcile the r ## List of `+kubebuilder:scaffold` Markers -| Marker | Usual Location | Function | -|--------------------------------------------|------------------------------|---------------------------------------------------------------------------------| -| `+kubebuilder:scaffold:imports` | `main.go` | Marks where imports for new controllers, webhooks, or APIs should be injected. | -| `+kubebuilder:scaffold:scheme` | `init()` in `main.go` | Used to add API versions to the scheme for runtime. | -| `+kubebuilder:scaffold:builder` | `main.go` | Marks where new controllers should be registered with the manager. | -| `+kubebuilder:scaffold:webhook` | `webhooks suite tests` files | Marks where webhook setup functions are added. | -| `+kubebuilder:scaffold:crdkustomizeresource`| `config/crd` | Marks where CRD custom resource patches are added. | -| `+kubebuilder:scaffold:crdkustomizewebhookpatch` | `config/crd` | Marks where CRD webhook patches are added. | -| `+kubebuilder:scaffold:crdkustomizecainjectionns` | `config/default` | Marks where CA injection patches are added for the conversion webhooks. | -| `+kubebuilder:scaffold:crdkustomizecainjectioname` | `config/default` | Marks where CA injection patches are added for the conversion webhooks. | +| Marker | Usual Location | Function | +|--------------------------------------------------------------------------------|------------------------------|---------------------------------------------------------------------------------| +| `+kubebuilder:scaffold:imports` | `main.go` | Marks where imports for new controllers, webhooks, or APIs should be injected. | +| `+kubebuilder:scaffold:scheme` | `init()` in `main.go` | Used to add API versions to the scheme for runtime. | +| `+kubebuilder:scaffold:builder` | `main.go` | Marks where new controllers should be registered with the manager. | +| `+kubebuilder:scaffold:webhook` | `webhooks suite tests` files | Marks where webhook setup functions are added. | +| `+kubebuilder:scaffold:crdkustomizeresource` | `config/crd` | Marks where CRD custom resource patches are added. | +| `+kubebuilder:scaffold:crdkustomizewebhookpatch` | `config/crd` | Marks where CRD webhook patches are added. | +| `+kubebuilder:scaffold:crdkustomizecainjectionns` | `config/default` | Marks where CA injection patches are added for the conversion webhooks. | +| `+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-checks` | `test/e2e` | Adds e2e checks for webhooks depending on the types of webhooks scaffolded. | - +| `+kubebuilder:scaffold:manifestskustomizesamples` | `config/samples` | Marks where Kustomize sample manifests are injected. | +| `+kubebuilder:scaffold:e2e-webhooks-checks` | `test/e2e` | Adds e2e checks for webhooks depending on the types of webhooks scaffolded. | +| `+kubebuilder:scaffold:e2e-metrics-webhooks-readiness` | `test/e2e` | Adds readiness logic so metrics e2e tests wait for webhook service endpoints before creating pods. |