Files
cozystack/packages/system/postgres-operator/tests/webhook-ready-hook_test.yaml
Aleksei Sviridkin fc057c0393 fix(postgres-operator): set resources on webhook-ready wait container
Address review feedback from gemini-code-assist on
packages/system/postgres-operator/templates/webhook-ready-hook.yaml:115.

The wait container had no resource requests or limits, so schedulers
treated it as BestEffort and downstream quota enforcement had no signal.
Set small requests (10m CPU, 32Mi memory) and conservative limits
(100m CPU, 64Mi memory) matching the actual footprint of the kubectl
polling loop.

Add a matching unittest assertion so the values stay in sync if anyone
touches the template.

Assisted-By: Claude <noreply@anthropic.com>
Signed-off-by: Aleksei Sviridkin <f@lex.la>
2026-04-24 13:32:33 +03:00

329 lines
10 KiB
YAML

suite: cnpg webhook post-install readiness gate
templates:
- templates/webhook-ready-hook.yaml
- charts/cloudnative-pg/templates/service.yaml
release:
name: postgres-operator
namespace: cozy-postgres-operator
tests:
- it: renders four hook objects (SA + Role + RoleBinding + Job)
template: templates/webhook-ready-hook.yaml
asserts:
- hasDocuments:
count: 4
- it: every rendered object carries post-install and post-upgrade hook annotations
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 0
equal:
path: metadata.annotations["helm.sh/hook"]
value: post-install,post-upgrade
- documentIndex: 1
equal:
path: metadata.annotations["helm.sh/hook"]
value: post-install,post-upgrade
- documentIndex: 2
equal:
path: metadata.annotations["helm.sh/hook"]
value: post-install,post-upgrade
- documentIndex: 3
equal:
path: metadata.annotations["helm.sh/hook"]
value: post-install,post-upgrade
- it: RBAC is created before the Job (hook-weight ordering)
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 0
equal:
path: kind
value: ServiceAccount
- documentIndex: 0
equal:
path: metadata.annotations["helm.sh/hook-weight"]
value: "0"
- documentIndex: 1
equal:
path: kind
value: Role
- documentIndex: 1
equal:
path: metadata.annotations["helm.sh/hook-weight"]
value: "0"
- documentIndex: 2
equal:
path: kind
value: RoleBinding
- documentIndex: 2
equal:
path: metadata.annotations["helm.sh/hook-weight"]
value: "0"
- documentIndex: 3
equal:
path: kind
value: Job
- documentIndex: 3
equal:
path: metadata.annotations["helm.sh/hook-weight"]
value: "10"
- it: RBAC resourceName matches the exact proxy URL segment the Job probes
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 1
equal:
path: rules[0].resources[0]
value: services/proxy
- documentIndex: 1
equal:
path: rules[0].resourceNames[0]
value: https:cnpg-webhook-service:webhook-server
- documentIndex: 3
matchRegex:
path: spec.template.spec.containers[0].command[2]
pattern: "/api/v1/namespaces/\\$\\{ns\\}/services/https:cnpg-webhook-service:webhook-server/proxy/readyz"
- it: hardcoded service name in the hook matches the vendored cnpg subchart Service (drift guard for make update)
template: charts/cloudnative-pg/templates/service.yaml
asserts:
- equal:
path: metadata.name
value: cnpg-webhook-service
- equal:
path: spec.ports[0].name
value: webhook-server
- it: Job calls kubectl get --raw on the proxy path
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 3
matchRegex:
path: spec.template.spec.containers[0].command[2]
pattern: "kubectl get --raw"
- it: Job image is digest-pinned when webhookReady.image.digest is set
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
image:
repository: docker.io/clastix/kubectl
tag: v1.32
digest: sha256:b9ef7d8dbe65bcc81a46c09b8dc7543103055021c4f43287bf59e92a8f4fe05c
asserts:
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].image
value: docker.io/clastix/kubectl:v1.32@sha256:b9ef7d8dbe65bcc81a46c09b8dc7543103055021c4f43287bf59e92a8f4fe05c
- it: Job image falls back to tag-only when digest is not configured
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
image:
repository: docker.io/clastix/kubectl
tag: v1.32
digest: ""
asserts:
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].image
value: docker.io/clastix/kubectl:v1.32
- it: backoffLimit defaults to 2 so transient pod-level failures retry instead of killing the HelmRelease
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 3
equal:
path: spec.backoffLimit
value: 2
- it: backoffLimit is overridable
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
backoffLimit: 5
asserts:
- documentIndex: 3
equal:
path: spec.backoffLimit
value: 5
- it: chart render fails when webhookReady.image.repository is empty
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
image:
repository: ""
tag: v1.32
asserts:
- failedTemplate:
errorMessage: "webhookReady.image.repository must be set to the container image providing kubectl for the post-install readiness Job"
- it: chart render fails when webhookReady.image.tag is empty
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
image:
repository: docker.io/clastix/kubectl
tag: ""
asserts:
- failedTemplate:
errorMessage: "webhookReady.image.tag must be set for the post-install readiness Job"
- it: retry loop bounds default when blanked so a wiped override still produces a working Job
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
image:
repository: docker.io/clastix/kubectl
tag: v1.32
maxAttempts: null
sleepSeconds: null
asserts:
- documentIndex: 3
matchRegex:
path: spec.template.spec.containers[0].command[2]
pattern: "max_attempts=60"
- documentIndex: 3
matchRegex:
path: spec.template.spec.containers[0].command[2]
pattern: "sleep_seconds=2"
- it: Job pod runs non-root with seccomp RuntimeDefault for restricted-PSA clusters
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 3
equal:
path: spec.template.spec.securityContext.runAsNonRoot
value: true
- documentIndex: 3
equal:
path: spec.template.spec.securityContext.seccompProfile.type
value: RuntimeDefault
- it: wait container declares resource requests and limits for predictable scheduling
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].resources.requests.cpu
value: 10m
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].resources.requests.memory
value: 32Mi
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].resources.limits.cpu
value: 100m
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].resources.limits.memory
value: 64Mi
- it: Job container drops all capabilities and runs read-only rootfs
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation
value: false
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem
value: true
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].securityContext.capabilities.drop[0]
value: ALL
- it: imagePullPolicy is IfNotPresent when digest-pinned, Always when tag-only
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
image:
repository: docker.io/clastix/kubectl
tag: v1.32
digest: sha256:b9ef7d8dbe65bcc81a46c09b8dc7543103055021c4f43287bf59e92a8f4fe05c
asserts:
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].imagePullPolicy
value: IfNotPresent
- it: imagePullPolicy is Always when no digest is configured
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
image:
repository: docker.io/clastix/kubectl
tag: v1.32
digest: ""
asserts:
- documentIndex: 3
equal:
path: spec.template.spec.containers[0].imagePullPolicy
value: Always
- it: retry loop captures and surfaces the last kubectl error message on timeout
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 3
matchRegex:
path: spec.template.spec.containers[0].command[2]
pattern: 'last_err=\$\(kubectl get --raw'
- documentIndex: 3
matchRegex:
path: spec.template.spec.containers[0].command[2]
pattern: 'last error: \$\{last_err\}'
- it: retry loop error message stays in sync when maxAttempts is bumped
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
image:
repository: docker.io/clastix/kubectl
tag: v1.32
maxAttempts: 90
sleepSeconds: 3
asserts:
- documentIndex: 3
matchRegex:
path: spec.template.spec.containers[0].command[2]
pattern: "max_attempts=90"
- documentIndex: 3
matchRegex:
path: spec.template.spec.containers[0].command[2]
pattern: "sleep_seconds=3"
- documentIndex: 3
matchRegex:
path: spec.template.spec.containers[0].command[2]
pattern: 'after \$\{max_attempts\} attempts'
- it: activeDeadlineSeconds scales with retry bounds so an override raise does not silently cut
template: templates/webhook-ready-hook.yaml
set:
webhookReady:
image:
repository: docker.io/clastix/kubectl
tag: v1.32
maxAttempts: 180
sleepSeconds: 3
asserts:
- documentIndex: 3
equal:
path: spec.activeDeadlineSeconds
value: 600
- it: activeDeadlineSeconds defaults include 60s slack over the default retry window
template: templates/webhook-ready-hook.yaml
asserts:
- documentIndex: 3
equal:
path: spec.activeDeadlineSeconds
value: 180