Repository navigation
chore(packages): factor webhook-readiness gate into cozy-lib helper #2519
Description
Context
#2482 added a post-install Helm hook to packages/system/postgres-operator that blocks the HelmRelease from reporting Ready until the cnpg admission webhook actually serves through the apiserver service proxy. This closes a confirmed bootstrap race where dependent HelmReleases (cozy-keycloak, tenant Postgres apps) hit dial tcp <svc-ip>:443: connect: connection refused against the cnpg mutating webhook.
The same race class exists in other packages, but copy-pasting the 148-line hook + 328-line test file into each of them is the wrong shape.
Proposal
Factor the gate into a cozy-lib partial so adopters opt in with ~10 lines.
Helper
packages/library/cozy-lib/templates/_webhook-ready.tpl exposing something like:
{{- define "cozy-lib.webhook-ready-hook" -}}
{{- /* args: dict "release" .Release "service" "<svc>" "port" "<portname>" "image" .Values.webhookReady.image ... */ -}}
...
{{- end -}}
Adopter site (per package)
{{- include "cozy-lib.webhook-ready-hook" (dict
"release" .Release
"service" "cnpg-webhook-service"
"port" "webhook-server"
"values" .Values.webhookReady
) }}Centralized image pin
Move the clastix/kubectl@sha256:… digest to a single place (cozy-lib default values or a shared images.yaml) so renovate updates land in one PR instead of N. Today it is duplicated in packages/system/postgres-operator/values.yaml and would be duplicated again in every adopter.
Drift-guard test pattern
Document the pattern (re-render the vendored subchart Service and assert metadata.name / ports[0].name against the literals passed into the helper) so each adopter can wire it in their own helm-unittest suite.
Candidate adopters (in priority order)
Conditions for adoption: package ships an admission webhook and has at least one consumer with dependsOn: against it that creates a CR/object the webhook intercepts on the first reconcile. Mapped against packages/core/platform/sources/*.yaml:
| Package | Downstream consumers | Trigger |
|---|---|---|
postgres-operator |
5 (already done in #2482) | postgresql.cnpg.io CRs |
kamaji |
capi-provider-cp-kamaji |
kamaji.clastix.io/TenantControlPlane |
mariadb-operator |
mariadb-application |
MariaDB CRs |
rabbitmq-operator |
rabbitmq-application |
RabbitmqCluster CRs |
victoria-metrics-operator |
monitoring, monitoring-agents, monitoring-application, kubeovn-plunger, linstor |
VMServiceScrape, VMRule, … |
keycloak-operator |
cozystack-engine |
Keycloak/KeycloakRealm |
etcd-operator |
(tenant flows) | etcd CRs |
Out of scope (the race exists but dependsOn is not the trigger — the webhook intercepts continuously created core resources from users, not the first dependent install): metallb, kubeovn-webhook, lineage-controller-webhook, linstor-scheduler, openbao injector, telepresence agent injector.
Already covered upstream (no work needed): cert-manager ships a startupapicheck Job as a post-install hook, enabled by default in the cozystack package.
Non-goals
- Do not retrofit reactively. Wait for a second incident in this class. This issue exists so that when one shows up, the response is "instantiate the helper" rather than "copy 476 lines from postgres-operator".
Acceptance criteria
-
cozy-lib.webhook-ready-hookhelper exists, takes service name + port name + image + retry knobs as inputs. - At least one adopter (postgres-operator) is migrated to the helper, dropping the inlined template.
- Drift-guard test pattern documented in cozy-lib README.
-
clastix/kubectldigest centralized.
Refs
- fix(postgres-operator): block HelmRelease Ready until the cnpg webhook actually serves #2482 — original fix that this issue follows up on
Activity
myasnikovdaniil commentedon Jun 9, 2026
need check if that is relevant with new kstatus based readiness in flux