{{- $replicas := include "valkey.replicas" (dict "scaleDown" .Values.scaleDown "replicas" .Values.valkey.replicas) -}}
{{- $limitBytes := include "valkey.memoryLimitBytes" .Values.valkey.resources -}}
{{- $maxmemory := include "valkey.maxmemoryBytes" (dict "resources" .Values.valkey.resources "maxmemory" .Values.valkey.maxmemory "maxmemoryFactor" .Values.valkey.maxmemoryFactor) -}}
Valkey {{ .Chart.AppVersion }} — release {{ .Release.Name }} in namespace {{ .Release.Namespace }}.

ACCESS — IN-CLUSTER ONLY
  {{ .Release.Name }}-{{ .Chart.Name }}-service.{{ .Release.Namespace }}.svc.cluster.local:6379

  There is no Ingress and no value to add one: this is one application's cache
  or queue backend, and its only authentication is the password. Applications
  address it with a redis:// URL (Valkey speaks the same protocol, and every
  client library still calls the scheme redis://):

    redis://:<password>@{{ .Release.Name }}-{{ .Chart.Name }}-service.{{ .Release.Namespace }}.svc.cluster.local:6379/0

  The password belongs in the CONSUMING application's own vault item, where its
  connection URL lives. Nothing here writes it there.

  Check by hand from inside the namespace, with the password out of the pod's own
  mounted file so it never reaches your shell history:

    kubectl -n {{ .Release.Namespace }} exec {{ .Release.Name }}-{{ .Chart.Name }}-sfs-0 -- /bin/sh /etc/valkey/ping.sh && echo OK

THE 1PASSWORD ITEM MUST CARRY ONE FIELD, AND ITS NAME IS PART OF THE CHART
  secrets.authSecretRef points at
    {{ .Values.secrets.authSecretRef }}
  The 1Password operator materializes that item as the Kubernetes Secret
  {{ .Release.Name }}-{{ .Chart.Name }}-secret, with one Secret key per field of the item. This chart
  reads exactly one field:

    auth-conf        a COMPLETE Valkey configuration line, not the bare
                     password:

                         requirepass <the password>

  A differently named field produces no such key, and the pod then stays in
  ContainerCreating with "couldn't find key auth-conf" in its events.

  Why a whole configuration line instead of the password: the file is mounted and
  "include"d by the configuration, so the password never appears in the process
  list, in an environment variable, or in anything Helm renders. The cost is that
  a typo in that line would be a Valkey WITHOUT a password — running, healthy,
  and reachable from the whole pod network, because the official image compiles
  protected-mode off. An init container therefore checks the mounted file for a
  "requirepass " line before the server starts and refuses to let the pod run
  otherwise. If the pod is stuck in Init:Error or Init:CrashLoopBackOff, read it:

    kubectl -n {{ .Release.Namespace }} logs {{ .Release.Name }}-{{ .Chart.Name }}-sfs-0 -c {{ .Release.Name }}-{{ .Chart.Name }}-check-auth

  It never prints the field's contents.

  Watch the materialization with

    kubectl -n {{ .Release.Namespace }} get onepassworditem {{ .Release.Name }}-{{ .Chart.Name }}-secret
    kubectl -n {{ .Release.Namespace }} get secret {{ .Release.Name }}-{{ .Chart.Name }}-secret

THIS RELEASE IS CONFIGURED AS A {{ if .Values.persistence.enabled }}{{ if eq .Values.valkey.maxmemoryPolicy "noeviction" }}QUEUE{{ else }}PERSISTENT CACHE{{ end }}{{ else }}{{ if eq .Values.valkey.maxmemoryPolicy "noeviction" }}VOLATILE STORE — PROBABLY BY MISTAKE{{ else }}CACHE{{ end }}{{ end }}
  persistence.enabled:        {{ .Values.persistence.enabled }}
  valkey.maxmemoryPolicy:     {{ .Values.valkey.maxmemoryPolicy }}
  memory limit (computed):    {{ include "valkey.humanBytes" $limitBytes }} ({{ $limitBytes }} bytes)
  maxmemory:                  {{ include "valkey.humanBytes" $maxmemory }} ({{ $maxmemory }} bytes){{ if kindIs "invalid" .Values.valkey.maxmemory }}, derived as maxmemoryFactor {{ .Values.valkey.maxmemoryFactor | default 0.75 }} x the limit{{ else }}, set explicitly in values and checked against the limit{{ end }}
{{ if .Values.persistence.enabled }}
  {{- if eq .Values.valkey.maxmemoryPolicy "noeviction" }}
  The combination this chart is built for. When memory runs out Valkey REFUSES
  WRITES instead of discarding keys, so a full queue is an error in the
  application rather than jobs that quietly disappeared.
  {{- else }}
  Persistence with an evicting policy: the data survives a restart but not
  memory pressure. Fine for a cache that is expensive to rebuild — wrong for a
  Sidekiq or Celery queue, which would lose jobs while staying green.
  {{- end }}
{{- else }}
  {{- if eq .Values.valkey.maxmemoryPolicy "noeviction" }}
  READ THIS: no persistence AND noeviction is almost never intended. The data is
  gone on every pod restart, so nothing is being protected — but once memory is
  full, writes start FAILING instead of cold keys being dropped. For a cache set
  valkey.maxmemoryPolicy: allkeys-lru; for a queue set persistence.enabled: true.
  {{- else }}
  Cache shape: the dataset lives in the pod only. Both AOF and the RDB save
  points are switched off, so a restart starts from empty and nothing is written
  to ephemeral storage.
  {{- end }}
{{- end }}
{{- if .Values.persistence.enabled }}

STORAGE
  {{ .Release.Name }}-{{ .Chart.Name }}-pvc, {{ .Values.persistence.size }}, {{ if .Values.persistence.storageClass }}storage class "{{ .Values.persistence.storageClass }}"{{ else }}on the cluster's default storage class
  (persistence.storageClass is unset — the default class is not encrypted){{ end }}.
  Persistence mode: {{ if .Values.persistence.appendonly }}append-only file (every write appended; a crash loses at most
  the last fsync interval){{ else }}RDB snapshots only (a crash loses every write since the last
  snapshot, silently — the instance comes back healthy, only shorter){{ end }}.

  helm uninstall does NOT delete this PVC, which is deliberate — the data
  survives a reinstall of the same release name. It also means a release removed
  and recreated under a DIFFERENT name starts on an empty volume while the old
  one keeps occupying space. On encrypted Longhorn volumes that space is never
  returned to the pool.
{{- end }}
{{ if eq $replicas "0" }}
SCALED TO ZERO
  {{ if .Values.scaleDown }}scaleDown: true{{ else }}valkey.replicas: 0{{ end }} — the StatefulSet runs with replicas: 0, so nothing answers on
  the address above and every application configured against it will fail its own
  checks. Nothing else is removed: Service and Secret stay{{ if .Values.persistence.enabled }}, the PVC keeps
  the data{{ end }}{{ if .Values.networkPolicy.enabled }}, and the NetworkPolicy stays in force{{ end }}.
{{ end }}
CHANGING THE PASSWORD IS NOT COVERED BY A CHECKSUM
  The pod template carries checksum/config over the configuration ConfigMap and
  checksum/secret-ref over the rendered OnePasswordItem. So a changed
  maxmemory/policy rolls the pod, and so does repointing secrets.authSecretRef at
  a DIFFERENT vault item. What cannot be covered is a new password inside the
  same item: Helm never sees the content of a Secret the 1Password operator
  fills in. After changing it there:

    kubectl -n {{ .Release.Namespace }} rollout restart statefulset {{ .Release.Name }}-{{ .Chart.Name }}-sfs

  (operator.1password.io/auto-restart is not set on purpose — the operator
  restarts Deployments only, so on a StatefulSet it would be a silent no-op.)

  Unverified, and named so rather than promised: because the probes read the
  password out of the same mounted file, the kubelet's refresh of that file
  (roughly a minute) should make the liveness probe fail against the still-old
  server and restart the container by itself. Do the rollout restart instead of
  waiting for it.
{{ if .Values.networkPolicy.enabled }}
NETWORK POLICY IS ACTIVE
  Ingress to port 6379 is allowed from namespace {{ .Release.Namespace }}{{ if .Values.networkPolicy.allowedNamespaces }} and from
  {{ join ", " .Values.networkPolicy.allowedNamespaces }}{{ end }}. Egress is unrestricted (this instance opens no
  outbound connection of its own).

  It is only a boundary where the CNI enforces NetworkPolicies. Where it does
  not, the object is accepted and nothing is filtered — so verify it instead of
  reading it off the manifest:

    kubectl -n <some-other-namespace> run t --rm -it --image=docker.io/valkey/valkey:{{ .Chart.AppVersion }} \
      -- valkey-cli -h {{ .Release.Name }}-{{ .Chart.Name }}-service.{{ .Release.Namespace }} ping

  That must hang or be refused. "NOAUTH Authentication required." means the
  policy is not being enforced and the password is your only boundary.
{{- else }}
NO NETWORK POLICY
  networkPolicy.enabled is false, so the password is the only thing between this
  instance and every pod in the cluster. The official image compiles
  protected-mode off, so there is no second line of defence behind it.
{{- end }}

WHAT A GREEN POD PROVES
  All three probes run "valkey-cli -e ping" AUTHENTICATED with the password from
  the mounted file and require the answer PONG. So Ready means: the server
  accepted a connection, accepted that password, and answered.

  Two things it does not mean. It does not say anything about the dataset — a
  restarted instance whose AOF was lost answers PONG on an empty database. And
  it does not say your application's keys are reachable: that depends on the
  connection URL in the application's own vault item, which this chart neither
  writes nor reads.

  The probe asserts the answer (PONG), not just that the command returned, and
  it passes "-e" so that valkey-cli reports an error reply through its exit code
  at all — without it a bare "valkey-cli ping" exits 0 while printing
  "NOAUTH Authentication required.", which would be a probe that cannot fail.
