Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions openshift/tests-extension/test/webhooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,32 @@ func ensureCleanupWebhookConfigurations(ctx context.Context, k8sClient client.Cl
}).WithTimeout(helpers.DefaultTimeout).WithPolling(helpers.DefaultPolling).Should(Succeed())
}

func waitForWebhookConfigurationsDeleted(ctx context.Context, k8sClient client.Client, validatingPrefix, mutatingPrefix string) {
Eventually(func(g Gomega) {
whList := &admissionregistrationv1.ValidatingWebhookConfigurationList{}
err := k8sClient.List(ctx, whList)
g.Expect(err).ToNot(HaveOccurred(), "failed to list ValidatingWebhookConfigurations")
staleValidatingWebhooks := []string{}
for _, wh := range whList.Items {
if validatingPrefix != "" && strings.HasPrefix(wh.Name, validatingPrefix) {
staleValidatingWebhooks = append(staleValidatingWebhooks, wh.Name)
}
}
g.Expect(staleValidatingWebhooks).To(BeEmpty(), "validating webhook configurations still exist: %v", staleValidatingWebhooks)

mwhList := &admissionregistrationv1.MutatingWebhookConfigurationList{}
err = k8sClient.List(ctx, mwhList)
g.Expect(err).ToNot(HaveOccurred(), "failed to list MutatingWebhookConfigurations")
staleMutatingWebhooks := []string{}
for _, mwh := range mwhList.Items {
if mutatingPrefix != "" && strings.HasPrefix(mwh.Name, mutatingPrefix) {
staleMutatingWebhooks = append(staleMutatingWebhooks, mwh.Name)
}
}
g.Expect(staleMutatingWebhooks).To(BeEmpty(), "mutating webhook configurations still exist: %v", staleMutatingWebhooks)
}).WithTimeout(helpers.DefaultTimeout).WithPolling(helpers.DefaultPolling).Should(Succeed())
}

var webhookTestV1 = schema.GroupVersionResource{
Group: "webhook.operators.coreos.io",
Version: "v1",
Expand Down Expand Up @@ -455,6 +481,14 @@ func setupWebhookOperator(ctx SpecContext, k8sClient client.Client, webhookOpera
g.Expect(client.IgnoreNotFound(err)).To(Succeed())
g.Expect(apierrors.IsNotFound(err)).To(BeTrue(), "ClusterExtension still exists")
}).WithTimeout(helpers.DefaultTimeout).WithPolling(helpers.DefaultPolling).Should(Succeed())

// Wait for OLMv1 finalizer cleanup to remove the webhook configurations before
// the namespace DeferCleanup runs. The webhook operator registers failurePolicy:Fail
// admission webhooks; if they outlive their backing service, the namespace controller
// cannot delete resources inside the terminating namespace, causing a 300s deadlock.
// This is deterministic on OVN because pod route teardown is immediate.
By("waiting for webhook configurations to be removed by OLMv1 cleanup")
waitForWebhookConfigurationsDeleted(ctx, k8sClient, "vwebhooktest", "mwebhooktest")
Comment on lines +485 to +491

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiosity, what prevents the OLMv1 finalizer cleanup from continuing to try to delete the webhook configurations concurrently with the namespace (and backing services) being deleted?

It seems like it should be fine to delete the webhook configs and namespace concurrently, and even if the backing services disappear, the webhook config deletion isn't far behind, at which point the rest of the namespace deletion proceeds?

})

By("waiting for the webhook operator to be installed")
Expand Down