mirror of
https://github.com/cozystack/cozystack.git
synced 2026-11-05 19:47:37 +09:00
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>
329 lines
10 KiB
YAML
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
|